class TracWiki::Parser

Constants

MACRO_BEG_INSIDE_REX
MACRO_BEG_REX

macro {{$var}} | {{#comment}} | {{!cmd}} | {{template}} | {{/template}} string begins with macro

MACRO_END_REX

find end of marcro or begin of inner macro

Attributes

allow_html[W]

allow some <b> <form> <html> html will be sanitized

allowed_schemes[RW]

Allowed url schemes Examples: http https ftp ftps

at_callback[RW]

Proc or nil at_callback.call(env, key) -> computed value

base[W]

url base for links

base_url[RW]
div_around_table[W]

Enable <div> around <table>

edit_heading[W]

add '<a class='editheading' href=“?edit=N>edit</a>' to each heading

env[RW]
headings[RW]

structure where headings are stroed list of hasheses with `level` and `title`, `sline` [ { leven: 1, # <h1>

  sline: 3, # line where head starts
  eline: 4, # line before next heading starts
  aname: 'anchor-to-this-heading',
  title: 'heading title'
},
...

]

id_from_heading[W]

every heading had id, generated from heading text

id_translit[W]

when id_from_heading, non ascii char are transliterated to ascii

macro_commands[RW]

like template but more powerfull do no use.

macros[W]

use macros? defalut yes

math[W]

math syntax extension: $e^x$ for inline math $$ e^x $$ for display math

merge[W]

understand merge tags (see diff3(1)) >>>>>>> mine ||||||| orig

<<<<<<< yours convert to <div class=“merge merge-mine”>mine</div>

no_escape[W]

Disable url escaping for local links Escaping: [[/Test]] –> %2FTest No escaping: [[/Test]] –> Test

root[W]

url base for /links

template_handler[RW]

template_handler(macroname) -> template_text when macros enabled and {{myCoolMacro}} ocured, result fo `template_handler('myCoolMacro') inserted

used_templates[R]

Public Class Methods

new(options = {}) click to toggle source

Create a new Parser instance.

# File lib/trac-wiki/parser.rb, line 147
def initialize(options = {})
  init_macros
  @at_callback = nil
  @env = Env.new(self)
  @macros = true
  @allowed_schemes = %w(http https ftp ftps)
  macro_commands = options.delete :macro_commands
  @macro_commands.merge! macro_commands if ! macro_commands.nil?
  @no_escape = nil
  @base = ''
  @root = ''
  options.each_pair {|k,v| send("#{k}=", v) }
  @base += '/' if !@base.empty? && @base[-1] != '/'
  @root += '/' if @root.empty? || @root[-1] != '/'
end

Protected Class Methods

escapeHTML(string) click to toggle source
# File lib/trac-wiki/parser.rb, line 332
def self.escapeHTML(string)
  string.gsub(/&/, '&amp;').gsub(/\"/, '&quot;').gsub(/>/, '&gt;').gsub(/</, '&lt;')
end

Public Instance Methods

add_macro_command(name, &block) click to toggle source
# File lib/trac-wiki/parser.rb, line 196
def add_macro_command(name, &block)
    @macro_commands[name] = block
end
allow_html?() click to toggle source
# File lib/trac-wiki/parser.rb, line 97
def allow_html?; @allow_html; end
div_around_table?() click to toggle source
# File lib/trac-wiki/parser.rb, line 86
def div_around_table?; @div_around_table; end
edit_heading?() click to toggle source
# File lib/trac-wiki/parser.rb, line 102
def edit_heading?; @edit_heading; end
id_from_heading?() click to toggle source
# File lib/trac-wiki/parser.rb, line 115
def id_from_heading?; @id_from_heading; end
id_translit?() click to toggle source
# File lib/trac-wiki/parser.rb, line 123
def id_translit?; @id_translit; end
macros?() click to toggle source
# File lib/trac-wiki/parser.rb, line 119
def macros?; @macros; end
make_toc_html() click to toggle source
# File lib/trac-wiki/parser.rb, line 190
def make_toc_html
  @tree = TracWiki::Tree.new
  parse_block(make_toc)
  @tree.to_html
end
math?() click to toggle source
# File lib/trac-wiki/parser.rb, line 92
def math?; @math; end
merge?() click to toggle source
# File lib/trac-wiki/parser.rb, line 111
def merge?; @merge; end
no_escape?() click to toggle source
# File lib/trac-wiki/parser.rb, line 77
def no_escape?; @no_escape; end
text(text) click to toggle source
# File lib/trac-wiki/parser.rb, line 163
def text(text)
  @text = text
  return self
end
to_html(text = nil, base_url = '') click to toggle source
# File lib/trac-wiki/parser.rb, line 170
def to_html(text = nil, base_url = '')
  text(text) if ! text.nil?
  @base_url = base_url
  @used_templates = {}
  @was_math = false
  @anames = {}
  @count_lines_level = 0
  @text = text if !text.nil?
  @tree = TracWiki::Tree.new
  @edit_heading_class = 'editheading'
  @headings = [ {level: 0, sline: 1 } ]
  @p = false
  @stack = []
  @stacki = []
  @was_math = false
  @line_no = 1
  parse_block(@text)
  @tree.to_html
end
was_math?() click to toggle source
# File lib/trac-wiki/parser.rb, line 168
def was_math?; @was_math; end

Protected Instance Methods

_parse_attrs_to_hash(str) click to toggle source
# File lib/trac-wiki/parser.rb, line 818
def _parse_attrs_to_hash(str)
  ret = {}
  @env.atput('lineno', @line_no);
  while str =~ /\A\s*([-\w]+)\s*=\s*'([^>']*)'/ ||
        str =~ /\A\s*([-\w]+)\s*=\s*"([^>"]*)"/ ||
        str =~ /\A\s*([-\w]+)\s*=\s*(\S*)/
    ret[$1] = @env.expand($2)
    str = $'
  end
  ret
end
_translit(text) click to toggle source
# File lib/trac-wiki/parser.rb, line 967
def _translit(text)
   # iconv is obsolete, but translit funcionality was not replaced
   # see http://stackoverflow.com/questions/20224915/iconv-will-be-deprecated-in-the-future-transliterate
   # return Iconv.iconv('ascii//translit', 'utf-8', text).join

   # http://unicode-utils.rubyforge.org/UnicodeUtils.html#method-c-compatibility_decomposition
   return UnicodeUtils.compatibility_decomposition(text).chars.grep(/\p{^Mn}/).join('')
end
add_line_no(count) click to toggle source
# File lib/trac-wiki/parser.rb, line 202
def add_line_no(count)
  @line_no += count if @count_lines_level == 0
end
aname_nice(aname, title) click to toggle source
# File lib/trac-wiki/parser.rb, line 951
def aname_nice(aname, title)

  if aname.nil? && id_from_heading?
    aname = title.gsub /\s+/, '_'
    aname = _translit(aname) if id_translit?
  end
  return nil if aname.nil?
  aname_ori = aname
  count = 2
  while @anames[aname]
    aname = aname_ori + ".#{count}"
    count+=1
  end
  @anames[aname] = true
  aname
end
blockquote_level_to(level) click to toggle source
# File lib/trac-wiki/parser.rb, line 739
def blockquote_level_to(level)
  cur_level = @stack.count('blockquote')
  if cur_level ==  level
    @tree.add(' ')
    return
  end
  while cur_level < level
    cur_level += 1
    start_tag('blockquote')
  end
  while cur_level > level
    cur_level -= 1 if @stack.last == 'blockquote'
    end_tag
  end
end
do_citation(level) click to toggle source
# File lib/trac-wiki/parser.rb, line 858
def do_citation(level)
  start_paragraph if !@stack.include? 'p'
  blockquote_level_to(level)
end
do_heading(level, title, aname, title_offset) click to toggle source
# File lib/trac-wiki/parser.rb, line 835
def do_heading(level, title, aname, title_offset)
  aname= aname_nice(aname, title)
  @headings.last[:eline] = @line_no - 1
  @headings.push({ :title =>  title, :sline => @line_no, :aname => aname, :level => level, })
  end_paragraph
  make_headline(level, title, aname, title_offset)
end
do_hr() click to toggle source
# File lib/trac-wiki/parser.rb, line 830
def do_hr
  end_paragraph
  @tree.tag(:hr)
end
do_math(text) click to toggle source
# File lib/trac-wiki/parser.rb, line 755
def do_math(text)
  end_paragraph
  #@tree.add("$$#{text}$$\n")
  @tree.tag(:div, {class:'math'}, text)
  @was_math = true
end
do_merge(merge_type, who) click to toggle source
# File lib/trac-wiki/parser.rb, line 761
def do_merge(merge_type, who)
  merge_class = case merge_type[0]
                  when '<' ; 'merge-mine'
                  when '=' ; 'merge-split'
                  when '|' ; 'merge-orig'
                  when '>' ; 'merge-your'
                end
  end_paragraph
  @tree.tag(:div, { class: "merge #{merge_class}" }, who)
end
do_ord_line(spc_size) click to toggle source
# File lib/trac-wiki/parser.rb, line 863
def do_ord_line(spc_size)

  if @stack.include?('li') || @stack.include?('dl')

    # dl, li continuation
    parse_inline(' ', 0)

  elsif spc_size > 0
    # quote continuation
    start_paragraph if !@stack.include? 'p'
    blockquote_level_to(1)

  else
    # real ordinary line
    start_paragraph
  end
end
do_pre(text) click to toggle source
# File lib/trac-wiki/parser.rb, line 795
def do_pre(text)
  end_paragraph
  nowikiblock = make_nowikiblock(text)
  @tree.tag(:pre, nowikiblock)
end
do_raw_tag(eot, tag, attrs, closed, tail_size) click to toggle source
# File lib/trac-wiki/parser.rb, line 801
def do_raw_tag(eot, tag, attrs, closed, tail_size)
  if !eot
    end_paragraph if tag == 'p' || tag == 'div'
    #print "open tag #{tag},'#{attrs}'\n"
    attrs_h = _parse_attrs_to_hash(attrs)
    @tree.tag_beg(tag, attrs_h)
    @tree.tag_end(tag) if closed
  else
    #print "close tag #{tag}\n"
    @tree.tag_end(tag)
    if tag == 'p' || tag == 'div'
      end_paragraph
      start_paragraph if tail_size > 0
    end
  end
end
do_table_row(text) click to toggle source
# File lib/trac-wiki/parser.rb, line 842
def do_table_row(text)
  if !@stack.include?('table')
    end_paragraph
    start_tag('div', class: 'table-div') if div_around_table?
    start_tag('table')
  end
  parse_table_row(text)
end
do_term(term) click to toggle source
# File lib/trac-wiki/parser.rb, line 850
def do_term(term)
  start_tag('dl')
  start_tag('dt')
  @tree.add(term)
  end_tag
  start_tag('dd')
end
do_wikimedia_table(text) click to toggle source
# File lib/trac-wiki/parser.rb, line 772
def do_wikimedia_table(text)
  end_paragraph
  start_tag('div', class: 'table-div') if div_around_table?
  start_tag(:table)
  start_tag(:tr)
  offset = 0
  text.split("\n").each do |line|
    offset += line.length + 1
    if line == '|-'
      end_to_tag :tr
      start_tag(:tr)
    elsif line =~ /^([!\|])(.*)/
      end_to_tag :td
      fst, rest = $1, $2
      start_tag($1 == '|'  ? :td : :th)
      parse_inline(rest.strip, offset)
    else
      parse_inline(' ' +line.strip, offset)
    end
  end
  end_to_tag :table
end
end_paragraph() click to toggle source
# File lib/trac-wiki/parser.rb, line 386
def end_paragraph
  end_tag while !@stack.empty?
  @p = false
end
end_tag() click to toggle source
# File lib/trac-wiki/parser.rb, line 355
def end_tag
  tag = @stack.pop
  tagi = @stacki.pop
  if tag == 'strongem'
    @tree.tag_end(:em).tag_end(:strong);
  elsif tag == 'p'
    @tree.tag_end(:p)
  else
    @tree.tag_end(tag)
  end
end
end_to_tag(tag) click to toggle source
# File lib/trac-wiki/parser.rb, line 379
def end_to_tag(tag)
  if @stack.include?(tag)
    end_tag while @stack.last != tag
    end_tag
  end
end
escape_html(string) click to toggle source

Escape any characters with special meaning in HTML using HTML entities. (&<>“ not ')

# File lib/trac-wiki/parser.rb, line 328
def escape_html(string)
  string.nil? ? '' : Parser.escapeHTML(string)
end
escape_url(string) click to toggle source

Escape any characters with special meaning in URLs using URL encoding.

# File lib/trac-wiki/parser.rb, line 338
def escape_url(string)
  CGI::escape(string)
end
init_macros() click to toggle source
# File lib/trac-wiki/parser.rb, line 206
def init_macros
  @macro_commands = {
    '!ifeq'  => proc { |env| what = env.expand_arg(0)
                             count = env.arg_count
                             i = 1
                             ret = ''
                             while count > i
                                 argi = env.expand_arg(i)
                                 # this is else:
                                 if count <= i + 1
                                   ret = argi
                                   break
                                 end

                                 # we found it
                                 if what == argi
                                   ret = env.expand_arg(i+1)
                                   break
                                 end

                                 # next
                                 i +=2
                             end
                             ret.sub /\n\s+\Z/, ''
                     },
    '!ifdef' => proc { |env| env.at(env.expand_arg(0), nil, false).nil? ? env.expand_arg(2) : env.expand_arg(1) },
    '!set'   => proc { |env| env[env.expand_arg(0)] = env.expand_arg(1); '' },
    '!append'=> proc { |env| key = env.expand_arg(0)
                             sep = env.expand_arg(2,'')
                             env[key] = (env[key].nil? ? '' : env[key] + sep ) + env.expand_arg(1);
                             ''
                     },
    '!yset'  => proc { |env| env[env.expand_arg(0)] = YAML.load(env.arg(1)); '' },
    '!sub'   => proc { |env| pat = env.expand_arg(1)
                             pat = Regexp.new(pat[1..-2]) if pat =~ /\A\/.*\/\Z/
                             env.expand_arg(0).gsub(pat, env.expand_arg(2))
                     },
    '!macpos'=> proc { |env| "#{env.at('lineno')}.#{env.at('offset')}-#{env.at('elineno')}.#{env.at('eoffset')}"  },
    # in macro {{arg {{$i}}} -> i=4 => ctyry
    '!arg'   => proc { |env|
         #print "arg: #{env.arg(0)}, #{env} }"
         "#{env.at(env.expand(env.arg(0)))}"
         },

    # {{!forargs i|3|i:{$$i}}}} -> 0,1,2
    # {{!forargs i||i:{$$i}}}} -> 0,1,2
    '!sprintf'   => proc { |env|
                           fmt = env.arg(0)
                           args = (1 .. env.arg_count ).map{ |i| env.expand_arg(i)}
                           begin
                             sprintf fmt, *args
                           rescue Exception => e
                             "(sprintf error:`#{e}`)"
                           end
                    },
    '!digest'    => proc { |env| Base64.urlsafe_encode64(Digest::SHA256.digest(env.expand_arg(0))) },
    '!base64'    => proc { |env| Base64.urlsafe_encode64(env.expand_arg(0)) },
    '!tt'        => proc { |env| "`#{env.expand_arg(0)}`" },
    '!forargs'   => proc { |env| i_name = env.arg(0)
                           i_name = env.arg(0)
                           start = env.arg(1).to_i # side efect '' => 0
                           start = 1 if start < 1
                           template = env.arg(2)
                           argcount =
                           (start .. env.arg_count ).map do |i|
                             env.atput(i_name, i.to_s)
                             env.expand(template)
                           end.join('')
                     },
    # {{!for i|1,3|i:{$$i}}}} -> 0,1,2
    # {{!for i|1,3,data|i:{$$i}}}} -> data[1,2,3]
    # {{!for i|data|i:{$$i}}}} -> vsechny data
    # {{!for i|1|i:{$$i}}}} -> vsechny data
    '!for'   => proc { |env| i_name = env.arg(0)

                           raise "!for takes exactly 3 argumentsif not #{env.arg_count}" if env.arg_count != 3

                           i_name = env.arg(0)
                           range =  env.expand_arg(1)
                           templ =  env.arg(2)

                           arange = range.split(/,/)
                           arange = [ nil, nil, arange[0]] if arange.size == 1

                           bot = arange[0]
                           top = arange[1]
                           var = arange[2]

                           if var.nil?
                             set = (bot.to_i||1 .. top.to_i)
                           else
                             obj = env.at(var, nil, false)

                             if obj.is_a?(Hash)
                               set = obj.keys.sort
                             elsif obj.is_a?(Array)
                               #print "ble:#{bot} #{bot}, #{obj.size}\n"
                               set = (bot||0 .. obj.size-1)
                             elsif obj.nil?
                               set = []
                             else
                               raise "Error: wrong arg #{obj} class='#{obj.class}'"
                             end
                           end
                           #set.select! { |x| x >= bot } if bot
                           #set.select! { |x| x <= top } if top

                           #print "for set#{set} tmpl#{templ||"nic"}\n"

                           set.map do |i|
                             #print "for#{i} #{templ}\n"
                             env[i_name] = i.to_s
                             env.atput(i_name, i.to_s)
                             env.expand(templ)
                           end.join('')
                   },
  }

