asciidoctor 1.5.5 → 1.5.6
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.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +216 -1
- data/CONTRIBUTING.adoc +2 -2
- data/Gemfile +20 -1
- data/LICENSE.adoc +1 -1
- data/README-fr.adoc +4 -3
- data/README-jp.adoc +11 -10
- data/README-zh_CN.adoc +4 -3
- data/README.adoc +17 -202
- data/Rakefile +41 -25
- data/asciidoctor.gemspec +9 -10
- data/data/locale/attributes.adoc +216 -34
- data/data/stylesheets/asciidoctor-default.css +23 -16
- data/features/step_definitions.rb +15 -19
- data/features/xref.feature +584 -20
- data/lib/asciidoctor.rb +292 -278
- data/lib/asciidoctor/abstract_block.rb +155 -94
- data/lib/asciidoctor/abstract_node.rb +108 -94
- data/lib/asciidoctor/attribute_list.rb +30 -22
- data/lib/asciidoctor/block.rb +7 -7
- data/lib/asciidoctor/cli/invoker.rb +47 -34
- data/lib/asciidoctor/cli/options.rb +22 -11
- data/lib/asciidoctor/converter.rb +3 -3
- data/lib/asciidoctor/converter/base.rb +2 -2
- data/lib/asciidoctor/converter/composite.rb +1 -1
- data/lib/asciidoctor/converter/docbook45.rb +2 -2
- data/lib/asciidoctor/converter/docbook5.rb +132 -87
- data/lib/asciidoctor/converter/factory.rb +0 -1
- data/lib/asciidoctor/converter/html5.rb +116 -98
- data/lib/asciidoctor/converter/manpage.rb +51 -52
- data/lib/asciidoctor/converter/template.rb +47 -36
- data/lib/asciidoctor/core_ext.rb +8 -2
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +4 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +5 -0
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +1 -1
- data/lib/asciidoctor/core_ext/1.8.7/string/{limit.rb → limit_bytesize.rb} +7 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +1 -1
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +5 -5
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +3 -0
- data/lib/asciidoctor/core_ext/string/{limit.rb → limit_bytesize.rb} +2 -2
- data/lib/asciidoctor/document.rb +216 -213
- data/lib/asciidoctor/extensions.rb +318 -185
- data/lib/asciidoctor/helpers.rb +35 -35
- data/lib/asciidoctor/inline.rb +32 -1
- data/lib/asciidoctor/list.rb +22 -6
- data/lib/asciidoctor/parser.rb +1008 -1038
- data/lib/asciidoctor/path_resolver.rb +46 -50
- data/lib/asciidoctor/reader.rb +275 -251
- data/lib/asciidoctor/section.rb +86 -58
- data/lib/asciidoctor/stylesheets.rb +6 -6
- data/lib/asciidoctor/substitutors.rb +567 -649
- data/lib/asciidoctor/table.rb +163 -108
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +18 -16
- data/man/asciidoctor.adoc +15 -13
- data/test/attributes_test.rb +138 -22
- data/test/blocks_test.rb +377 -97
- data/test/converter_test.rb +13 -0
- data/test/document_test.rb +244 -34
- data/test/extensions_test.rb +409 -42
- data/test/fixtures/asciidoc_index.txt +521 -0
- data/test/fixtures/basic-docinfo-footer.html +6 -0
- data/test/fixtures/basic-docinfo-footer.xml +8 -0
- data/test/fixtures/basic-docinfo.html +1 -0
- data/test/fixtures/basic-docinfo.xml +4 -0
- data/test/fixtures/basic.asciidoc +5 -0
- data/test/fixtures/chapter-a.adoc +3 -0
- data/test/fixtures/child-include.adoc +5 -0
- data/test/fixtures/circle.svg +9 -0
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +1 -0
- data/test/fixtures/custom-docinfodir/docinfo.html +1 -0
- data/test/fixtures/docinfo-footer.html +1 -0
- data/test/fixtures/docinfo-footer.xml +9 -0
- data/test/fixtures/docinfo.html +1 -0
- data/test/fixtures/docinfo.xml +3 -0
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +13 -0
- data/test/fixtures/grandchild-include.adoc +3 -0
- data/test/fixtures/hello-asciidoctor.pdf +69 -0
- data/test/fixtures/include-file.asciidoc +24 -0
- data/test/fixtures/include-file.ml +3 -0
- data/test/fixtures/include-file.xml +5 -0
- data/test/fixtures/master.adoc +5 -0
- data/test/fixtures/mismatched-end-tag.adoc +7 -0
- data/test/fixtures/parent-include-restricted.adoc +5 -0
- data/test/fixtures/parent-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +26 -0
- data/test/fixtures/stylesheets/custom.css +3 -0
- data/test/fixtures/subs-docinfo.html +2 -0
- data/test/fixtures/subs.adoc +7 -0
- data/test/fixtures/tagged-class-enclosed.rb +26 -0
- data/test/fixtures/tagged-class.rb +23 -0
- data/test/fixtures/tip.gif +0 -0
- data/test/invoker_test.rb +82 -4
- data/test/links_test.rb +312 -37
- data/test/lists_test.rb +204 -25
- data/test/manpage_test.rb +191 -4
- data/test/options_test.rb +18 -1
- data/test/paragraphs_test.rb +32 -7
- data/test/parser_test.rb +150 -30
- data/test/paths_test.rb +47 -13
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +366 -126
- data/test/sections_test.rb +203 -56
- data/test/substitutions_test.rb +339 -131
- data/test/tables_test.rb +315 -15
- data/test/test_helper.rb +400 -0
- data/test/text_test.rb +5 -5
- metadata +110 -22
| @@ -10,7 +10,7 @@ module Asciidoctor | |
| 10 10 | 
             
                TAB = %(\t)
         | 
