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/substitutions_test.rb
    CHANGED
    
    | @@ -17,6 +17,15 @@ context 'Substitutions' do | |
| 17 17 | 
             
                  assert_equal %{<em class="blue"><a href="http://asciidoc.org">AsciiDoc</a></em> & <strong class="red">Ruby</strong>\n§ Making <u>documentation</u> together<br>\nsince © 2012.}, result
         | 
| 18 18 | 
             
                end
         | 
| 19 19 |  | 
| 20 | 
            +
                test 'apply_subs should not modify string directly' do
         | 
| 21 | 
            +
                  input = '<html> -- the root of all web'
         | 
| 22 | 
            +
                  para = block_from_string input
         | 
| 23 | 
            +
                  para_source = para.source
         | 
| 24 | 
            +
                  result = para.apply_subs para_source
         | 
| 25 | 
            +
                  assert_equal '<html> — the root of all web', result
         | 
| 26 | 
            +
                  assert_equal input, para_source
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 20 29 | 
             
                test 'should not drop trailing blank lines when performing substitutions' do
         | 
| 21 30 | 
             
                  para = block_from_string %([%hardbreaks]\nthis\nis\n-> {program})
         | 
| 22 31 | 
             
                  para.lines << ''
         | 
| @@ -28,15 +37,12 @@ context 'Substitutions' do | |
| 28 37 | 
             
                  assert_equal %(this<br>\nis<br>\n→ Asciidoctor<br>\n<br>\n), result
         | 
| 29 38 | 
             
                end
         | 
| 30 39 |  | 
| 31 | 
            -
                test 'should expand subs  | 
| 40 | 
            +
                test 'should expand subs passe to expand_subs' do
         | 
| 32 41 | 
             
                  para = block_from_string %({program}\n*bold*\n2 > 1)
         | 
| 33 42 | 
             
                  para.document.attributes['program'] = 'Asciidoctor'
         | 
| 34 | 
            -
                   | 
| 35 | 
            -
                   | 
| 36 | 
            -
                   | 
| 37 | 
            -
                  assert_equal ['{program}', '*bold*', '2 > 1'], result
         | 
| 38 | 
            -
                  result = para.apply_subs para.lines, [:normal], true
         | 
| 39 | 
            -
                  assert_equal ['Asciidoctor', '<strong>bold</strong>', '2 > 1'], result
         | 
| 43 | 
            +
                  assert_equal [:specialcharacters], (para.expand_subs [:specialchars])
         | 
| 44 | 
            +
                  refute para.expand_subs([:none])
         | 
| 45 | 
            +
                  assert_equal [:specialcharacters, :quotes, :attributes, :replacements, :macros, :post_replacements], (para.expand_subs [:normal])
         | 
| 40 46 | 
             
                end
         | 
| 41 47 |  | 
| 42 48 | 
             
                test 'apply_subs should allow the subs argument to be nil' do
         | 
| @@ -53,6 +59,9 @@ context 'Substitutions' do | |
| 53 59 |  | 
| 54 60 | 
             
                  para = block_from_string(%q{"`a few quoted words`"})
         | 
| 55 61 | 
             
                  assert_equal '“a few quoted words”', para.sub_quotes(para.source)
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  para = block_from_string(%q{"`a few quoted words`"}, :backend => 'docbook')
         | 
| 64 | 
            +
                  assert_equal '<quote>a few quoted words</quote>', para.sub_quotes(para.source)
         | 
| 56 65 | 
             
                end
         | 
| 57 66 |  | 
| 58 67 | 
             
                test 'escaped single-line double-quoted string' do
         | 
| @@ -107,6 +116,9 @@ context 'Substitutions' do | |
| 107 116 |  | 
| 108 117 | 
             
                  para = block_from_string(%q{'`a few quoted words`'})
         | 
| 109 118 | 
             
                  assert_equal '‘a few quoted words’', para.sub_quotes(para.source)
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                  para = block_from_string(%q{'`a few quoted words`'}, :backend => 'docbook')
         | 
| 121 | 
            +
                  assert_equal '<quote>a few quoted words</quote>', para.sub_quotes(para.source)
         | 
| 110 122 | 
             
                end
         | 
| 111 123 |  | 
| 112 124 | 
             
                test 'escaped single-line single-quoted string' do
         | 
| @@ -538,12 +550,12 @@ context 'Substitutions' do | |
| 538 550 |  | 
| 539 551 | 
             
                test 'quoted text with id shorthand' do
         | 
