trac-wiki 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/trac_wiki/parser.rb +203 -91
- data/lib/trac_wiki/version.rb +1 -1
- data/test/parser_test.rb +150 -94
- metadata +1 -1
    
        data/lib/trac_wiki/parser.rb
    CHANGED
    
    | @@ -3,7 +3,7 @@ require 'uri' | |
| 3 3 |  | 
| 4 4 | 
             
            # :main: TracWiki
         | 
| 5 5 |  | 
| 6 | 
            -
            # The  | 
| 6 | 
            +
            # The TracWiki parses and translates Trac formatted text into
         | 
| 7 7 | 
             
            # XHTML. Creole is a lightweight markup syntax similar to what many
         | 
| 8 8 | 
             
            # WikiWikiWebs use. Example syntax:
         | 
| 9 9 | 
             
            #
         | 
| @@ -11,11 +11,11 @@ require 'uri' | |
| 11 11 | 
             
            # == Heading 2 ==
         | 
| 12 12 | 
             
            # === Heading 3 ===
         | 
| 13 13 | 
             
            # **Bold text**
         | 
| 14 | 
            -
            #  | 
| 14 | 
            +
            # ''Italic text''
         | 
| 15 15 | 
             
            # [[Links]]
         | 
| 16 | 
            -
            #  | 
| 17 | 
            -
            #  | 
| 18 | 
            -
            #  | 
| 16 | 
            +
            # ||=Table||=Heading||
         | 
| 17 | 
            +
            # || Table|| Cells ||
         | 
| 18 | 
            +
            # [[Image(image.png)]]
         | 
| 19 19 | 
             
            #
         | 
| 20 20 | 
             
            # The simplest interface is TracWiki.render. The default handling of
         | 
| 21 21 | 
             
            # links allow explicit local links using the [[link]] syntax. External
         | 
| @@ -74,6 +74,7 @@ module TracWiki | |
| 74 74 | 
             
                  @out = ''
         | 
| 75 75 | 
             
                  @p = false
         | 
| 76 76 | 
             
                  @stack = []
         | 
| 77 | 
            +
                  @stacki = []
         | 
| 77 78 | 
             
                  parse_block(@text)
         | 
| 78 79 | 
             
                  @out
         | 
| 79 80 | 
             
                end
         | 
| @@ -92,13 +93,27 @@ module TracWiki | |
| 92 93 | 
             
                  CGI::escape(string)
         | 
| 93 94 | 
             
                end
         | 
| 94 95 |  | 
| 95 | 
            -
                def start_tag(tag)
         | 
| 96 | 
            +
                def start_tag(tag, args = '', lindent = nil)
         | 
| 97 | 
            +
                  lindent = @stacki.last || -1  if lindent.nil?
         | 
| 98 | 
            +
             | 
| 96 99 | 
             
                  @stack.push(tag)
         | 
| 97 | 
            -
                  @ | 
| 100 | 
            +
                  @stacki.push(lindent)
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  if tag == 'strongem'
         | 
| 103 | 
            +
                    @out << '<strong><em>'
         | 
| 104 | 
            +
                  else
         | 
| 105 | 
            +
                    @out << '<' << tag << args << '>'
         | 
| 106 | 
            +
                  end
         | 
| 98 107 | 
             
                end
         | 
| 99 108 |  | 
| 100 109 | 
             
                def end_tag
         | 
| 101 | 
            -
                   | 
| 110 | 
            +
                  tag = @stack.pop
         | 
| 111 | 
            +
                  tagi = @stacki.pop
         | 
| 112 | 
            +
                  if tag == 'strongem'
         | 
| 113 | 
            +
                    @out << '</em></strong>'
         | 
| 114 | 
            +
                  else
         | 
| 115 | 
            +
                    @out << "</#{tag}>"
         | 
| 116 | 
            +
                  end
         | 
| 102 117 | 
             
                end
         | 
| 103 118 |  | 
| 104 119 | 
             
                def toggle_tag(tag, match)
         | 
| @@ -185,11 +200,11 @@ module TracWiki | |
| 185 200 | 
             
                # method can be overridden to generate custom
         | 
| 186 201 | 
             
                # markup, for example to add html additional attributes or
         | 
| 187 202 | 
             
                # to put divs around the imgs.
         | 
| 188 | 
            -
                def make_image(uri, alt)
         | 
| 203 | 
            +
                def make_image(uri, alt='')
         | 
| 189 204 | 
             
                  if alt
         | 
| 190 | 
            -
                     | 
| 205 | 
            +
                    "<img src='" << escape_html(uri) << "' alt='" << escape_html(alt) << "'/>"
         | 
| 191 206 | 
             
                  else
         | 
| 192 | 
            -
                     | 
| 207 | 
            +
                    "<img src='" << escape_html(uri) << "'/>"
         | 
| 193 208 | 
             
                  end
         | 
| 194 209 | 
             
                end
         | 
| 195 210 |  | 
| @@ -209,6 +224,7 @@ module TracWiki | |
| 209 224 | 
             
                def parse_inline(str)
         | 
| 210 225 | 
             
                  until str.empty?
         | 
| 211 226 | 
             
                    case str
         | 
| 227 | 
            +
                    # raw url
         | 