| 11 11 | 
             
                WHITESPACE = %(#{LF}#{TAB} )
         | 
| 12 12 | 
             
                ET = ' ' * 8
         | 
| 13 | 
            -
                ESC = %(\u001b) | 
| 13 | 
            +
                ESC = %(\u001b) # troff leader marker
         | 
| 14 14 | 
             
                ESC_BS = %(#{ESC}\\) # escaped backslash (indicates troff formatting sequence)
         | 
| 15 15 | 
             
                ESC_FS = %(#{ESC}.)  # escaped full stop (indicates troff macro)
         | 
| 16 16 |  | 
| @@ -60,6 +60,7 @@ module Asciidoctor | |
| 60 60 | 
             
                    gsub('\'', '\(aq').       # apostrophe-quote
         | 
| 61 61 | 
             
                    gsub(MockBoundaryRx, ''). # mock boundary
         | 
| 62 62 | 
             
                    gsub(ESC_BS, '\\').       # unescape troff backslash (NOTE update if more escapes are added)
         | 
| 63 | 
            +
                    gsub(ESC_FS, '.').        # unescape full stop in troff commands (NOTE must take place after gsub(LeadingPeriodRx))
         | 
| 63 64 | 
             
                    rstrip                    # strip trailing space
         | 
| 64 65 | 
             
                  opts[:append_newline] ? %(#{str}#{LF}) : str
         | 
| 65 66 | 
             
                end
         | 
| @@ -159,13 +160,10 @@ Author(s). | |
| 159 160 | 
             
                end
         | 
| 160 161 |  | 
| 161 162 | 
             
                def section node
         | 
| 162 | 
            -
                  slevel = node.level
         | 
| 163 | 
            -
                  # QUESTION should the check for slevel be done in section?
         | 
| 164 | 
            -
                  slevel = 1 if slevel == 0 && node.special
         | 
| 165 163 | 
             
                  result = []
         | 
| 166 | 
            -
                  if  | 
| 164 | 
            +
                  if node.level > 1
         | 
| 167 165 | 
             
                    macro = 'SS'
         | 
| 168 | 
            -
                    # QUESTION why captioned title? why not  | 
| 166 | 
            +
                    # QUESTION why captioned title? why not when level == 1?
         | 
| 169 167 | 
             
                    stitle = node.captioned_title
         | 
| 170 168 | 
             
                  else
         | 
| 171 169 | 
             
                    macro = 'SH'
         | 
| @@ -187,7 +185,7 @@ Author(s). | |
| 187 185 | 
             
            .nr an-break-flag 1
         | 
| 188 186 | 
             
            .br
         | 
| 189 187 | 
             
            .ps +1
         | 
| 190 | 
            -
            .B #{node. | 
| 188 | 
            +
            .B #{node.attr 'textlabel'}#{node.title? ? "\\fP: #{manify node.title}" : nil}
         | 
| 191 189 | 
             
            .ps -1
         | 
| 192 190 | 
             
            .br
         | 
| 193 191 | 
             
            #{resolve_content node}
         | 
| @@ -196,7 +194,7 @@ Author(s). | |
| 196 194 | 
             
                  result * LF
         | 
| 197 195 | 
             
                end
         | 
| 198 196 |  | 
| 199 | 
            -
                alias  | 
| 197 | 
            +
                alias audio skip_with_warning
         | 
| 200 198 |  | 
| 201 199 | 
             
                def colist node
         | 
| 202 200 | 
             
                  result = []
         | 
| @@ -207,10 +205,12 @@ Author(s). | |
| 207 205 | 
             
            tab(:);
         | 
| 208 206 | 
             
            r lw(\n(.lu*75u/100u).'
         | 
| 209 207 |  | 
| 210 | 
            -
                   | 
| 211 | 
            -
             | 
| 212 | 
            -
            #{ | 
| 213 | 
            -
             | 
| 208 | 
            +
                  num = 0
         | 
| 209 | 
            +
                  node.items.each do |item|
         | 
| 210 | 
            +
                    result << %(\\fB(#{num += 1})\\fP\\h'-2n':T{)
         | 
| 211 | 
            +
                    result << (manify item.text)
         | 
| 212 | 
            +
                    result << item.content if item.blocks?
         | 
| 213 | 
            +
                    result << 'T}'
         | 
| 214 214 | 
             
                  end
         | 
| 215 215 | 
             
                  result << '.TE'
         | 
| 216 216 | 
             
                  result * LF
         | 
| @@ -226,11 +226,11 @@ T}) | |
| 226 226 | 
             
                    case node.style
         | 
| 227 227 | 
             
                    when 'qanda'
         | 
| 228 228 | 
             
                      result << %(.sp
         | 
| 229 | 
            -
            #{counter}. #{manify([*terms].map {|dt| dt.text } | 
| 229 | 
            +
            #{counter}. #{manify([*terms].map {|dt| dt.text } * ' ')}
         | 
| 230 230 | 
             
            .RS 4)
         | 
| 231 231 | 
             
                    else
         | 
| 232 232 | 
             
                      result << %(.sp
         | 
| 233 | 
            -
            #{manify([*terms].map {|dt| dt.text } | 
| 233 | 
            +
            #{manify([*terms].map {|dt| dt.text } * ', ')}
         | 
| 234 234 | 
             
            .RS 4)
         | 
| 235 235 | 
             
                    end
         | 
| 236 236 | 
             
                    if dd
         | 
| @@ -257,7 +257,7 @@ T}) | |
| 257 257 | 
             
                  %(.SS "#{manify node.title}")
         | 
| 258 258 | 
             
                end
         | 
| 259 259 |  | 
| 260 | 
            -
                alias  | 
| 260 | 
            +
                alias image skip_with_warning
         | 
| 261 261 |  | 
| 262 262 | 
             
                def listing node
         | 
| 263 263 | 
             
                  result = []
         | 
| @@ -328,7 +328,7 @@ T}) | |
| 328 328 | 
             
                end
         | 
| 329 329 |  | 
| 330 330 | 
             
                # TODO use Page Control https://www.gnu.org/software/groff/manual/html_node/Page-Control.html#Page-Control
         | 
| 331 | 
            -
                alias  | 
| 331 | 
            +
                alias page_break skip
         | 
| 332 332 |  | 
| 333 333 | 
             
                def paragraph node
         | 
| 334 334 | 
             
                  if node.title?
         | 
| @@ -342,7 +342,7 @@ T}) | |
| 342 342 | 
             
                  end
         | 