| 540 552 | 
             
                  para = block_from_string(%q{[#bond]#007#})
         | 
| 541 | 
            -
                  assert_equal '< | 
| 553 | 
            +
                  assert_equal '<span id="bond">007</span>', para.sub_quotes(para.source)
         | 
| 542 554 | 
             
                end
         | 
| 543 555 |  | 
| 544 556 | 
             
                test 'quoted text with id and role shorthand' do
         | 
| 545 557 | 
             
                  para = block_from_string(%q{[#bond.white.red-background]#007#})
         | 
| 546 | 
            -
                  assert_equal '< | 
| 558 | 
            +
                  assert_equal '<span id="bond" class="white red-background">007</span>', para.sub_quotes(para.source)
         | 
| 547 559 | 
             
                end
         | 
| 548 560 |  | 
| 549 561 | 
             
                test 'quoted text with id and role shorthand using docbook backend' do
         | 
| @@ -593,12 +605,12 @@ context 'Substitutions' do | |
| 593 605 | 
             
                end
         | 
| 594 606 |  | 
| 595 607 | 
             
                test 'a mailto macro with text and subject should be interpreted as a mailto link' do
         | 
| 596 | 
            -
                  para = block_from_string('mailto:doc.writer@asciidoc.org[Doc Writer, Pull request]' | 
| 608 | 
            +
                  para = block_from_string('mailto:doc.writer@asciidoc.org[Doc Writer, Pull request]')
         | 
| 597 609 | 
             
                  assert_equal %q{<a href="mailto:doc.writer@asciidoc.org?subject=Pull%20request">Doc Writer</a>}, para.sub_macros(para.source)
         | 
| 598 610 | 
             
                end
         | 
| 599 611 |  | 
| 600 612 | 
             
                test 'a mailto macro with text, subject and body should be interpreted as a mailto link' do
         | 
| 601 | 
            -
                  para = block_from_string('mailto:doc.writer@asciidoc.org[Doc Writer, Pull request, Please accept my pull request]' | 
| 613 | 
            +
                  para = block_from_string('mailto:doc.writer@asciidoc.org[Doc Writer, Pull request, Please accept my pull request]')
         | 
| 602 614 | 
             
                  assert_equal %q{<a href="mailto:doc.writer@asciidoc.org?subject=Pull%20request&body=Please%20accept%20my%20pull%20request">Doc Writer</a>}, para.sub_macros(para.source)
         | 
| 603 615 | 
             
                end
         | 
| 604 616 |  | 
| @@ -698,7 +710,7 @@ context 'Substitutions' do | |
| 698 710 | 
             
                end
         | 
| 699 711 |  | 
| 700 712 | 
             
                test 'an image macro with an inline SVG image should be converted to an svg element' do
         | 
| 701 | 
            -
                  para = block_from_string('image:circle.svg[Tiger,100,opts=inline]', :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'imagesdir' => 'fixtures', 'docdir' =>  | 
| 713 | 
            +
                  para = block_from_string('image:circle.svg[Tiger,100,opts=inline]', :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'imagesdir' => 'fixtures', 'docdir' => testdir })
         | 
| 702 714 | 
             
                  result = para.sub_macros(para.source).gsub(/>\s+</, '><')
         | 
| 703 715 | 
             
                  assert_match(/<svg\s[^>]*width="100px"[^>]*>/, result)
         | 
| 704 716 | 
             
                  refute_match(/<svg\s[^>]*width="500px"[^>]*>/, result)
         | 
| @@ -707,7 +719,7 @@ context 'Substitutions' do | |
| 707 719 | 
             
                end
         | 
| 708 720 |  | 
| 709 721 | 
             
                test 'an image macro with an inline SVG image should be converted to an svg element even when data-uri is set' do
         | 
| 710 | 
            -
                  para = block_from_string('image:circle.svg[Tiger,100,opts=inline]', :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'data-uri' => '', 'imagesdir' => 'fixtures', 'docdir' =>  | 
| 722 | 
            +
                  para = block_from_string('image:circle.svg[Tiger,100,opts=inline]', :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'data-uri' => '', 'imagesdir' => 'fixtures', 'docdir' => testdir })
         | 
| 711 723 | 
             
                  assert_match(/<svg\s[^>]*width="100px">/, para.sub_macros(para.source).gsub(/>\s+</, '><'))
         | 
| 712 724 | 
             
                end
         | 
| 713 725 |  | 
| @@ -751,6 +763,12 @@ context 'Substitutions' do | |
| 751 763 | 
             
                      para.sub_macros(para.source).gsub(/>\s+</, '><')
         | 
| 752 764 | 
             
                end
         | 
| 753 765 |  | 
| 766 | 
            +
                test 'rel=nofollow should be added to an image with a link when the nofollow option is set' do
         | 
| 767 | 
            +
                  para = block_from_string 'image:tiger.png[Tiger,link=http://en.wikipedia.org/wiki/Tiger,opts=nofollow]'
         | 
| 768 | 
            +
                  assert_equal %{<span class="image"><a class="image" href="http://en.wikipedia.org/wiki/Tiger" rel="nofollow"><img src="tiger.png" alt="Tiger"></a></span>},
         | 
| 769 | 
            +
                      para.sub_macros(para.source).gsub(/>\s+</, '><')
         | 
| 770 | 
            +
                end
         | 
| 771 | 
            +
             | 
| 754 772 | 
             
                test 'a multi-line image macro with text and dimensions should be interpreted as an image with alt text and dimensions' do
         | 
| 755 773 | 
             
                  para = block_from_string(%(image:tiger.png[Another\nAwesome\nTiger, 200,\n100]))
         | 
| 756 774 | 
             
                  assert_equal %{<span class="image"><img src="tiger.png" alt="Another Awesome Tiger" width="200" height="100"></span>},
         | 
| @@ -796,7 +814,7 @@ context 'Substitutions' do | |
| 796 814 | 
             
                test 'should not match an inline image macro if target contains an endline character' do
         | 
| 797 815 | 
             
                  para = block_from_string(%(Fear not. There are no image:big\ncats.png[] around here.))
         | 
| 798 816 | 
             
                  result = para.sub_macros(para.source)
         | 
| 799 | 
            -
                   | 
| 817 | 
            +
                  refute_includes result, '<img '
         | 
| 800 818 | 
             
                  assert_includes result, %(image:big\ncats.png[])
         | 
| 801 819 | 
             
                end
         | 
| 802 820 |  | 
| @@ -804,7 +822,7 @@ context 'Substitutions' do | |
| 804 822 | 
             
                  ['image: big cats.png[]', 'image:big cats.png []'].each do |input|
         | 
| 805 823 | 
             
                    para = block_from_string %(Fear not. There are no #{input} around here.)
         | 
| 806 824 | 
             
                    result = para.sub_macros(para.source)
         | 
| 807 | 
            -
                     | 
| 825 | 
            +
                    refute_includes result, '<img '
         | 
| 808 826 | 
             
                    assert_includes result, input
         | 
| 809 827 | 
             
                  end
         | 
| 810 828 | 
             
                end
         | 
| @@ -812,8 +830,8 @@ context 'Substitutions' do | |
| 812 830 | 
             
                test 'should not detect a block image macro found inline' do
         | 
| 813 831 | 
             
                  para = block_from_string(%(Not an inline image macro image::tiger.png[].))
         | 
| 814 832 | 
             
                  result = para.sub_macros(para.source)
         | 
| 815 | 
            -
                   | 
| 816 | 
            -
                   | 
| 833 | 
            +
                  refute_includes result, '<img '
         | 
| 834 | 
            +
                  assert_includes result, 'image::tiger.png[]'
         | 
| 817 835 | 
             
                end
         | 
| 818 836 |  | 
| 819 837 | 
             
                # NOTE this test verifies attributes get substituted eagerly in target of image in title
         | 
| @@ -822,12 +840,11 @@ context 'Substitutions' do | |
| 822 840 | 
             
            == image:{iconsdir}/dot.gif[dot] Title
         | 
| 823 841 | 
             
                  EOS
         | 
| 824 842 |  | 
| 825 | 
            -
                   | 
| 826 | 
            -
                     | 
| 843 | 
            +
                  using_memory_logger do |logger|
         | 
| 844 | 
            +
                    sect = block_from_string input, :attributes => { 'data-uri' => '', 'iconsdir' => 'fixtures', 'docdir' => testdir }, :safe => :server, :catalog_assets => true
         | 
| 845 | 
            +
                    assert_includes sect.document.catalog[:images], 'fixtures/dot.gif'
         | 
| 846 | 
            +
                    assert logger.empty?
         | 
| 827 847 | 
             
                  end
         | 
| 828 | 
            -
                  assert sect.document.catalog[:images].include? 'fixtures/dot.gif'
         | 
| 829 | 
            -
                  refute_nil warnings
         | 
| 830 | 
            -
                  assert_empty warnings
         | 
| 831 848 | 
             
                end
         | 
| 832 849 |  | 
| 833 850 | 
             
                test 'an icon macro should be interpreted as an icon if icons are enabled' do
         | 
| @@ -862,7 +879,7 @@ context 'Substitutions' do | |
| 862 879 |  | 
| 863 880 | 
             
                test 'a single-line footnote macro should be registered and rendered as a footnote' do
         | 
| 864 881 | 
             
                  para = block_from_string('Sentence text footnote:[An example footnote.].')
         | 
| 865 | 
            -
                  assert_equal %(Sentence text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="# | 
| 882 | 
            +
                  assert_equal %(Sentence text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
         | 
| 866 883 | 
             
                  assert_equal 1, para.document.catalog[:footnotes].size
         | 
| 867 884 | 
             
                  footnote = para.document.catalog[:footnotes].first
         | 
| 868 885 | 
             
                  assert_equal 1, footnote.index
         | 
| @@ -872,7 +889,7 @@ context 'Substitutions' do | |
| 872 889 |  | 
| 873 890 | 
             
                test 'a multi-line footnote macro should be registered and rendered as a footnote without endline' do
         | 
| 874 891 | 
             
                  para = block_from_string("Sentence text footnote:[An example footnote\nwith wrapped text.].")
         | 
| 875 | 
            -
                  assert_equal %(Sentence text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="# | 
| 892 | 
            +
                  assert_equal %(Sentence text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
         | 
| 876 893 | 
             
                  assert_equal 1, para.document.catalog[:footnotes].size
         | 
| 877 894 | 
             
                  footnote = para.document.catalog[:footnotes].first
         | 
| 878 895 | 
             
                  assert_equal 1, footnote.index
         | 
| @@ -882,7 +899,7 @@ context 'Substitutions' do | |
| 882 899 |  | 
| 883 900 | 
             
                test 'an escaped closing square bracket in a footnote should be unescaped when rendered' do
         | 
| 884 901 | 
             
                  para = block_from_string(%(footnote:[a #{BACKSLASH}] b].))
         | 
| 885 | 
            -
                  assert_equal %(<sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="# | 
| 902 | 
            +
                  assert_equal %(<sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
         | 
| 886 903 | 
             
                  assert_equal 1, para.document.catalog[:footnotes].size
         | 
| 887 904 | 
             
                  footnote = para.document.catalog[:footnotes].first
         | 
| 888 905 | 
             
                  assert_equal "a ] b", footnote.text
         | 
| @@ -890,7 +907,7 @@ context 'Substitutions' do | |
| 890 907 |  | 
| 891 908 | 
             
                test 'a footnote macro can be directly adjacent to preceding word' do
         | 
| 892 909 | 
             
                  para = block_from_string('Sentence textfootnote:[An example footnote.].')
         | 
| 893 | 
            -
                  assert_equal %(Sentence text<sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="# | 
| 910 | 
            +
                  assert_equal %(Sentence text<sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
         | 
| 894 911 | 
             
                end
         | 
| 895 912 |  | 
| 896 913 | 
             
                test 'a footnote macro may contain an escaped backslash' do
         | 
| @@ -907,7 +924,7 @@ context 'Substitutions' do | |
| 907 924 |  | 
| 908 925 | 
             
                test 'a footnote macro may contain a link macro' do
         | 
| 909 926 | 
             
                  para = block_from_string('Share your code. footnote:[https://github.com[GitHub]]')
         | 
| 910 | 
            -
                  assert_equal %(Share your code. <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="# | 
| 927 | 
            +
                  assert_equal %(Share your code. <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>), para.sub_macros(para.source)
         | 
| 911 928 | 
             
                  assert_equal 1, para.document.catalog[:footnotes].size
         | 
| 912 929 | 
             
                  footnote1 = para.document.catalog[:footnotes][0]
         | 
| 913 930 | 
             
                  assert_equal '<a href="https://github.com">GitHub</a>', footnote1.text
         | 
| @@ -916,7 +933,7 @@ context 'Substitutions' do | |
| 916 933 | 
             
                test 'a footnote macro may contain a plain URL' do
         | 
| 917 934 | 
             
                  para = block_from_string %(the JLine footnote:[https://github.com/jline/jline2]\nlibrary.)
         | 
| 918 935 | 
             
                  result = para.sub_macros para.source
         | 
| 919 | 
            -
                  assert_equal %(the JLine <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="# | 
| 936 | 
            +
                  assert_equal %(the JLine <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>\nlibrary.), result
         | 
| 920 937 | 
             
                  assert_equal 1, para.document.catalog[:footnotes].size
         | 
| 921 938 | 
             
                  fn1 = para.document.catalog[:footnotes].first
         | 
| 922 939 | 
             
                  assert_equal '<a href="https://github.com/jline/jline2" class="bare">https://github.com/jline/jline2</a>', fn1.text
         | 
| @@ -925,7 +942,7 @@ context 'Substitutions' do | |
| 925 942 | 
             
                test 'a footnote macro followed by a semi-colon may contain a plain URL' do
         | 
| 926 943 | 
             
                  para = block_from_string %(the JLine footnote:[https://github.com/jline/jline2];\nlibrary.)
         | 
| 927 944 | 
             
                  result = para.sub_macros para.source
         | 
| 928 | 
            -
                  assert_equal %(the JLine <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="# | 
| 945 | 
            +
                  assert_equal %(the JLine <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>;\nlibrary.), result
         | 
| 929 946 | 
             
                  assert_equal 1, para.document.catalog[:footnotes].size
         | 
| 930 947 | 
             
                  fn1 = para.document.catalog[:footnotes].first
         | 
| 931 948 | 
             
                  assert_equal '<a href="https://github.com/jline/jline2" class="bare">https://github.com/jline/jline2</a>', fn1.text
         | 
| @@ -937,7 +954,7 @@ context 'Substitutions' do | |
| 937 954 | 
             
                  doc = para.document
         | 
| 938 955 | 
             
                  doc.register :refs, ['_install', (Asciidoctor::Inline.new doc, :anchor, 'Install', :type => :ref, :target => '_install'), 'Install']
         | 
| 939 956 | 
             
                  catalog = doc.catalog
         | 
| 940 | 
            -
                  assert_equal %(text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="# | 
| 957 | 
            +
                  assert_equal %(text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>), para.sub_macros(para.source)
         | 
| 941 958 | 
             
                  assert_equal 1, catalog[:footnotes].size
         | 
| 942 959 | 
             
                  footnote1 = catalog[:footnotes][0]
         | 
| 943 960 | 
             
                  assert_equal '<a href="#_install">install</a>', footnote1.text
         | 
| @@ -945,7 +962,7 @@ context 'Substitutions' do | |
| 945 962 |  | 
| 946 963 | 
             
                test 'a footnote macro may contain an anchor macro' do
         | 
| 947 964 | 
             
                  para = block_from_string('text footnote:[a [[b\]\] \[[c\]\] d]')
         | 
| 948 | 
            -
                  assert_equal %(text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="# | 
| 965 | 
            +
                  assert_equal %(text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>), para.sub_macros(para.source)
         | 
| 949 966 | 
             
                  assert_equal 1, para.document.catalog[:footnotes].size
         | 
| 950 967 | 
             
                  footnote1 = para.document.catalog[:footnotes][0]
         | 
| 951 968 | 
             
                  assert_equal 'a <a id="b"></a> [[c]] d', footnote1.text
         | 
| @@ -962,7 +979,7 @@ foofootnote:[+http://example.com+]barfootnote:[+http://acme.com+]baz | |
| 962 979 |  | 
| 963 980 | 
             
                test 'should increment index of subsequent footnote macros' do
         | 
| 964 981 | 
             
                  para = block_from_string("Sentence text footnote:[An example footnote.]. Sentence text footnote:[Another footnote.].")
         | 
| 965 | 
            -
                  assert_equal %(Sentence text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="# | 
| 982 | 
            +
                  assert_equal %(Sentence text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>. Sentence text <sup class="footnote">[<a id="_footnoteref_2" class="footnote" href="#_footnotedef_2" title="View footnote.">2</a>]</sup>.), para.sub_macros(para.source)
         | 
| 966 983 | 
             
                  assert_equal 2, para.document.catalog[:footnotes].size
         | 
| 967 984 | 
             
                  footnote1 = para.document.catalog[:footnotes][0]
         | 
| 968 985 | 
             
                  assert_equal 1, footnote1.index
         | 
| @@ -976,7 +993,7 @@ foofootnote:[+http://example.com+]barfootnote:[+http://acme.com+]baz | |
| 976 993 |  | 
| 977 994 | 
             
                test 'a footnoteref macro with id and single-line text should be registered and rendered as a footnote' do
         | 
| 978 995 | 
             
                  para = block_from_string('Sentence text footnoteref:[ex1, An example footnote.].')
         | 
| 979 | 
            -
                  assert_equal %(Sentence text <sup class="footnote" id="_footnote_ex1">[<a id="_footnoteref_1" class="footnote" href="# | 
| 996 | 
            +
                  assert_equal %(Sentence text <sup class="footnote" id="_footnote_ex1">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
         | 
| 980 997 | 
             
                  assert_equal 1, para.document.catalog[:footnotes].size
         | 
| 981 998 | 
             
                  footnote = para.document.catalog[:footnotes].first
         | 
| 982 999 | 
             
                  assert_equal 1, footnote.index
         | 
| @@ -986,7 +1003,7 @@ foofootnote:[+http://example.com+]barfootnote:[+http://acme.com+]baz | |
| 986 1003 |  | 
| 987 1004 | 
             
                test 'a footnoteref macro with id and multi-line text should be registered and rendered as a footnote without endlines' do
         | 
| 988 1005 | 
             
                  para = block_from_string("Sentence text footnoteref:[ex1, An example footnote\nwith wrapped text.].")
         | 
| 989 | 
            -
                  assert_equal %(Sentence text <sup class="footnote" id="_footnote_ex1">[<a id="_footnoteref_1" class="footnote" href="# | 
| 1006 | 
            +
                  assert_equal %(Sentence text <sup class="footnote" id="_footnote_ex1">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
         | 
| 990 1007 | 
             
                  assert_equal 1, para.document.catalog[:footnotes].size
         | 
| 991 1008 | 
             
                  footnote = para.document.catalog[:footnotes].first
         | 
| 992 1009 | 
             
                  assert_equal 1, footnote.index
         | 
| @@ -996,7 +1013,7 @@ foofootnote:[+http://example.com+]barfootnote:[+http://acme.com+]baz | |
| 996 1013 |  | 
| 997 1014 | 
             
                test 'a footnoteref macro with id should refer to footnoteref with same id' do
         | 
| 998 1015 | 
             
                  para = block_from_string('Sentence text footnoteref:[ex1, An example footnote.]. Sentence text footnoteref:[ex1].')
         | 
| 999 | 
            -
                  assert_equal %(Sentence text <sup class="footnote" id="_footnote_ex1">[<a id="_footnoteref_1" class="footnote" href="# | 
| 1016 | 
            +
                  assert_equal %(Sentence text <sup class="footnote" id="_footnote_ex1">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>. Sentence text <sup class="footnoteref">[<a class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
         | 
| 1000 1017 | 
             
                  assert_equal 1, para.document.catalog[:footnotes].size
         | 
| 1001 1018 | 
             
                  footnote = para.document.catalog[:footnotes].first
         | 
| 1002 1019 | 
             
                  assert_equal 1, footnote.index
         | 
| @@ -1004,9 +1021,66 @@ foofootnote:[+http://example.com+]barfootnote:[+http://acme.com+]baz | |
| 1004 1021 | 
             
                  assert_equal 'An example footnote.', footnote.text
         | 
| 1005 1022 | 
             
                end
         | 
| 1006 1023 |  | 
| 1007 | 
            -
                test 'an unresolved  | 
| 1008 | 
            -
                   | 
| 1009 | 
            -
                   | 
| 1024 | 
            +
                test 'an unresolved footnote reference should produce a warning message' do
         | 
| 1025 | 
            +
                  input = 'Sentence text.footnote:ex1[]'
         | 
| 1026 | 
            +
                  using_memory_logger do |logger|
         | 
| 1027 | 
            +
                    para = block_from_string input
         | 
| 1028 | 
            +
                    para.sub_macros para.source
         | 
| 1029 | 
            +
                    assert_message logger, :WARN, 'invalid footnote reference: ex1'
         | 
| 1030 | 
            +
                  end
         | 
| 1031 | 
            +
                end
         | 
| 1032 | 
            +
             | 
| 1033 | 
            +
                test 'inline footnote macro can be used to define and reference a footnote reference' do
         | 
| 1034 | 
            +
                  input = <<-EOS
         | 
| 1035 | 
            +
            You can download the software from the product page.footnote:sub[Option only available if you have an active subscription.]
         | 
| 1036 | 
            +
             | 
| 1037 | 
            +
            You can also file a support request.footnote:sub[]
         | 
| 1038 | 
            +
             | 
| 1039 | 
            +
            If all else fails, you can give us a call.footnoteref:[sub]
         | 
| 1040 | 
            +
                  EOS
         | 
| 1041 | 
            +
             | 
| 1042 | 
            +
                  output = render_embedded_string input
         | 
| 1043 | 
            +
                  assert_css '#_footnotedef_1', output, 1
         | 
| 1044 | 
            +
                  assert_css 'p a[href="#_footnotedef_1"]', output, 3
         | 
| 1045 | 
            +
                  assert_css '#footnotes .footnote', output, 1
         | 
| 1046 | 
            +
                end
         | 
| 1047 | 
            +
             | 
| 1048 | 
            +
                test 'should parse multiple footnote references in a single line' do
         | 
| 1049 | 
            +
                  input = <<-'EOS'
         | 
| 1050 | 
            +
            notable text.footnote:id[about this [text\]], footnote:id[], footnote:id[]
         | 
| 1051 | 
            +
                  EOS
         | 
| 1052 | 
            +
             | 
| 1053 | 
            +
                  output = render_embedded_string input
         | 
| 1054 | 
            +
                  assert_xpath '(//p)[1]/sup[starts-with(@class,"footnote")]', output, 3
         | 
| 1055 | 
            +
                  assert_xpath '(//p)[1]/sup[@class="footnote"]', output, 1
         | 
| 1056 | 
            +
                  assert_xpath '(//p)[1]/sup[@class="footnoteref"]', output, 2
         | 
| 1057 | 
            +
                  assert_xpath '(//p)[1]/sup[starts-with(@class,"footnote")]/a[@class="footnote"][text()="1"]', output, 3
         | 
| 1058 | 
            +
                  assert_css '#footnotes .footnote', output, 1
         | 
| 1059 | 
            +
                end
         | 
| 1060 | 
            +
             | 
| 1061 | 
            +
                test 'should not resolve an inline footnote macro missing both id and text' do
         | 
| 1062 | 
            +
                  input = <<-EOS
         | 
| 1063 | 
            +
            The footnote:[] macro can be used for defining and referencing footnotes.
         | 
| 1064 | 
            +
             | 
| 1065 | 
            +
            The footnoteref:[] macro is now deprecated.
         | 
| 1066 | 
            +
                  EOS
         | 
| 1067 | 
            +
             | 
| 1068 | 
            +
                  output = render_embedded_string input
         | 
| 1069 | 
            +
                  assert_includes output, 'The footnote:[] macro'
         | 
| 1070 | 
            +
                  assert_includes output, 'The footnoteref:[] macro'
         | 
| 1071 | 
            +
                end
         | 
| 1072 | 
            +
             | 
| 1073 | 
            +
                test 'inline footnote macro can define a numeric id without conflicting with auto-generated ID' do
         | 
| 1074 | 
            +
                  input = <<-EOS
         | 
| 1075 | 
            +
            You can download the software from the product page.footnote:1[Option only available if you have an active subscription.]
         | 
| 1076 | 
            +
                  EOS
         | 
| 1077 | 
            +
             | 
| 1078 | 
            +
                  output = render_embedded_string input
         | 
| 1079 | 
            +
                  assert_css '#_footnote_1', output, 1
         | 
| 1080 | 
            +
                  assert_css 'p sup#_footnote_1', output, 1
         | 
| 1081 | 
            +
                  assert_css 'p a#_footnoteref_1', output, 1
         | 
| 1082 | 
            +
                  assert_css 'p a[href="#_footnotedef_1"]', output, 1
         | 
| 1083 | 
            +
                  assert_css '#footnotes #_footnotedef_1', output, 1
         | 
| 1010 1084 | 
             
                end
         | 
| 1011 1085 |  | 
| 1012 1086 | 
             
                test 'a single-line index term macro with a primary term should be registered as an index reference' do
         | 
| @@ -1057,6 +1131,16 @@ foofootnote:[+http://example.com+]barfootnote:[+http://acme.com+]baz | |
| 1057 1131 | 
             
                  end
         | 
| 1058 1132 | 
             
                end
         | 
| 1059 1133 |  | 
| 1134 | 
            +
                test 'should only escape enclosing brackets if concealed index term is preceded by a backslash' do
         | 
| 1135 | 
            +
                  input = %[National Institute of Science and Technology #{BACKSLASH}(((NIST)))]
         | 
| 1136 | 
            +
                  doc = document_from_string input, :header_footer => false
         | 
| 1137 | 
            +
                  output = doc.convert
         | 
| 1138 | 
            +
                  assert_xpath '//p[text()="National Institute of Science and Technology (NIST)"]', output, 1
         | 
| 1139 | 
            +
                  term = doc.catalog[:indexterms].first
         | 
| 1140 | 
            +
                  assert_equal 1, term.size
         | 
| 1141 | 
            +
                  assert_equal 'NIST', term.first
         | 
| 1142 | 
            +
                end
         | 
| 1143 | 
            +
             | 
| 1060 1144 | 
             
                test 'should not split index terms on commas inside of quoted terms' do
         | 
| 1061 1145 | 
             
                  inputs = []
         | 
| 1062 1146 | 
             
                  inputs.push <<-EOS
         | 
| @@ -1585,18 +1669,34 @@ EOS | |
| 1585 1669 | 
             
                    assert_equal '\$a < b\$', para.content
         | 
| 1586 1670 | 
             
                  end
         | 
| 1587 1671 |  | 
| 1588 | 
            -
                   | 
| 1589 | 
            -
             | 
| 1590 | 
            -
             | 
| 1591 | 
            -
             | 
| 1592 | 
            -
             | 
| 1593 | 
            -
             | 
| 1594 | 
            -
             | 
| 1672 | 
            +
                  test 'should convert contents of asciimath macro to MathML in DocBook output if asciimath gem is available' do
         | 
| 1673 | 
            +
                    asciimath_available = !(Asciidoctor::Helpers.require_library 'asciimath', true, :ignore).nil?
         | 
| 1674 | 
            +
                    input = 'asciimath:[a < b]'
         | 
| 1675 | 
            +
                    expected = '<inlineequation><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"><mml:mi>a</mml:mi><mml:mo><</mml:mo><mml:mi>b</mml:mi></mml:math></inlineequation>'
         | 
| 1676 | 
            +
                    using_memory_logger do |logger|
         | 
| 1677 | 
            +
                      para = block_from_string input, :backend => :docbook
         | 
| 1678 | 
            +
                      actual = para.content
         | 
| 1679 | 
            +
                      if asciimath_available
         | 
| 1680 | 
            +
                        assert_equal expected, actual
         | 
| 1681 | 
            +
                        assert_equal :loaded, para.document.converter.instance_variable_get(:@asciimath)
         | 
| 1682 | 
            +
                      else
         | 
| 1683 | 
            +
                        assert_message logger, :WARN, 'optional gem \'asciimath\' is not installed. Functionality disabled.'
         | 
| 1684 | 
            +
                        assert_equal :unavailable, para.document.converter.instance_variable_get(:@asciimath)
         | 
| 1685 | 
            +
                      end
         | 
| 1686 | 
            +
                    end
         | 
| 1687 | 
            +
                  end
         | 
| 1595 1688 |  | 
| 1596 | 
            -
                  test 'should  | 
| 1689 | 
            +
                  test 'should not perform specialcharacters subs on asciimath macro content in Docbook output if asciimath gem not available' do
         | 
| 1690 | 
            +
                    asciimath_available = !(Asciidoctor::Helpers.require_library 'asciimath', true, :ignore).nil?
         | 
| 1597 1691 | 
             
                    input = 'asciimath:[a < b]'
         | 
| 1598 1692 | 
             
                    para = block_from_string input, :backend => :docbook
         | 
| 1599 | 
            -
                     | 
| 1693 | 
            +
                    para.document.converter.instance_variable_set :@asciimath, :unavailable
         | 
| 1694 | 
            +
                    if asciimath_available
         | 
| 1695 | 
            +
                      old_asciimath = ::AsciiMath
         | 
| 1696 | 
            +
                      Object.send :remove_const, 'AsciiMath'
         | 
| 1697 | 
            +
                    end
         | 
| 1698 | 
            +
                    assert_equal '<inlineequation><mathphrase><![CDATA[a < b]]></mathphrase></inlineequation>', para.content
         | 
| 1699 | 
            +
                    ::AsciiMath = old_asciimath if asciimath_available
         | 
| 1600 1700 | 
             
                  end
         | 
| 1601 1701 |  | 
| 1602 1702 | 
             
                  test 'should honor explicit subslist on asciimath macro' do
         | 
| @@ -1649,17 +1749,36 @@ EOS | |
| 1649 1749 | 
             
                    assert_equal 'the text <code>asciimath:[x = y]</code> should be passed through as <code>literal</code> text', para.content
         | 
| 1650 1750 | 
             
                  end
         | 
| 1651 1751 |  | 
| 1752 | 
            +
                  test 'should not process an escaped passthrough macro inside a monospaced phrase' do
         | 
| 1753 | 
            +
                    input = 'use the `\pass:c[]` macro'
         | 
| 1754 | 
            +
                    para = block_from_string input
         | 
| 1755 | 
            +
                    assert_equal 'use the <code>pass:c[]</code> macro', para.content
         | 
| 1756 | 
            +
                  end
         | 
| 1757 | 
            +
             | 
| 1758 | 
            +
                  test 'should not process an escaped passthrough macro inside a monospaced phrase with attributes' do
         | 
| 1759 | 
            +
                    input = 'use the [syntax]`\pass:c[]` macro'
         | 
| 1760 | 
            +
                    para = block_from_string input
         | 
| 1761 | 
            +
                    assert_equal 'use the <code class="syntax">pass:c[]</code> macro', para.content
         | 
| 1762 | 
            +
                  end
         | 
| 1763 | 
            +
             | 
| 1764 | 
            +
                  test 'should honor an escaped single plus passthrough inside a monospaced phrase' do
         | 
| 1765 | 
            +
                    input = 'use `\+{author}+` to show an attribute reference'
         | 
| 1766 | 
            +
                    para = block_from_string input
         | 
| 1767 | 
            +
                    assert_equal 'use <code>+{author}+</code> to show an attribute reference', para.content
         | 
| 1768 | 
            +
                  end
         | 
| 1769 | 
            +
             | 
| 1652 1770 | 
             
                  test 'should not recognize stem macro with no content' do
         | 
| 1653 1771 | 
             
                    input = 'stem:[]'
         | 
| 1654 1772 | 
             
                    para = block_from_string input
         | 
| 1655 1773 | 
             
                    assert_equal input, para.content
         | 
| 1656 1774 | 
             
                  end
         | 
| 1657 1775 |  | 
| 1658 | 
            -
                  test 'should passthrough text in stem macro and surround with AsciiMath delimiters if stem attribute  | 
| 1776 | 
            +
                  test 'should passthrough text in stem macro and surround with AsciiMath delimiters if stem attribute is asciimath, empty, or not set' do
         | 
| 1659 1777 | 
             
                    [
         | 
| 1660 1778 | 
             
                      {},
         | 
| 1661 1779 | 
             
                      {'stem' => ''},
         | 
| 1662 | 
            -
                      {'stem' => 'asciimath'}
         | 
| 1780 | 
            +
                      {'stem' => 'asciimath'},
         | 
| 1781 | 
            +
                      {'stem' => 'bogus'}
         | 
| 1663 1782 | 
             
                    ].each do |attributes|
         | 
| 1664 1783 | 
             
                      input = 'stem:[x/x={(1,if x!=0),(text{undefined},if x=0):}]'
         | 
| 1665 1784 | 
             
                      para = block_from_string input, :attributes => attributes
         | 
| @@ -1667,10 +1786,16 @@ EOS | |
| 1667 1786 | 
             
                    end
         | 
| 1668 1787 | 
             
                  end
         | 
| 1669 1788 |  | 
| 1670 | 
            -
                  test 'should passthrough text in stem macro and surround with LaTeX math delimiters if stem attribute  | 
| 1671 | 
            -
                     | 
| 1672 | 
            -
             | 
| 1673 | 
            -
             | 
| 1789 | 
            +
                  test 'should passthrough text in stem macro and surround with LaTeX math delimiters if stem attribute is latexmath, latex, or tex' do
         | 
| 1790 | 
            +
                    [
         | 
| 1791 | 
            +
                      {'stem' => 'latexmath'},
         | 
| 1792 | 
            +
                      {'stem' => 'latex'},
         | 
| 1793 | 
            +
                      {'stem' => 'tex'}
         | 
| 1794 | 
            +
                    ].each do |attributes|
         | 
| 1795 | 
            +
                      input = 'stem:[C = \alpha + \beta Y^{\gamma} + \epsilon]'
         | 
| 1796 | 
            +
                      para = block_from_string input, :attributes => attributes
         | 
| 1797 | 
            +
                      assert_equal '\(C = \alpha + \beta Y^{\gamma} + \epsilon\)', para.content
         | 
| 1798 | 
            +
                    end
         | 
| 1674 1799 | 
             
                  end
         | 
| 1675 1800 |  | 
| 1676 1801 | 
             
                  test 'should apply substitutions specified on stem macro' do
         | 
| @@ -1779,25 +1904,25 @@ foo — ' | |
| 1779 1904 | 
             
              context 'Post replacements' do
         | 
| 1780 1905 | 
             
                test 'line break inserted after line with line break character' do
         | 
| 1781 1906 | 
             
                  para = block_from_string("First line +\nSecond line")
         | 
| 1782 | 
            -
                  result = para.apply_subs | 
| 1907 | 
            +
                  result = para.apply_subs para.lines, (para.expand_subs :post_replacements)
         | 
| 1783 1908 | 
             
                  assert_equal 'First line<br>', result.first
         | 
| 1784 1909 | 
             
                end
         | 
| 1785 1910 |  | 
| 1786 1911 | 
             
                test 'line break inserted after line wrap with hardbreaks enabled' do
         | 
| 1787 1912 | 
             
                  para = block_from_string("First line\nSecond line", :attributes => {'hardbreaks' => ''})
         | 
| 1788 | 
            -
                  result = para.apply_subs | 
| 1913 | 
            +
                  result = para.apply_subs para.lines, (para.expand_subs :post_replacements)
         | 
| 1789 1914 | 
             
                  assert_equal 'First line<br>', result.first
         | 
| 1790 1915 | 
             
                end
         | 
| 1791 1916 |  | 
| 1792 1917 | 
             
                test 'line break character stripped from end of line with hardbreaks enabled' do
         | 
| 1793 1918 | 
             
                  para = block_from_string("First line +\nSecond line", :attributes => {'hardbreaks' => ''})
         | 
| 1794 | 
            -
                  result = para.apply_subs | 
| 1919 | 
            +
                  result = para.apply_subs para.lines, (para.expand_subs :post_replacements)
         | 
| 1795 1920 | 
             
                  assert_equal 'First line<br>', result.first
         | 
| 1796 1921 | 
             
                end
         | 
| 1797 1922 |  | 
| 1798 1923 | 
             
                test 'line break not inserted for single line with hardbreaks enabled' do
         | 
| 1799 1924 | 
             
                  para = block_from_string('First line', :attributes => {'hardbreaks' => ''})
         | 
| 1800 | 
            -
                  result = para.apply_subs | 
| 1925 | 
            +
                  result = para.apply_subs para.lines, (para.expand_subs :post_replacements)
         | 
| 1801 1926 | 
             
                  assert_equal 'First line', result.first
         | 
| 1802 1927 | 
             
                end
         | 
| 1803 1928 | 
             
              end
         |