end
make_headline(level, title, aname, title_offset) click to toggle source
# File lib/trac-wiki/parser.rb, line 479
def make_headline(level, title, aname, title_offset)

  hN = "h#{level}".to_sym

  @tree.tag_beg(hN, { id: aname } )
  parse_inline(title, title_offset)
  if edit_heading?
    edit_heading_link(@headings.size - 1)
  end
  @tree.tag_end(hN)
end
make_image(uri, attrs='') click to toggle source

Create image markup. This method can be overridden to generate custom markup, for example to add html additional attributes or to put divs around the imgs.

# File lib/trac-wiki/parser.rb, line 443
def make_image(uri, attrs='')
  attrs =  make_image_attrs(uri, attrs)
  link = attrs.delete('link')

  @tree.tag_beg(:a, {href: make_explicit_link(link)}) if link
  @tree.tag(:img, attrs)
  @tree.tag_end(:a) if link
end
make_image_attrs(uri, attrs) click to toggle source
# File lib/trac-wiki/parser.rb, line 452
def make_image_attrs(uri, attrs)
   a = {src: make_explicit_link(uri)}
   style = []
   attrs ||= ''
   attrs.strip.split(/\s*,\s*/).each do |opt|
     case opt
       when /^\d+[^\d]*$/
         a['width'] = opt
       when /^(right|left|center)/i
         a['align'] = opt
       when  /^(top|bottom|middle)$/i
         a['valign'] = opt
       when  /^link=(.*)$/i
         a['link'] = $1
       when  /^nolink$/i
         # pass
       when /^(align|valign|border|width|height|alt|title|longdesc|class|id|usemap)=(.*)$/i
        a[$1]= $2
       when /^(margin|margin-(left|right|top|bottom))=(\d+)$/
        style.push($1 + ':' + $3)
     end
   end
   a[:style] = style.join(';') if ! style.empty?
   return {}  if a.empty?
   return a;