| 343 343 | 
             
                end
         | 
| 344 344 |  | 
| 345 | 
            -
                alias  | 
| 345 | 
            +
                alias preamble content
         | 
| 346 346 |  | 
| 347 347 | 
             
                def quote node
         | 
| 348 348 | 
             
                  result = []
         | 
| @@ -373,7 +373,7 @@ T}) | |
| 373 373 | 
             
                  result * LF
         | 
| 374 374 | 
             
                end
         | 
| 375 375 |  | 
| 376 | 
            -
                alias  | 
| 376 | 
            +
                alias sidebar skip_with_warning
         | 
| 377 377 |  | 
| 378 378 | 
             
                def stem node
         | 
| 379 379 | 
             
                  title_element = node.title? ? %(.sp
         | 
| @@ -402,15 +402,16 @@ T}) | |
| 402 402 | 
             
            .nr an-no-space-flag 1
         | 
| 403 403 | 
             
            .nr an-break-flag 1
         | 
| 404 404 | 
             
            .br
         | 
| 405 | 
            -
            .B #{manify node.captioned_title} | 
| 405 | 
            +
            .B #{manify node.captioned_title}
         | 
| 406 | 
            +
            )
         | 
| 406 407 | 
             
                  end
         | 
| 407 408 | 
             
                  result << '.TS
         | 
| 408 409 | 
             
            allbox tab(:);'
         | 
| 409 410 | 
             
                  row_header = []
         | 
| 410 411 | 
             
                  row_text = []
         | 
| 411 412 | 
             
                  row_index = 0
         | 
| 412 | 
            -
                   | 
| 413 | 
            -
                     | 
| 413 | 
            +
                  node.rows.by_section.each do |tsec, rows|
         | 
| 414 | 
            +
                    rows.each do |row|
         | 
| 414 415 | 
             
                      row_header[row_index] ||= []
         | 
| 415 416 | 
             
                      row_text[row_index] ||= []
         | 
| 416 417 | 
             
                      # result << LF
         | 