| 212 228 | 
             
                    when /\A(\~)?((https?|ftps?):\/\/\S+?)(?=([\,.?!:;"'\)]+)?(\s|$))/
         | 
| 213 229 | 
             
                      str = $'
         | 
| 214 230 | 
             
                      if $1
         | 
| @@ -220,26 +236,44 @@ module TracWiki | |
| 220 236 | 
             
                          @out << escape_html($&)
         | 
| 221 237 | 
             
                        end
         | 
| 222 238 | 
             
                      end
         | 
| 239 | 
            +
                    # [[Image(pic.jpg|tag)]]
         | 
| 240 | 
            +
                    when /\A\[\[Image\(([^|].*?)(\|(.*?))?\)\]\]/   # image 
         | 
| 241 | 
            +
                      str = $'
         | 
| 242 | 
            +
                      @out << make_image($1, $3)
         | 
| 243 | 
            +
                    # [[link]]
         | 
| 223 244 | 
             
                    when /\A\[\[\s*([^|]*?)\s*(\|\s*(.*?))?\s*\]\]/m
         | 
| 224 245 | 
             
                      str = $'
         | 
| 225 | 
            -
                      link, content = $1, $3
         | 
| 226 | 
            -
                       | 
| 227 | 
            -
                        @out << '<a href="' << escape_html(uri) << '">'
         | 
| 228 | 
            -
                        if content
         | 
| 229 | 
            -
                          until content.empty?
         | 
| 230 | 
            -
                            content = parse_inline_tag(content)
         | 
| 231 | 
            -
                          end
         | 
| 232 | 
            -
                        else
         | 
| 233 | 
            -
                          @out << escape_html(link)
         | 
| 234 | 
            -
                        end
         | 
| 235 | 
            -
                        @out << '</a>'
         | 
| 236 | 
            -
                      else
         | 
| 237 | 
            -
                        @out << escape_html($&)
         | 
| 238 | 
            -
                      end
         | 
| 246 | 
            +
                      link, content, whole= $1, $3, $&
         | 
| 247 | 
            +
                      make_link(link, content, whole)
         | 
| 239 248 | 
             
                    else
         | 
| 240 249 | 
             
                      str = parse_inline_tag(str)
         | 
| 241 250 | 
             
                    end
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                  end
         | 
| 253 | 
            +
                end
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                def make_link(link, content, whole)
         | 
| 256 | 
            +
                  uri = make_explicit_link(link)
         | 
| 257 | 
            +
                  # specail "link" [[BR]]:
         | 
| 258 | 
            +
                  if link =~ /br/i
         | 
| 259 | 
            +
                    @out << '<br/>'
         | 
| 260 | 
            +
                    return
         | 
| 261 | 
            +
                  end
         | 
| 262 | 
            +
                  if not uri
         | 
| 263 | 
            +
                    @out << escape_html(whole)
         | 
| 264 | 
            +
                    return
         | 
| 265 | 
            +
                  end
         | 
| 266 | 
            +
             | 
| 267 | 
            +
                  make_explicit_link(link)
         | 
| 268 | 
            +
                  @out << '<a href="' << escape_html(uri) << '">'
         | 
| 269 | 
            +
                  if content
         | 
| 270 | 
            +
                    until content.empty?
         | 
| 271 | 
            +
                      content = parse_inline_tag(content)
         | 
| 272 | 
            +
                    end
         | 
| 273 | 
            +
                  else
         | 
| 274 | 
            +
                      @out << escape_html(link)
         | 
| 242 275 | 
             
                  end
         | 
| 276 | 
            +
                  @out << '</a>'
         | 
| 243 277 | 
             
                end
         | 
| 244 278 |  | 
| 245 279 | 
             
                def parse_inline_tag(str)
         | 
| @@ -248,21 +282,27 @@ module TracWiki | |
| 248 282 | 
             
                    @out << '<tt>' << escape_html($1) << '</tt>'
         | 
| 249 283 | 
             
                  when /\A`(.*?)`/                  # inline pre (tt)
         | 
| 250 284 | 
             
                    @out << '<tt>' << escape_html($1) << '</tt>'
         | 
| 251 | 
            -
                  when /\A\ | 
| 252 | 
            -
             | 
| 253 | 
            -
             | 
| 254 | 
            -
             | 
| 255 | 
            -
             | 
| 256 | 
            -
             | 
| 285 | 
            +
            #      when /\A\[\[Image\(([^|].*?)(\|(.*?))?\)\]\]/   # image 
         | 
| 286 | 
            +
            #       @out << make_image($1, $3)
         | 
| 287 | 
            +
             | 
| 288 | 
            +
            #      when /\A\{\{\s*(.*?)\s*(\|\s*(.*?)\s*)?\}\}/
         | 
| 289 | 
            +
            #        if uri = make_image_link($1)
         | 
| 290 | 
            +
            #          @out << make_image(uri, $3)
         | 
| 291 | 
            +
            #        else
         | 
| 292 | 
            +
            #          @out << escape_html($&)
         | 
| 293 | 
            +
            #        end                             # link
         | 
| 294 | 
            +
             | 
| 257 295 | 
             
                  when /\A([:alpha:]|[:digit:])+/
         | 
| 258 296 | 
             
                    @out << $&                      # word
         | 
| 259 297 | 
             
                  when /\A\s+/
         | 
| 260 298 | 
             
                    @out << ' ' if @out[-1] != ?\s  # spaces
         | 
| 261 | 
            -
                  when /\A | 
| 299 | 
            +
                  when /\A'''''/
         | 
| 300 | 
            +
                    toggle_tag 'strongem', $&       # bolditallic
         | 
| 301 | 
            +
                  when /\A\*\*/, /\A'''/
         | 
| 262 302 | 
             
                    toggle_tag 'strong', $&         # bold
         | 
| 263 | 
            -
                  when /\A'' | 
| 303 | 
            +
                  when /\A''/, /\A\/\//
         | 
| 264 304 | 
             
                    toggle_tag 'em', $&             # italic
         | 
| 265 | 
            -
                  when /\A | 
| 305 | 
            +
                  when /\A\\\\/, /\A\[\[br\]\]/i
         | 
| 266 306 | 
             
                    @out << '<br/>'                 # newline
         | 
| 267 307 | 
             
                  when /\A__/
         | 
| 268 308 | 
             
                    toggle_tag 'u', $&              # underline
         | 
| @@ -270,7 +310,7 @@ module TracWiki | |
| 270 310 | 
             
                    toggle_tag 'del', $&            # delete
         | 
| 271 311 | 
             
            #      when /\A\+\+/
         | 
| 272 312 | 
             
            #        toggle_tag 'ins', $&           # insert
         | 
| 273 | 
            -
                  when /\A | 
| 313 | 
            +
                  when /\A\^/
         | 
| 274 314 | 
             
                    toggle_tag 'sup', $&            # ^{}
         | 
| 275 315 | 
             
                  when /\A,,/
         | 
| 276 316 | 
             
                    toggle_tag 'sub', $&            # _{}
         | 
| @@ -287,35 +327,106 @@ module TracWiki | |
| 287 327 | 
             
                end
         | 
| 288 328 |  | 
| 289 329 | 
             
                def parse_table_row(str)
         | 
| 290 | 
            -
                   | 
| 291 | 
            -
                   | 
| 292 | 
            -
                   | 
| 293 | 
            -
             | 
| 294 | 
            -
             | 
| 295 | 
            -
             | 
| 296 | 
            -
             | 
| 297 | 
            -
             | 
| 298 | 
            -
             | 
| 299 | 
            -
             | 
| 300 | 
            -
             | 
| 301 | 
            -
             | 
| 302 | 
            -
             | 
| 303 | 
            -
             | 
| 304 | 
            -
                       | 
| 305 | 
            -
                      @out << ('<' + tag + style + '>' )
         | 
| 306 | 
            -
                      parse_inline(txt.strip) if txt
         | 
| 307 | 
            -
                      end_tag while @stack.last != 'table'
         | 
| 308 | 
            -
                      @out << ('</' + tag + '>')
         | 
| 330 | 
            +
                  start_tag('tr') if !@stack.include?('tr')
         | 
| 331 | 
            +
                  colspan = 1
         | 
| 332 | 
            +
                  print_tr = true
         | 
| 333 | 
            +
                  last_tail  = ''
         | 
| 334 | 
            +
                  last_txt  = ''
         | 
| 335 | 
            +
                  str.scan(/(=?)(\s*)(.*?)\1?($ | \|\|\\\s*$ | \|\| )/x) do
         | 
| 336 | 
            +
                    tdth = $1.empty? ? 'td' : 'th'
         | 
| 337 | 
            +
                    le, txt, tail  = $2.size, $3, $4
         | 
| 338 | 
            +
             | 
| 339 | 
            +
                    # do not end row, continue on next line
         | 
| 340 | 
            +
                    print_tr = false if tail =~ /^\|\|\\/
         | 
| 341 | 
            +
             | 
| 342 | 
            +
                    if txt.empty? && le == 0
         | 
| 343 | 
            +
                      colspan += 1
         | 
| 344 | 
            +
                      next
         | 
| 309 345 | 
             
                    end
         | 
| 346 | 
            +
             | 
| 347 | 
            +
                    style = ''
         | 
| 348 | 
            +
                    if  txt =~ /\S(\s*)$/
         | 
| 349 | 
            +
                          ri = $1.size
         | 
| 350 | 
            +
                          ri += 100 if tail.empty? # do not right when last || omnited
         | 
| 351 | 
            +
                          style = " style='text-align:right'"  if ri == 0 && le >= 1
         | 
| 352 | 
            +
                          style = " style='text-align:center'" if le >= 2 && ri >= 2
         | 
| 353 | 
            +
                          #print "le#{le} ri#{ri} st:#{style}\n"
         | 
| 354 | 
            +
                    end
         | 
| 355 | 
            +
             | 
| 356 | 
            +
                    colspan_txt  =  colspan > 1 ? " colspan='#{colspan}'" : ''
         | 
| 357 | 
            +
                    start_tag(tdth, style + colspan_txt);
         | 
| 358 | 
            +
                    colspan = 1
         | 
| 359 | 
            +
             | 
| 360 | 
            +
                    parse_inline(txt.strip) if txt
         | 
| 361 | 
            +
                    end_tag while @stack.last != 'tr'
         | 
| 362 | 
            +
                  end
         | 
| 363 | 
            +
                  if print_tr
         | 
| 364 | 
            +
                    end_tag
         | 
| 310 365 | 
             
                  end
         | 
| 311 | 
            -
                  @out << '</tr>'
         | 
| 312 366 | 
             
                end
         | 
| 313 367 |  | 
| 314 368 | 
             
                def make_nowikiblock(input)
         | 
| 315 369 | 
             
                  input.gsub(/^ (?=\}\}\})/, '')
         | 
| 316 370 | 
             
                end
         | 
| 317 371 |  | 
| 318 | 
            -
                def  | 
| 372 | 
            +
                def parse_li_line(spc_size, bullet, text)
         | 
| 373 | 
            +
             | 
| 374 | 
            +
                  while !@stacki.empty? && @stacki.last >  spc_size
         | 
| 375 | 
            +
                    end_tag
         | 
| 376 | 
            +
                  end
         | 
| 377 | 
            +
             | 
| 378 | 
            +
                  if @stack.include?('li')
         | 
| 379 | 
            +
                    while @stack.last != 'li'
         | 
| 380 | 
            +
                      end_tag
         | 
| 381 | 
            +
                    end
         | 
| 382 | 
            +
             | 
| 383 | 
            +
                    # end list if type differ
         | 
| 384 | 
            +
                    # @stack.last is now ul or li
         | 
| 385 | 
            +
                    if @stacki.last == spc_size
         | 
| 386 | 
            +
                      end_tag # li
         | 
| 387 | 
            +
                      ulol_last = @stack.last
         | 
| 388 | 
            +
                      ulol_now =  bullet =~ /[*-]/ ? 'ul' : 'ol'
         | 
| 389 | 
            +
                      if ulol_last != ulol_now
         | 
| 390 | 
            +
                        end_tag # ol | ul
         | 
| 391 | 
            +
                      end
         | 
| 392 | 
            +
                    end
         | 
| 393 | 
            +
                  else
         | 
| 394 | 
            +
                    end_paragraph
         | 
| 395 | 
            +
                  end
         | 
| 396 | 
            +
             | 
| 397 | 
            +
                  if @stacki.empty? || @stacki.last <  spc_size
         | 
| 398 | 
            +
                    bullet.gsub!(/\.$/,'')
         | 
| 399 | 
            +
                    ulol = bullet =~ /[-*]/ ? 'ul' : 'ol';
         | 
| 400 | 
            +
                    attr = ""
         | 
| 401 | 
            +
                    attr = " type='i'" if bullet =~ /i/i;
         | 
| 402 | 
            +
                    attr = " type='a'" if bullet =~ /a/i;
         | 
| 403 | 
            +
             | 
| 404 | 
            +
                    if bullet =~ /^\d+$/ && bullet != '1'
         | 
| 405 | 
            +
                            attr += " start='#{bullet}'"
         | 
| 406 | 
            +
                    end
         | 
| 407 | 
            +
                    start_tag(ulol, attr, spc_size)
         | 
