module TextileParser
Constants
- BQ_LEFT
- RX_SPACE_CHARS
Ruby s does not match extra unicode space characters.
- RX_URL
- SYMS
Symbol table, in operator precedence order:
0. Symbol name. 1. Start string for optimized matching. 2. Complete match definition.
- SYM_TO_INDEX
- SYM_TO_REGEX
Public Instance Methods
find_syms(text)
click to toggle source
# File lib/textile/parser.rb, line 13 def find_syms(text) # Find possible symbol matches syms = SYM_TO_INDEX.map { |sym, index| [sym, text.index(index)] } .reject { |sym, index| index.nil? } # Sort by starting position - closer is better syms = syms.sort_by{ |x| x[1] } # Get associated regexps and find first matchdata = nil match = syms.map { |sym, index| [sym, SYM_TO_REGEX[sym]] } .detect { |sym, re| matchdata = re.match(text) } # [sym, matchdata] [match[0], matchdata] if match end
operand(ary, text)
click to toggle source
# File lib/textile/parser.rb, line 30 def operand(ary, text) sym, md = find_syms(text) if sym.nil? || md.nil? # No match, consume entire string. return ary << TextNode.new(text.slice!(0 .. text.length)) end # Consume string before match. if md.pre_match.size > 0 ary << TextNode.new(text.slice!(0 ... md.pre_match.size)) end # Act on match. # FIXME: Separate logic for string consumption: case sym when :raw_bracket balanced = balance_markup(text, md.to_s, '[==', '==]').match(SYM_TO_REGEX[:raw_bracket])[1] ary << RawTextNode.new(balanced) when :bq_author balanced = balance_markup(text, md.to_s, BQ_LEFT, '[/bq]').match(SYM_TO_REGEX[:bq_author])[2] ary << HTMLNode.new(:blockquote, parse(balanced), title: $1) when :bq balanced = balance_markup(text, md.to_s, BQ_LEFT, '[/bq]').match(SYM_TO_REGEX[:bq])[1] ary << HTMLNode.new(:blockquote, parse(balanced)) when :spoiler balanced = balance_markup(text, md.to_s, '[spoiler]', '[/spoiler]').match(SYM_TO_REGEX[:spoiler])[1] ary << HTMLNode.new(:span, parse(balanced), class: 'spoiler') else text.slice!(0 .. md.to_s.size) end case sym when :raw ary << RawTextNode.new(md[1]) when :link_title_bracket, :link_title ary << HTMLNode.new(:a, parse(md[1]), title: md[2], href: md[3]) when :link_bracket, :link ary << HTMLNode.new(:a, parse(md[1]), href: md[2]) when :image_link_title_bracket, :image_link_title ary << HTMLNode.new(:a, ImageNode.new(md[1]), title: md[2], href: md[3]) when :image_link_bracket, :image_link ary << HTMLNode.new(:a, ImageNode.new(md[1]), href: md[2]) when :image_title_bracket, :image_title ary << HTMLNode.new(:span, ImageNode.new(md[1]), title: md[2]) when :image_bracket, :image ary << ImageNode.new(md[1]) when :dblbold_bracket, :dblbold ary << HTMLNode.new(:b, parse(md[1])) when :bold_bracket, :bold ary << HTMLNode.new(:strong, parse(md[1])) when :dblitalic_bracket, :dblitalic ary << HTMLNode.new(:i, parse(md[1])) when :italic_bracket, :italic ary << HTMLNode.new(:em, parse(md[1])) when :code_bracket, :code ary << HTMLNode.new(:code, parse(md[1])) when :ins_bracket, :ins ary << HTMLNode.new(:ins, parse(md[1])) when :sup_bracket, :sup ary << HTMLNode.new(:sup, parse(md[1])) when :del_bracket, :del ary << HTMLNode.new(:del, parse(md[1])) when :sub_bracket, :sub ary << HTMLNode.new(:sub, parse(md[1])) when :cite_bracket, :cite ary << HTMLNode.new(:cite, parse(md[1])) end end
parse(text)
click to toggle source
# File lib/textile/parser.rb, line 7 def parse(text) ary = [] operand(ary, text) until text.empty? MultiNode.new(ary) end
Private Instance Methods
balance_markup(text, matched, left, right)
click to toggle source
Find the longest substring that contains balanced markup, or the whole string if this is impossible.
# File lib/textile/parser.rb, line 103 def balance_markup(text, matched, left, right) both = Regexp.union(left, right) left = Regexp.union(left) right = Regexp.union(right) s = StringScanner.new(matched) n, lowest_pos = 0, 0 i = loop do match = s.scan(both) case when match =~ left n += 1 when match =~ right n -= 1 lowest_pos = s.pos else m = s.scan_until(both) s.pos = s.pos - s.matched.size if m s.terminate if m.nil? end break lowest_pos.pred if n.zero? || s.eos? end text.slice!(0 .. i) matched[0 .. i] end