| @@ -430,19 +431,17 @@ allbox tab(:);' | |
| 430 431 | 
             
                          row_text[row_index] << %(T{#{LF}.sp#{LF}T}:)
         | 
| 431 432 | 
             
                        end
         | 
| 432 433 | 
             
                        row_text[row_index] << %(T{#{LF}.sp#{LF})
         | 
| 433 | 
            -
                        cell_halign = (cell.attr 'halign', 'left') | 
| 434 | 
            +
                        cell_halign = (cell.attr 'halign', 'left').chr
         | 
| 434 435 | 
             
                        if tsec == :head
         | 
| 435 | 
            -
                          if row_header[row_index].empty? ||
         | 
| 436 | 
            -
                             row_header[row_index][cell_index].empty?
         | 
| 436 | 
            +
                          if row_header[row_index].empty? || row_header[row_index][cell_index].empty?
         | 
| 437 437 | 
             
                            row_header[row_index][cell_index] << %(#{cell_halign}tB)
         | 
| 438 438 | 
             
                          else
         | 
| 439 439 | 
             
                            row_header[row_index][cell_index + 1] ||= []
         | 
| 440 440 | 
             
                            row_header[row_index][cell_index + 1] << %(#{cell_halign}tB)
         | 
| 441 441 | 
             
                          end
         | 
| 442 | 
            -
                          row_text[row_index] << %(#{cell.text}#{LF})
         | 
| 442 | 
            +
                          row_text[row_index] << %(#{manify cell.text}#{LF})
         | 
| 443 443 | 
             
                        elsif tsec == :body
         | 
| 444 | 
            -
                          if row_header[row_index].empty? ||
         | 
| 445 | 
            -
                             row_header[row_index][cell_index].empty?
         | 
| 444 | 
            +
                          if row_header[row_index].empty? || row_header[row_index][cell_index].empty?
         | 
| 446 445 | 
             
                            row_header[row_index][cell_index] << %(#{cell_halign}t)
         | 
| 447 446 | 
             
                          else
         | 
| 448 447 | 
             
                            row_header[row_index][cell_index + 1] ||= []
         | 
| @@ -451,26 +450,26 @@ allbox tab(:);' | |
| 451 450 | 
             
                          case cell.style
         | 
| 452 451 | 
             
                          when :asciidoc
         | 
| 453 452 | 
             
                            cell_content = cell.content
         | 
| 454 | 
            -
                          when : | 
| 455 | 
            -
                            cell_content = cell.text
         | 
| 453 | 
            +
                          when :literal
         | 
| 454 | 
            +
                            cell_content = %(.nf#{LF}#{manify cell.text}#{LF}.fi)
         | 
| 455 | 
            +
                          when :verse
         | 
| 456 | 
            +
                            cell_content = %(.nf#{LF}#{manify cell.text}#{LF}.fi)
         | 
| 456 457 | 
             
                          else
         | 
| 457 | 
            -
                            cell_content = cell.content.join
         | 
| 458 | 
            +
                            cell_content = manify cell.content.join
         | 
| 458 459 | 
             
                          end
         | 
| 459 460 | 
             
                          row_text[row_index] << %(#{cell_content}#{LF})
         | 
| 460 461 | 
             
                        elsif tsec == :foot
         | 
| 461 | 
            -
                          if row_header[row_index].empty? ||
         | 
| 462 | 
            -
                             row_header[row_index][cell_index].empty?
         | 
| 462 | 
            +
                          if row_header[row_index].empty? || row_header[row_index][cell_index].empty?
         | 
| 463 463 | 
             
                            row_header[row_index][cell_index] << %(#{cell_halign}tB)
         | 
| 464 464 | 
             
                          else
         | 
| 465 465 | 
             
                            row_header[row_index][cell_index + 1] ||= []
         | 
| 466 466 | 
             
                            row_header[row_index][cell_index + 1] << %(#{cell_halign}tB)
         | 
| 467 467 | 
             
                          end
         | 
| 468 | 
            -
                          row_text[row_index] << %(#{cell.text}#{LF})
         | 
| 468 | 
            +
                          row_text[row_index] << %(#{manify cell.text}#{LF})
         | 
| 469 469 | 
             
                        end
         | 
| 470 470 | 
             
                        if cell.colspan && cell.colspan > 1
         | 
| 471 471 | 
             
                          (cell.colspan - 1).times do |i|
         | 
| 472 | 
            -
                            if row_header[row_index].empty? ||
         | 
| 473 | 
            -
                               row_header[row_index][cell_index].empty?
         | 
| 472 | 
            +
                            if row_header[row_index].empty? || row_header[row_index][cell_index].empty?
         | 
| 474 473 | 
             
                              row_header[row_index][cell_index + i] << 'st'
         | 
| 475 474 | 
             
                            else
         | 
| 476 475 | 
             
                              row_header[row_index][cell_index + 1 + i] ||= []
         | 
| @@ -481,8 +480,7 @@ allbox tab(:);' | |
| 481 480 | 
             
                        if cell.rowspan && cell.rowspan > 1
         | 
| 482 481 | 
             
                          (cell.rowspan - 1).times do |i|
         | 
| 483 482 | 
             
                            row_header[row_index + 1 + i] ||= []
         | 
| 484 | 
            -
                            if row_header[row_index + 1 + i].empty? ||
         | 
| 485 | 
            -
                               row_header[row_index + 1 + i][cell_index].empty?
         | 
| 483 | 
            +
                            if row_header[row_index + 1 + i].empty? || row_header[row_index + 1 + i][cell_index].empty?
         | 
| 486 484 | 
             
                              row_header[row_index + 1 + i][cell_index] ||= []
         | 
| 487 485 | 
             
                              row_header[row_index + 1 + i][cell_index] << '^t'
         | 
| 488 486 | 
             
                            else
         | 
| @@ -498,19 +496,19 @@ allbox tab(:);' | |
| 498 496 | 
             
                        end
         | 
| 499 497 | 
             
                      end
         | 
| 500 498 | 
             
                      row_index += 1
         | 
| 501 | 
            -
                    end
         | 
| 499 | 
            +
                    end unless rows.empty?
         | 
| 502 500 | 
             
                  end
         | 
| 503 501 |  | 
| 504 502 | 
             
                  #row_header.each do |row|
         | 
| 505 503 | 
             
                  #  result << LF
         | 
| 506 504 | 
             
                  #  row.each_with_index do |cell, i|
         | 
| 507 | 
            -
                  #    result << (cell | 
| 505 | 
            +
                  #    result << (cell * ' ')
         | 
| 508 506 | 
             
                  #    result << ' ' if row.size > i + 1
         | 
| 509 507 | 
             
                  #  end
         | 
| 510 508 | 
             
                  #end
         | 
| 511 509 | 
             
                  # FIXME temporary fix to get basic table to display
         | 
| 512 510 | 
             
                  result << LF
         | 
| 513 | 
            -
                  result << row_header. | 
| 511 | 
            +
                  result << row_header[0].map { 'lt' } * ' '
         | 
| 514 512 |  | 
| 515 513 | 
             
                  result << %(.#{LF})
         | 
| 516 514 | 
             
                  row_text.each do |row|
         | 
| @@ -526,7 +524,7 @@ allbox tab(:);' | |
| 526 524 | 
             
            \l\'\n(.lu*25u/100u\(ap\''
         | 
| 527 525 | 
             
                end
         | 
| 528 526 |  | 
| 529 | 
            -
                alias  | 
| 527 | 
            +
                alias toc skip
         | 
| 530 528 |  | 
| 531 529 | 
             
                def ulist node
         | 
| 532 530 | 
             
                  result = []
         | 
| @@ -578,8 +576,12 @@ allbox tab(:);' | |
| 578 576 | 
             
                def video node
         | 
| 579 577 | 
             
                  start_param = (node.attr? 'start', nil, false) ? %(&start=#{node.attr 'start'}) : nil
         | 
| 580 578 | 
             
                  end_param = (node.attr? 'end', nil, false) ? %(&end=#{node.attr 'end'}) : nil
         | 
| 581 | 
            -
                   | 
| 582 | 
            -
             | 
| 579 | 
            +
                  result = []
         | 
| 580 | 
            +
                  result << %(.sp
         | 
| 581 | 
            +
            .B #{manify node.title}
         | 
| 582 | 
            +
            .br) if node.title?
         | 
| 583 | 
            +
                  result << %(<#{node.media_uri(node.attr 'target')}#{start_param}#{end_param}> (video))
         | 
| 584 | 
            +
                  result * LF
         | 
| 583 585 | 
             
                end
         | 
| 584 586 |  | 
| 585 587 | 
             
                def inline_anchor node
         | 
| @@ -600,9 +602,9 @@ allbox tab(:);' | |
| 600 602 | 
             
                    %(#{ESC_BS}c#{LF}#{ESC_FS}#{macro} "#{target}" "#{text}" )
         | 
| 601 603 | 
             
                  when :xref
         | 
| 602 604 | 
             
                    refid = (node.attr 'refid') || target
         | 
| 603 | 
            -
                    node.text || (node.document. | 
| 605 | 
            +
                    node.text || (node.document.catalog[:ids][refid] || %([#{refid}]))
         | 
| 604 606 | 
             
                  when :ref, :bibref
         | 
| 605 | 
            -
                    # These are anchor points, which shouldn't be  | 
| 607 | 
            +
                    # These are anchor points, which shouldn't be visible
         | 
| 606 608 | 
             
                    ''
         | 
| 607 609 | 
             
                  else
         | 
| 608 610 | 
             
                    warn %(asciidoctor: WARNING: unknown anchor type: #{node.type.inspect})
         | 
| @@ -610,8 +612,7 @@ allbox tab(:);' | |
| 610 612 | 
             
                end
         | 
| 611 613 |  | 
| 612 614 | 
             
                def inline_break node
         | 
| 613 | 
            -
                  %(#{node.text}
         | 
| 614 | 
            -
            .br)
         | 
| 615 | 
            +
                  %(#{node.text}#{LF}#{ESC_FS}br)
         | 
| 615 616 | 
             
                end
         | 
| 616 617 |  | 
| 617 618 | 
             
                def inline_button node
         | 
| @@ -632,9 +633,7 @@ allbox tab(:);' | |
| 632 633 | 
             
                end
         | 
| 633 634 |  | 
| 634 635 | 
             
                def inline_image node
         | 
| 635 | 
            -
                   | 
| 636 | 
            -
                  alt_text = (node.attr? 'alt') ? (node.attr 'alt') : node.target
         | 
| 637 | 
            -
                  (node.attr? 'link') ? %([#{alt_text}] <#{node.attr 'link'}>) : %([#{alt_text}])
         | 
| 636 | 
            +
                  (node.attr? 'link') ? %([#{node.alt}] <#{node.attr 'link'}>) : %([#{node.alt}])
         | 
| 638 637 | 
             
                end
         | 
| 639 638 |  | 
| 640 639 | 
             
                def inline_indexterm node
         | 
| @@ -645,7 +644,7 @@ allbox tab(:);' | |
| 645 644 | 
             
                  if (keys = node.attr 'keys').size == 1
         | 
| 646 645 | 
             
                    keys[0]
         | 
| 647 646 | 
             
                  else
         | 
| 648 | 
            -
                    keys | 
| 647 | 
            +
                    keys * %(#{ESC_BS}0+#{ESC_BS}0)
         | 
| 649 648 | 
             
                  end
         | 
| 650 649 | 
             
                end
         | 
| 651 650 |  | 
| @@ -653,7 +652,7 @@ allbox tab(:);' | |
| 653 652 | 
             
                  caret = %[#{ESC_BS}0#{ESC_BS}(fc#{ESC_BS}0]
         | 
| 654 653 | 
             
                  menu = node.attr 'menu'
         | 
| 655 654 | 
             
                  if !(submenus = node.attr 'submenus').empty?
         | 
| 656 | 
            -
                    submenu_path = submenus.map {|item| %(#{ESC_BS}fI#{item}#{ESC_BS}fP) } | 
| 655 | 
            +
                    submenu_path = submenus.map {|item| %(#{ESC_BS}fI#{item}#{ESC_BS}fP) } * caret
         | 
| 657 656 | 
             
                    %(#{ESC_BS}fI#{menu}#{ESC_BS}fP#{caret}#{submenu_path}#{caret}#{ESC_BS}fI#{node.attr 'menuitem'}#{ESC_BS}fP)
         | 
| 658 657 | 
             
                  elsif (menuitem = node.attr 'menuitem')
         | 
| 659 658 | 
             
                    %(#{ESC_BS}fI#{menu}#{caret}#{menuitem}#{ESC_BS}fP)
         | 
| @@ -5,9 +5,9 @@ module Asciidoctor | |
| 5 5 | 
             
              # {AbstractNode} objects from a parsed AsciiDoc document tree to the backend
         | 
| 6 6 | 
             
              # format.
         | 
| 7 7 | 
             
              #
         | 
| 8 | 
            -
              # The converter scans the  | 
| 8 | 
            +
              # The converter scans the specified directories for template files that are
         | 
| 9 9 | 
             
              # supported by Tilt. If an engine name (e.g., "slim") is specified in the
         | 
| 10 | 
            -
              # options Hash passed to the constructor, the scan is  | 
| 10 | 
            +
              # options Hash passed to the constructor, the scan is restricted to template
         | 
| 11 11 | 
             
              # files that have a matching extension (e.g., ".slim"). The scanner trims any
         | 
| 12 12 | 
             
              # extensions from the basename of the file and uses the resulting name as the
         | 
| 13 13 | 
             
              # key under which to store the template. When the {Converter#convert} method
         | 
| @@ -15,20 +15,21 @@ module Asciidoctor | |
| 15 15 | 
             
              # table and use it to convert the node.
         | 
| 16 16 | 
             
              #
         | 
| 17 17 | 
             
              # For example, the template file "path/to/templates/paragraph.html.slim" will
         | 
| 18 | 
            -
              # be registered as the "paragraph" transform. The template  | 
| 19 | 
            -
              #  | 
| 20 | 
            -
              #  | 
| 18 | 
            +
              # be registered as the "paragraph" transform. The template is then used to
         | 
| 19 | 
            +
              # convert a paragraph {Block} object from the parsed AsciiDoc tree to an HTML
         | 
| 20 | 
            +
              # backend format (e.g., "html5").
         | 
| 21 21 | 
             
              #
         | 
| 22 22 | 
             
              # As an optimization, scan results and templates are cached for the lifetime
         | 
| 23 23 | 
             
              # of the Ruby process. If the {https://rubygems.org/gems/thread_safe
         | 
| 24 24 | 
             
              # thread_safe} gem is installed, these caches are guaranteed to be thread
         | 
| 25 | 
            -
              # safe. If this gem is not present,  | 
| 25 | 
            +
              # safe. If this gem is not present, there is no such guarantee and a warning
         | 
| 26 | 
            +
              # will be issued.
         | 
| 26 27 | 
             
              class Converter::TemplateConverter < Converter::Base
         | 
| 27 28 | 
             
                DEFAULT_ENGINE_OPTIONS = {
         | 
| 28 29 | 
             
                  :erb =>  { :trim => '<' },
         | 
| 29 30 | 
             
                  # TODO line 466 of haml/compiler.rb sorts the attributes; file an issue to make this configurable
         | 
| 30 31 | 
             
                  # NOTE AsciiDoc syntax expects HTML/XML output to use double quotes around attribute values
         | 
| 31 | 
            -
                  :haml => { :format => :xhtml, :attr_wrapper => '"', : | 
| 32 | 
            +
                  :haml => { :format => :xhtml, :attr_wrapper => '"', :escape_attrs => false, :ugly => true },
         | 
| 32 33 | 
             
                  :slim => { :disable_escape => true, :sort_attrs => false, :pretty => false }
         | 
| 33 34 | 
             
                }
         | 
| 34 35 |  | 
| @@ -58,6 +59,7 @@ module Asciidoctor | |
| 58 59 | 
             
                  @template_dirs = template_dirs
         | 
| 59 60 | 
             
                  @eruby = opts[:eruby]
         | 
| 60 61 | 
             
                  @safe = opts[:safe]
         | 
| 62 | 
            +
                  @active_engines = {}
         | 
| 61 63 | 
             
                  @engine = opts[:template_engine]
         | 
| 62 64 | 
             
                  @engine_options = DEFAULT_ENGINE_OPTIONS.inject({}) do |accum, (engine, default_opts)|
         | 
| 63 65 | 
             
                    accum[engine] = default_opts.dup
         | 
| @@ -67,6 +69,7 @@ module Asciidoctor | |
| 67 69 | 
             
                    @engine_options[:haml][:format] = :html5
         | 
| 68 70 | 
             
                    @engine_options[:slim][:format] = :html
         | 
| 69 71 | 
             
                  end
         | 
| 72 | 
            +
                  @engine_options[:slim][:include_dirs] = template_dirs.reverse.map {|dir| ::File.expand_path dir }
         | 
| 70 73 | 
             
                  if (overrides = opts[:template_engine_options])
         | 
| 71 74 | 
             
                    overrides.each do |engine, override_opts|
         | 
| 72 75 | 
             
                      (@engine_options[engine] ||= {}).update override_opts
         | 
| @@ -208,7 +211,7 @@ module Asciidoctor | |
| 208 211 | 
             
                #
         | 
| 209 212 | 
             
                # Returns a [Hash] of Tilt template objects keyed by template name.
         | 
| 210 213 | 
             
                def templates
         | 
| 211 | 
            -
                  @templates.dup | 
| 214 | 
            +
                  @templates.dup
         | 
| 212 215 | 
             
                end
         | 
| 213 216 |  | 
| 214 217 | 
             
                # Public: Registers a Tilt template with this converter.
         | 
| @@ -231,45 +234,53 @@ module Asciidoctor | |
| 231 234 | 
             
                #
         | 
| 232 235 | 
             
                # Returns the scan result as a [Hash]
         | 
| 233 236 | 
             
                def scan_dir template_dir, pattern, template_cache = nil
         | 
| 234 | 
            -
                  result = {}
         | 
| 235 | 
            -
                  eruby_loaded = nil
         | 
| 237 | 
            +
                  result, helpers = {}, nil
         | 
| 236 238 | 
             
                  # Grab the files in the top level of the directory (do not recurse)
         | 
| 237 239 | 
             
                  ::Dir.glob(pattern).select {|match| ::File.file? match }.each do |file|
         | 
| 238 | 
            -
                    if (basename = ::File.basename file) == 'helpers.rb' | 
| 240 | 
            +
                    if (basename = ::File.basename file) == 'helpers.rb'
         | 
| 241 | 
            +
                      helpers = file
         | 
| 242 | 
            +
                      next
         | 
| 243 | 
            +
                    elsif (path_segments = basename.split '.').size < 2
         | 
| 239 244 | 
             
                      next
         | 
| 240 245 | 
             
                    end
         | 
| 241 | 
            -
                     | 
| 242 | 
            -
                    #name, *rest, ext_name = *path_segments # this form only works in Ruby >= 1.9
         | 
| 243 | 
            -
                    name = path_segments[0]
         | 
| 244 | 
            -
                    if name == 'block_ruler'
         | 
| 246 | 
            +
                    if (name = path_segments[0]) == 'block_ruler'
         | 
| 245 247 | 
             
                      name = 'thematic_break'
         | 
| 246 248 | 
             
                    elsif name.start_with? 'block_'
         | 
| 247 | 
            -
                      name = name | 
| 248 | 
            -
                    end
         | 
| 249 | 
            -
                    
         | 
| 250 | 
            -
                    template_class = ::Tilt
         | 
| 251 | 
            -
                    extra_engine_options = {}
         | 
| 252 | 
            -
                    case (ext_name = path_segments[-1])
         | 
| 253 | 
            -
                    when 'slim'
         | 
| 254 | 
            -
                      # slim doesn't get loaded by Tilt, so we have to load it explicitly
         | 
| 255 | 
            -
                      Helpers.require_library 'slim' unless defined? ::Slim
         | 
| 256 | 
            -
                      # align safe mode of AsciiDoc embedded in Slim template with safe mode of current document
         | 
| 257 | 
            -
                      (@engine_options[:slim][:asciidoc] ||= {})[:safe] ||= @safe if @safe && ::Slim::VERSION >= '3.0'
         | 
| 258 | 
            -
                      # load include plugin when using Slim >= 2.1
         | 
| 259 | 
            -
                      require 'slim/include' unless (defined? ::Slim::Include) || ::Slim::VERSION < '2.1'
         | 
| 260 | 
            -
                    when 'erb'
         | 
| 261 | 
            -
                      template_class, extra_engine_options = (eruby_loaded ||= load_eruby(@eruby))
         | 
| 262 | 
            -
                    when 'rb'
         | 
| 263 | 
            -
                      next
         | 
| 264 | 
            -
                    else
         | 
| 265 | 
            -
                      next unless ::Tilt.registered? ext_name
         | 
| 249 | 
            +
                      name = name.slice 6, name.length
         | 
| 266 250 | 
             
                    end
         | 
| 267 251 | 
             
                    unless template_cache && (template = template_cache[file])
         | 
| 268 | 
            -
                       | 
| 252 | 
            +
                      template_class, extra_engine_options, extsym = ::Tilt, {}, path_segments[-1].to_sym
         | 
| 253 | 
            +
                      case extsym
         | 
| 254 | 
            +
                      when :slim
         | 
| 255 | 
            +
                        unless @active_engines[extsym]
         | 
| 256 | 
            +
                          # NOTE slim doesn't get automatically loaded by Tilt
         | 
| 257 | 
            +
                          Helpers.require_library 'slim' unless defined? ::Slim
         | 
| 258 | 
            +
                          # align safe mode of AsciiDoc embedded in Slim template with safe mode of current document
         | 
| 259 | 
            +
                          # NOTE safe mode won't get updated if using template cache and changing safe mode
         | 
| 260 | 
            +
                          (@engine_options[extsym][:asciidoc] ||= {})[:safe] ||= @safe if @safe && ::Slim::VERSION >= '3.0'
         | 
| 261 | 
            +
                          # load include plugin when using Slim >= 2.1
         | 
| 262 | 
            +
                          require 'slim/include' unless (defined? ::Slim::Include) || ::Slim::VERSION < '2.1'
         | 
| 263 | 
            +
                          @active_engines[extsym] = true
         | 
| 264 | 
            +
                        end
         | 
| 265 | 
            +
                      when :haml
         | 
| 266 | 
            +
                        unless @active_engines[extsym]
         | 
| 267 | 
            +
                          Helpers.require_library 'haml' unless defined? ::Haml
         | 
| 268 | 
            +
                          # NOTE Haml 5 dropped support for pretty printing
         | 
| 269 | 
            +
                          @engine_options[extsym].delete :ugly if defined? ::Haml::TempleEngine
         | 
| 270 | 
            +
                          @active_engines[extsym] = true
         | 
| 271 | 
            +
                        end
         | 
| 272 | 
            +
                      when :erb
         | 
| 273 | 
            +
                        template_class, extra_engine_options = (@active_engines[extsym] ||= (load_eruby @eruby))
         | 
| 274 | 
            +
                      when :rb
         | 
| 275 | 
            +
                        next
         | 
| 276 | 
            +
                      else
         | 
| 277 | 
            +
                        next unless ::Tilt.registered? extsym.to_s
         | 
| 278 | 
            +
                      end
         | 
| 279 | 
            +
                      template = template_class.new file, 1, (@engine_options[extsym] ||= {}).merge(extra_engine_options)
         | 
| 269 280 | 
             
                    end
         | 
| 270 281 | 
             
                    result[name] = template
         | 
| 271 282 | 
             
                  end
         | 
| 272 | 
            -
                  if ::File.file?(helpers = (::File.join template_dir, 'helpers.rb'))
         | 
| 283 | 
            +
                  if helpers || ::File.file?(helpers = (::File.join template_dir, 'helpers.rb'))
         | 
| 273 284 | 
             
                    require helpers
         | 
| 274 285 | 
             
                  end
         | 
| 275 286 | 
             
                  result
         | 
    
        data/lib/asciidoctor/core_ext.rb
    CHANGED
    
    | @@ -1,8 +1,14 @@ | |
| 1 1 | 
             
            require 'asciidoctor/core_ext/nil_or_empty'
         | 
| 2 | 
            +
            require 'asciidoctor/core_ext/regexp/is_match'
         | 
| 2 3 | 
             
            if RUBY_MIN_VERSION_1_9
         | 
| 3 | 
            -
              require 'asciidoctor/core_ext/string/ | 
| 4 | 
            +
              require 'asciidoctor/core_ext/string/limit_bytesize'
         | 
| 5 | 
            +
              require 'asciidoctor/core_ext/1.8.7/io/write' if RUBY_ENGINE == 'opal'
         | 
| 4 6 | 
             
            elsif RUBY_ENGINE != 'opal'
         | 
| 7 | 
            +
              require 'asciidoctor/core_ext/1.8.7/hash/key'
         | 
| 8 | 
            +
              require 'asciidoctor/core_ext/1.8.7/io/binread'
         | 
| 9 | 
            +
              require 'asciidoctor/core_ext/1.8.7/io/write'
         | 
| 5 10 | 
             
              require 'asciidoctor/core_ext/1.8.7/string/chr'
         | 
| 6 | 
            -
              require 'asciidoctor/core_ext/1.8.7/string/ | 
| 11 | 
            +
              require 'asciidoctor/core_ext/1.8.7/string/limit_bytesize'
         | 
| 12 | 
            +
              require 'asciidoctor/core_ext/1.8.7/symbol/empty'
         | 
| 7 13 | 
             
              require 'asciidoctor/core_ext/1.8.7/symbol/length'
         | 
| 8 14 | 
             
            end
         |