| 408 | 
            +
                  end
         | 
| 409 | 
            +
             | 
| 410 | 
            +
                  start_tag('li')
         | 
| 411 | 
            +
                  parse_inline(text)
         | 
| 412 | 
            +
             | 
| 413 | 
            +
                end
         | 
| 414 | 
            +
             | 
| 415 | 
            +
                def blockquote_level_to(level)
         | 
| 416 | 
            +
                  cur_level = @stack.count('blockquote')
         | 
| 417 | 
            +
                  if cur_level ==  level
         | 
| 418 | 
            +
                    @out << ' '
         | 
| 419 | 
            +
                    return
         | 
| 420 | 
            +
                  end
         | 
| 421 | 
            +
                  while cur_level < level
         | 
| 422 | 
            +
                    cur_level += 1
         | 
| 423 | 
            +
                    start_tag('blockquote')
         | 
| 424 | 
            +
                  end
         | 
| 425 | 
            +
                  while cur_level > level
         | 
| 426 | 
            +
                    cur_level -= 1 if @stack.last == 'blockquote'
         | 
| 427 | 
            +
                    end_tag
         | 
| 428 | 
            +
                  end
         | 
| 429 | 
            +
                end
         | 
| 319 430 |  | 
| 320 431 | 
             
                def parse_block(str)
         | 
| 321 432 | 
             
                  until str.empty?
         | 
| @@ -339,58 +450,59 @@ module TracWiki | |
| 339 450 | 
             
                      @out << make_headline(level, $2)
         | 
| 340 451 |  | 
| 341 452 | 
             
                    # table row
         | 
| 342 | 
            -
                    when /\A[ \t] | 
| 453 | 
            +
                    when /\A[ \t]*\|\|(.*)$(\r?\n)?/
         | 
| 343 454 | 
             
                      if !@stack.include?('table')
         | 
| 344 455 | 
             
                        end_paragraph
         | 
| 345 456 | 
             
                        start_tag('table')
         | 
| 346 457 | 
             
                      end
         | 
