asciidoctor 1.5.6.2 → 1.5.7
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 +330 -143
- data/README-fr.adoc +441 -0
- data/README-jp.adoc +418 -0
- data/README-zh_CN.adoc +430 -0
- data/README.adoc +454 -0
- data/Rakefile +57 -0
- data/asciidoctor.gemspec +7 -1
- data/data/locale/attributes-ar.adoc +22 -0
- data/data/locale/attributes-bg.adoc +22 -0
- data/data/locale/attributes-ca.adoc +22 -0
- data/data/locale/attributes-cs.adoc +22 -0
- data/data/locale/attributes-da.adoc +22 -0
- data/data/locale/attributes-de.adoc +22 -0
- data/data/locale/attributes-en.adoc +23 -0
- data/data/locale/attributes-es.adoc +22 -0
- data/data/locale/attributes-fa.adoc +22 -0
- data/data/locale/attributes-fi.adoc +22 -0
- data/data/locale/attributes-fr.adoc +22 -0
- data/data/locale/attributes-hu.adoc +22 -0
- data/data/locale/attributes-id.adoc +22 -0
- data/data/locale/attributes-it.adoc +22 -0
- data/data/locale/attributes-ja.adoc +22 -0
- data/data/locale/attributes-kr.adoc +22 -0
- data/data/locale/attributes-nb.adoc +22 -0
- data/data/locale/attributes-nl.adoc +22 -0
- data/data/locale/attributes-nn.adoc +22 -0
- data/data/locale/attributes-pl.adoc +22 -0
- data/data/locale/attributes-pt.adoc +22 -0
- data/data/locale/attributes-pt_BR.adoc +22 -0
- data/data/locale/attributes-ro.adoc +22 -0
- data/data/locale/attributes-ru.adoc +22 -0
- data/data/locale/attributes-sr.adoc +22 -0
- data/data/locale/attributes-sr_Latn.adoc +22 -0
- data/data/locale/attributes-tr.adoc +22 -0
- data/data/locale/attributes-uk.adoc +22 -0
- data/data/locale/attributes-zh_CN.adoc +22 -0
- data/data/locale/attributes-zh_TW.adoc +22 -0
- data/data/locale/attributes.adoc +8 -649
- data/data/stylesheets/asciidoctor-default.css +77 -72
- data/features/xref.feature +366 -7
- data/lib/asciidoctor.rb +107 -93
- data/lib/asciidoctor/abstract_block.rb +247 -239
- data/lib/asciidoctor/abstract_node.rb +56 -58
- data/lib/asciidoctor/block.rb +3 -3
- data/lib/asciidoctor/callouts.rb +1 -1
- data/lib/asciidoctor/cli/invoker.rb +36 -9
- data/lib/asciidoctor/cli/options.rb +63 -25
- data/lib/asciidoctor/converter.rb +23 -13
- data/lib/asciidoctor/converter/base.rb +4 -0
- data/lib/asciidoctor/converter/docbook45.rb +16 -9
- data/lib/asciidoctor/converter/docbook5.rb +115 -97
- data/lib/asciidoctor/converter/factory.rb +29 -31
- data/lib/asciidoctor/converter/html5.rb +229 -192
- data/lib/asciidoctor/converter/manpage.rb +72 -50
- data/lib/asciidoctor/converter/template.rb +12 -12
- data/lib/asciidoctor/core_ext.rb +5 -1
- data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +6 -0
- data/lib/asciidoctor/document.rb +168 -77
- data/lib/asciidoctor/extensions.rb +79 -47
- data/lib/asciidoctor/helpers.rb +33 -11
- data/lib/asciidoctor/inline.rb +3 -2
- data/lib/asciidoctor/list.rb +2 -1
- data/lib/asciidoctor/logging.rb +122 -0
- data/lib/asciidoctor/parser.rb +406 -382
- data/lib/asciidoctor/path_resolver.rb +169 -162
- data/lib/asciidoctor/reader.rb +166 -121
- data/lib/asciidoctor/section.rb +45 -28
- data/lib/asciidoctor/stylesheets.rb +13 -5
- data/lib/asciidoctor/substitutors.rb +328 -254
- data/lib/asciidoctor/table.rb +105 -48
- data/lib/asciidoctor/timings.rb +34 -6
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +41 -23
- data/man/asciidoctor.adoc +14 -8
- data/test/api_test.rb +1004 -0
- data/test/attributes_test.rb +241 -50
- data/test/blocks_test.rb +549 -124
- data/test/converter_test.rb +170 -78
- data/test/document_test.rb +208 -767
- data/test/extensions_test.rb +188 -53
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +1 -1
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +1 -1
- data/test/fixtures/file-with-missing-include.adoc +1 -0
- data/test/fixtures/include-file.jsx +8 -0
- data/test/fixtures/lists.adoc +96 -0
- data/test/fixtures/other-chapters.adoc +11 -0
- data/test/fixtures/outer-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +5 -1
- data/test/fixtures/subdir/index.adoc +3 -0
- data/test/fixtures/subdir/inner-include.adoc +3 -0
- data/test/fixtures/subdir/middle-include.adoc +5 -0
- data/test/fixtures/tagged-class-enclosed.rb +0 -1
- data/test/fixtures/unclosed-tag.adoc +3 -0
- data/test/fixtures/unexpected-end-tag.adoc +4 -0
- data/test/invoker_test.rb +101 -40
- data/test/links_test.rb +266 -72
- data/test/lists_test.rb +243 -45
- data/test/logger_test.rb +211 -0
- data/test/manpage_test.rb +124 -6
- data/test/options_test.rb +46 -1
- data/test/paragraphs_test.rb +23 -10
- data/test/parser_test.rb +30 -1
- data/test/paths_test.rb +115 -33
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +337 -81
- data/test/sections_test.rb +656 -72
- data/test/substitutions_test.rb +182 -57
- data/test/tables_test.rb +324 -57
- data/test/test_helper.rb +77 -32
- data/test/text_test.rb +7 -7
- metadata +67 -3
    
        data/test/blocks_test.rb
    CHANGED
    
    | @@ -4,7 +4,17 @@ unless defined? ASCIIDOCTOR_PROJECT_DIR | |
| 4 4 | 
             
              require 'test_helper'
         | 
| 5 5 | 
             
            end
         | 
| 6 6 |  | 
| 7 | 
            -
            context  | 
| 7 | 
            +
            context 'Blocks' do
         | 
| 8 | 
            +
              default_logger = Asciidoctor::LoggerManager.logger
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              setup do
         | 
| 11 | 
            +
                Asciidoctor::LoggerManager.logger = (@logger = Asciidoctor::MemoryLogger.new)
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              teardown do
         | 
| 15 | 
            +
                Asciidoctor::LoggerManager.logger = default_logger
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 8 18 | 
             
              context 'Layout Breaks' do
         | 
| 9 19 | 
             
                test 'horizontal rule' do
         | 