end
make_nowikiblock(input) click to toggle source
# File lib/trac-wiki/parser.rb, line 692
def make_nowikiblock(input)
  input.gsub(/^ (?=\}\}\})/, '')
end
make_toc() click to toggle source
# File lib/trac-wiki/parser.rb, line 505
def make_toc
    @headings.map do |h|
       if h[:level] < 1
         ''
       else
         ind = "  " * (h[:level] - 1)
         "#{ind}* [[##{h[:aname]}|#{h[:title]}]]\n"
       end
    end.join
end
parse_block(str, want_end_paragraph = true) click to toggle source
# File lib/trac-wiki/parser.rb, line 881
def parse_block(str, want_end_paragraph = true)
  #print "BLOCK.str(#{str})\n"
  until str.empty?
    case
    # macro
    when macros? && str =~ MACRO_BEG_REX
      mac, str, lines, offset = parse_macro($1, $', 0, $&.size)
      raise 'lines is nil' if lines.nil?
      raise 'offset is nil' if offset.nil?
      #print "MACRO.lines(#{$1})lines:#{lines}, str:'#{str}'\n"
      add_line_no(lines)
      @count_lines_level +=1
      parse_block(mac, false)
      @count_lines_level -=1
      if mac.size > 0 && str =~ /^(.*)(\r?\n)?/
        line, str = $1 , $'
        add_line_no($&.count("\n"))
        parse_inline(line, offset)
      end
      next
    # display math $$
    when math? && str =~ /\A\$\$(.*?)\$\$/m
      do_math($1)
    # merge
    when merge? && str =~ /\A(<{7}|={7}|>{7}|\|{7}) *(\S*).*$(\r?\n)?/
      do_merge($1, $2)
    # pre {{{ ... }}}
    when str =~ /\A\{\{\{\r?\n(.*?)\r?\n\}\}\}/m
      do_pre($1)
    # wikimedia table {| ... |}
    when str =~ /\A\{\|\r?\n(.*?)\r?\n\|\}/m
      do_wikimedia_table($1)
    # horizontal rule
    when str =~ /\A\s*-{4,}\s*$/
      do_hr()
    # heading == Wiki Ruless ==
    # heading == Wiki Ruless ==  #tag
    when str =~ /\A([[:blank:]]*(={1,6})\s*)(.*?)\s*=*\s*(#(\S*))?\s*$(\r?\n)?/
      do_heading($2.size, $3, $5, $1.size)
    # table row ||
    when str =~ /\A[ \t]*\|\|(.*)$(\r?\n)?/
      do_table_row($1)
    # empty line
    when str =~ /\A\s*$(\r?\n)?/
      end_paragraph
    #when str =~ /\A([:\w\s]+)::(\s+|\r?\n)/
    when str =~ /\A(.+)::(\s+|\r?\n)/
      do_term($1)
    # li *
    when str =~ /\A((\s*)([*-]|[aAIi\d]\.)\s+)(.*?)$(\r?\n)?/
      parse_li_line($2.size, $3)
      parse_inline($4, $1.size)
    # citation >
    when str =~ /\A(>[>\s]*)(.*?)$(\r?\n)?/
      do_citation($1.count('>'))
      parse_inline($2, $1.size)
    # ordinary line
    when str =~ /\A(\s*)(\S+.*?)$(\r?\n)?/
      text = $2
      do_ord_line($1.size)
      parse_inline(text.rstrip, $1.size)
    else # case str
      raise "Parse error at #{str[0,30].inspect}"
    end
    add_line_no(($`).count("\n")+($&).count("\n"))
    str = $'
  end
  end_paragraph if want_end_paragraph
  @headings.last[:eline] = @line_no - 1
end
parse_inline(str, offset) click to toggle source
# File lib/trac-wiki/parser.rb, line 516
    def parse_inline(str, offset)
      raise "offset is nil" if offset.nil?
      until str.empty?
        case
        # raw url http://example.com/
        when str =~ /\A(!)?((https?|ftps?):\/\/\S+?)(?=([\]\,.?!:;"'\)]+)?(\s|$))/
          notlink, link = $1, $2
          make_link(link, nil, link, 0, !!notlink)
        # [[Image(pic.jpg|tag)]]
        when str =~ /\A\[\[Image\(([^,]*?)(,(.*?))?\)\]\]/   # image
          make_image($1, $3)
        # [[link]]
        #          [     link2          | text5          ]
        when str =~ /\A (\[ \s* ([^\[|]*?) \s*) ((\|\s*)(.*?))? \s* \] /mx
          link, content, content_offset, whole  = $2, $5, $1.size + ($4||'').size, $&
          make_link(link, content, "[#{whole}]",offset + content_offset)
        #          [[     link2          | text5          ]]
        when  str =~ /\A (\[\[ \s* ([^|]*?) \s*) ((\|\s*)(.*?))? \s* \]\] /mx
          link, content, content_offset, whole= $2, $5, $1.size + ($4||'').size, $&
          #print "link: #{content_offset} of:#{offset}, '#{$1}', '#{$4||''}'\n"
          make_link(link, content, whole, offset + content_offset)
        when allow_html? && str =~ /\A<(\/)?(\w+)(?:([^>]*?))?(\/\s*)?>/     # single inline <html> tag
          eot, tag, args, closed = $1, $2, $3, $4
          do_raw_tag(eot, tag, args, closed, $'.size)
        when str =~ /\A\{\{\{(.*?\}*)\}\}\}/     # inline {{{ }}} pre (tt)
          @tree.tag(:tt, $1)
        when macros? && str =~ MACRO_BEG_REX                # macro  {{
          mac, str, lines, offset = parse_macro($1, $', offset, $&.size)
          parse_inline(mac.gsub(/\n/,  ' '),0);
          #print "MACRO.inline(#{$1}), next:#{str}"
          #return str, offset
          next
        when str =~ /\A`(.*?)`/                  # inline pre (tt)
          @tree.tag(:tt, $1)
        when math? && str =~ /\A\$(.+?)\$/       # inline math  (tt)
          @tree.tag(:span, {:class => 'math'},  $1)
          @was_math = true
        when str =~ /\A(\&\w*;)/       # html entity
          #print "add html ent: #{$1}\n"
          @tree.add_raw($1)
        when str =~ /\A([:alpha:]|[:digit:])+/
          @tree.add($&)                      # word
        when str =~ /\A\s+/
          @tree.add_spc
        when str =~ /\A'''''/
          toggle_tag 'strongem', $&       # bolditallic
        when str =~ /\A\*\*/ || str =~ /\A'''/
          toggle_tag 'strong', $&         # bold
        when str =~ /\A''/ || str =~ /\A\/\//
          toggle_tag 'em', $&             # italic
        when str =~ /\A\\\\/ || str =~ /\A\[\[br\]\]/i
          @tree.tag(:br)                  # newline
        when str =~ /\A__/
          toggle_tag 'u', $&              # underline
        when str =~ /\A~~/
          toggle_tag 'del', $&            # delete
        when str =~ /\A~/
          @tree.add_raw('&nbsp;')         # tilde
#       when /\A\+\+/
#         toggle_tag 'ins', $&           # insert
        when str =~ /\A\^/
          toggle_tag 'sup', $&            # ^{}
        when str =~ /\A,,/
          toggle_tag 'sub', $&            # _{}
        when str =~ /\A!\./
          @tree.add('')                   # !. \relax
        when str =~ /\A!(\{\{|[\S])/
          @tree.add($1)                   # !neco !{{
#        when str =~ /\A!(\{\{)/
#          @tree.add($1)                   # !neco !{
        when str =~ /\A./
          @tree.add($&)                   # ordinal char
        end
        str = $'
        offset += $&.size
      end
      return offset
    end
parse_li_line(spc_size, bullet) click to toggle source
# File lib/trac-wiki/parser.rb, line 696
def parse_li_line(spc_size, bullet)

  while !@stacki.empty? && @stacki.last >  spc_size
    end_tag
  end

  if @stack.include?('li')
    while @stack.last != 'li'
      end_tag
    end

    # end list if type differ
    # @stack.last is now ul or li
    if @stacki.last == spc_size
      end_tag # li
      ulol_last = @stack.last
      ulol_now =  bullet =~ /[*-]/ ? 'ul' : 'ol'
      if ulol_last != ulol_now
        end_tag # ol | ul
      end
    end
  else
    end_paragraph
  end

  if @stacki.empty? || @stacki.last <  spc_size
    bullet.gsub!(/\.$/,'')
    ulol = bullet =~ /[-*]/ ? 'ul' : 'ol';

    type = nil
    type = 'i' if bullet =~ /i/i;
    type = 'a' if bullet =~ /a/i;

    start = nil
    start = bullet if bullet =~ /^\d+$/ && bullet != '1'

    start_tag(ulol, {type: type, start: start}, spc_size)
  end

  start_tag('li')

end
parse_macro(macro_name, str, offset, macro_name_size) click to toggle source

r: expanded macro , rest of str, count lines taken from str sideefect: parse result of macro

# File lib/trac-wiki/parser.rb, line 601
def parse_macro(macro_name, str, offset, macro_name_size)
  raise "offset is nil" if offset.nil?
  raise "offset is nil" if macro_name_size.nil?
  @env.atput('offset',  offset)
  @env.atput('lineno',  @line_no)
  begin
    mac_out, rest, lines, rest_offset = @env.parse_macro_all(macro_name, str, macro_name_size)
    raise "lines is nil" if lines.nil?
    #print "mac: '#{mac_out}' rest: '#{rest}'\n"
    #print  "mac: ro #{rest_offset}, of#{offset}, lines: #{lines} ms: #{macro_name_size} strlen#{str.size}, str'#{str}' rest:'#{rest}'\n"
    rest_offset += offset + macro_name_size if lines == 0
    #print "ro#{rest_offset}\n"
    return mac_out, rest, lines, rest_offset
  rescue  TooLongException => e
    return '', "TOO_LONG_EXPANSION_OF_MACRO(#{macro_name})QUIT", 0, 0
  rescue  Exception => e
    #@tree.tag(:span, {:title => "#{e}\", :class=>'parse-error'}, "!!!")
    @tree.tag(:span, {:title => "#{e}\n#{e.backtrace}", :class=>'parse-error'}, "!!!")
    print "tace#{e.backtrace.to_s}\n"
    return '', '', 0, 0
  end
end
parse_table_row(str) click to toggle source
# File lib/trac-wiki/parser.rb, line 648
def parse_table_row(str)
  offset = 0;
  start_tag('tr') if !@stack.include?('tr')
  str.sub!(/\r/, '')
  colspan = 1
  print_tr = true
  last_tail  = ''
  last_txt  = ''
  str.scan(/(=?)(\s*)(.*?)\1?($ | \|\|\\\s*$ | \|\| )/x) do
    tdth = $1.empty? ? 'td' : 'th'
    tdth_size = $1.size
    le, txt, tail, cell_size  = $2.size, $3, $4, $&.size

    # do not end row, continue on next line
    print_tr = false if tail =~ /^\|\|\\/

    if txt.empty? && le == 0
      colspan += 1
      next
    end

    style = nil
    if  txt =~ /\S(\s*)$/
          ri = $1.size
          ri += 100 if tail.empty? # do not right when last || omnited
          style = 'text-align:right'  if ri == 0 && le >= 1
          style = 'text-align:center' if le >= 2 && ri >= 2
          #print "le#{le} ri#{ri} st:#{style}\n"
    end

    colspan =  colspan > 1 ? colspan : nil;
    start_tag(tdth, { style:style, colspan: colspan});
    colspan = 1

    parse_inline(txt.strip, offset + tdth_size + le + 2) if txt
    end_tag while @stack.last != 'tr'
    offset += cell_size
  end
  if print_tr
    end_tag
  end
  return offset
end
start_paragraph(add_spc = true) click to toggle source
# File lib/trac-wiki/parser.rb, line 391
def start_paragraph(add_spc = true)
  if @p
    #FIXME: multiple space s
    @tree.add_spc if add_spc
  else
    end_paragraph
    start_tag('p')
    @p = true
  end
end
start_tag(tag, args = {}, lindent = nil) click to toggle source
# File lib/trac-wiki/parser.rb, line 342
def start_tag(tag, args = {}, lindent = nil)
  lindent = @stacki.last || -1  if lindent.nil?

  @stack.push(tag)
  @stacki.push(lindent)

  if tag == 'strongem'
    @tree.tag_beg(:strong).tag_beg(:em)
  else
    @tree.tag_beg(tag, args)
  end
end
toggle_tag(tag, match) click to toggle source
# File lib/trac-wiki/parser.rb, line 367
def toggle_tag(tag, match)
  if @stack.include?(tag)
    if @stack.last == tag
      end_tag
    else
      @tree.add(match)
    end
  else
    start_tag(tag)
  end
end