| 347 | 
            -
                      parse_table_row( | 
| 458 | 
            +
                      parse_table_row($1)
         | 
| 348 459 |  | 
| 349 460 | 
             
                    # empty line
         | 
| 350 461 | 
             
                    when /\A\s*$(\r?\n)?/
         | 
| 351 462 | 
             
                      end_paragraph
         | 
| 463 | 
            +
                    when /\A([\w\s]*)::\s*/
         | 
| 464 | 
            +
                      term = $1
         | 
| 465 | 
            +
                      start_tag('dl')
         | 
| 466 | 
            +
                      start_tag('dt')
         | 
| 467 | 
            +
                      @out << escape_html(term)
         | 
| 468 | 
            +
                      end_tag
         | 
| 469 | 
            +
                      start_tag('dd')
         | 
| 352 470 |  | 
| 353 471 | 
             
                    # li
         | 
| 354 | 
            -
                    when /\A(\s*([ | 
| 355 | 
            -
                       | 
| 356 | 
            -
                      tag = (bullet[0,1] == '*' ? 'ul' : 'ol')
         | 
| 357 | 
            -
                      if bullet[0,1] == '#' || bullet.size != 2 || @stack.find {|x| ulol?(x) }
         | 
| 358 | 
            -
                        count = @stack.select { |x| ulol?(x) }.size
         | 
| 359 | 
            -
             | 
| 360 | 
            -
                        while !@stack.empty? && count > bullet.size
         | 
| 361 | 
            -
                          count -= 1 if ulol?(@stack.last)
         | 
| 362 | 
            -
                          end_tag
         | 
| 363 | 
            -
                        end
         | 
| 472 | 
            +
                    when /\A(\s*)([*-]|[aAIi\d]\.)\s+(.*?)$(\r?\n)?/
         | 
| 473 | 
            +
                      parse_li_line($1.size, $2, $3)
         | 
| 364 474 |  | 
| 365 | 
            -
             | 
| 475 | 
            +
                    when /\A(>[>\s]*)(.*?)$(\r?\n)?/
         | 
| 476 | 
            +
                      # citation
         | 
| 477 | 
            +
                      level, quote =  $1.count('>'), $2
         | 
| 366 478 |  | 
| 367 | 
            -
             | 
| 368 | 
            -
             | 
| 369 | 
            -
             | 
| 370 | 
            -
                            end_tag
         | 
| 371 | 
            -
                            count -= 1
         | 
| 372 | 
            -
                          end
         | 
| 373 | 
            -
                        end
         | 
| 479 | 
            +
                      start_paragraph if !@stack.include? 'p'
         | 
| 480 | 
            +
                      blockquote_level_to(level)
         | 
| 481 | 
            +
                      parse_inline(quote.strip)
         | 
| 374 482 |  | 
| 375 | 
            -
                        while count < bullet.size
         | 
| 376 | 
            -
                          start_tag tag
         | 
| 377 | 
            -
                          count += 1
         | 
| 378 | 
            -
                          start_tag 'li' if count < bullet.size
         | 
| 379 | 
            -
                        end
         | 
| 380 483 |  | 
| 381 | 
            -
             | 
| 382 | 
            -
             | 
| 383 | 
            -
             | 
| 484 | 
            +
                    # ordinary line
         | 
| 485 | 
            +
                    when /\A(\s*)(\S+.*?)$(\r?\n)?/
         | 
| 486 | 
            +
                      spc_size, text =  $1.size, $2
         | 
| 487 | 
            +
             | 
| 488 | 
            +
                      if @stack.include?('li') ||@stack.include?('dl')
         | 
| 489 | 
            +
             | 
| 490 | 
            +
                        # dl, li continuation
         | 
| 491 | 
            +
                        parse_inline(' ')
         | 
| 492 | 
            +
                        parse_inline(text)
         | 
| 493 | 
            +
             | 
| 494 | 
            +
                      elsif spc_size > 0
         | 
| 495 | 
            +
                        # quote continuation
         | 
| 496 | 
            +
                        start_paragraph if !@stack.include? 'p'
         | 
| 497 | 
            +
                        blockquote_level_to(1)
         | 
| 498 | 
            +
                        parse_inline(text)
         | 
| 499 | 
            +
             | 
| 384 500 | 
             
                      else
         | 
| 501 | 
            +
                        # real ordinary line
         | 
| 385 502 | 
             
                        start_paragraph
         | 
| 386 | 
            -
                        parse_inline( | 
| 503 | 
            +
                        parse_inline(text)
         | 
| 387 504 | 
             
                      end
         | 
| 388 | 
            -
             | 
| 389 | 
            -
                    # ordinary line
         | 
| 390 | 
            -
                    when /\A([ \t]*\S+.*?)$(\r?\n)?/
         | 
| 391 | 
            -
                      start_paragraph
         | 
| 392 | 
            -
                      parse_inline($1)
         | 
| 393 | 
            -
                    else
         | 
| 505 | 
            +
                    else # case str
         | 
| 394 506 | 
             
                      raise "Parse error at #{str[0,30].inspect}"
         | 
| 395 507 | 
             
                    end
         | 
| 396 508 | 
             
                    str = $'
         | 
    
        data/lib/trac_wiki/version.rb
    CHANGED
    
    
    
        data/test/parser_test.rb
    CHANGED
    
    | @@ -46,6 +46,24 @@ describe TracWiki::Parser do | |
| 46 46 | 
             
                tc "<p>This <strong>is bold</strong></p>", "This **is\nbold**"
         | 
| 47 47 | 
             
              end
         | 
| 48 48 |  | 
| 49 | 
            +
              it 'should parse bolditalic' do
         | 
| 50 | 
            +
                tc '<p>This is <strong><em>bolditallic</em></strong>.</p>', "This is '''''bolditallic'''''."
         | 
| 51 | 
            +
                tc '<p>This is <strong> <em>bolditallic</em> </strong>.</p>', "This is ''' ''bolditallic'' '''."
         | 
| 52 | 
            +
                tc '<p>This is <em> <strong>bolditallic</strong> </em>.</p>', "This is '' '''bolditallic''' ''."
         | 
| 53 | 
            +
                tc '<p>This is <strong>bold</strong>.</p>', "This is '''bold'''."
         | 
| 54 | 
            +
                #fuj tc '<p>This is <strong><em>bolditallic</em></strong>.</p>', "This is **''bolditallic**''."
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
              it 'should parse monospace' do
         | 
| 57 | 
            +
                tc "<p>This is <tt>monospace</tt>.</p>", "This is {{{monospace}}}."
         | 
| 58 | 
            +
                tc "<p>This is <tt>mon**o**space</tt>.</p>", "This is {{{mon**o**space}}}."
         | 
| 59 | 
            +
                tc "<p>This is <tt>mon<o>space</tt>.</p>", "This is {{{mon<o>space}}}."
         | 
| 60 | 
            +
                tc "<p>This is <tt>mon''o''space</tt>.</p>", "This is {{{mon''o''space}}}."
         | 
| 61 | 
            +
                tc "<p>This is <tt>mon''o''space</tt>.</p>", "This is `mon''o''space`."
         | 
| 62 | 
            +
                tc "<p>This is <tt>mon{{o}}space</tt>.</p>", "This is {{{mon{{o}}space}}}."
         | 
| 63 | 
            +
                tc "<p>This is <tt>mon``o''space</tt>.</p>", "This is {{{mon``o''space}}}."
         | 
| 64 | 
            +
                tc "<p>This is <tt>mon{{o}}space</tt>.</p>", "This is `mon{{o}}space`."
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 49 67 | 
             
              it 'should parse italic' do
         | 
| 50 68 | 
             
                # Italic can be used inside paragraphs
         | 
| 51 69 | 
             
                tc("<p>This <em>is</em> italic</p>",
         | 
| @@ -156,7 +174,7 @@ describe TracWiki::Parser do | |
| 156 174 |  | 
| 157 175 | 
             
                # WRNING: Parsing markup within a link is optional
         | 
| 158 176 | 
             
                tc "<p><a href=\"Weird+Stuff\"><strong>Weird</strong> <em>Stuff</em></a></p>", "[[Weird Stuff|**Weird** ''Stuff'']]"
         | 
| 159 | 
            -
                tc("<p><a href=\"http://example.org/\"><img src | 
| 177 | 
            +
                #tc("<p><a href=\"http://example.org/\"><img src='image.jpg'/></a></p>", "[[http://example.org/|{{image.jpg}}]]")
         | 
| 160 178 |  | 
| 161 179 | 
             
                # Inside bold
         | 
| 162 180 | 
             
                tc "<p><strong><a href=\"link\">link</a></strong></p>", "**[[link]]**"
         | 
| @@ -210,19 +228,35 @@ describe TracWiki::Parser do | |
| 210 228 | 
             
              it 'should parse linebreaks' do
         | 
| 211 229 | 
             
                #  \\ (wiki-style) for line breaks.
         | 
| 212 230 | 
             
                tc "<p>This is the first line,<br/>and this is the second.</p>", "This is the first line,\\\\and this is the second."
         | 
| 231 | 
            +
                tc "<p>This is the first line,<br/>and this is the second.</p>", "This is the first line,[[br]]and this is the second."
         | 
| 232 | 
            +
                tc "<p>This is the first line,<br/>and this is the second.</p>", "This is the first line,[[Br]]and this is the second."
         | 
| 213 233 | 
             
              end
         | 
| 214 234 |  | 
| 235 | 
            +
              it 'should parse blockquote' do
         | 
| 236 | 
            +
                tc "<p><blockquote>Monty Python</blockquote></p>", "> Monty Python\n"
         | 
| 237 | 
            +
                tc "<p><blockquote>Monty Python q2</blockquote></p>", "> Monty Python\n> q2\n"
         | 
| 238 | 
            +
                tc "<p><blockquote>Monty Python q2</blockquote></p>", "> Monty Python\n>q2\n"
         | 
| 239 | 
            +
                tc "<p><blockquote>Monty Python <strong>q2</strong></blockquote></p>", "> Monty Python\n>**q2**\n"
         | 
| 240 | 
            +
                tc "<p><blockquote>Monty Python<blockquote>q2</blockquote></blockquote></p>", "> Monty Python\n> > q2\n"
         | 
| 241 | 
            +
                tc "<p><blockquote>Monty Python<blockquote>q2 q3</blockquote></blockquote></p>", "> Monty Python\n> > q2\n>>q3\n"
         | 
| 242 | 
            +
                tc "<p><blockquote>Monty Python<blockquote><em>q2</em></blockquote>q1</blockquote></p>", ">Monty Python\n> > ''q2''\n>q1"
         | 
| 243 | 
            +
                tc "<p><blockquote>Monty Python rules</blockquote></p>", "  Monty Python\n rules\n"
         | 
| 244 | 
            +
              end
         | 
| 245 | 
            +
              it 'should parse definition list' do
         | 
| 246 | 
            +
                # FIXME: trailing space 
         | 
| 247 | 
            +
                tc "<dl><dt>Monty Python</dt><dd> definition</dd></dl>", "Monty Python:: \n   definition\n"
         | 
| 248 | 
            +
              end
         | 
| 215 249 | 
             
              it 'should parse unordered_lists' do
         | 
| 216 250 | 
             
                # List items begin with a * at the beginning of a line.
         | 
| 217 251 | 
             
                # An item ends at the next *
         | 
| 218 | 
            -
             | 
| 252 | 
            +
             | 
| 253 | 
            +
                tc "<ul><li>Item 1 next</li></ul>", "* Item 1\n  next\n"
         | 
| 219 254 |  | 
| 220 255 | 
             
                #  Whitespace is optional before and after the *.
         | 
| 221 256 | 
             
                tc("<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>",
         | 
| 222 | 
            -
                   " * Item 1\n*Item 2\n  | 
| 257 | 
            +
                   " * Item 1\n * Item 2\n *\t\tItem 3\n")
         | 
| 223 258 |  | 
| 224 259 | 
             
                #  A space is required if if the list element starts with bold text.
         | 
| 225 | 
            -
                tc("<ul><li><ul><li><ul><li>Item 1</li></ul></li></ul></li></ul>", "***Item 1")
         | 
| 226 260 | 
             
                tc("<ul><li><strong>Item 1</strong></li></ul>", "* **Item 1")
         | 
| 227 261 |  | 
| 228 262 | 
             
                #  An item ends at blank line
         | 
| @@ -239,107 +273,110 @@ describe TracWiki::Parser do | |
| 239 273 |  | 
| 240 274 | 
             
                #  An item can span multiple lines
         | 
| 241 275 | 
             
                tc("<ul><li>The quick brown fox jumps over lazy dog.</li><li>Humpty Dumpty sat on a wall.</li></ul>",
         | 
| 242 | 
            -
                   "* The quick\nbrown fox\n\tjumps over\nlazy dog.\n*Humpty Dumpty\nsat\t\non a wall.")
         | 
| 276 | 
            +
                   "* The quick\nbrown fox\n\tjumps over\nlazy dog.\n* Humpty Dumpty\nsat\t\non a wall.")
         | 
| 243 277 |  | 
| 244 278 | 
             
                #  An item can contain line breaks
         | 
| 245 279 | 
             
                tc("<ul><li>The quick brown<br/>fox jumps over lazy dog.</li></ul>",
         | 
| 246 280 | 
             
                   "* The quick brown\\\\fox jumps over lazy dog.")
         | 
| 247 281 |  | 
| 248 282 | 
             
                #  Nested
         | 
| 249 | 
            -
                tc "<ul><li>Item 1<ul><li>Item 2</li></ul></li><li>Item 3</li></ul>", "* Item 1\n  | 
| 283 | 
            +
                tc "<ul><li>Item 1<ul><li>Item 2</li></ul></li><li>Item 3</li></ul>", "* Item 1\n  * Item 2\n*\t\tItem 3\n"
         | 
| 250 284 |  | 
| 251 285 | 
             
                #  Nested up to 5 levels
         | 
| 252 286 | 
             
                tc("<ul><li>Item 1<ul><li>Item 2<ul><li>Item 3<ul><li>Item 4<ul><li>Item 5</li></ul></li></ul></li></ul></li></ul></li></ul>",
         | 
| 253 | 
            -
                   "*Item 1\n | 
| 287 | 
            +
                   "* Item 1\n * Item 2\n   * Item 3\n    *    Item 4\n     * Item 5\n")
         | 
| 288 | 
            +
             | 
| 289 | 
            +
                tc("<ul><li>Item 1<ul><li>Item 2<ul><li>Item 3<ul><li>Item 4</li></ul></li></ul></li></ul></li><li>Item 5</li></ul>",
         | 
| 290 | 
            +
                   "* Item 1\n * Item 2\n   * Item 3\n    *    Item 4\n* Item 5\n")
         | 
| 254 291 |  | 
| 255 292 | 
             
                #  ** immediatly following a list element will be treated as a nested unordered element.
         | 
| 256 293 | 
             
                tc("<ul><li>Hello, World!<ul><li>Not bold</li></ul></li></ul>",
         | 
| 257 | 
            -
                   "*Hello,\ | 
| 294 | 
            +
                   "* Hello,\n  World!\n  * Not bold\n")
         | 
| 258 295 |  | 
| 259 296 | 
             
                #  ** immediatly following a list element will be treated as a nested unordered element.
         | 
| 260 297 | 
             
                tc("<ol><li>Hello, World!<ul><li>Not bold</li></ul></li></ol>",
         | 
| 261 | 
            -
                   " | 
| 298 | 
            +
                   "1. Hello,\n   World!\n  * Not bold\n")
         | 
| 262 299 |  | 
| 263 300 | 
             
                #  [...] otherwise it will be treated as the beginning of bold text.
         | 
| 264 301 | 
             
                tc("<ul><li>Hello, World!</li></ul><p><strong>Not bold</strong></p>",
         | 
| 265 | 
            -
                   "*Hello,\nWorld!\n\n**Not bold\n")
         | 
| 302 | 
            +
                   "* Hello,\nWorld!\n\n**Not bold\n")
         | 
| 266 303 | 
             
              end
         | 
| 267 304 |  | 
| 268 305 | 
             
              it 'should parse ordered lists' do
         | 
| 269 306 | 
             
                #  List items begin with a * at the beginning of a line.
         | 
| 270 307 | 
             
                #  An item ends at the next *
         | 
| 271 | 
            -
                tc "<ol><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol>", " | 
| 308 | 
            +
                tc "<ol><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol>", "1. Item 1\n2. Item 2\n3. \t\tItem 3\n"
         | 
| 272 309 |  | 
| 273 310 | 
             
                #  Whitespace is optional before and after the #.
         | 
| 274 311 | 
             
                tc("<ol><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol>",
         | 
| 275 | 
            -
                   "  | 
| 312 | 
            +
                   "1. Item 1\n1.   Item 2\n4.\t\tItem 3\n")
         | 
| 276 313 |  | 
| 277 314 | 
             
                #  A space is required if if the list element starts with bold text.
         | 
| 278 | 
            -
                tc("<ol><li><ol><li><ol><li>Item 1</li></ol></li></ol></li></ol>", "###Item 1")
         | 
| 279 | 
            -
                tc("<ol><li><strong>Item 1</strong></li></ol>", " | 
| 315 | 
            +
            #    tc("<ol><li><ol><li><ol><li>Item 1</li></ol></li></ol></li></ol>", "###Item 1")
         | 
| 316 | 
            +
                tc("<ol><li><strong>Item 1</strong></li></ol>", "1. **Item 1")
         | 
| 280 317 |  | 
| 281 318 | 
             
                #  An item ends at blank line
         | 
| 282 | 
            -
                tc("<ol><li>Item</li></ol><p>Par</p>", " | 
| 319 | 
            +
                tc("<ol><li>Item</li></ol><p>Par</p>", "1. Item\n\nPar\n")
         | 
| 283 320 |  | 
| 284 321 | 
             
                #  An item ends at a heading
         | 
| 285 | 
            -
                tc("<ol><li>Item</li></ol><h1>Heading</h1>", " | 
| 322 | 
            +
                tc("<ol><li>Item</li></ol><h1>Heading</h1>", "1. Item\n= Heading =\n")
         | 
| 286 323 |  | 
| 287 324 | 
             
                #  An item ends at a table
         | 
| 288 | 
            -
                tc("<ol><li>Item</li></ol><table><tr><td>Cell</td></tr></table>", " | 
| 325 | 
            +
                tc("<ol><li>Item</li></ol><table><tr><td>Cell</td></tr></table>", "1. Item\n||Cell||\n")
         | 
| 289 326 |  | 
| 290 327 | 
             
                #  An item ends at a nowiki block
         | 
| 291 | 
            -
                tc("<ol><li>Item</li></ol><pre>Code</pre>", " | 
| 328 | 
            +
                tc("<ol><li>Item</li></ol><pre>Code</pre>", "1. Item\n{{{\nCode\n}}}\n")
         | 
| 292 329 |  | 
| 293 330 | 
             
                #  An item can span multiple lines
         | 
| 294 331 | 
             
                tc("<ol><li>The quick brown fox jumps over lazy dog.</li><li>Humpty Dumpty sat on a wall.</li></ol>",
         | 
| 295 | 
            -
                   " | 
| 332 | 
            +
                   "1. The quick\nbrown fox\n\tjumps over\nlazy dog.\n2. Humpty Dumpty\nsat\t\non a wall.")
         | 
| 296 333 |  | 
| 297 334 | 
             
                #  An item can contain line breaks
         | 
| 298 335 | 
             
                tc("<ol><li>The quick brown<br/>fox jumps over lazy dog.</li></ol>",
         | 
| 299 | 
            -
                   " | 
| 336 | 
            +
                   "1. The quick brown\\\\fox jumps over lazy dog.")
         | 
| 300 337 |  | 
| 301 338 | 
             
                #  Nested
         | 
| 302 | 
            -
                tc "<ol><li>Item 1<ol><li>Item 2</li></ol></li><li>Item 3</li></ol>", " | 
| 339 | 
            +
                tc "<ol><li>Item 1<ol><li>Item 2</li></ol></li><li>Item 3</li></ol>", "1. Item 1\n  1. Item 2\n2.\t\tItem 3\n"
         | 
| 303 340 |  | 
| 304 341 | 
             
                #  Nested up to 5 levels
         | 
| 305 342 | 
             
                tc("<ol><li>Item 1<ol><li>Item 2<ol><li>Item 3<ol><li>Item 4<ol><li>Item 5</li></ol></li></ol></li></ol></li></ol></li></ol>",
         | 
| 306 | 
            -
                   " | 
| 343 | 
            +
                   "1. Item 1\n  1. Item 2\n     1. Item 3\n      1. Item 4\n               1. Item 5\n")
         | 
| 307 344 |  | 
| 308 345 | 
             
                #  The two-bullet rule only applies to **.
         | 
| 309 | 
            -
                tc("<ol><li><ol><li>Item</li></ol></li></ol>", "##Item")
         | 
| 346 | 
            +
            #    tc("<ol><li><ol><li>Item</li></ol></li></ol>", "##Item")
         | 
| 310 347 | 
             
              end
         | 
| 311 348 |  | 
| 312 349 | 
             
              it 'should parse ordered lists #2' do
         | 
| 313 | 
            -
                tc "<ol><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol>", " | 
| 350 | 
            +
                tc "<ol><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol>", "1. Item 1\n1.    Item 2\n1.\t\tItem 3\n"
         | 
| 314 351 | 
             
                # Nested
         | 
| 315 | 
            -
                tc "<ol><li>Item 1<ol><li>Item 2</li></ol></li><li>Item 3</li></ol>", " | 
| 352 | 
            +
                tc "<ol><li>Item 1<ol><li>Item 2</li></ol></li><li>Item 3</li></ol>", "1. Item 1\n  1. Item 2\n1.\t\tItem 3\n"
         | 
| 316 353 | 
             
                # Multiline
         | 
| 317 | 
            -
                tc "<ol><li>Item 1 on multiple lines</li></ol>", " | 
| 354 | 
            +
                tc "<ol><li>Item 1 on multiple lines</li></ol>", "1. Item 1\non multiple lines"
         | 
| 318 355 | 
             
              end
         | 
| 319 356 |  | 
| 320 357 | 
             
              it 'should parse ambiguious mixed lists' do
         | 
| 321 358 | 
             
                # ol following ul
         | 
| 322 | 
            -
                tc("<ul><li>uitem</li></ul><ol><li>oitem</li></ol>", "*uitem\ | 
| 359 | 
            +
                tc("<ul><li>uitem</li></ul><ol><li>oitem</li></ol>", "* uitem\n1. oitem\n")
         | 
| 323 360 |  | 
| 324 361 | 
             
                # ul following ol
         | 
| 325 | 
            -
                tc("<ol><li>uitem</li></ol><ul><li>oitem</li></ul>", " | 
| 362 | 
            +
                tc("<ol><li>uitem</li></ol><ul><li>oitem</li></ul>", "1. uitem\n* oitem\n")
         | 
| 326 363 |  | 
| 327 364 | 
             
                # 2ol following ul
         | 
| 328 | 
            -
                tc("<ul><li>uitem<ol><li>oitem</li></ol></li></ul>", "*uitem\n | 
| 365 | 
            +
                tc("<ul><li>uitem<ol><li>oitem</li></ol></li></ul>", "* uitem\n  1. oitem\n")
         | 
| 329 366 |  | 
| 330 367 | 
             
                # 2ul following ol
         | 
| 331 | 
            -
                tc("<ol><li>uitem<ul><li>oitem</li></ul></li></ol>", " | 
| 368 | 
            +
                tc("<ol><li>uitem<ul><li>oitem</li></ul></li></ol>", "1. uitem\n  * oitem\n")
         | 
| 332 369 |  | 
| 333 370 | 
             
                # 3ol following 3ul
         | 
| 334 | 
            -
                tc("<ul><li><ul><li><ul><li>uitem</li></ul><ol><li>oitem</li></ol></li></ul></li></ul>", "***uitem\n###oitem\n")
         | 
| 371 | 
            +
            #    tc("<ul><li><ul><li><ul><li>uitem</li></ul><ol><li>oitem</li></ol></li></ul></li></ul>", "***uitem\n###oitem\n")
         | 
| 335 372 |  | 
| 336 373 | 
             
                # 2ul following 2ol
         | 
| 337 | 
            -
                tc("<ol><li><ol><li>uitem</li></ol><ul><li>oitem</li></ul></li></ol>", "##uitem\n**oitem\n")
         | 
| 374 | 
            +
            #    tc("<ol><li><ol><li>uitem</li></ol><ul><li>oitem</li></ul></li></ol>", "##uitem\n**oitem\n")
         | 
| 338 375 |  | 
| 339 376 | 
             
                # ol following 2ol
         | 
| 340 | 
            -
                tc("<ol><li><ol><li>oitem1</li></ol></li><li>oitem2</li></ol>", "##oitem1\n#oitem2\n")
         | 
| 377 | 
            +
            #    tc("<ol><li><ol><li>oitem1</li></ol></li><li>oitem2</li></ol>", "##oitem1\n#oitem2\n")
         | 
| 341 378 | 
             
                # ul following 2ol
         | 
| 342 | 
            -
                tc("<ol><li><ol><li>oitem1</li></ol></li></ol><ul><li>oitem2</li></ul>", "##oitem1\n*oitem2\n")
         | 
| 379 | 
            +
            #    tc("<ol><li><ol><li>oitem1</li></ol></li></ol><ul><li>oitem2</li></ul>", "##oitem1\n*oitem2\n")
         | 
| 343 380 | 
             
              end
         | 
| 344 381 |  | 
| 345 382 | 
             
              it 'should parse ambiguious italics and url' do
         | 
| @@ -358,12 +395,13 @@ describe TracWiki::Parser do | |
| 358 395 |  | 
| 359 396 | 
             
              it 'should parse ambiguious bold and lists' do
         | 
| 360 397 | 
             
                tc "<p><strong> bold text </strong></p>", "** bold text **"
         | 
| 361 | 
            -
                tc "<p | 
| 398 | 
            +
                tc "<p><blockquote><strong> bold text </strong></blockquote></p>", " ** bold text **"
         | 
| 362 399 | 
             
              end
         | 
| 363 400 |  | 
| 364 401 | 
             
              it 'should parse nowiki' do
         | 
| 365 402 | 
             
                # ... works as block
         | 
| 366 403 | 
             
                tc "<pre>Hello</pre>", "{{{\nHello\n}}}\n"
         | 
| 404 | 
            +
                tc "<p><tt>{{{-}}}</tt></p>", "`{{{-}}}`\n"
         | 
| 367 405 |  | 
| 368 406 | 
             
                # ... works inline
         | 
| 369 407 | 
             
                tc "<p>Hello <tt>world</tt>.</p>", "Hello {{{world}}}."
         | 
| @@ -373,8 +411,8 @@ describe TracWiki::Parser do | |
| 373 411 | 
             
                tc "<pre>**Hello**</pre>", "{{{\n**Hello**\n}}}\n"
         | 
| 374 412 |  | 
| 375 413 | 
             
                # Leading whitespaces are not permitted
         | 
| 376 | 
            -
                tc("<p> | 
| 377 | 
            -
                tc("<p>{{{ Hello | 
| 414 | 
            +
            #    tc("<p>{{{ Hello }}}</p>", " {{{\nHello\n}}}")
         | 
| 415 | 
            +
                tc("<p>{{{ Hello<blockquote>}}}</blockquote></p>", "{{{\nHello\n }}}")
         | 
| 378 416 |  | 
| 379 417 | 
             
                # Assumed: Should preserve whitespace
         | 
| 380 418 | 
             
                tc("<pre> \t Hello, \t \n \t World \t </pre>",
         | 
| @@ -395,7 +433,8 @@ describe TracWiki::Parser do | |
| 395 433 | 
             
                tc("<p><b>not bold</b></p>", "<b>not bold</b>")
         | 
| 396 434 |  | 
| 397 435 | 
             
                # Image tags should be escape
         | 
| 398 | 
            -
                tc("<p><img src | 
| 436 | 
            +
                tc("<p><img src='image.jpg'/></p>", "[[Image(image.jpg)]]")
         | 
| 437 | 
            +
                tc("<p><img src='image.jpg' alt='"tag"'/></p>", "[[Image(image.jpg|\"tag\")]]")
         | 
| 399 438 |  | 
| 400 439 | 
             
                # Malicious links should not be converted.
         | 
| 401 440 | 
             
                tc("<p><a href=\"javascript%3Aalert%28%22Boo%21%22%29\">Click</a></p>", "[[javascript:alert(\"Boo!\")|Click]]")
         | 
| @@ -407,7 +446,9 @@ describe TracWiki::Parser do | |
| 407 446 | 
             
                tc "<p>* Not Bullet</p>", "!* Not Bullet"
         | 
| 408 447 | 
             
                # Following char is not a blank (space or line feed)
         | 
| 409 448 | 
             
                tc "<p>Hello ~ world</p>", "Hello ~ world\n"
         | 
| 410 | 
            -
                tc "<p>Hello  | 
| 449 | 
            +
                tc "<p>Hello ! world</p>", "Hello ! world\n"
         | 
| 450 | 
            +
                tc "<p>Hello ! world</p>", "Hello ! world\n"
         | 
| 451 | 
            +
                tc "<p>Hello ! world</p>", "Hello !\nworld\n"
         | 
| 411 452 | 
             
                # Not escaping inside URLs 
         | 
| 412 453 | 
             
                tc "<p><a href=\"http://example.org/~user/\">http://example.org/~user/</a></p>", "http://example.org/~user/"
         | 
| 413 454 |  | 
| @@ -430,11 +471,22 @@ describe TracWiki::Parser do | |
| 430 471 | 
             
                tc "<p>---- foo</p>", "---- foo\n"
         | 
| 431 472 |  | 
| 432 473 | 
             
                # [...] no whitespace is allowed between them
         | 
| 433 | 
            -
                tc "<p | 
| 434 | 
            -
                tc "<p | 
| 474 | 
            +
                tc "<p>-- -- </p>", "-- -- "
         | 
| 475 | 
            +
                tc "<p>-- -- </p>", "--\t-- "
         | 
| 435 476 | 
             
              end
         | 
| 436 477 |  | 
| 437 478 | 
             
              it 'should parse table' do
         | 
| 479 | 
            +
                tc "<table><tr><td>Hello</td><td>World!</td></tr></table>", "||Hello||World!||"
         | 
| 480 | 
            +
                tc "<table><tr><td>Hello</td><td>World!</td></tr></table>", "||Hello||\\\n||World!||"
         | 
| 481 | 
            +
                tc "<table><tr><td>He</td><td>llo</td><td>World!</td></tr></table>", "||He||llo||\\\n||World!||"
         | 
| 482 | 
            +
                tc "<table><tr><td>Hello</td><td colspan='2'>World!</td></tr></table>", "||Hello||||World!||"
         | 
| 483 | 
            +
                tc "<table><tr><td>Hello</td><td colspan='2'>kuk</td><td>World!</td></tr></table>", "||Hello||||kuk||\\\n||World!||"
         | 
| 484 | 
            +
                tc "<table><tr><td>1</td><td>2</td><td>3</td></tr><tr><td colspan='2'>1-2</td><td>3</td></tr><tr><td>1</td><td colspan='2'>2-3</td></tr><tr><td colspan='3'>1-2-3</td></tr></table>", "|| 1 || 2 || 3 ||\n|||| 1-2 || 3 ||\n|| 1 |||| 2-3 ||\n|||||| 1-2-3 ||\n"
         | 
| 485 | 
            +
             | 
| 486 | 
            +
                tc "<table><tr><td>table</td><td style='text-align:center'>center</td></tr></table>", "||table||   center  ||"
         | 
| 487 | 
            +
                tc "<table><tr><td>table</td><td style='text-align:right'>right</td></tr></table>", "||table||   right||"
         | 
| 488 | 
            +
                tc "<table><tr><td>table</td><td style='text-align:center'>center</td><td style='text-align:right'>right</td></tr></table>", "||table||  center  ||   right||"
         | 
| 489 | 
            +
             | 
| 438 490 | 
             
                tc "<table><tr><td>Hello, World!</td></tr></table>", "||Hello, World!||"
         | 
| 439 491 | 
             
                tc "<table><tr><td style='text-align:right'>Hello, Right World!</td></tr></table>", "|| Hello, Right World!||"
         | 
| 440 492 | 
             
                tc "<table><tr><th style='text-align:right'>Hello, Right World!</th></tr></table>", "||= Hello, Right World!=||"
         | 
| @@ -457,7 +509,7 @@ describe TracWiki::Parser do | |
| 457 509 | 
             
                # Equal sign after pipe make a header
         | 
| 458 510 | 
             
                tc "<table><tr><th>Header</th></tr></table>", "||=Header=||"
         | 
| 459 511 |  | 
| 460 | 
            -
                tc "<table><tr><td>c1</td><td><a href=\"Link\">Link text</a></td><td><img src | 
| 512 | 
            +
                tc "<table><tr><td>c1</td><td><a href=\"Link\">Link text</a></td><td><img src='Image'/></td></tr></table>", "||c1||[[Link|Link text]]||[[Image(Image)]]||"
         | 
| 461 513 | 
             
              end
         | 
| 462 514 |  | 
| 463 515 | 
             
              it 'should parse following table' do
         | 
| @@ -468,11 +520,11 @@ describe TracWiki::Parser do | |
| 468 520 | 
             
                tc("<table><tr><td>table</td></tr></table><p>par</p>", "||table||\npar\n")
         | 
| 469 521 | 
             
                tc("<table><tr><td>table</td></tr></table><p>par</p>", "||table||\n\npar\n")
         | 
| 470 522 | 
             
                # table followed by unordered list
         | 
| 471 | 
            -
                tc("<table><tr><td>table</td></tr></table><ul><li>item</li></ul>", "||table||\n*item\n")
         | 
| 472 | 
            -
                tc("<table><tr><td>table</td></tr></table><ul><li>item</li></ul>", "||table||\n\n*item\n")
         | 
| 523 | 
            +
                tc("<table><tr><td>table</td></tr></table><ul><li>item</li></ul>", "||table||\n* item\n")
         | 
| 524 | 
            +
                tc("<table><tr><td>table</td></tr></table><ul><li>item</li></ul>", "||table||\n\n* item\n")
         | 
| 473 525 | 
             
                # table followed by ordered list
         | 
| 474 | 
            -
                tc("<table><tr><td>table</td></tr></table><ol><li>item</li></ol>", "||table||\ | 
| 475 | 
            -
                tc("<table><tr><td>table</td></tr></table><ol><li>item</li></ol>", "||table||\n\ | 
| 526 | 
            +
                tc("<table><tr><td>table</td></tr></table><ol><li>item</li></ol>", "||table||\n1. item\n")
         | 
| 527 | 
            +
                tc("<table><tr><td>table</td></tr></table><ol><li>item</li></ol>", "||table||\n\n1. item\n")
         | 
| 476 528 | 
             
                # table followed by horizontal rule
         | 
| 477 529 | 
             
                tc("<table><tr><td>table</td></tr></table><hr/>", "||table||\n----\n")
         | 
| 478 530 | 
             
                tc("<table><tr><td>table</td></tr></table><hr/>", "||table||\n\n----\n")
         | 
| @@ -492,11 +544,11 @@ describe TracWiki::Parser do | |
| 492 544 | 
             
                tc("<h1>heading</h1><p>par</p>", "=heading=\npar\n")
         | 
| 493 545 | 
             
                tc("<h1>heading</h1><p>par</p>", "=heading=\n\npar\n")
         | 
| 494 546 | 
             
                # unordered list
         | 
| 495 | 
            -
                tc("<h1>heading</h1><ul><li>item</li></ul>", "=heading=\n*item\n")
         | 
| 496 | 
            -
                tc("<h1>heading</h1><ul><li>item</li></ul>", "=heading=\n\n*item\n")
         | 
| 547 | 
            +
                tc("<h1>heading</h1><ul><li>item</li></ul>", "=heading=\n* item\n")
         | 
| 548 | 
            +
                tc("<h1>heading</h1><ul><li>item</li></ul>", "=heading=\n\n* item\n")
         | 
| 497 549 | 
             
                # ordered list
         | 
| 498 | 
            -
                tc("<h1>heading</h1><ol><li>item</li></ol>", "=heading=\ | 
| 499 | 
            -
                tc("<h1>heading</h1><ol><li>item</li></ol>", "=heading=\n\ | 
| 550 | 
            +
                tc("<h1>heading</h1><ol><li>item</li></ol>", "=heading=\n1. item\n")
         | 
| 551 | 
            +
                tc("<h1>heading</h1><ol><li>item</li></ol>", "=heading=\n\n1. item\n")
         | 
| 500 552 | 
             
                # horizontal rule
         | 
| 501 553 | 
             
                tc("<h1>heading</h1><hr/>", "=heading=\n----\n")
         | 
| 502 554 | 
             
                tc("<h1>heading</h1><hr/>", "=heading=\n\n----\n")
         | 
| @@ -516,11 +568,11 @@ describe TracWiki::Parser do | |
| 516 568 | 
             
                tc("<p>par par</p>", "par\npar\n")
         | 
| 517 569 | 
             
                tc("<p>par</p><p>par</p>", "par\n\npar\n")
         | 
| 518 570 | 
             
                # unordered
         | 
| 519 | 
            -
                tc("<p>par</p><ul><li>item</li></ul>", "par\n*item")
         | 
| 520 | 
            -
                tc("<p>par</p><ul><li>item</li></ul>", "par\n\n*item")
         | 
| 571 | 
            +
                tc("<p>par</p><ul><li>item</li></ul>", "par\n* item")
         | 
| 572 | 
            +
                tc("<p>par</p><ul><li>item</li></ul>", "par\n\n* item")
         | 
| 521 573 | 
             
                # ordered
         | 
| 522 | 
            -
                tc("<p>par</p><ol><li>item</li></ol>", "par\ | 
| 523 | 
            -
                tc("<p>par</p><ol><li>item</li></ol>", "par\n\ | 
| 574 | 
            +
                tc("<p>par</p><ol><li>item</li></ol>", "par\n1. item\n")
         | 
| 575 | 
            +
                tc("<p>par</p><ol><li>item</li></ol>", "par\n\n1. item\n")
         | 
| 524 576 | 
             
                # horizontal
         | 
| 525 577 | 
             
                tc("<p>par</p><hr/>", "par\n----\n")
         | 
| 526 578 | 
             
                tc("<p>par</p><hr/>", "par\n\n----\n")
         | 
| @@ -534,50 +586,50 @@ describe TracWiki::Parser do | |
| 534 586 |  | 
| 535 587 | 
             
              it 'should parse following unordered list' do
         | 
| 536 588 | 
             
                # heading
         | 
| 537 | 
            -
                tc("<ul><li>item</li></ul><h1>heading</h1>", "*item\n=heading=")
         | 
| 538 | 
            -
                tc("<ul><li>item</li></ul><h1>heading</h1>", "*item\n\n=heading=")
         | 
| 589 | 
            +
                tc("<ul><li>item</li></ul><h1>heading</h1>", "* item\n=heading=")
         | 
| 590 | 
            +
                tc("<ul><li>item</li></ul><h1>heading</h1>", "* item\n\n=heading=")
         | 
| 539 591 | 
             
                # paragraph
         | 
| 540 | 
            -
                tc("<ul><li>item par</li></ul>", "*item\npar\n") # items may span multiple lines
         | 
| 541 | 
            -
                tc("<ul><li>item</li></ul><p>par</p>", "*item\n\npar\n")
         | 
| 592 | 
            +
                tc("<ul><li>item par</li></ul>", "* item\npar\n") # items may span multiple lines
         | 
| 593 | 
            +
                tc("<ul><li>item</li></ul><p>par</p>", "* item\n\npar\n")
         | 
| 542 594 | 
             
                # unordered
         | 
| 543 | 
            -
                tc("<ul><li>item</li><li>item</li></ul>", "*item\n*item\n")
         | 
| 544 | 
            -
                tc("<ul><li>item</li></ul><ul><li>item</li></ul>", "*item\n\n*item\n")
         | 
| 595 | 
            +
                tc("<ul><li>item</li><li>item</li></ul>", "* item\n* item\n")
         | 
| 596 | 
            +
                tc("<ul><li>item</li></ul><ul><li>item</li></ul>", "* item\n\n* item\n")
         | 
| 545 597 | 
             
                # ordered
         | 
| 546 | 
            -
                tc("<ul><li>item</li></ul><ol><li>item</li></ol>", "*item\ | 
| 547 | 
            -
                tc("<ul><li>item</li></ul><ol><li>item</li></ol>", "*item\n\ | 
| 598 | 
            +
                tc("<ul><li>item</li></ul><ol><li>item</li></ol>", "* item\n1. item\n")
         | 
| 599 | 
            +
                tc("<ul><li>item</li></ul><ol><li>item</li></ol>", "* item\n\n1. item\n")
         | 
| 548 600 | 
             
                # horizontal rule
         | 
| 549 | 
            -
                tc("<ul><li>item</li></ul><hr/>", "*item\n----\n")
         | 
| 550 | 
            -
                tc("<ul><li>item</li></ul><hr/>", "*item\n\n----\n")
         | 
| 601 | 
            +
                tc("<ul><li>item</li></ul><hr/>", "* item\n----\n")
         | 
| 602 | 
            +
                tc("<ul><li>item</li></ul><hr/>", "* item\n\n----\n")
         | 
| 551 603 | 
             
                # nowiki
         | 
| 552 | 
            -
                tc("<ul><li>item</li></ul><pre>nowiki</pre>", "*item\n{{{\nnowiki\n}}}\n")
         | 
| 553 | 
            -
                tc("<ul><li>item</li></ul><pre>nowiki</pre>", "*item\n\n{{{\nnowiki\n}}}\n")
         | 
| 604 | 
            +
                tc("<ul><li>item</li></ul><pre>nowiki</pre>", "* item\n{{{\nnowiki\n}}}\n")
         | 
| 605 | 
            +
                tc("<ul><li>item</li></ul><pre>nowiki</pre>", "* item\n\n{{{\nnowiki\n}}}\n")
         | 
| 554 606 | 
             
                # table
         | 
| 555 | 
            -
                tc("<ul><li>item</li></ul><table><tr><td>table</td></tr></table>", "*item\n||table||\n")
         | 
| 556 | 
            -
                tc("<ul><li>item</li></ul><table><tr><td>table</td></tr></table>", "*item\n\n||table||\n")
         | 
| 607 | 
            +
                tc("<ul><li>item</li></ul><table><tr><td>table</td></tr></table>", "* item\n||table||\n")
         | 
| 608 | 
            +
                tc("<ul><li>item</li></ul><table><tr><td>table</td></tr></table>", "* item\n\n||table||\n")
         | 
| 557 609 | 
             
              end
         | 
| 558 610 |  | 
| 559 611 | 
             
              it 'should parse following ordered list' do
         | 
| 560 612 | 
             
                # heading
         | 
| 561 | 
            -
                tc("<ol><li>item</li></ol><h1>heading</h1>", " | 
| 562 | 
            -
                tc("<ol><li>item</li></ol><h1>heading</h1>", " | 
| 613 | 
            +
                tc("<ol><li>item</li></ol><h1>heading</h1>", "1. item\n=heading=")
         | 
| 614 | 
            +
                tc("<ol><li>item</li></ol><h1>heading</h1>", "1. item\n\n=heading=")
         | 
| 563 615 | 
             
                # paragraph
         | 
| 564 | 
            -
                tc("<ol><li>item par</li></ol>", " | 
| 565 | 
            -
                tc("<ol><li>item</li></ol><p>par</p>", " | 
| 616 | 
            +
                tc("<ol><li>item par</li></ol>", "1. item\npar\n") # items may span multiple lines
         | 
| 617 | 
            +
                tc("<ol><li>item</li></ol><p>par</p>", "1. item\n\npar\n")
         | 
| 566 618 | 
             
                # unordered
         | 
| 567 | 
            -
                tc("<ol><li>item</li></ol><ul><li>item</li></ul>", " | 
| 568 | 
            -
                tc("<ol><li>item</li></ol><ul><li>item</li></ul>", " | 
| 619 | 
            +
                tc("<ol><li>item</li></ol><ul><li>item</li></ul>", "1. item\n* item\n")
         | 
| 620 | 
            +
                tc("<ol><li>item</li></ol><ul><li>item</li></ul>", "1. item\n\n*   item\n")
         | 
| 569 621 | 
             
                # ordered
         | 
| 570 | 
            -
                tc("<ol><li>item</li><li>item</li></ol>", " | 
| 571 | 
            -
                tc("<ol><li>item</li></ol><ol><li>item</li></ol>", " | 
| 622 | 
            +
                tc("<ol><li>item</li><li>item</li></ol>", "1. item\n2. item\n")
         | 
| 623 | 
            +
                tc("<ol><li>item</li></ol><ol><li>item</li></ol>", "1. item\n\n1. item\n")
         | 
| 572 624 | 
             
                # horizontal role
         | 
| 573 | 
            -
                tc("<ol><li>item</li></ol><hr/>", " | 
| 574 | 
            -
                tc("<ol><li>item</li></ol><hr/>", " | 
| 625 | 
            +
                tc("<ol><li>item</li></ol><hr/>", "1. item\n----\n")
         | 
| 626 | 
            +
                tc("<ol><li>item</li></ol><hr/>", "1. item\n\n----\n")
         | 
| 575 627 | 
             
                # nowiki
         | 
| 576 | 
            -
                tc("<ol><li>item</li></ol><pre>nowiki</pre>", " | 
| 577 | 
            -
                tc("<ol><li>item</li></ol><pre>nowiki</pre>", " | 
| 628 | 
            +
                tc("<ol><li>item</li></ol><pre>nowiki</pre>", "1. item\n{{{\nnowiki\n}}}\n")
         | 
| 629 | 
            +
                tc("<ol><li>item</li></ol><pre>nowiki</pre>", "1. item\n\n{{{\nnowiki\n}}}\n")
         | 
| 578 630 | 
             
                # table
         | 
| 579 | 
            -
                tc("<ol><li>item</li></ol><table><tr><td>table</td></tr></table>", " | 
| 580 | 
            -
                tc("<ol><li>item</li></ol><table><tr><td>table</td></tr></table>", " | 
| 631 | 
            +
                tc("<ol><li>item</li></ol><table><tr><td>table</td></tr></table>", "1. item\n||table||\n")
         | 
| 632 | 
            +
                tc("<ol><li>item</li></ol><table><tr><td>table</td></tr></table>", "1. item\n\n||table||\n")
         | 
| 581 633 | 
             
              end
         | 
| 582 634 |  | 
| 583 635 | 
             
              it 'should parse following horizontal rule' do
         | 
| @@ -588,11 +640,14 @@ describe TracWiki::Parser do | |
| 588 640 | 
             
                tc("<hr/><p>par</p>", "----\npar\n")
         | 
| 589 641 | 
             
                tc("<hr/><p>par</p>", "----\n\npar\n")
         | 
| 590 642 | 
             
                # unordered
         | 
| 591 | 
            -
                tc("<hr/><ul><li>item</li></ul>", "----\n*item")
         | 
| 592 | 
            -
                tc("<hr/><ul><li>item</li></ul>", "----\n*item")
         | 
| 643 | 
            +
                tc("<hr/><ul><li>item</li></ul>", "----\n* item")
         | 
| 644 | 
            +
                tc("<hr/><ul><li>item</li></ul>", "----\n* item")
         | 
| 645 | 
            +
                tc("<hr/><ul><li>item</li></ul>", "----\n- item")
         | 
| 646 | 
            +
                tc("<hr/><ul><li>item</li></ul>", "----\n- item")
         | 
| 647 | 
            +
                tc("<hr/><ul><li>item</li></ul>", "----\n - item")
         | 
| 593 648 | 
             
                # ordered
         | 
| 594 | 
            -
                tc("<hr/><ol><li>item</li></ol>", "----\ | 
| 595 | 
            -
                tc("<hr/><ol><li>item</li></ol>", "----\ | 
| 649 | 
            +
                tc("<hr/><ol><li>item</li></ol>", "----\n1. item")
         | 
| 650 | 
            +
                tc("<hr/><ol><li>item</li></ol>", "----\n1. item")
         | 
| 596 651 | 
             
                # horizontal
         | 
| 597 652 | 
             
                tc("<hr/><hr/>", "----\n----\n")
         | 
| 598 653 | 
             
                tc("<hr/><hr/>", "----\n\n----\n")
         | 
| @@ -612,11 +667,11 @@ describe TracWiki::Parser do | |
| 612 667 | 
             
                tc("<pre>nowiki</pre><p>par</p>", "{{{\nnowiki\n}}}\npar")
         | 
| 613 668 | 
             
                tc("<pre>nowiki</pre><p>par</p>", "{{{\nnowiki\n}}}\n\npar")
         | 
| 614 669 | 
             
                # unordered
         | 
| 615 | 
            -
                tc("<pre>nowiki</pre><ul><li>item</li></ul>", "{{{\nnowiki\n}}}\n*item\n")
         | 
| 616 | 
            -
                tc("<pre>nowiki</pre><ul><li>item</li></ul>", "{{{\nnowiki\n}}}\n\n*item\n")
         | 
| 670 | 
            +
                tc("<pre>nowiki</pre><ul><li>item</li></ul>", "{{{\nnowiki\n}}}\n* item\n")
         | 
| 671 | 
            +
                tc("<pre>nowiki</pre><ul><li>item</li></ul>", "{{{\nnowiki\n}}}\n\n* item\n")
         | 
| 617 672 | 
             
                # ordered
         | 
| 618 | 
            -
                tc("<pre>nowiki</pre><ol><li>item</li></ol>", "{{{\nnowiki\n}}}\ | 
| 619 | 
            -
                tc("<pre>nowiki</pre><ol><li>item</li></ol>", "{{{\nnowiki\n}}}\n\ | 
| 673 | 
            +
                tc("<pre>nowiki</pre><ol><li>item</li></ol>", "{{{\nnowiki\n}}}\n1. item\n")
         | 
| 674 | 
            +
                tc("<pre>nowiki</pre><ol><li>item</li></ol>", "{{{\nnowiki\n}}}\n\n1. item\n")
         | 
| 620 675 | 
             
                # horizontal
         | 
| 621 676 | 
             
                tc("<pre>nowiki</pre><hr/>", "{{{\nnowiki\n}}}\n----\n")
         | 
| 622 677 | 
             
                tc("<pre>nowiki</pre><hr/>", "{{{\nnowiki\n}}}\n\n----\n")
         | 
| @@ -629,9 +684,9 @@ describe TracWiki::Parser do | |
| 629 684 | 
             
              end
         | 
| 630 685 |  | 
| 631 686 | 
             
              it 'should parse image' do
         | 
| 632 | 
            -
                tc("<p><img src | 
| 633 | 
            -
                tc("<p><img src | 
| 634 | 
            -
                tc("<p><img src | 
| 687 | 
            +
                tc("<p><img src='image.jpg'/></p>", "[[Image(image.jpg)]]")
         | 
| 688 | 
            +
                tc("<p><img src='image.jpg' alt='tag'/></p>", "[[Image(image.jpg|tag)]]")
         | 
| 689 | 
            +
                tc("<p><img src='http://example.org/image.jpg'/></p>", "[[Image(http://example.org/image.jpg)]]")
         | 
| 635 690 | 
             
              end
         | 
| 636 691 |  | 
| 637 692 | 
             
              it 'should parse bold combo' do
         | 
| @@ -647,7 +702,7 @@ describe TracWiki::Parser do | |
| 647 702 | 
             
                    "This is ~~deleted~~")
         | 
| 648 703 |  | 
| 649 704 | 
             
                tce("<p>This is <sup>super</sup></p>",
         | 
| 650 | 
            -
                    "This is  | 
| 705 | 
            +
                    "This is ^super^")
         | 
| 651 706 |  | 
| 652 707 | 
             
                tce("<p>This is <sub>sub</sub></p>",
         | 
| 653 708 | 
             
                    "This is ,,sub,,")
         | 
| @@ -663,3 +718,4 @@ describe TracWiki::Parser do | |
| 663 718 | 
             
                tc("<p><a href=\"a/b/c\">a/b/c</a></p>", "[[a/b/c]]", :no_escape => true)
         | 
| 664 719 | 
             
              end
         | 
| 665 720 | 
             
            end
         | 
| 721 | 
            +
            # vim: tw=0
         |