| 10 20 | 
             
                  %w(''' '''' '''''').each do |line|
         | 
| @@ -141,7 +151,7 @@ block comment | |
| 141 151 | 
             
                  EOS
         | 
| 142 152 | 
             
                  d = document_from_string input
         | 
| 143 153 | 
             
                  assert_equal 1, d.blocks.size
         | 
| 144 | 
            -
                  assert_xpath '//p', d. | 
| 154 | 
            +
                  assert_xpath '//p', d.convert, 1
         | 
| 145 155 | 
             
                end
         | 
| 146 156 |  | 
| 147 157 | 
             
                test 'line starting with three slashes should not be line comment' do
         | 
| @@ -181,6 +191,36 @@ line should be rendered | |
| 181 191 | 
             
                  assert_xpath '//p[text() = "line should be rendered"]', output, 1
         | 
| 182 192 | 
             
                end
         | 
| 183 193 |  | 
| 194 | 
            +
                test 'should warn if unterminated comment block is detected in body' do
         | 
| 195 | 
            +
                  input = <<-EOS
         | 
| 196 | 
            +
            before comment block
         | 
| 197 | 
            +
             | 
| 198 | 
            +
            ////
         | 
| 199 | 
            +
            content that has been disabled
         | 
| 200 | 
            +
             | 
| 201 | 
            +
            supposed to be after comment block, except it got swallowed by block comment
         | 
| 202 | 
            +
                  EOS
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                  render_embedded_string input
         | 
| 205 | 
            +
                  assert_message @logger, :WARN, '<stdin>: line 3: unterminated comment block', Hash
         | 
| 206 | 
            +
                end
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                test 'should warn if unterminated comment block is detected inside another block' do
         | 
| 209 | 
            +
                  input = <<-EOS
         | 
| 210 | 
            +
            before sidebar block
         | 
| 211 | 
            +
             | 
| 212 | 
            +
            ****
         | 
| 213 | 
            +
            ////
         | 
| 214 | 
            +
            content that has been disabled
         | 
| 215 | 
            +
            ****
         | 
| 216 | 
            +
             | 
| 217 | 
            +
            supposed to be after sidebar block, except it got swallowed by block comment
         | 
| 218 | 
            +
                  EOS
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                  render_embedded_string input
         | 
| 221 | 
            +
                  assert_message @logger, :WARN, '<stdin>: line 4: unterminated comment block', Hash
         | 
| 222 | 
            +
                end
         | 
| 223 | 
            +
             | 
| 184 224 | 
             
                # WARNING if first line of content is a directive, it will get interpretted before we know it's a comment block
         | 
| 185 225 | 
             
                # it happens because we always look a line ahead...not sure what we can do about it
         | 
| 186 226 | 
             
                test 'preprocessor directives should not be processed within comment open block' do
         | 
| @@ -311,15 +351,30 @@ ____ | |
| 311 351 |  | 
| 312 352 | 
             
                test 'quote block with attribute and id and role shorthand' do
         | 
| 313 353 | 
             
                  input = <<-EOS
         | 
| 314 | 
            -
            [quote# | 
| 354 | 
            +
            [quote#justice-to-all.solidarity, Martin Luther King, Jr.]
         | 
| 315 355 | 
             
            ____
         | 
| 316 | 
            -
             | 
| 356 | 
            +
            Injustice anywhere is a threat to justice everywhere.
         | 
| 317 357 | 
             
            ____
         | 
| 318 358 | 
             
                  EOS
         | 
| 319 359 |  | 
| 320 360 | 
             
                  output = render_embedded_string input
         | 
| 321 361 | 
             
                  assert_css '.quoteblock', output, 1
         | 
| 322 | 
            -
                  assert_css '# | 
| 362 | 
            +
                  assert_css '#justice-to-all.quoteblock.solidarity', output, 1
         | 
| 363 | 
            +
                  assert_css '.quoteblock > .attribution', output, 1
         | 
| 364 | 
            +
                end
         | 
| 365 | 
            +
             | 
| 366 | 
            +
                test 'setting ID using style shorthand should not reset block style' do
         | 
| 367 | 
            +
                  input = <<-EOS
         | 
| 368 | 
            +
            [quote]
         | 
| 369 | 
            +
            [#justice-to-all.solidarity, Martin Luther King, Jr.]
         | 
| 370 | 
            +
            ____
         | 
| 371 | 
            +
            Injustice anywhere is a threat to justice everywhere.
         | 
| 372 | 
            +
            ____
         | 
| 373 | 
            +
                  EOS
         | 
| 374 | 
            +
             | 
| 375 | 
            +
                  output = render_embedded_string input
         | 
| 376 | 
            +
                  assert_css '.quoteblock', output, 1
         | 
| 377 | 
            +
                  assert_css '#justice-to-all.quoteblock.solidarity', output, 1
         | 
| 323 378 | 
             
                  assert_css '.quoteblock > .attribution', output, 1
         | 
| 324 379 | 
             
                end
         | 
| 325 380 |  | 
| @@ -338,6 +393,42 @@ ____ | |
| 338 393 | 
             
                  assert_css '.quoteblock > blockquote > .paragraph + .admonitionblock', output, 1
         | 
| 339 394 | 
             
                end
         | 
| 340 395 |  | 
| 396 | 
            +
                test 'quote block with attribution converted to DocBook' do
         | 
| 397 | 
            +
                  input = <<-EOS
         | 
| 398 | 
            +
            [quote, Famous Person, Famous Book (1999)]
         | 
| 399 | 
            +
            ____
         | 
| 400 | 
            +
            A famous quote.
         | 
| 401 | 
            +
            ____
         | 
| 402 | 
            +
                  EOS
         | 
| 403 | 
            +
                  output = render_string input, :backend => :docbook
         | 
| 404 | 
            +
                  assert_css 'blockquote', output, 1
         | 
| 405 | 
            +
                  assert_css 'blockquote > simpara', output, 1
         | 
| 406 | 
            +
                  assert_css 'blockquote > attribution', output, 1
         | 
| 407 | 
            +
                  assert_css 'blockquote > attribution > citetitle', output, 1
         | 
| 408 | 
            +
                  assert_xpath '//blockquote/attribution/citetitle[text() = "Famous Book (1999)"]', output, 1
         | 
| 409 | 
            +
                  attribution = xmlnodes_at_xpath '//blockquote/attribution', output, 1
         | 
| 410 | 
            +
                  author = attribution.children.first
         | 
| 411 | 
            +
                  assert_equal 'Famous Person', author.text.strip
         | 
| 412 | 
            +
                end
         | 
| 413 | 
            +
             
         | 
| 414 | 
            +
                test 'epigraph quote block with attribution converted to DocBook' do
         | 
| 415 | 
            +
                  input = <<-EOS
         | 
| 416 | 
            +
            [.epigraph, Famous Person, Famous Book (1999)]
         | 
| 417 | 
            +
            ____
         | 
| 418 | 
            +
            A famous quote.
         | 
| 419 | 
            +
            ____
         | 
| 420 | 
            +
                  EOS
         | 
| 421 | 
            +
                  output = render_string input, :backend => :docbook
         | 
| 422 | 
            +
                  assert_css 'epigraph', output, 1
         | 
| 423 | 
            +
                  assert_css 'epigraph > simpara', output, 1
         | 
| 424 | 
            +
                  assert_css 'epigraph > attribution', output, 1
         | 
| 425 | 
            +
                  assert_css 'epigraph > attribution > citetitle', output, 1
         | 
| 426 | 
            +
                  assert_xpath '//epigraph/attribution/citetitle[text() = "Famous Book (1999)"]', output, 1
         | 
| 427 | 
            +
                  attribution = xmlnodes_at_xpath '//epigraph/attribution', output, 1
         | 
| 428 | 
            +
                  author = attribution.children.first
         | 
| 429 | 
            +
                  assert_equal 'Famous Person', author.text.strip
         | 
| 430 | 
            +
                end
         | 
| 431 | 
            +
             | 
| 341 432 | 
             
                test 'quote block using air quotes with no attribution' do
         | 
| 342 433 | 
             
                  input = <<-EOS
         | 
| 343 434 | 
             
            ""
         | 
| @@ -429,6 +520,18 @@ Some more inspiring words. | |
| 429 520 | 
             
                  assert_equal "#{decode_char 8212} Famous Person", author.text.strip
         | 
| 430 521 | 
             
                end
         | 
| 431 522 |  | 
| 523 | 
            +
                test 'should parse credit line in markdown-style quote block like positional block attributes' do
         | 
| 524 | 
            +
                  input = <<-EOS
         | 
| 525 | 
            +
            > I hold it that a little rebellion now and then is a good thing,
         | 
| 526 | 
            +
            > and as necessary in the political world as storms in the physical.
         | 
| 527 | 
            +
            -- Thomas Jefferson, https://jeffersonpapers.princeton.edu/selected-documents/james-madison-1[The Papers of Thomas Jefferson, Volume 11]
         | 
| 528 | 
            +
                  EOS
         | 
| 529 | 
            +
             | 
| 530 | 
            +
                  output = render_embedded_string input
         | 
| 531 | 
            +
                  assert_css '.quoteblock', output, 1
         | 
| 532 | 
            +
                  assert_css '.quoteblock cite a[href="https://jeffersonpapers.princeton.edu/selected-documents/james-madison-1"]', output, 1
         | 
| 533 | 
            +
                end
         | 
| 534 | 
            +
             | 
| 432 535 | 
             
                test 'quoted paragraph-style quote block with attribution' do
         | 
| 433 536 | 
             
                  input = <<-EOS
         | 
| 434 537 | 
             
            "A famous quote.
         | 
| @@ -448,6 +551,18 @@ Some more inspiring words." | |
| 448 551 | 
             
                  assert_equal "#{decode_char 8212} Famous Person", author.text.strip
         | 
| 449 552 | 
             
                end
         | 
| 450 553 |  | 
| 554 | 
            +
                test 'should parse credit line in quoted paragraph-style quote block like positional block attributes' do
         | 
| 555 | 
            +
                  input = <<-EOS
         | 
| 556 | 
            +
            "I hold it that a little rebellion now and then is a good thing,
         | 
| 557 | 
            +
            and as necessary in the political world as storms in the physical."
         | 
| 558 | 
            +
            -- Thomas Jefferson, https://jeffersonpapers.princeton.edu/selected-documents/james-madison-1[The Papers of Thomas Jefferson, Volume 11]
         | 
| 559 | 
            +
                  EOS
         | 
| 560 | 
            +
             | 
| 561 | 
            +
                  output = render_embedded_string input
         | 
| 562 | 
            +
                  assert_css '.quoteblock', output, 1
         | 
| 563 | 
            +
                  assert_css '.quoteblock cite a[href="https://jeffersonpapers.princeton.edu/selected-documents/james-madison-1"]', output, 1
         | 
| 564 | 
            +
                end
         | 
| 565 | 
            +
             | 
| 451 566 | 
             
                test 'single-line verse block without attribution' do
         | 
| 452 567 | 
             
                  input = <<-EOS
         | 
| 453 568 | 
             
            [verse]
         | 
| @@ -483,6 +598,44 @@ ____ | |
| 483 598 | 
             
                  assert_equal "#{decode_char 8212} Famous Poet", author.text.strip
         | 
| 484 599 | 
             
                end
         | 
| 485 600 |  | 
| 601 | 
            +
                test 'single-line verse block with attribution converted to DocBook' do
         | 
| 602 | 
            +
                  input = <<-EOS
         | 
| 603 | 
            +
            [verse, Famous Poet, Famous Poem]
         | 
| 604 | 
            +
            ____
         | 
| 605 | 
            +
            A famous verse.
         | 
| 606 | 
            +
            ____
         | 
| 607 | 
            +
                  EOS
         | 
| 608 | 
            +
                  output = render_string input, :backend => :docbook
         | 
| 609 | 
            +
                  assert_css 'blockquote', output, 1
         | 
| 610 | 
            +
                  assert_css 'blockquote simpara', output, 0
         | 
| 611 | 
            +
                  assert_css 'blockquote > literallayout', output, 1
         | 
| 612 | 
            +
                  assert_css 'blockquote > attribution', output, 1
         | 
| 613 | 
            +
                  assert_css 'blockquote > attribution > citetitle', output, 1
         | 
| 614 | 
            +
                  assert_xpath '//blockquote/attribution/citetitle[text() = "Famous Poem"]', output, 1
         | 
| 615 | 
            +
                  attribution = xmlnodes_at_xpath '//blockquote/attribution', output, 1
         | 
| 616 | 
            +
                  author = attribution.children.first
         | 
| 617 | 
            +
                  assert_equal 'Famous Poet', author.text.strip
         | 
| 618 | 
            +
                end
         | 
| 619 | 
            +
             
         | 
| 620 | 
            +
                test 'single-line epigraph verse block with attribution converted to DocBook' do
         | 
| 621 | 
            +
                  input = <<-EOS
         | 
| 622 | 
            +
            [verse.epigraph, Famous Poet, Famous Poem]
         | 
| 623 | 
            +
            ____
         | 
| 624 | 
            +
            A famous verse.
         | 
| 625 | 
            +
            ____
         | 
| 626 | 
            +
                  EOS
         | 
| 627 | 
            +
                  output = render_string input, :backend => :docbook
         | 
| 628 | 
            +
                  assert_css 'epigraph', output, 1
         | 
| 629 | 
            +
                  assert_css 'epigraph simpara', output, 0
         | 
| 630 | 
            +
                  assert_css 'epigraph > literallayout', output, 1
         | 
| 631 | 
            +
                  assert_css 'epigraph > attribution', output, 1
         | 
| 632 | 
            +
                  assert_css 'epigraph > attribution > citetitle', output, 1
         | 
| 633 | 
            +
                  assert_xpath '//epigraph/attribution/citetitle[text() = "Famous Poem"]', output, 1
         | 
| 634 | 
            +
                  attribution = xmlnodes_at_xpath '//epigraph/attribution', output, 1
         | 
| 635 | 
            +
                  author = attribution.children.first
         | 
| 636 | 
            +
                  assert_equal 'Famous Poet', author.text.strip
         | 
| 637 | 
            +
                end
         | 
| 638 | 
            +
             | 
| 486 639 | 
             
                test 'multi-stanza verse block' do
         | 
| 487 640 | 
             
                  input = <<-EOS
         | 
| 488 641 | 
             
            [verse]
         | 
| @@ -539,9 +692,9 @@ ____ | |
| 539 692 | 
             
            <1> Not pointing to a callout
         | 
| 540 693 | 
             
                  EOS
         | 
| 541 694 |  | 
| 542 | 
            -
                  output | 
| 695 | 
            +
                  output = render_embedded_string input
         | 
| 543 696 | 
             
                  assert_xpath '//pre[text()="La la la <1>"]', output, 1
         | 
| 544 | 
            -
                   | 
| 697 | 
            +
                  assert_message @logger, :WARN, '<stdin>: line 5: no callout found for <1>', Hash
         | 
| 545 698 | 
             
                end
         | 
| 546 699 |  | 
| 547 700 | 
             
                test 'should perform normal subs on a verse block' do
         | 
| @@ -553,7 +706,7 @@ ____ | |
| 553 706 | 
             
                  EOS
         | 
| 554 707 |  | 
| 555 708 | 
             
                  output = render_embedded_string input
         | 
| 556 | 
            -
                   | 
| 709 | 
            +
                  assert_includes output, '<pre class="content"><em>GET /groups/<a href="#group-id">{group-id}</a></em></pre>'
         | 
| 557 710 | 
             
                end
         | 
| 558 711 | 
             
              end
         | 
| 559 712 |  | 
| @@ -591,7 +744,7 @@ You futz with XML. | |
| 591 744 | 
             
                  doc = document_from_string input
         | 
| 592 745 | 
             
                  assert_equal 1, doc.blocks[0].number
         | 
| 593 746 | 
             
                  assert_equal 2, doc.blocks[1].number
         | 
| 594 | 
            -
                  output = doc. | 
| 747 | 
            +
                  output = doc.convert
         | 
| 595 748 | 
             
                  assert_xpath '(//*[@class="exampleblock"])[1]/*[@class="title"][text()="Example 1. Writing Docs with AsciiDoc"]', output, 1
         | 
| 596 749 | 
             
                  assert_xpath '(//*[@class="exampleblock"])[2]/*[@class="title"][text()="Example 2. Writing Docs with DocBook"]', output, 1
         | 
| 597 750 | 
             
                  assert_equal 2, doc.attributes['example-number']
         | 
| @@ -619,7 +772,7 @@ You futz with XML. | |
| 619 772 | 
             
                  doc = document_from_string input
         | 
| 620 773 | 
             
                  assert_equal 'A', doc.blocks[0].number
         | 
| 621 774 | 
             
                  assert_equal 'B', doc.blocks[1].number
         | 
| 622 | 
            -
                  output = doc. | 
| 775 | 
            +
                  output = doc.convert
         | 
| 623 776 | 
             
                  assert_xpath '(//*[@class="exampleblock"])[1]/*[@class="title"][text()="Example A. Writing Docs with AsciiDoc"]', output, 1
         | 
| 624 777 | 
             
                  assert_xpath '(//*[@class="exampleblock"])[2]/*[@class="title"][text()="Example B. Writing Docs with DocBook"]', output, 1
         | 
| 625 778 | 
             
                  assert_equal 'B', doc.attributes['example-number']
         | 
| @@ -638,7 +791,7 @@ You just write. | |
| 638 791 |  | 
| 639 792 | 
             
                  doc = document_from_string input
         | 
| 640 793 | 
             
                  assert_nil doc.blocks[0].number
         | 
| 641 | 
            -
                  output = doc. | 
| 794 | 
            +
                  output = doc.convert
         | 
| 642 795 | 
             
                  assert_xpath '(//*[@class="exampleblock"])[1]/*[@class="title"][text()="Look! Writing Docs with AsciiDoc"]', output, 1
         | 
| 643 796 | 
             
                  refute doc.attributes.has_key?('example-number')
         | 
| 644 797 | 
             
                end
         | 
| @@ -672,41 +825,58 @@ yet another example | |
| 672 825 | 
             
                  assert_xpath '(/*[@class="exampleblock"])[2]/*[@class="title"][text()="second example"]', output, 1
         | 
| 673 826 | 
             
                  assert_xpath '(/*[@class="exampleblock"])[3]/*[@class="title"][starts-with(text(), "Exhibit ")]', output, 1
         | 
| 674 827 | 
             
                end
         | 
| 828 | 
            +
             | 
| 829 | 
            +
                test 'should warn if example block is not terminated' do
         | 
| 830 | 
            +
                  input = <<-EOS
         | 
| 831 | 
            +
            outside
         | 
| 832 | 
            +
             | 
| 833 | 
            +
            ====
         | 
| 834 | 
            +
            inside
         | 
| 835 | 
            +
             | 
| 836 | 
            +
            still inside
         | 
| 837 | 
            +
             | 
| 838 | 
            +
            eof
         | 
| 839 | 
            +
                  EOS
         | 
| 840 | 
            +
             | 
| 841 | 
            +
                  output = render_embedded_string input
         | 
| 842 | 
            +
                  assert_xpath '/*[@class="exampleblock"]', output, 1
         | 
| 843 | 
            +
                  assert_message @logger, :WARN, '<stdin>: line 3: unterminated example block', Hash
         | 
| 844 | 
            +
                end
         | 
| 675 845 | 
             
              end
         | 
| 676 846 |  | 
| 677 847 | 
             
              context 'Admonition Blocks' do
         | 
| 678 848 | 
             
                test 'caption block-level attribute should be used as caption' do
         | 
| 679 | 
            -
             | 
| 849 | 
            +
                  input = <<-EOS
         | 
| 680 850 | 
             
            :tip-caption: Pro Tip
         | 
| 681 851 |  | 
| 682 852 | 
             
            [caption="Pro Tip"]
         | 
| 683 853 | 
             
            TIP: Override the caption of an admonition block using an attribute entry
         | 
| 684 | 
            -
             | 
| 854 | 
            +
                  EOS
         | 
| 685 855 |  | 
| 686 | 
            -
             | 
| 687 | 
            -
             | 
| 856 | 
            +
                  output = render_embedded_string input
         | 
| 857 | 
            +
                  assert_xpath '/*[@class="admonitionblock tip"]//*[@class="icon"]/*[@class="title"][text()="Pro Tip"]', output, 1
         | 
| 688 858 | 
             
                end
         | 
| 689 859 |  | 
| 690 860 | 
             
                test 'can override caption of admonition block using document attribute' do
         | 
| 691 | 
            -
             | 
| 861 | 
            +
                  input = <<-EOS
         | 
| 692 862 | 
             
            :tip-caption: Pro Tip
         | 
| 693 863 |  | 
| 694 864 | 
             
            TIP: Override the caption of an admonition block using an attribute entry
         | 
| 695 | 
            -
             | 
| 865 | 
            +
                  EOS
         | 
| 696 866 |  | 
| 697 | 
            -
             | 
| 698 | 
            -
             | 
| 867 | 
            +
                  output = render_embedded_string input
         | 
| 868 | 
            +
                  assert_xpath '/*[@class="admonitionblock tip"]//*[@class="icon"]/*[@class="title"][text()="Pro Tip"]', output, 1
         | 
| 699 869 | 
             
                end
         | 
| 700 870 |  | 
| 701 871 | 
             
                test 'blank caption document attribute should not blank admonition block caption' do
         | 
| 702 | 
            -
             | 
| 872 | 
            +
                  input = <<-EOS
         | 
| 703 873 | 
             
            :caption:
         | 
| 704 874 |  | 
| 705 875 | 
             
            TIP: Override the caption of an admonition block using an attribute entry
         | 
| 706 | 
            -
             | 
| 876 | 
            +
                  EOS
         | 
| 707 877 |  | 
| 708 | 
            -
             | 
| 709 | 
            -
             | 
| 878 | 
            +
                  output = render_embedded_string input
         | 
| 879 | 
            +
                  assert_xpath '/*[@class="admonitionblock tip"]//*[@class="icon"]/*[@class="title"][text()="Tip"]', output, 1
         | 
| 710 880 | 
             
                end
         | 
| 711 881 | 
             
              end
         | 
| 712 882 |  | 
| @@ -820,7 +990,7 @@ last line | |
| 820 990 | 
             
                  doc = document_from_string input, :header_footer => false
         | 
| 821 991 | 
             
                  block = doc.blocks.first
         | 
| 822 992 | 
             
                  assert_equal ['', '', '  first line', '', 'last line', '', '{empty}', ''], block.lines
         | 
| 823 | 
            -
                  result = doc. | 
| 993 | 
            +
                  result = doc.convert
         | 
| 824 994 | 
             
                  assert_xpath %(//pre[text()="  first line\n\nlast line"]), result, 1
         | 
| 825 995 | 
             
                end
         | 
| 826 996 |  | 
| @@ -1014,8 +1184,8 @@ Map<String, String> *attributes*; //<1> | |
| 1014 1184 |  | 
| 1015 1185 | 
             
                  block = block_from_string input
         | 
| 1016 1186 | 
             
                  assert_equal [:specialcharacters,:callouts,:quotes], block.subs
         | 
| 1017 | 
            -
                  output = block. | 
| 1018 | 
            -
                   | 
| 1187 | 
            +
                  output = block.convert
         | 
| 1188 | 
            +
                  assert_includes output, 'Map<String, String> <strong>attributes</strong>;'
         | 
| 1019 1189 | 
             
                  assert_xpath '//pre/b[text()="(1)"]', output, 1
         | 
| 1020 1190 | 
             
                end
         | 
| 1021 1191 |  | 
| @@ -1028,7 +1198,7 @@ No callout here <1> | |
| 1028 1198 | 
             
                  EOS
         | 
| 1029 1199 | 
             
                  block = block_from_string input
         | 
| 1030 1200 | 
             
                  assert_equal [:specialcharacters], block.subs
         | 
| 1031 | 
            -
                  output = block. | 
| 1201 | 
            +
                  output = block.convert
         | 
| 1032 1202 | 
             
                  assert_xpath '//pre/b[text()="(1)"]', output, 0
         | 
| 1033 1203 | 
             
                end
         | 
| 1034 1204 |  | 
| @@ -1067,6 +1237,20 @@ AssertionError | |
| 1067 1237 | 
             
                  assert_equal output.rstrip, output2.rstrip
         | 
| 1068 1238 | 
             
                end
         | 
| 1069 1239 |  | 
| 1240 | 
            +
                test 'first character of block title may be a period if not followed by space' do
         | 
| 1241 | 
            +
                  input = <<-EOS
         | 
| 1242 | 
            +
            ..gitignore
         | 
| 1243 | 
            +
            ----
         | 
| 1244 | 
            +
            /.bundle/
         | 
| 1245 | 
            +
            /build/
         | 
| 1246 | 
            +
            /Gemfile.lock
         | 
| 1247 | 
            +
            ----
         | 
| 1248 | 
            +
                  EOS
         | 
| 1249 | 
            +
             | 
| 1250 | 
            +
                  output = render_embedded_string input
         | 
| 1251 | 
            +
                  assert_xpath '//*[@class="title"][text()=".gitignore"]', output
         | 
| 1252 | 
            +
                end
         | 
| 1253 | 
            +
             | 
| 1070 1254 | 
             
                test 'listing block without title should generate screen element in docbook' do
         | 
| 1071 1255 | 
             
                  input = <<-EOS
         | 
| 1072 1256 | 
             
            ----
         | 
| @@ -1151,6 +1335,111 @@ ____ | |
| 1151 1335 | 
             
                  assert_xpath '//*[@class="openblock"]//p', output, 3
         | 
| 1152 1336 | 
             
                  assert_xpath '//*[@class="openblock"]//*[@class="quoteblock"]', output, 1
         | 
| 1153 1337 | 
             
                end
         | 
| 1338 | 
            +
             | 
| 1339 | 
            +
                test 'should transfer id and reftext on open block to DocBook output' do
         | 
| 1340 | 
            +
                  input = <<-EOS
         | 
| 1341 | 
            +
            Check out that <<open>>!
         | 
| 1342 | 
            +
             | 
| 1343 | 
            +
            [[open,Open Block]]
         | 
| 1344 | 
            +
            --
         | 
| 1345 | 
            +
            This is an open block.
         | 
| 1346 | 
            +
             | 
| 1347 | 
            +
            TIP: An open block can have other blocks inside of it.
         | 
| 1348 | 
            +
            --
         | 
| 1349 | 
            +
             | 
| 1350 | 
            +
            Back to our regularly scheduled programming.
         | 
| 1351 | 
            +
                  EOS
         | 
| 1352 | 
            +
             | 
| 1353 | 
            +
                  output = render_string input, :backend => :docbook, :keep_namespaces => true
         | 
| 1354 | 
            +
                  assert_css 'article > simpara', output, 2
         | 
| 1355 | 
            +
                  assert_css 'article > para', output, 1
         | 
| 1356 | 
            +
                  assert_css 'article > para > simpara', output, 1
         | 
| 1357 | 
            +
                  assert_css 'article > para > tip', output, 1
         | 
| 1358 | 
            +
                  open = xmlnodes_at_xpath '/xmlns:article/xmlns:para', output, 1
         | 
| 1359 | 
            +
                  # nokogiri can't make up its mind
         | 
| 1360 | 
            +
                  id = open.attribute('id') || open.attribute('xml:id')
         | 
| 1361 | 
            +
                  refute_nil id
         | 
| 1362 | 
            +
                  assert_equal 'open', id.value
         | 
| 1363 | 
            +
                  xreflabel = open.attribute('xreflabel')
         | 
| 1364 | 
            +
                  refute_nil xreflabel
         | 
| 1365 | 
            +
                  assert_equal 'Open Block', xreflabel.value
         | 
| 1366 | 
            +
                end
         | 
| 1367 | 
            +
             | 
| 1368 | 
            +
                test 'should transfer id and reftext on open paragraph to DocBook output' do
         | 
| 1369 | 
            +
                  input = <<-EOS
         | 
| 1370 | 
            +
            [open#openpara,reftext="Open Paragraph"]
         | 
| 1371 | 
            +
            This is an open paragraph.
         | 
| 1372 | 
            +
                  EOS
         | 
| 1373 | 
            +
             | 
| 1374 | 
            +
                  output = render_string input, :backend => :docbook, :keep_namespaces => true
         | 
| 1375 | 
            +
                  assert_css 'article > simpara', output, 1
         | 
| 1376 | 
            +
                  open = xmlnodes_at_xpath '/xmlns:article/xmlns:simpara', output, 1
         | 
| 1377 | 
            +
                  open = xmlnodes_at_xpath '/xmlns:article/xmlns:simpara[text()="This is an open paragraph."]', output, 1
         | 
| 1378 | 
            +
                  # nokogiri can't make up its mind
         | 
| 1379 | 
            +
                  id = open.attribute('id') || open.attribute('xml:id')
         | 
| 1380 | 
            +
                  refute_nil id
         | 
| 1381 | 
            +
                  assert_equal 'openpara', id.value
         | 
| 1382 | 
            +
                  xreflabel = open.attribute('xreflabel')
         | 
| 1383 | 
            +
                  refute_nil xreflabel
         | 
| 1384 | 
            +
                  assert_equal 'Open Paragraph', xreflabel.value
         | 
| 1385 | 
            +
                end
         | 
| 1386 | 
            +
             | 
| 1387 | 
            +
                test 'should transfer title on open block to DocBook output' do
         | 
| 1388 | 
            +
                  input = <<-EOS
         | 
| 1389 | 
            +
            .Behold the open
         | 
| 1390 | 
            +
            --
         | 
| 1391 | 
            +
            This is an open block with a title.
         | 
| 1392 | 
            +
            --
         | 
| 1393 | 
            +
                  EOS
         | 
| 1394 | 
            +
             | 
| 1395 | 
            +
                  output = render_string input, :backend => :docbook
         | 
| 1396 | 
            +
                  assert_css 'article > formalpara', output, 1
         | 
| 1397 | 
            +
                  assert_css 'article > formalpara > *', output, 2
         | 
| 1398 | 
            +
                  assert_css 'article > formalpara > title', output, 1
         | 
| 1399 | 
            +
                  assert_xpath '/article/formalpara/title[text()="Behold the open"]', output, 1
         | 
| 1400 | 
            +
                  assert_css 'article > formalpara > para', output, 1
         | 
| 1401 | 
            +
                  assert_css 'article > formalpara > para > simpara', output, 1
         | 
| 1402 | 
            +
                end
         | 
| 1403 | 
            +
             | 
| 1404 | 
            +
                test 'should transfer title on open paragraph to DocBook output' do
         | 
| 1405 | 
            +
                  input = <<-EOS
         | 
| 1406 | 
            +
            .Behold the open
         | 
| 1407 | 
            +
            This is an open paragraph with a title.
         | 
| 1408 | 
            +
                  EOS
         | 
| 1409 | 
            +
             | 
| 1410 | 
            +
                  output = render_string input, :backend => :docbook
         | 
| 1411 | 
            +
                  assert_css 'article > formalpara', output, 1
         | 
| 1412 | 
            +
                  assert_css 'article > formalpara > *', output, 2
         | 
| 1413 | 
            +
                  assert_css 'article > formalpara > title', output, 1
         | 
| 1414 | 
            +
                  assert_xpath '/article/formalpara/title[text()="Behold the open"]', output, 1
         | 
| 1415 | 
            +
                  assert_css 'article > formalpara > para', output, 1
         | 
| 1416 | 
            +
                  assert_css 'article > formalpara > para[text()="This is an open paragraph with a title."]', output, 1
         | 
| 1417 | 
            +
                end
         | 
| 1418 | 
            +
             | 
| 1419 | 
            +
                test 'should transfer role on open block to DocBook output' do
         | 
| 1420 | 
            +
                  input = <<-EOS
         | 
| 1421 | 
            +
            [.container]
         | 
| 1422 | 
            +
            --
         | 
| 1423 | 
            +
            This is an open block.
         | 
| 1424 | 
            +
            It holds stuff.
         | 
| 1425 | 
            +
            --
         | 
| 1426 | 
            +
                  EOS
         | 
| 1427 | 
            +
             | 
| 1428 | 
            +
                  output = render_string input, :backend => :docbook
         | 
| 1429 | 
            +
                  assert_css 'article > para[role=container]', output, 1
         | 
| 1430 | 
            +
                  assert_css 'article > para[role=container] > simpara', output, 1
         | 
| 1431 | 
            +
                end
         | 
| 1432 | 
            +
             | 
| 1433 | 
            +
                test 'should transfer role on open paragraph to DocBook output' do
         | 
| 1434 | 
            +
                  input = <<-EOS
         | 
| 1435 | 
            +
            [.container]
         | 
| 1436 | 
            +
            This is an open block.
         | 
| 1437 | 
            +
            It holds stuff.
         | 
| 1438 | 
            +
                  EOS
         | 
| 1439 | 
            +
             | 
| 1440 | 
            +
                  output = render_string input, :backend => :docbook
         | 
| 1441 | 
            +
                  assert_css 'article > simpara[role=container]', output, 1
         | 
| 1442 | 
            +
                end
         | 
| 1154 1443 | 
             
              end
         | 
| 1155 1444 |  | 
| 1156 1445 | 
             
              context 'Passthrough Blocks' do
         | 
| @@ -1240,7 +1529,7 @@ line below | |
| 1240 1529 | 
             
                  doc = document_from_string input, :header_footer => false
         | 
| 1241 1530 | 
             
                  block = doc.blocks[1]
         | 
| 1242 1531 | 
             
                  assert_equal ['', '', '  first line', '', 'last line', '', ''], block.lines
         | 
| 1243 | 
            -
                  result = doc. | 
| 1532 | 
            +
                  result = doc.convert
         | 
| 1244 1533 | 
             
                  assert_equal "line above\n  first line\n\nlast line\nline below", result, 1
         | 
| 1245 1534 | 
             
                end
         | 
| 1246 1535 | 
             
              end
         | 
| @@ -1293,6 +1582,88 @@ line below | |
| 1293 1582 | 
             
                  assert_equal expect.strip, output.strip
         | 
| 1294 1583 | 
             
                end
         | 
| 1295 1584 |  | 
| 1585 | 
            +
                test 'should not split equation in AsciiMath block at single newline' do
         | 
| 1586 | 
            +
                  input = <<-'EOS'
         | 
| 1587 | 
            +
            [asciimath]
         | 
| 1588 | 
            +
            ++++
         | 
| 1589 | 
            +
            f: bbb"N" -> bbb"N"
         | 
| 1590 | 
            +
            f: x |-> x + 1
         | 
| 1591 | 
            +
            ++++
         | 
| 1592 | 
            +
                  EOS
         | 
| 1593 | 
            +
                  expected = <<-'EOS'.chomp
         | 
| 1594 | 
            +
            \$f: bbb"N" -> bbb"N"
         | 
| 1595 | 
            +
            f: x |-> x + 1\$
         | 
| 1596 | 
            +
                  EOS
         | 
| 1597 | 
            +
             | 
| 1598 | 
            +
                  output = render_embedded_string input
         | 
| 1599 | 
            +
                  assert_css '.stemblock', output, 1
         | 
| 1600 | 
            +
                  nodes = xmlnodes_at_xpath '//*[@class="content"]', output
         | 
| 1601 | 
            +
                  assert_equal expected, nodes.first.inner_html.strip
         | 
| 1602 | 
            +
                end
         | 
| 1603 | 
            +
             | 
| 1604 | 
            +
                test 'should split equation in AsciiMath block at escaped newline' do
         | 
| 1605 | 
            +
                  input = <<-'EOS'
         | 
| 1606 | 
            +
            [asciimath]
         | 
| 1607 | 
            +
            ++++
         | 
| 1608 | 
            +
            f: bbb"N" -> bbb"N" \
         | 
| 1609 | 
            +
            f: x |-> x + 1
         | 
| 1610 | 
            +
            ++++
         | 
| 1611 | 
            +
                  EOS
         | 
| 1612 | 
            +
                  expected = <<-'EOS'.chomp
         | 
| 1613 | 
            +
            \$f: bbb"N" -> bbb"N"\$<br>
         | 
| 1614 | 
            +
            \$f: x |-> x + 1\$
         | 
| 1615 | 
            +
                  EOS
         | 
| 1616 | 
            +
             | 
| 1617 | 
            +
                  output = render_embedded_string input
         | 
| 1618 | 
            +
                  assert_css '.stemblock', output, 1
         | 
| 1619 | 
            +
                  nodes = xmlnodes_at_xpath '//*[@class="content"]', output
         | 
| 1620 | 
            +
                  assert_equal expected, nodes.first.inner_html.strip
         | 
| 1621 | 
            +
                end
         | 
| 1622 | 
            +
             | 
| 1623 | 
            +
                test 'should split equation in AsciiMath block at sequence of escaped newlines' do
         | 
| 1624 | 
            +
                  input = <<-'EOS'
         | 
| 1625 | 
            +
            [asciimath]
         | 
| 1626 | 
            +
            ++++
         | 
| 1627 | 
            +
            f: bbb"N" -> bbb"N" \
         | 
| 1628 | 
            +
            \
         | 
| 1629 | 
            +
            f: x |-> x + 1
         | 
| 1630 | 
            +
            ++++
         | 
| 1631 | 
            +
                  EOS
         | 
| 1632 | 
            +
                  expected = <<-'EOS'.chomp
         | 
| 1633 | 
            +
            \$f: bbb"N" -> bbb"N"\$<br>
         | 
| 1634 | 
            +
            <br>
         | 
| 1635 | 
            +
            \$f: x |-> x + 1\$
         | 
| 1636 | 
            +
                  EOS
         | 
| 1637 | 
            +
             | 
| 1638 | 
            +
                  output = render_embedded_string input
         | 
| 1639 | 
            +
                  assert_css '.stemblock', output, 1
         | 
| 1640 | 
            +
                  nodes = xmlnodes_at_xpath '//*[@class="content"]', output
         | 
| 1641 | 
            +
                  assert_equal expected, nodes.first.inner_html.strip
         | 
| 1642 | 
            +
                end
         | 
| 1643 | 
            +
             | 
| 1644 | 
            +
                test 'should split equation in AsciiMath block at newline sequence and preserve breaks' do
         | 
| 1645 | 
            +
                  input = <<-'EOS'
         | 
| 1646 | 
            +
            [asciimath]
         | 
| 1647 | 
            +
            ++++
         | 
| 1648 | 
            +
            f: bbb"N" -> bbb"N"
         | 
| 1649 | 
            +
             | 
| 1650 | 
            +
             | 
| 1651 | 
            +
            f: x |-> x + 1
         | 
| 1652 | 
            +
            ++++
         | 
| 1653 | 
            +
                  EOS
         | 
| 1654 | 
            +
                  expected = <<-'EOS'.chomp
         | 
| 1655 | 
            +
            \$f: bbb"N" -> bbb"N"\$<br>
         | 
| 1656 | 
            +
            <br>
         | 
| 1657 | 
            +
            <br>
         | 
| 1658 | 
            +
            \$f: x |-> x + 1\$
         | 
| 1659 | 
            +
            EOS
         | 
| 1660 | 
            +
             | 
| 1661 | 
            +
                  output = render_embedded_string input
         | 
| 1662 | 
            +
                  assert_css '.stemblock', output, 1
         | 
| 1663 | 
            +
                  nodes = xmlnodes_at_xpath '//*[@class="content"]', output
         | 
| 1664 | 
            +
                  assert_equal expected, nodes.first.inner_html.strip
         | 
| 1665 | 
            +
                end
         | 
| 1666 | 
            +
             | 
| 1296 1667 | 
             
                test 'should add AsciiMath delimiters around asciimath block content' do
         | 
| 1297 1668 | 
             
                  input = <<-'EOS'
         | 
| 1298 1669 | 
             
            [asciimath]
         | 
| @@ -1321,7 +1692,8 @@ sqrt(3x-1)+(1+x)^2 < y | |
| 1321 1692 | 
             
                  assert_equal '\$sqrt(3x-1)+(1+x)^2 < y\$', nodes.first.to_s.strip
         | 
| 1322 1693 | 
             
                end
         | 
| 1323 1694 |  | 
| 1324 | 
            -
                test 'should  | 
| 1695 | 
            +
                test 'should convert contents of asciimath block to MathML in DocBook output if asciimath gem is available' do
         | 
| 1696 | 
            +
                  asciimath_available = !(Asciidoctor::Helpers.require_library 'asciimath', true, :ignore).nil?
         | 
| 1325 1697 | 
             
                  input = <<-'EOS'
         | 
| 1326 1698 | 
             
            [asciimath]
         | 
| 1327 1699 | 
             
            ++++
         | 
| @@ -1333,8 +1705,17 @@ x+b/(2a)<+-sqrt((b^2)/(4a^2)-c/a) | |
| 1333 1705 | 
             
            <mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"><mml:mi>x</mml:mi><mml:mo>+</mml:mo><mml:mfrac><mml:mi>b</mml:mi><mml:mrow><mml:mn>2</mml:mn><mml:mi>a</mml:mi></mml:mrow></mml:mfrac><mml:mo><</mml:mo><mml:mo>±</mml:mo><mml:msqrt><mml:mrow><mml:mfrac><mml:msup><mml:mi>b</mml:mi><mml:mn>2</mml:mn></mml:msup><mml:mrow><mml:mn>4</mml:mn><mml:msup><mml:mi>a</mml:mi><mml:mn>2</mml:mn></mml:msup></mml:mrow></mml:mfrac><mml:mo>−</mml:mo><mml:mfrac><mml:mi>c</mml:mi><mml:mi>a</mml:mi></mml:mfrac></mml:mrow></mml:msqrt></mml:math>
         | 
| 1334 1706 | 
             
            </informalequation>)
         | 
| 1335 1707 |  | 
| 1336 | 
            -
                   | 
| 1337 | 
            -
             | 
| 1708 | 
            +
                  using_memory_logger do |logger|
         | 
| 1709 | 
            +
                    doc = document_from_string input, :backend => :docbook, :header_footer => false
         | 
| 1710 | 
            +
                    actual = doc.convert
         | 
| 1711 | 
            +
                    if asciimath_available
         | 
| 1712 | 
            +
                      assert_equal expect.strip, actual.strip
         | 
| 1713 | 
            +
                      assert_equal :loaded, doc.converter.instance_variable_get(:@asciimath)
         | 
| 1714 | 
            +
                    else
         | 
| 1715 | 
            +
                      assert_message logger, :WARN, 'optional gem \'asciimath\' is not installed. Functionality disabled.'
         | 
| 1716 | 
            +
                      assert_equal :unavailable, doc.converter.instance_variable_get(:@asciimath)
         | 
| 1717 | 
            +
                    end
         | 
| 1718 | 
            +
                  end
         | 
| 1338 1719 | 
             
                end
         | 
| 1339 1720 |  | 
| 1340 1721 | 
             
                test 'should output title for latexmath block if defined' do
         | 
| @@ -1371,7 +1752,7 @@ a//b | |
| 1371 1752 | 
             
                  assert_xpath '//*[@class="title"][text()="Simple fraction"]', output, 1
         | 
| 1372 1753 | 
             
                end
         | 
| 1373 1754 |  | 
| 1374 | 
            -
                test 'should add AsciiMath delimiters around stem block content if stem attribute  | 
| 1755 | 
            +
                test 'should add AsciiMath delimiters around stem block content if stem attribute is asciimath, empty, or not set' do
         | 
| 1375 1756 | 
             
                  input = <<-'EOS'
         | 
| 1376 1757 | 
             
            [stem]
         | 
| 1377 1758 | 
             
            ++++
         | 
| @@ -1382,7 +1763,8 @@ sqrt(3x-1)+(1+x)^2 < y | |
| 1382 1763 | 
             
                  [
         | 
| 1383 1764 | 
             
                    {},
         | 
| 1384 1765 | 
             
                    {'stem' => ''},
         | 
| 1385 | 
            -
                    {'stem' => 'asciimath'}
         | 
| 1766 | 
            +
                    {'stem' => 'asciimath'},
         | 
| 1767 | 
            +
                    {'stem' => 'bogus'}
         | 
| 1386 1768 | 
             
                  ].each do |attributes|
         | 
| 1387 1769 | 
             
                    output = render_embedded_string input, :attributes => attributes
         | 
| 1388 1770 | 
             
                    assert_css '.stemblock', output, 1
         | 
| @@ -1391,7 +1773,7 @@ sqrt(3x-1)+(1+x)^2 < y | |
| 1391 1773 | 
             
                  end
         | 
| 1392 1774 | 
             
                end
         | 
| 1393 1775 |  | 
| 1394 | 
            -
                test 'should add LaTeX math delimiters around stem block content if stem attribute is latexmath' do
         | 
| 1776 | 
            +
                test 'should add LaTeX math delimiters around stem block content if stem attribute is latexmath, latex, or tex' do
         | 
| 1395 1777 | 
             
                  input = <<-'EOS'
         | 
| 1396 1778 | 
             
            [stem]
         | 
| 1397 1779 | 
             
            ++++
         | 
| @@ -1399,10 +1781,36 @@ sqrt(3x-1)+(1+x)^2 < y | |
| 1399 1781 | 
             
            ++++
         | 
| 1400 1782 | 
             
                  EOS
         | 
| 1401 1783 |  | 
| 1402 | 
            -
                   | 
| 1784 | 
            +
                  [
         | 
| 1785 | 
            +
                    {'stem' => 'latexmath'},
         | 
| 1786 | 
            +
                    {'stem' => 'latex'},
         | 
| 1787 | 
            +
                    {'stem' => 'tex'}
         | 
| 1788 | 
            +
                  ].each do |attributes|
         | 
| 1789 | 
            +
                    output = render_embedded_string input, :attributes => attributes
         | 
| 1790 | 
            +
                    assert_css '.stemblock', output, 1
         | 
| 1791 | 
            +
                    nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output
         | 
| 1792 | 
            +
                    assert_equal '\[\sqrt{3x-1}+(1+x)^2 < y\]', nodes.first.to_s.strip
         | 
| 1793 | 
            +
                  end
         | 
| 1794 | 
            +
                end
         | 
| 1795 | 
            +
             | 
| 1796 | 
            +
                test 'should allow stem style to be set using second positional argument of block attributes' do
         | 
| 1797 | 
            +
                  input = <<-EOS
         | 
| 1798 | 
            +
            :stem: latexmath
         | 
| 1799 | 
            +
             | 
| 1800 | 
            +
            [stem,asciimath]
         | 
| 1801 | 
            +
            ++++
         | 
| 1802 | 
            +
            sqrt(3x-1)+(1+x)^2 < y
         | 
| 1803 | 
            +
            ++++
         | 
| 1804 | 
            +
                  EOS
         | 
| 1805 | 
            +
             | 
| 1806 | 
            +
                  doc = document_from_string input
         | 
| 1807 | 
            +
                  stemblock = doc.blocks[0]
         | 
| 1808 | 
            +
                  assert_equal :stem, stemblock.context
         | 
| 1809 | 
            +
                  assert_equal 'asciimath', stemblock.attributes['style']
         | 
| 1810 | 
            +
                  output = doc.convert :header_footer => false
         | 
| 1403 1811 | 
             
                  assert_css '.stemblock', output, 1
         | 
| 1404 1812 | 
             
                  nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output
         | 
| 1405 | 
            -
                  assert_equal ' | 
| 1813 | 
            +
                  assert_equal '\$sqrt(3x-1)+(1+x)^2 < y\$', nodes.first.to_s.strip
         | 
| 1406 1814 | 
             
                end
         | 
| 1407 1815 | 
             
              end
         | 
| 1408 1816 |  | 
| @@ -1427,18 +1835,13 @@ paragraph | |
| 1427 1835 |  | 
| 1428 1836 | 
             
            section paragraph
         | 
| 1429 1837 | 
             
                  EOS
         | 
| 1430 | 
            -
                  output | 
| 1431 | 
            -
                  redirect_streams do |stdout, stderr|
         | 
| 1432 | 
            -
                    output = render_string input
         | 
| 1433 | 
            -
                    errors = stderr.string
         | 
| 1434 | 
            -
                  end
         | 
| 1838 | 
            +
                  output = render_string input
         | 
| 1435 1839 | 
             
                  assert_xpath '//*[@id="header"]/*', output, 0
         | 
| 1436 1840 | 
             
                  assert_xpath '//*[@id="preamble"]/*', output, 0
         | 
| 1437 1841 | 
             
                  assert_xpath '//*[@id="content"]/h1[text()="Section Title"]', output, 1
         | 
| 1438 1842 | 
             
                  assert_xpath '//*[@class="paragraph"]', output, 1
         | 
| 1439 1843 | 
             
                  assert_xpath '//*[@class="paragraph"]/*[@class="title"][text()="Block title"]', output, 1
         | 
| 1440 | 
            -
                   | 
| 1441 | 
            -
                  assert_match(/only book doctypes can contain level 0 sections/, errors)
         | 
| 1844 | 
            +
                  assert_message @logger, :ERROR, '<stdin>: line 2: level 0 sections can only be used when doctype is book', Hash
         | 
| 1442 1845 | 
             
                end
         | 
| 1443 1846 |  | 
| 1444 1847 | 
             
                test 'block title above document title gets carried over to first block in first section if no preamble' do
         | 
| @@ -1467,8 +1870,8 @@ Block content | |
| 1467 1870 | 
             
                  EOS
         | 
| 1468 1871 |  | 
| 1469 1872 | 
             
                  output = render_embedded_string input
         | 
| 1470 | 
            -
                   | 
| 1471 | 
            -
                   | 
| 1873 | 
            +
                  assert_includes output, 'Block content'
         | 
| 1874 | 
            +
                  refute_includes output, '[]'
         | 
| 1472 1875 | 
             
                end
         | 
| 1473 1876 |  | 
| 1474 1877 | 
             
                test 'empty block anchor should not appear in output' do
         | 
| @@ -1480,8 +1883,8 @@ Block content | |
| 1480 1883 | 
             
                  EOS
         | 
| 1481 1884 |  | 
| 1482 1885 | 
             
                  output = render_embedded_string input
         | 
| 1483 | 
            -
                   | 
| 1484 | 
            -
                   | 
| 1886 | 
            +
                  assert_includes output, 'Block content'
         | 
| 1887 | 
            +
                  refute_includes output, '[[]]'
         | 
| 1485 1888 | 
             
                end
         | 
| 1486 1889 | 
             
              end
         | 
| 1487 1890 |  | 
| @@ -1570,7 +1973,7 @@ image::http://example.org/tiger-svg[Tiger,100,format=svg] | |
| 1570 1973 | 
             
            image::circle.svg[Tiger,100]
         | 
| 1571 1974 | 
             
                  EOS
         | 
| 1572 1975 |  | 
| 1573 | 
            -
                  output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'docdir' =>  | 
| 1976 | 
            +
                  output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'docdir' => testdir }
         | 
| 1574 1977 | 
             
                  assert_match(/<svg\s[^>]*width="100px"[^>]*>/, output, 1)
         | 
| 1575 1978 | 
             
                  refute_match(/<svg\s[^>]*width="500px"[^>]*>/, output)
         | 
| 1576 1979 | 
             
                  refute_match(/<svg\s[^>]*height="500px"[^>]*>/, output)
         | 
| @@ -1586,7 +1989,7 @@ image::circle.svg[Tiger,100] | |
| 1586 1989 | 
             
            image::circle.svg[Tiger,100]
         | 
| 1587 1990 | 
             
                  EOS
         | 
| 1588 1991 |  | 
| 1589 | 
            -
                  output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'docdir' =>  | 
| 1992 | 
            +
                  output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'docdir' => testdir }
         | 
| 1590 1993 | 
             
                  assert_match(/<svg\s[^>]*width="100px">/, output, 1)
         | 
| 1591 1994 | 
             
                end
         | 
| 1592 1995 |  | 
| @@ -1596,9 +1999,9 @@ image::circle.svg[Tiger,100] | |
| 1596 1999 | 
             
            image::no-such-image.svg[Alt Text]
         | 
| 1597 2000 | 
             
                  EOS
         | 
| 1598 2001 |  | 
| 1599 | 
            -
                  output | 
| 2002 | 
            +
                  output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER
         | 
| 1600 2003 | 
             
                  assert_xpath '//span[@class="alt"][text()="Alt Text"]', output, 1
         | 
| 1601 | 
            -
                   | 
| 2004 | 
            +
                  assert_message @logger, :WARN, '~SVG does not exist or cannot be read'
         | 
| 1602 2005 | 
             
                end
         | 
| 1603 2006 |  | 
| 1604 2007 | 
             
                test 'can render block image with alt text defined in macro containing square bracket' do
         | 
| @@ -1735,6 +2138,15 @@ image::images/tiger.png[Tiger,link=http://en.wikipedia.org/wiki/Tiger,window=nam | |
| 1735 2138 | 
             
                  assert_xpath '/*[@class="imageblock"]//a[@class="image"][@href="http://en.wikipedia.org/wiki/Tiger"][@target="name"][@rel="noopener"]/img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
         | 
| 1736 2139 | 
             
                end
         | 
| 1737 2140 |  | 
| 2141 | 
            +
                test 'adds rel=nofollow attribute to block image with a link when the nofollow option is set' do
         | 
| 2142 | 
            +
                  input = <<-EOS
         | 
| 2143 | 
            +
            image::images/tiger.png[Tiger,link=http://en.wikipedia.org/wiki/Tiger,opts=nofollow]
         | 
| 2144 | 
            +
                  EOS
         | 
| 2145 | 
            +
             | 
| 2146 | 
            +
                  output = render_embedded_string input
         | 
| 2147 | 
            +
                  assert_xpath '/*[@class="imageblock"]//a[@class="image"][@href="http://en.wikipedia.org/wiki/Tiger"][@rel="nofollow"]/img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
         | 
| 2148 | 
            +
                end
         | 
| 2149 | 
            +
             | 
| 1738 2150 | 
             
                test 'can render block image with caption' do
         | 
| 1739 2151 | 
             
                  input = <<-EOS
         | 
| 1740 2152 | 
             
            .The AsciiDoc Tiger
         | 
| @@ -1743,7 +2155,7 @@ image::images/tiger.png[Tiger] | |
| 1743 2155 |  | 
| 1744 2156 | 
             
                  doc = document_from_string input
         | 
| 1745 2157 | 
             
                  assert_equal 1, doc.blocks[0].number
         | 
| 1746 | 
            -
                  output = doc. | 
| 2158 | 
            +
                  output = doc.convert
         | 
| 1747 2159 | 
             
                  assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
         | 
| 1748 2160 | 
             
                  assert_xpath '//*[@class="imageblock"]/*[@class="title"][text() = "Figure 1. The AsciiDoc Tiger"]', output, 1
         | 
| 1749 2161 | 
             
                  assert_equal 1, doc.attributes['figure-number']
         | 
| @@ -1758,7 +2170,7 @@ image::images/tiger.png[Tiger] | |
| 1758 2170 |  | 
| 1759 2171 | 
             
                  doc = document_from_string input
         | 
| 1760 2172 | 
             
                  assert_nil doc.blocks[0].number
         | 
| 1761 | 
            -
                  output = doc. | 
| 2173 | 
            +
                  output = doc.convert
         | 
| 1762 2174 | 
             
                  assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
         | 
| 1763 2175 | 
             
                  assert_xpath '//*[@class="imageblock"]/*[@class="title"][text() = "Voila! The AsciiDoc Tiger"]', output, 1
         | 
| 1764 2176 | 
             
                  refute doc.attributes.has_key?('figure-number')
         | 
| @@ -1831,9 +2243,9 @@ image::images/sunset.jpg[Sunset,scaledwidth=25] | |
| 1831 2243 | 
             
            image::{bogus}[]
         | 
| 1832 2244 | 
             
                  EOS
         | 
| 1833 2245 |  | 
| 1834 | 
            -
                  output | 
| 1835 | 
            -
                   | 
| 1836 | 
            -
                   | 
| 2246 | 
            +
                  output = render_embedded_string input
         | 
| 2247 | 
            +
                  assert_includes output, 'image::{bogus}[]'
         | 
| 2248 | 
            +
                  assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: bogus'
         | 
| 1837 2249 | 
             
                end
         | 
| 1838 2250 |  | 
| 1839 2251 | 
             
                test 'drops line if image target is missing attribute reference and attribute-missing is drop' do
         | 
| @@ -1843,9 +2255,9 @@ image::{bogus}[] | |
| 1843 2255 | 
             
            image::{bogus}[]
         | 
| 1844 2256 | 
             
                  EOS
         | 
| 1845 2257 |  | 
| 1846 | 
            -
                  output | 
| 2258 | 
            +
                  output = render_embedded_string input
         | 
| 1847 2259 | 
             
                  assert_empty output.strip
         | 
| 1848 | 
            -
                   | 
| 2260 | 
            +
                  assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: bogus'
         | 
| 1849 2261 | 
             
                end
         | 
| 1850 2262 |  | 
| 1851 2263 | 
             
                test 'drops line if image target is missing attribute reference and attribute-missing is drop-line' do
         | 
| @@ -1855,9 +2267,9 @@ image::{bogus}[] | |
| 1855 2267 | 
             
            image::{bogus}[]
         | 
| 1856 2268 | 
             
                  EOS
         | 
| 1857 2269 |  | 
| 1858 | 
            -
                  output | 
| 2270 | 
            +
                  output = render_embedded_string input
         | 
| 1859 2271 | 
             
                  assert_empty output.strip
         | 
| 1860 | 
            -
                   | 
| 2272 | 
            +
                  assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: bogus'
         | 
| 1861 2273 | 
             
                end
         | 
| 1862 2274 |  | 
| 1863 2275 | 
             
                test 'dropped image does not break processing of following section and attribute-missing is drop-line' do
         | 
| @@ -1869,11 +2281,11 @@ image::{bogus}[] | |
| 1869 2281 | 
             
            == Section Title
         | 
| 1870 2282 | 
             
                  EOS
         | 
| 1871 2283 |  | 
| 1872 | 
            -
                  output | 
| 2284 | 
            +
                  output = render_embedded_string input
         | 
| 1873 2285 | 
             
                  assert_css 'img', output, 0
         | 
| 1874 2286 | 
             
                  assert_css 'h2', output, 1
         | 
| 1875 | 
            -
                   | 
| 1876 | 
            -
                   | 
| 2287 | 
            +
                  refute_includes output, '== Section Title'
         | 
| 2288 | 
            +
                  assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: bogus'
         | 
| 1877 2289 | 
             
                end
         | 
| 1878 2290 |  | 
| 1879 2291 | 
             
                test 'should pass through image that references uri' do
         | 
| @@ -1915,9 +2327,9 @@ image::tiger.png[Tiger] | |
| 1915 2327 | 
             
            image::dot.gif[Dot]
         | 
| 1916 2328 | 
             
                  EOS
         | 
| 1917 2329 |  | 
| 1918 | 
            -
                  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' =>  | 
| 2330 | 
            +
                  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => testdir }
         | 
| 1919 2331 | 
             
                  assert_equal 'fixtures', doc.attributes['imagesdir']
         | 
| 1920 | 
            -
                  output = doc. | 
| 2332 | 
            +
                  output = doc.convert
         | 
| 1921 2333 | 
             
                  assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
         | 
| 1922 2334 | 
             
                end
         | 
| 1923 2335 |  | 
| @@ -1929,11 +2341,11 @@ image::dot.gif[Dot] | |
| 1929 2341 | 
             
            image::unreadable.gif[Dot]
         | 
| 1930 2342 | 
             
                  EOS
         | 
| 1931 2343 |  | 
| 1932 | 
            -
                  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' =>  | 
| 2344 | 
            +
                  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => testdir }
         | 
| 1933 2345 | 
             
                  assert_equal 'fixtures', doc.attributes['imagesdir']
         | 
| 1934 | 
            -
                  output | 
| 2346 | 
            +
                  output = doc.convert
         | 
| 1935 2347 | 
             
                  assert_xpath '//img[@src="data:image/gif;base64,"]', output, 1
         | 
| 1936 | 
            -
                   | 
| 2348 | 
            +
                  assert_message @logger, :WARN, '~image to embed not found or not readable'
         | 
| 1937 2349 | 
             
                end
         | 
| 1938 2350 |  | 
| 1939 2351 | 
             
                test 'embeds base64-encoded data uri for remote image when data-uri attribute is set' do
         | 
| @@ -1973,16 +2385,12 @@ image::dot.gif[Dot] | |
| 1973 2385 | 
             
            image::#{image_uri}[Missing image]
         | 
| 1974 2386 | 
             
                  EOS
         | 
| 1975 2387 |  | 
| 1976 | 
            -
                  output =  | 
| 1977 | 
            -
             | 
| 1978 | 
            -
                    output = using_test_webserver do
         | 
| 1979 | 
            -
                      render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
         | 
| 1980 | 
            -
                    end
         | 
| 1981 | 
            -
                    warnings = err.string
         | 
| 2388 | 
            +
                  output = using_test_webserver do
         | 
| 2389 | 
            +
                    render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
         | 
| 1982 2390 | 
             
                  end
         | 
| 1983 2391 |  | 
| 1984 2392 | 
             
                  assert_xpath %(/*[@class="imageblock"]//img[@src="#{image_uri}"][@alt="Missing image"]), output, 1
         | 
| 1985 | 
            -
                   | 
| 2393 | 
            +
                  assert_message @logger, :WARN, '~could not retrieve image data from URI'
         | 
| 1986 2394 | 
             
                end
         | 
| 1987 2395 |  | 
| 1988 2396 | 
             
                test 'uses remote image uri when data-uri attribute is set and allow-uri-read is not set' do
         | 
| @@ -2028,13 +2436,13 @@ image::data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=[Do | |
| 2028 2436 | 
             
            image::dot.gif[Dot]
         | 
| 2029 2437 | 
             
                  EOS
         | 
| 2030 2438 |  | 
| 2031 | 
            -
                  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' =>  | 
| 2439 | 
            +
                  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => testdir }
         | 
| 2032 2440 | 
             
                  assert_equal '../..//fixtures/./../../fixtures', doc.attributes['imagesdir']
         | 
| 2033 | 
            -
                  output | 
| 2441 | 
            +
                  output = doc.convert
         | 
| 2034 2442 | 
             
                  # image target resolves to fixtures/dot.gif relative to docdir (which is explicitly set to the directory of this file)
         | 
| 2035 2443 | 
             
                  # the reference cannot fall outside of the document directory in safe mode
         | 
| 2036 2444 | 
             
                  assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
         | 
| 2037 | 
            -
                   | 
| 2445 | 
            +
                  assert_message @logger, :WARN, 'image has illegal reference to ancestor of jail; recovering automatically'
         | 
| 2038 2446 | 
             
                end
         | 
| 2039 2447 |  | 
| 2040 2448 | 
             
                test 'cleans reference to ancestor directories in target before reading image if safe mode level is at least SAFE' do
         | 
| @@ -2045,13 +2453,13 @@ image::dot.gif[Dot] | |
| 2045 2453 | 
             
            image::../..//fixtures/./../../fixtures/dot.gif[Dot]
         | 
| 2046 2454 | 
             
                  EOS
         | 
| 2047 2455 |  | 
| 2048 | 
            -
                  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' =>  | 
| 2456 | 
            +
                  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'docdir' => testdir }
         | 
| 2049 2457 | 
             
                  assert_equal './', doc.attributes['imagesdir']
         | 
| 2050 | 
            -
                  output | 
| 2458 | 
            +
                  output = doc.convert
         | 
| 2051 2459 | 
             
                  # image target resolves to fixtures/dot.gif relative to docdir (which is explicitly set to the directory of this file)
         | 
| 2052 2460 | 
             
                  # the reference cannot fall outside of the document directory in safe mode
         | 
| 2053 2461 | 
             
                  assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
         | 
| 2054 | 
            -
                   | 
| 2462 | 
            +
                  assert_message @logger, :WARN, 'image has illegal reference to ancestor of jail; recovering automatically'
         | 
| 2055 2463 | 
             
                end
         | 
| 2056 2464 | 
             
              end
         | 
| 2057 2465 |  | 
| @@ -2293,7 +2701,22 @@ Override the icon of an admonition block using an attribute | |
| 2293 2701 | 
             
            You can use icons for admonitions by setting the 'icons' attribute.
         | 
| 2294 2702 | 
             
                  EOS
         | 
| 2295 2703 |  | 
| 2296 | 
            -
                  output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' =>  | 
| 2704 | 
            +
                  output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'docdir' => testdir }
         | 
| 2705 | 
            +
                  assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
         | 
| 2706 | 
            +
                end
         | 
| 2707 | 
            +
             | 
| 2708 | 
            +
                test 'should embed base64-encoded data uri of custom icon when data-uri attribute is set' do
         | 
| 2709 | 
            +
                  input = <<-EOS
         | 
| 2710 | 
            +
            :icons:
         | 
| 2711 | 
            +
            :iconsdir: fixtures
         | 
| 2712 | 
            +
            :icontype: gif
         | 
| 2713 | 
            +
            :data-uri:
         | 
| 2714 | 
            +
             | 
| 2715 | 
            +
            [TIP,icon=tip]
         | 
| 2716 | 
            +
            You can set a custom icon using the icon attribute on the block.
         | 
| 2717 | 
            +
                  EOS
         | 
| 2718 | 
            +
             | 
| 2719 | 
            +
                  output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'docdir' => testdir }
         | 
| 2297 2720 | 
             
                  assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
         | 
| 2298 2721 | 
             
                end
         | 
| 2299 2722 |  | 
| @@ -2323,11 +2746,9 @@ You can use icons for admonitions by setting the 'icons' attribute. | |
| 2323 2746 | 
             
            You can use icons for admonitions by setting the 'icons' attribute.
         | 
| 2324 2747 | 
             
                  EOS
         | 
| 2325 2748 |  | 
| 2326 | 
            -
                  output | 
| 2327 | 
            -
                    [(render_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}), err.string]
         | 
| 2328 | 
            -
                  end
         | 
| 2749 | 
            +
                  output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'docdir' => testdir }
         | 
| 2329 2750 | 
             
                  assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
         | 
| 2330 | 
            -
                   | 
| 2751 | 
            +
                  assert_message @logger, :WARN, 'image has illegal reference to ancestor of jail; recovering automatically'
         | 
| 2331 2752 | 
             
                end
         | 
| 2332 2753 |  | 
| 2333 2754 | 
             
                test 'should import Font Awesome and use font-based icons when value of icons attribute is font' do
         | 
| @@ -2339,7 +2760,7 @@ You can use icons for admonitions by setting the 'icons' attribute. | |
| 2339 2760 | 
             
                  EOS
         | 
| 2340 2761 |  | 
| 2341 2762 | 
             
                  output = render_string input, :safe => Asciidoctor::SafeMode::SERVER
         | 
| 2342 | 
            -
                  assert_css  | 
| 2763 | 
            +
                  assert_css %(html > head > link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/#{Asciidoctor::FONT_AWESOME_VERSION}/css/font-awesome.min.css"]), output, 1
         | 
| 2343 2764 | 
             
                  assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/i[@class="fa icon-tip"]', output, 1
         | 
| 2344 2765 | 
             
                end
         | 
| 2345 2766 |  | 
| @@ -2370,7 +2791,7 @@ puts "AsciiDoc, FTW!" | |
| 2370 2791 | 
             
                  EOS
         | 
| 2371 2792 |  | 
| 2372 2793 | 
             
                  output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
         | 
| 2373 | 
            -
                  assert_css  | 
| 2794 | 
            +
                  assert_css %(html > head > link[rel="stylesheet"][href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/#{Asciidoctor::FONT_AWESOME_VERSION}/css/font-awesome.min.css"]), output, 1
         | 
| 2374 2795 | 
             
                  assert_css 'html > body > script[src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"]', output, 1
         | 
| 2375 2796 | 
             
                end
         | 
| 2376 2797 |  | 
| @@ -2387,32 +2808,31 @@ puts "AsciiDoc, FTW!" | |
| 2387 2808 | 
             
                  EOS
         | 
| 2388 2809 |  | 
| 2389 2810 | 
             
                  output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
         | 
| 2390 | 
            -
                  assert_css  | 
| 2811 | 
            +
                  assert_css %(html > head > link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/#{Asciidoctor::FONT_AWESOME_VERSION}/css/font-awesome.min.css"]), output, 1
         | 
| 2391 2812 | 
             
                  assert_css 'html > body > script[src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"]', output, 1
         | 
| 2392 2813 | 
             
                end
         | 
| 2393 2814 | 
             
              end
         | 
| 2394 2815 |  | 
| 2395 2816 | 
             
              context 'Image paths' do
         | 
| 2396 | 
            -
             | 
| 2397 2817 | 
             
                test 'restricts access to ancestor directories when safe mode level is at least SAFE' do
         | 
| 2398 2818 | 
             
                  input = <<-EOS
         | 
| 2399 2819 | 
             
            image::asciidoctor.png[Asciidoctor]
         | 
| 2400 2820 | 
             
                  EOS
         | 
| 2401 | 
            -
                  basedir =  | 
| 2821 | 
            +
                  basedir = testdir
         | 
| 2402 2822 | 
             
                  block = block_from_string input, :attributes => {'docdir' => basedir}
         | 
| 2403 2823 | 
             
                  doc = block.document
         | 
| 2404 2824 | 
             
                  assert doc.safe >= Asciidoctor::SafeMode::SAFE
         | 
| 2405 2825 |  | 
| 2406 2826 | 
             
                  assert_equal File.join(basedir, 'images'), block.normalize_asset_path('images')
         | 
| 2407 | 
            -
                  assert_equal File.join(basedir, 'etc/images'),  | 
| 2408 | 
            -
                  assert_equal File.join(basedir, 'images'),  | 
| 2827 | 
            +
                  assert_equal File.join(basedir, 'etc/images'), block.normalize_asset_path("#{disk_root}etc/images")
         | 
| 2828 | 
            +
                  assert_equal File.join(basedir, 'images'), block.normalize_asset_path('../../images')
         | 
| 2409 2829 | 
             
                end
         | 
| 2410 2830 |  | 
| 2411 2831 | 
             
                test 'does not restrict access to ancestor directories when safe mode is disabled' do
         | 
| 2412 2832 | 
             
                  input = <<-EOS
         | 
| 2413 2833 | 
             
            image::asciidoctor.png[Asciidoctor]
         | 
| 2414 2834 | 
             
                  EOS
         | 
| 2415 | 
            -
                  basedir =  | 
| 2835 | 
            +
                  basedir = testdir
         | 
| 2416 2836 | 
             
                  block = block_from_string input, :safe => Asciidoctor::SafeMode::UNSAFE, :attributes => {'docdir' => basedir}
         | 
| 2417 2837 | 
             
                  doc = block.document
         | 
| 2418 2838 | 
             
                  assert doc.safe == Asciidoctor::SafeMode::UNSAFE
         | 
| @@ -2686,7 +3106,7 @@ public class Printer { | |
| 2686 3106 | 
             
                  assert_match(/\.<em>out<\/em>\./, output, 1)
         | 
| 2687 3107 | 
             
                  assert_match(/\*asterisks\*/, output, 1)
         | 
| 2688 3108 | 
             
                  assert_match(/<strong>bold<\/strong>/, output, 1)
         | 
| 2689 | 
            -
                   | 
| 3109 | 
            +
                  refute_includes output, Asciidoctor::Substitutors::PASS_START
         | 
| 2690 3110 | 
             
                end
         | 
| 2691 3111 |  | 
| 2692 3112 | 
             
                test 'should link to CodeRay stylesheet if source-highlighter is coderay and linkcss is set' do
         | 
| @@ -2780,6 +3200,23 @@ puts HTML::Pipeline.new(filters, {}).call(input)[:output] | |
| 2780 3200 | 
             
                  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SERVER
         | 
| 2781 3201 | 
             
                  assert_nil doc.attributes['source-highlighter']
         | 
| 2782 3202 | 
             
                end
         | 
| 3203 | 
            +
             | 
| 3204 | 
            +
                test 'should warn if listing block is not terminated' do
         | 
| 3205 | 
            +
                  input = <<-EOS
         | 
| 3206 | 
            +
            outside
         | 
| 3207 | 
            +
             | 
| 3208 | 
            +
            ----
         | 
| 3209 | 
            +
            inside
         | 
| 3210 | 
            +
             | 
| 3211 | 
            +
            still inside
         | 
| 3212 | 
            +
             | 
| 3213 | 
            +
            eof
         | 
| 3214 | 
            +
                  EOS
         | 
| 3215 | 
            +
             | 
| 3216 | 
            +
                  output = render_embedded_string input
         | 
| 3217 | 
            +
                  assert_xpath '/*[@class="listingblock"]', output, 1
         | 
| 3218 | 
            +
                  assert_message @logger, :WARN, '<stdin>: line 3: unterminated listing block', Hash
         | 
| 3219 | 
            +
                end
         | 
| 2783 3220 | 
             
              end
         | 
| 2784 3221 |  | 
| 2785 3222 | 
             
              context 'Abstract and Part Intro' do
         | 
| @@ -2852,15 +3289,9 @@ Abstract for book with title is valid | |
| 2852 3289 | 
             
            Abstract for book without title is invalid.
         | 
| 2853 3290 | 
             
                  EOS
         | 
| 2854 3291 |  | 
| 2855 | 
            -
                   | 
| 2856 | 
            -
                  output = nil
         | 
| 2857 | 
            -
                  redirect_streams do |stdout, stderr|
         | 
| 2858 | 
            -
                    output = render_string input
         | 
| 2859 | 
            -
                    warnings = stderr.string
         | 
| 2860 | 
            -
                  end
         | 
| 3292 | 
            +
                  output = render_string input
         | 
| 2861 3293 | 
             
                  assert_css '.abstract', output, 0
         | 
| 2862 | 
            -
                   | 
| 2863 | 
            -
                  assert_match(/WARNING:.*abstract block/, warnings)
         | 
| 3294 | 
            +
                  assert_message @logger, :WARN, 'abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
         | 
| 2864 3295 | 
             
                end
         | 
| 2865 3296 |  | 
| 2866 3297 | 
             
                test 'should make abstract on open block without title rendered to DocBook' do
         | 
| @@ -2918,15 +3349,9 @@ Abstract for book with title is valid | |
| 2918 3349 | 
             
            Abstract for book is invalid.
         | 
| 2919 3350 | 
             
                  EOS
         | 
| 2920 3351 |  | 
| 2921 | 
            -
                  output =  | 
| 2922 | 
            -
                  warnings = nil
         | 
| 2923 | 
            -
                  redirect_streams do |stdout, stderr|
         | 
| 2924 | 
            -
                    output = render_string input, :backend => 'docbook'
         | 
| 2925 | 
            -
                    warnings = stderr.string
         | 
| 2926 | 
            -
                  end
         | 
| 3352 | 
            +
                  output = render_string input, :backend => 'docbook'
         | 
| 2927 3353 | 
             
                  assert_css 'abstract', output, 0
         | 
| 2928 | 
            -
                   | 
| 2929 | 
            -
                  assert_match(/WARNING:.*abstract block/, warnings)
         | 
| 3354 | 
            +
                  assert_message @logger, :WARN, 'abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
         | 
| 2930 3355 | 
             
                end
         | 
| 2931 3356 |  | 
| 2932 3357 | 
             
                # TODO partintro shouldn't be recognized if doctype is not book, should be in proper place
         | 
| @@ -2995,9 +3420,9 @@ content | |
| 2995 3420 | 
             
            part intro paragraph
         | 
| 2996 3421 | 
             
                  EOS
         | 
| 2997 3422 |  | 
| 2998 | 
            -
                  output | 
| 3423 | 
            +
                  output = render_string input
         | 
| 2999 3424 | 
             
                  assert_css '.partintro', output, 0
         | 
| 3000 | 
            -
                   | 
| 3425 | 
            +
                  assert_message @logger, :ERROR, 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
         | 
| 3001 3426 | 
             
                end
         | 
| 3002 3427 |  | 
| 3003 3428 | 
             
                test 'should not allow partintro unless doctype is book' do
         | 
| @@ -3006,9 +3431,9 @@ part intro paragraph | |
| 3006 3431 | 
             
            part intro paragraph
         | 
| 3007 3432 | 
             
                  EOS
         | 
| 3008 3433 |  | 
| 3009 | 
            -
                  output | 
| 3434 | 
            +
                  output = render_string input
         | 
| 3010 3435 | 
             
                  assert_css '.partintro', output, 0
         | 
| 3011 | 
            -
                   | 
| 3436 | 
            +
                  assert_message @logger, :ERROR, 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
         | 
| 3012 3437 | 
             
                end
         | 
| 3013 3438 |  | 
| 3014 3439 | 
             
                test 'should accept partintro on open block without title rendered to DocBook' do
         | 
| @@ -3070,9 +3495,9 @@ content | |
| 3070 3495 | 
             
            part intro paragraph
         | 
| 3071 3496 | 
             
                  EOS
         | 
| 3072 3497 |  | 
| 3073 | 
            -
                  output | 
| 3498 | 
            +
                  output = render_string input, :backend => 'docbook'
         | 
| 3074 3499 | 
             
                  assert_css 'partintro', output, 0
         | 
| 3075 | 
            -
                   | 
| 3500 | 
            +
                  assert_message @logger, :ERROR, 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
         | 
| 3076 3501 | 
             
                end
         | 
| 3077 3502 |  | 
| 3078 3503 | 
             
                test 'should not allow partintro unless doctype is book rendered to DocBook' do
         | 
| @@ -3081,9 +3506,9 @@ part intro paragraph | |
| 3081 3506 | 
             
            part intro paragraph
         | 
| 3082 3507 | 
             
                  EOS
         | 
| 3083 3508 |  | 
| 3084 | 
            -
                  output | 
| 3509 | 
            +
                  output = render_string input, :backend => 'docbook'
         | 
| 3085 3510 | 
             
                  assert_css 'partintro', output, 0
         | 
| 3086 | 
            -
                   | 
| 3511 | 
            +
                  assert_message @logger, :ERROR, 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
         | 
| 3087 3512 | 
             
                end
         | 
| 3088 3513 | 
             
              end
         | 
| 3089 3514 |  | 
| @@ -3148,15 +3573,15 @@ content | |
| 3148 3573 |  | 
| 3149 3574 | 
             
            [subs="attributes+,-verbatim,+specialcharacters,+macros"]
         | 
| 3150 3575 | 
             
            ....
         | 
| 3151 | 
            -
             | 
| 3576 | 
            +
            https://{application}.org[{gt}{gt}] <1>
         | 
| 3152 3577 | 
             
            ....
         | 
| 3153 3578 | 
             
                  EOS
         | 
| 3154 3579 |  | 
| 3155 3580 | 
             
                  doc = document_from_string input, :header_footer => false
         | 
| 3156 3581 | 
             
                  block = doc.blocks.first
         | 
| 3157 3582 | 
             
                  assert_equal [:attributes, :specialcharacters, :macros], block.subs
         | 
| 3158 | 
            -
                  result = doc. | 
| 3159 | 
            -
                   | 
| 3583 | 
            +
                  result = doc.convert
         | 
| 3584 | 
            +
                  assert_includes result, '<pre><a href="https://asciidoctor.org">>></a> <1></pre>'
         | 
| 3160 3585 | 
             
                end
         | 
| 3161 3586 |  | 
| 3162 3587 | 
             
                test 'should be able to set subs then modify them' do
         | 
| @@ -3168,8 +3593,8 @@ _hey now_ <1> | |
| 3168 3593 | 
             
                  doc = document_from_string input, :header_footer => false
         | 
| 3169 3594 | 
             
                  block = doc.blocks.first
         | 
| 3170 3595 | 
             
                  assert_equal [:specialcharacters], block.subs
         | 
| 3171 | 
            -
                  result = doc. | 
| 3172 | 
            -
                   | 
| 3596 | 
            +
                  result = doc.convert
         | 
| 3597 | 
            +
                  assert_includes result, '_hey now_ <1>'
         | 
| 3173 3598 | 
             
                end
         | 
| 3174 3599 | 
             
              end
         | 
| 3175 3600 |  |