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/converter_test.rb
    CHANGED
    
    | @@ -9,59 +9,65 @@ context 'Converter' do | |
| 9 9 |  | 
| 10 10 | 
             
              context 'View options' do
         | 
| 11 11 | 
             
                test 'should set Haml format to html5 for html5 backend' do
         | 
| 12 | 
            -
                  doc = Asciidoctor::Document.new [], :template_dir =>  | 
| 13 | 
            -
                   | 
| 12 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
         | 
| 13 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 14 14 | 
             
                  selected = doc.converter.find_converter('paragraph')
         | 
| 15 | 
            -
                   | 
| 16 | 
            -
                   | 
| 15 | 
            +
                  assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 16 | 
            +
                  assert_kind_of Tilt::HamlTemplate, selected.templates['paragraph']
         | 
| 17 17 | 
             
                  assert_equal :html5, selected.templates['paragraph'].options[:format]
         | 
| 18 18 | 
             
                end
         | 
| 19 19 |  | 
| 20 20 | 
             
                test 'should set Haml format to xhtml for docbook backend' do
         | 
| 21 | 
            -
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir =>  | 
| 22 | 
            -
                   | 
| 21 | 
            +
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
         | 
| 22 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 23 23 | 
             
                  selected = doc.converter.find_converter('paragraph')
         | 
| 24 | 
            -
                   | 
| 25 | 
            -
                   | 
| 24 | 
            +
                  assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 25 | 
            +
                  assert_kind_of Tilt::HamlTemplate, selected.templates['paragraph']
         | 
| 26 26 | 
             
                  assert_equal :xhtml, selected.templates['paragraph'].options[:format]
         | 
| 27 27 | 
             
                end
         | 
| 28 28 |  | 
| 29 29 | 
             
                test 'should configure Slim to resolve includes in specified template dirs' do
         | 
| 30 | 
            -
                  template_dirs = [
         | 
| 31 | 
            -
                    File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'),
         | 
| 32 | 
            -
                    File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim-overrides'),
         | 
| 33 | 
            -
                  ]
         | 
| 30 | 
            +
                  template_dirs = [(fixture_path 'custom-backends/slim'), (fixture_path 'custom-backends/slim-overrides')]
         | 
| 34 31 | 
             
                  doc = Asciidoctor::Document.new [], :template_dirs => template_dirs, :template_cache => false
         | 
| 35 | 
            -
                   | 
| 32 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 36 33 | 
             
                  selected = doc.converter.find_converter('paragraph')
         | 
| 37 | 
            -
                   | 
| 38 | 
            -
                   | 
| 34 | 
            +
                  assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 35 | 
            +
                  assert_kind_of Slim::Template, selected.templates['paragraph']
         | 
| 39 36 | 
             
                  assert_equal template_dirs.reverse.map {|dir| File.expand_path dir }, selected.templates['paragraph'].options[:include_dirs]
         | 
| 40 37 | 
             
                end
         | 
| 41 38 |  | 
| 39 | 
            +
                test 'should coerce template_dirs option to an Array' do
         | 
| 40 | 
            +
                  template_dirs = fixture_path 'custom-backends/slim'
         | 
| 41 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dirs => template_dirs, :template_cache => false
         | 
| 42 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 43 | 
            +
                  selected = doc.converter.find_converter('paragraph')
         | 
| 44 | 
            +
                  assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 45 | 
            +
                  assert_kind_of Array, (selected.instance_variable_get :@template_dirs)
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 42 48 | 
             
                test 'should set Slim format to html for html5 backend' do
         | 
| 43 | 
            -
                  doc = Asciidoctor::Document.new [], :template_dir =>  | 
| 44 | 
            -
                   | 
| 49 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false
         | 
| 50 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 45 51 | 
             
                  selected = doc.converter.find_converter('paragraph')
         | 
| 46 | 
            -
                   | 
| 47 | 
            -
                   | 
| 52 | 
            +
                  assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 53 | 
            +
                  assert_kind_of Slim::Template, selected.templates['paragraph']
         | 
| 48 54 | 
             
                  assert_equal :html, selected.templates['paragraph'].options[:format]
         | 
| 49 55 | 
             
                end
         | 
| 50 56 |  | 
| 51 57 | 
             
                test 'should set Slim format to nil for docbook backend' do
         | 
| 52 | 
            -
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir =>  | 
| 53 | 
            -
                   | 
| 58 | 
            +
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false
         | 
| 59 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 54 60 | 
             
                  selected = doc.converter.find_converter('paragraph')
         | 
| 55 | 
            -
                   | 
| 56 | 
            -
                   | 
| 61 | 
            +
                  assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 62 | 
            +
                  assert_kind_of Slim::Template, selected.templates['paragraph']
         | 
| 57 63 | 
             
                  assert_nil selected.templates['paragraph'].options[:format]
         | 
| 58 64 | 
             
                end
         | 
| 59 65 |  | 
| 60 66 | 
             
                test 'should set safe mode of Slim AsciiDoc engine to match document safe mode when Slim >= 3' do
         | 
| 61 | 
            -
                  doc = Asciidoctor::Document.new [], :template_dir =>  | 
| 62 | 
            -
                   | 
| 67 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false, :safe => :unsafe
         | 
| 68 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 63 69 | 
             
                  selected = doc.converter.find_converter('paragraph')
         | 
| 64 | 
            -
                   | 
| 70 | 
            +
                  assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 65 71 | 
             
                  slim_asciidoc_opts = selected.instance_variable_get(:@engine_options)[:slim][:asciidoc]
         | 
| 66 72 | 
             
                  if ::Slim::VERSION >= '3.0'
         | 
| 67 73 | 
             
                    assert_equal({ :safe => Asciidoctor::SafeMode::UNSAFE }, slim_asciidoc_opts)
         | 
| @@ -71,20 +77,20 @@ context 'Converter' do | |
| 71 77 | 
             
                end
         | 
| 72 78 |  | 
| 73 79 | 
             
                test 'should support custom template engine options for known engine' do
         | 
| 74 | 
            -
                  doc = Asciidoctor::Document.new [], :template_dir =>  | 
| 75 | 
            -
                   | 
| 80 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false, :template_engine_options => { :slim => { :pretty => true } }
         | 
| 81 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 76 82 | 
             
                  selected = doc.converter.find_converter('paragraph')
         | 
| 77 | 
            -
                   | 
| 78 | 
            -
                   | 
| 83 | 
            +
                  assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 84 | 
            +
                  assert_kind_of Slim::Template, selected.templates['paragraph']
         | 
| 79 85 | 
             
                  assert_equal true, selected.templates['paragraph'].options[:pretty]
         | 
| 80 86 | 
             
                end
         | 
| 81 87 |  | 
| 82 88 | 
             
                test 'should support custom template engine options' do
         | 
| 83 | 
            -
                  doc = Asciidoctor::Document.new [], :template_dir =>  | 
| 84 | 
            -
                   | 
| 89 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false, :template_engine_options => { :slim => { :pretty => true } }
         | 
| 90 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 85 91 | 
             
                  selected = doc.converter.find_converter('paragraph')
         | 
| 86 | 
            -
                   | 
| 87 | 
            -
                   | 
| 92 | 
            +
                  assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 93 | 
            +
                  assert_kind_of Slim::Template, selected.templates['paragraph']
         | 
| 88 94 | 
             
                  assert_equal false, selected.templates['paragraph'].options[:sort_attrs]
         | 
| 89 95 | 
             
                  assert_equal true, selected.templates['paragraph'].options[:pretty]
         | 
| 90 96 | 
             
                end
         | 
| @@ -92,43 +98,43 @@ context 'Converter' do | |
| 92 98 |  | 
| 93 99 | 
             
              context 'Custom backends' do
         | 
| 94 100 | 
             
                test 'should load Haml templates for default backend' do
         | 
| 95 | 
            -
                  doc = Asciidoctor::Document.new [], :template_dir =>  | 
| 96 | 
            -
                   | 
| 101 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
         | 
| 102 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 97 103 | 
             
                  ['paragraph', 'sidebar'].each do |node_name|
         | 
| 98 104 | 
             
                    selected = doc.converter.find_converter node_name
         | 
| 99 | 
            -
                     | 
| 100 | 
            -
                     | 
| 105 | 
            +
                    assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 106 | 
            +
                    assert_kind_of Tilt::HamlTemplate, selected.templates[node_name]
         | 
| 101 107 | 
             
                    assert_equal %(block_#{node_name}.html.haml), File.basename(selected.templates[node_name].file)
         | 
| 102 108 | 
             
                  end
         | 
| 103 109 | 
             
                end
         | 
| 104 110 |  | 
| 105 111 | 
             
                test 'should set outfilesuffix according to backend info' do
         | 
| 106 112 | 
             
                  doc = Asciidoctor.load 'content'
         | 
| 107 | 
            -
                  doc. | 
| 113 | 
            +
                  doc.convert
         | 
| 108 114 | 
             
                  assert_equal '.html', doc.attributes['outfilesuffix']
         | 
| 109 115 |  | 
| 110 | 
            -
                  doc = Asciidoctor.load 'content', :template_dir =>  | 
| 111 | 
            -
                  doc. | 
| 116 | 
            +
                  doc = Asciidoctor.load 'content', :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
         | 
| 117 | 
            +
                  doc.convert
         | 
| 112 118 | 
             
                  assert_equal '.html', doc.attributes['outfilesuffix']
         | 
| 113 119 | 
             
                end
         | 
| 114 120 |  | 
| 115 121 | 
             
                test 'should not override outfilesuffix attribute if locked' do
         | 
| 116 122 | 
             
                  doc = Asciidoctor.load 'content', :attributes => {'outfilesuffix' => '.foo'}
         | 
| 117 | 
            -
                  doc. | 
| 123 | 
            +
                  doc.convert
         | 
| 118 124 | 
             
                  assert_equal '.foo', doc.attributes['outfilesuffix']
         | 
| 119 125 |  | 
| 120 | 
            -
                  doc = Asciidoctor.load 'content', :template_dir =>  | 
| 121 | 
            -
                  doc. | 
| 126 | 
            +
                  doc = Asciidoctor.load 'content', :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false, :attributes => {'outfilesuffix' => '.foo'}
         | 
| 127 | 
            +
                  doc.convert
         | 
| 122 128 | 
             
                  assert_equal '.foo', doc.attributes['outfilesuffix']
         | 
| 123 129 | 
             
                end
         | 
| 124 130 |  | 
| 125 131 | 
             
                test 'should load Haml templates for docbook45 backend' do
         | 
| 126 | 
            -
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir =>  | 
| 127 | 
            -
                   | 
| 132 | 
            +
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
         | 
| 133 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 128 134 | 
             
                  ['paragraph'].each do |node_name|
         | 
| 129 135 | 
             
                    selected = doc.converter.find_converter node_name
         | 
| 130 | 
            -
                     | 
| 131 | 
            -
                     | 
| 136 | 
            +
                    assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 137 | 
            +
                    assert_kind_of Tilt::HamlTemplate, selected.templates[node_name]
         | 
| 132 138 | 
             
                    assert_equal %(block_#{node_name}.xml.haml), File.basename(selected.templates[node_name].file)
         | 
| 133 139 | 
             
                  end
         | 
| 134 140 | 
             
                end
         | 
| @@ -148,7 +154,7 @@ Sidebar content | |
| 148 154 | 
             
            ****
         | 
| 149 155 | 
             
                  EOS
         | 
| 150 156 |  | 
| 151 | 
            -
                  output = render_embedded_string input, :template_dir =>  | 
| 157 | 
            +
                  output = render_embedded_string input, :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
         | 
| 152 158 | 
             
                  assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p', output, 1
         | 
| 153 159 | 
             
                  assert_xpath '//aside', output, 1
         | 
| 154 160 | 
             
                  assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p/following-sibling::aside', output, 1
         | 
| @@ -161,12 +167,12 @@ Sidebar content | |
| 161 167 | 
             
                    # clear out any cache, just to be sure
         | 
| 162 168 | 
             
                    Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
         | 
| 163 169 |  | 
| 164 | 
            -
                    template_dir =  | 
| 170 | 
            +
                    template_dir = fixture_path 'custom-backends/haml'
         | 
| 165 171 | 
             
                    doc = Asciidoctor::Document.new [], :template_dir => template_dir
         | 
| 166 172 | 
             
                    doc.converter
         | 
| 167 173 | 
             
                    caches = Asciidoctor::Converter::TemplateConverter.caches
         | 
| 168 174 | 
             
                    if defined? ::ThreadSafe::Cache
         | 
| 169 | 
            -
                       | 
| 175 | 
            +
                      assert_kind_of ::ThreadSafe::Cache, caches[:templates]
         | 
| 170 176 | 
             
                      refute_empty caches[:templates]
         | 
| 171 177 | 
             
                      paragraph_template_before = caches[:templates].values.find {|t| File.basename(t.file) == 'block_paragraph.html.haml' }
         | 
| 172 178 | 
             
                      refute_nil paragraph_template_before
         | 
| @@ -194,7 +200,7 @@ Sidebar content | |
| 194 200 | 
             
                end
         | 
| 195 201 |  | 
| 196 202 | 
             
                test 'should use custom cache to cache templates' do
         | 
| 197 | 
            -
                  template_dir =  | 
| 203 | 
            +
                  template_dir = fixture_path 'custom-backends/haml'
         | 
| 198 204 | 
             
                  Asciidoctor::PathResolver.new.system_path(File.join(template_dir, 'html5', 'block_paragraph.html.haml'), nil)
         | 
| 199 205 | 
             
                  caches = { :scans => {}, :templates => {} }
         | 
| 200 206 | 
             
                  doc = Asciidoctor::Document.new [], :template_dir => template_dir, :template_cache => caches
         | 
| @@ -203,7 +209,7 @@ Sidebar content | |
| 203 209 | 
             
                  refute_empty caches[:templates]
         | 
| 204 210 | 
             
                  paragraph_template = caches[:templates].values.find {|t| File.basename(t.file) == 'block_paragraph.html.haml' }
         | 
| 205 211 | 
             
                  refute_nil paragraph_template
         | 
| 206 | 
            -
                   | 
| 212 | 
            +
                  assert_kind_of ::Tilt::HamlTemplate, paragraph_template
         | 
| 207 213 | 
             
                end
         | 
| 208 214 |  | 
| 209 215 | 
             
                test 'should be able to disable template cache' do
         | 
| @@ -211,8 +217,7 @@ Sidebar content | |
| 211 217 | 
             
                    # clear out any cache, just to be sure
         | 
| 212 218 | 
             
                    Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
         | 
| 213 219 |  | 
| 214 | 
            -
                    doc = Asciidoctor::Document.new [], :template_dir =>  | 
| 215 | 
            -
                        :template_cache => false
         | 
| 220 | 
            +
                    doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
         | 
| 216 221 | 
             
                    doc.converter
         | 
| 217 222 | 
             
                    caches = Asciidoctor::Converter::TemplateConverter.caches
         | 
| 218 223 | 
             
                    assert caches.empty? || caches[:scans].empty?
         | 
| @@ -224,51 +229,51 @@ Sidebar content | |
| 224 229 | 
             
                end
         | 
| 225 230 |  | 
| 226 231 | 
             
                test 'should load ERB templates using ERBTemplate if eruby is not set' do
         | 
| 227 | 
            -
                  doc = Asciidoctor::Document.new [], :template_dir =>  | 
| 228 | 
            -
                   | 
| 232 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/erb'), :template_cache => false
         | 
| 233 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 229 234 | 
             
                  ['paragraph'].each do |node_name|
         | 
| 230 235 | 
             
                    selected = doc.converter.find_converter node_name
         | 
| 231 | 
            -
                     | 
| 236 | 
            +
                    assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 232 237 | 
             
                    template = selected.templates[node_name]
         | 
| 233 | 
            -
                     | 
| 234 | 
            -
                     | 
| 235 | 
            -
                     | 
| 238 | 
            +
                    assert_kind_of Tilt::ERBTemplate, template
         | 
| 239 | 
            +
                    refute_kind_of Tilt::ErubisTemplate, template
         | 
| 240 | 
            +
                    assert_kind_of ::ERB, template.instance_variable_get('@engine')
         | 
| 236 241 | 
             
                    assert_equal %(block_#{node_name}.html.erb), File.basename(selected.templates[node_name].file)
         | 
| 237 242 | 
             
                  end
         | 
| 238 243 | 
             
                end
         | 
| 239 244 |  | 
| 240 245 | 
             
                test 'should load ERB templates using ErubisTemplate if eruby is set to erubis' do
         | 
| 241 | 
            -
                  doc = Asciidoctor::Document.new [], :template_dir =>  | 
| 242 | 
            -
                   | 
| 246 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/erb'), :template_cache => false, :eruby => 'erubis'
         | 
| 247 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 243 248 | 
             
                  ['paragraph'].each do |node_name|
         | 
| 244 249 | 
             
                    selected = doc.converter.find_converter node_name
         | 
| 245 | 
            -
                     | 
| 250 | 
            +
                    assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 246 251 | 
             
                    template = selected.templates[node_name]
         | 
| 247 | 
            -
                     | 
| 248 | 
            -
                     | 
| 249 | 
            -
                     | 
| 252 | 
            +
                    assert_kind_of Tilt::ERBTemplate, template
         | 
| 253 | 
            +
                    assert_kind_of Tilt::ErubisTemplate, template
         | 
| 254 | 
            +
                    assert_kind_of ::Erubis::FastEruby, template.instance_variable_get('@engine')
         | 
| 250 255 | 
             
                    assert_equal %(block_#{node_name}.html.erb), File.basename(selected.templates[node_name].file)
         | 
| 251 256 | 
             
                  end
         | 
| 252 257 | 
             
                end
         | 
| 253 258 |  | 
| 254 259 | 
             
                test 'should load Slim templates for default backend' do
         | 
| 255 | 
            -
                  doc = Asciidoctor::Document.new [], :template_dir =>  | 
| 256 | 
            -
                   | 
| 260 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false
         | 
| 261 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 257 262 | 
             
                  ['paragraph', 'sidebar'].each do |node_name|
         | 
| 258 263 | 
             
                    selected = doc.converter.find_converter node_name
         | 
| 259 | 
            -
                     | 
| 260 | 
            -
                     | 
| 264 | 
            +
                    assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 265 | 
            +
                    assert_kind_of Slim::Template, selected.templates[node_name]
         | 
| 261 266 | 
             
                    assert_equal %(block_#{node_name}.html.slim), File.basename(selected.templates[node_name].file)
         | 
| 262 267 | 
             
                  end
         | 
| 263 268 | 
             
                end
         | 
| 264 269 |  | 
| 265 270 | 
             
                test 'should load Slim templates for docbook45 backend' do
         | 
| 266 | 
            -
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir =>  | 
| 267 | 
            -
                   | 
| 271 | 
            +
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false
         | 
| 272 | 
            +
                  assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 268 273 | 
             
                  ['paragraph'].each do |node_name|
         | 
| 269 274 | 
             
                    selected = doc.converter.find_converter node_name
         | 
| 270 | 
            -
                     | 
| 271 | 
            -
                     | 
| 275 | 
            +
                    assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
         | 
| 276 | 
            +
                    assert_kind_of Slim::Template, selected.templates[node_name]
         | 
| 272 277 | 
             
                    assert_equal %(block_#{node_name}.xml.slim), File.basename(selected.templates[node_name].file)
         | 
| 273 278 | 
             
                  end
         | 
| 274 279 | 
             
                end
         | 
| @@ -288,7 +293,7 @@ Sidebar content | |
| 288 293 | 
             
            ****
         | 
| 289 294 | 
             
                  EOS
         | 
| 290 295 |  | 
| 291 | 
            -
                  output = render_embedded_string input, :template_dir =>  | 
| 296 | 
            +
                  output = render_embedded_string input, :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false
         | 
| 292 297 | 
             
                  assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p', output, 1
         | 
| 293 298 | 
             
                  assert_xpath '//aside', output, 1
         | 
| 294 299 | 
             
                  assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p/following-sibling::aside', output, 1
         | 
| @@ -350,6 +355,93 @@ content | |
| 350 355 | 
             
                  end
         | 
| 351 356 | 
             
                end
         | 
| 352 357 |  | 
| 358 | 
            +
                test 'should map handles? method on converter to respond_to? by default' do
         | 
| 359 | 
            +
                  class CustomConverterC
         | 
| 360 | 
            +
                    include Asciidoctor::Converter
         | 
| 361 | 
            +
                    def paragraph node
         | 
| 362 | 
            +
                      'paragraph'
         | 
| 363 | 
            +
                    end
         | 
| 364 | 
            +
                  end
         | 
| 365 | 
            +
             | 
| 366 | 
            +
                  converter = CustomConverterC.new 'myhtml'
         | 
| 367 | 
            +
                  assert_respond_to converter, :handles?
         | 
| 368 | 
            +
                  assert converter.handles?(:paragraph)
         | 
| 369 | 
            +
                end
         | 
| 370 | 
            +
             | 
| 371 | 
            +
                test 'should not configure converter to support templates by default' do
         | 
| 372 | 
            +
                  input = <<-EOS
         | 
| 373 | 
            +
            paragraph
         | 
| 374 | 
            +
                  EOS
         | 
| 375 | 
            +
             | 
| 376 | 
            +
                  begin
         | 
| 377 | 
            +
                    Asciidoctor::Converter::Factory.unregister_all
         | 
| 378 | 
            +
                    class CustomConverterD
         | 
| 379 | 
            +
                      include Asciidoctor::Converter
         | 
| 380 | 
            +
                      register_for 'myhtml'
         | 
| 381 | 
            +
                      def convert node, transform = nil, opts = {}
         | 
| 382 | 
            +
                        transform ||= node.node_name
         | 
| 383 | 
            +
                        send transform, node
         | 
| 384 | 
            +
                      end
         | 
| 385 | 
            +
             | 
| 386 | 
            +
                      def document node
         | 
| 387 | 
            +
                        ['<!DOCTYPE html>', '<html>', '<body>', node.content, '</body>', '</html>'] * %(\n)
         | 
| 388 | 
            +
                      end
         | 
| 389 | 
            +
             | 
| 390 | 
            +
                      def paragraph node
         | 
| 391 | 
            +
                        ['<div class="paragraph">', %(<p>#{node.content}</p>), '</div>'] * %(\n)
         | 
| 392 | 
            +
                      end
         | 
| 393 | 
            +
                    end
         | 
| 394 | 
            +
             | 
| 395 | 
            +
                    doc = document_from_string input, :backend => 'myhtml', :template_dir => (fixture_path 'custom-backends/slim/html5'), :template_cache => false
         | 
| 396 | 
            +
                    assert_kind_of CustomConverterD, doc.converter
         | 
| 397 | 
            +
                    refute doc.converter.supports_templates?
         | 
| 398 | 
            +
                    output = doc.convert
         | 
| 399 | 
            +
                    assert_xpath '//*[@class="paragraph"]/p[text()="paragraph"]', output, 1
         | 
| 400 | 
            +
                  ensure
         | 
| 401 | 
            +
                    Asciidoctor::Converter::Factory.unregister_all
         | 
| 402 | 
            +
                  end
         | 
| 403 | 
            +
                end
         | 
| 404 | 
            +
             | 
| 405 | 
            +
                test 'should wrap converter in composite converter with template converter if it declares that it supports templates' do
         | 
| 406 | 
            +
                  input = <<-EOS
         | 
| 407 | 
            +
            paragraph
         | 
| 408 | 
            +
                  EOS
         | 
| 409 | 
            +
             | 
| 410 | 
            +
                  begin
         | 
| 411 | 
            +
                    Asciidoctor::Converter::Factory.unregister_all
         | 
| 412 | 
            +
                    class CustomConverterE
         | 
| 413 | 
            +
                      include Asciidoctor::Converter
         | 
| 414 | 
            +
                      register_for 'myhtml'
         | 
| 415 | 
            +
             | 
| 416 | 
            +
                      def initialize *args
         | 
| 417 | 
            +
                        super
         | 
| 418 | 
            +
                        supports_templates
         | 
| 419 | 
            +
                      end
         | 
| 420 | 
            +
             | 
| 421 | 
            +
                      def convert node, transform = nil, opts = {}
         | 
| 422 | 
            +
                        transform ||= node.node_name
         | 
| 423 | 
            +
                        send transform, node
         | 
| 424 | 
            +
                      end
         | 
| 425 | 
            +
             | 
| 426 | 
            +
                      def document node
         | 
| 427 | 
            +
                        ['<!DOCTYPE html>', '<html>', '<body>', node.content, '</body>', '</html>'] * %(\n)
         | 
| 428 | 
            +
                      end
         | 
| 429 | 
            +
             | 
| 430 | 
            +
                      def paragraph node
         | 
| 431 | 
            +
                        ['<div class="paragraph">', %(<p>#{node.content}</p>), '</div>'] * %(\n)
         | 
| 432 | 
            +
                      end
         | 
| 433 | 
            +
                    end
         | 
| 434 | 
            +
             | 
| 435 | 
            +
                    doc = document_from_string input, :backend => 'myhtml', :template_dir => (fixture_path 'custom-backends/slim/html5'), :template_cache => false
         | 
| 436 | 
            +
                    assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
         | 
| 437 | 
            +
                    output = doc.convert
         | 
| 438 | 
            +
                    assert_xpath '//*[@class="paragraph"]/p[text()="paragraph"]', output, 0
         | 
| 439 | 
            +
                    assert_xpath '//body/p[text()="paragraph"]', output, 1
         | 
| 440 | 
            +
                  ensure
         | 
| 441 | 
            +
                    Asciidoctor::Converter::Factory.unregister_all
         | 
| 442 | 
            +
                  end
         | 
| 443 | 
            +
                end
         | 
| 444 | 
            +
             | 
| 353 445 | 
             
                test 'should fall back to catch all converter' do
         | 
| 354 446 | 
             
                  input = <<-EOS
         | 
| 355 447 | 
             
            content
         | 
| @@ -358,7 +450,7 @@ content | |
| 358 450 | 
             
                  begin
         | 
| 359 451 | 
             
                    Asciidoctor::Converter::Factory.unregister_all
         | 
| 360 452 |  | 
| 361 | 
            -
                    class  | 
| 453 | 
            +
                    class CustomConverterF
         | 
| 362 454 | 
             
                      include Asciidoctor::Converter
         | 
| 363 455 | 
             
                      register_for '*'
         | 
| 364 456 | 
             
                      def convert node, name = nil
         | 
| @@ -367,7 +459,7 @@ content | |
| 367 459 | 
             
                    end
         | 
| 368 460 |  | 
| 369 461 | 
             
                    converters = Asciidoctor::Converter::Factory.converters
         | 
| 370 | 
            -
                    assert converters['*'] ==  | 
| 462 | 
            +
                    assert converters['*'] == CustomConverterF
         | 
| 371 463 | 
             
                    output = render_string input, :backend => 'foobaz'
         | 
| 372 464 | 
             
                    assert 'foobaz content', output
         | 
| 373 465 | 
             
                  ensure
         | 
    
        data/test/document_test.rb
    CHANGED
    
    | @@ -131,718 +131,6 @@ content | |
| 131 131 | 
             
                end
         | 
| 132 132 | 
             
              end
         | 
| 133 133 |  | 
| 134 | 
            -
              context 'Load APIs' do
         | 
| 135 | 
            -
                test 'should load input file' do
         | 
| 136 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 137 | 
            -
                  doc = File.open(sample_input_path) {|file| Asciidoctor.load file, :safe => Asciidoctor::SafeMode::SAFE }
         | 
| 138 | 
            -
                  assert_equal 'Document Title', doc.doctitle
         | 
| 139 | 
            -
                  assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
         | 
| 140 | 
            -
                  assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
         | 
| 141 | 
            -
                  assert_equal '.asciidoc', doc.attr('docfilesuffix')
         | 
| 142 | 
            -
                end
         | 
| 143 | 
            -
             | 
| 144 | 
            -
                test 'should load input file from filename' do
         | 
| 145 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 146 | 
            -
                  doc = Asciidoctor.load_file(sample_input_path, :safe => Asciidoctor::SafeMode::SAFE)
         | 
| 147 | 
            -
                  assert_equal 'Document Title', doc.doctitle
         | 
| 148 | 
            -
                  assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
         | 
| 149 | 
            -
                  assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
         | 
| 150 | 
            -
                  assert_equal '.asciidoc', doc.attr('docfilesuffix')
         | 
| 151 | 
            -
                end
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                test 'should not load invalid file' do
         | 
| 154 | 
            -
                  sample_input_path = fixture_path('hello-asciidoctor.pdf')
         | 
| 155 | 
            -
                  exception = assert_raises ArgumentError do
         | 
| 156 | 
            -
                    Asciidoctor.load_file(sample_input_path, :safe => Asciidoctor::SafeMode::SAFE)
         | 
| 157 | 
            -
                  end
         | 
| 158 | 
            -
                  assert_match(/Failed to load AsciiDoc document/, exception.message)
         | 
| 159 | 
            -
                  # verify we have the correct backtrace (should be in at least first 5 lines)
         | 
| 160 | 
            -
                  assert_match((RUBY_ENGINE == 'rbx' ? /parser\.rb/ : /helpers\.rb/), exception.backtrace[0..4].join("\n"))
         | 
| 161 | 
            -
                end if RUBY_MIN_VERSION_1_9
         | 
| 162 | 
            -
             | 
| 163 | 
            -
                test 'should load input IO' do
         | 
| 164 | 
            -
                  input = StringIO.new(<<-EOS)
         | 
| 165 | 
            -
            Document Title
         | 
| 166 | 
            -
            ==============
         | 
| 167 | 
            -
             | 
| 168 | 
            -
            preamble
         | 
| 169 | 
            -
                  EOS
         | 
| 170 | 
            -
                  doc = Asciidoctor.load(input, :safe => Asciidoctor::SafeMode::SAFE)
         | 
| 171 | 
            -
                  assert_equal 'Document Title', doc.doctitle
         | 
| 172 | 
            -
                  refute doc.attr?('docfile')
         | 
| 173 | 
            -
                  assert_equal doc.base_dir, doc.attr('docdir')
         | 
| 174 | 
            -
                end
         | 
| 175 | 
            -
             | 
| 176 | 
            -
                test 'should load input string' do
         | 
| 177 | 
            -
                  input = <<-EOS
         | 
| 178 | 
            -
            Document Title
         | 
| 179 | 
            -
            ==============
         | 
| 180 | 
            -
             | 
| 181 | 
            -
            preamble
         | 
| 182 | 
            -
                  EOS
         | 
| 183 | 
            -
                  doc = Asciidoctor.load(input, :safe => Asciidoctor::SafeMode::SAFE)
         | 
| 184 | 
            -
                  assert_equal 'Document Title', doc.doctitle
         | 
| 185 | 
            -
                  refute doc.attr?('docfile')
         | 
| 186 | 
            -
                  assert_equal doc.base_dir, doc.attr('docdir')
         | 
| 187 | 
            -
                end
         | 
| 188 | 
            -
             | 
| 189 | 
            -
                test 'should load input string array' do
         | 
| 190 | 
            -
                  input = <<-EOS
         | 
| 191 | 
            -
            Document Title
         | 
| 192 | 
            -
            ==============
         | 
| 193 | 
            -
             | 
| 194 | 
            -
            preamble
         | 
| 195 | 
            -
                  EOS
         | 
| 196 | 
            -
                  doc = Asciidoctor.load(input.lines.entries, :safe => Asciidoctor::SafeMode::SAFE)
         | 
| 197 | 
            -
                  assert_equal 'Document Title', doc.doctitle
         | 
| 198 | 
            -
                  refute doc.attr?('docfile')
         | 
| 199 | 
            -
                  assert_equal doc.base_dir, doc.attr('docdir')
         | 
| 200 | 
            -
                end
         | 
| 201 | 
            -
             | 
| 202 | 
            -
                test 'should accept attributes as array' do
         | 
| 203 | 
            -
            	  # NOTE there's a tab character before idseparator
         | 
| 204 | 
            -
                  doc = Asciidoctor.load('text', :attributes => %w(toc sectnums   source-highlighter=coderay idprefix	idseparator=-))
         | 
| 205 | 
            -
                  assert_kind_of Hash, doc.attributes
         | 
| 206 | 
            -
                  assert doc.attr?('toc')
         | 
| 207 | 
            -
                  assert_equal '', doc.attr('toc')
         | 
| 208 | 
            -
                  assert doc.attr?('sectnums')
         | 
| 209 | 
            -
                  assert_equal '', doc.attr('sectnums')
         | 
| 210 | 
            -
                  assert doc.attr?('source-highlighter')
         | 
| 211 | 
            -
                  assert_equal 'coderay', doc.attr('source-highlighter')
         | 
| 212 | 
            -
                  assert doc.attr?('idprefix')
         | 
| 213 | 
            -
                  assert_equal '', doc.attr('idprefix')
         | 
| 214 | 
            -
                  assert doc.attr?('idseparator')
         | 
| 215 | 
            -
                  assert_equal '-', doc.attr('idseparator')
         | 
| 216 | 
            -
                end
         | 
| 217 | 
            -
             | 
| 218 | 
            -
                test 'should accept attributes as empty array' do
         | 
| 219 | 
            -
                  doc = Asciidoctor.load('text', :attributes => [])
         | 
| 220 | 
            -
                  assert_kind_of Hash, doc.attributes
         | 
| 221 | 
            -
                end
         | 
| 222 | 
            -
             | 
| 223 | 
            -
                test 'should accept attributes as string' do
         | 
| 224 | 
            -
                  doc = Asciidoctor.load('text', :attributes => 'toc sectnums
         | 
| 225 | 
            -
            source-highlighter=coderay
         | 
| 226 | 
            -
            idprefix
         | 
| 227 | 
            -
            idseparator=-')
         | 
| 228 | 
            -
                  assert_kind_of Hash, doc.attributes
         | 
| 229 | 
            -
                  assert doc.attr?('toc')
         | 
| 230 | 
            -
                  assert_equal '', doc.attr('toc')
         | 
| 231 | 
            -
                  assert doc.attr?('sectnums')
         | 
| 232 | 
            -
                  assert_equal '', doc.attr('sectnums')
         | 
| 233 | 
            -
                  assert doc.attr?('source-highlighter')
         | 
| 234 | 
            -
                  assert_equal 'coderay', doc.attr('source-highlighter')
         | 
| 235 | 
            -
                  assert doc.attr?('idprefix')
         | 
| 236 | 
            -
                  assert_equal '', doc.attr('idprefix')
         | 
| 237 | 
            -
                  assert doc.attr?('idseparator')
         | 
| 238 | 
            -
                  assert_equal '-', doc.attr('idseparator')
         | 
| 239 | 
            -
                end
         | 
| 240 | 
            -
             | 
| 241 | 
            -
                test 'should accept values containing spaces in attributes string' do
         | 
| 242 | 
            -
                  doc = Asciidoctor.load('text', :attributes => %(idprefix idseparator=-   note-caption=Note\\ to\\\tself toc))
         | 
| 243 | 
            -
                  assert_kind_of Hash, doc.attributes
         | 
| 244 | 
            -
                  assert doc.attr?('idprefix')
         | 
| 245 | 
            -
                  assert_equal '', doc.attr('idprefix')
         | 
| 246 | 
            -
                  assert doc.attr?('idseparator')
         | 
| 247 | 
            -
                  assert_equal '-', doc.attr('idseparator')
         | 
| 248 | 
            -
                  assert doc.attr?('note-caption')
         | 
| 249 | 
            -
                  assert_equal "Note to\tself", doc.attr('note-caption')
         | 
| 250 | 
            -
                end
         | 
| 251 | 
            -
             | 
| 252 | 
            -
                test 'should accept attributes as empty string' do
         | 
| 253 | 
            -
                  doc = Asciidoctor.load('text', :attributes => '')
         | 
| 254 | 
            -
                  assert_kind_of Hash, doc.attributes
         | 
| 255 | 
            -
                end
         | 
| 256 | 
            -
             | 
| 257 | 
            -
                test 'should accept attributes as nil' do
         | 
| 258 | 
            -
                  doc = Asciidoctor.load('text', :attributes => nil)
         | 
| 259 | 
            -
                  assert_kind_of Hash, doc.attributes
         | 
| 260 | 
            -
                end
         | 
| 261 | 
            -
             | 
| 262 | 
            -
                test 'should accept attributes if hash like' do
         | 
| 263 | 
            -
                  class Hashish
         | 
| 264 | 
            -
                    def initialize
         | 
| 265 | 
            -
                      @table = {'toc' => ''}
         | 
| 266 | 
            -
                    end
         | 
| 267 | 
            -
             | 
| 268 | 
            -
                    def keys
         | 
| 269 | 
            -
                      @table.keys
         | 
| 270 | 
            -
                    end
         | 
| 271 | 
            -
             | 
| 272 | 
            -
                    def [](key)
         | 
| 273 | 
            -
                      @table[key]
         | 
| 274 | 
            -
                    end
         | 
| 275 | 
            -
                  end
         | 
| 276 | 
            -
             | 
| 277 | 
            -
                  doc = Asciidoctor.load('text', :attributes => Hashish.new)
         | 
| 278 | 
            -
                  assert_kind_of Hash, doc.attributes
         | 
| 279 | 
            -
                  assert doc.attributes.has_key?('toc')
         | 
| 280 | 
            -
                end
         | 
| 281 | 
            -
             | 
| 282 | 
            -
                test 'should output timestamps by default' do
         | 
| 283 | 
            -
                  doc = document_from_string 'text', :backend => :html5, :attributes => nil
         | 
| 284 | 
            -
                  result = doc.convert
         | 
| 285 | 
            -
                  assert doc.attr?('docdate')
         | 
| 286 | 
            -
                  refute doc.attr? 'reproducible'
         | 
| 287 | 
            -
                  assert_xpath '//div[@id="footer-text" and contains(string(.//text()), "Last updated")]', result, 1
         | 
| 288 | 
            -
                end
         | 
| 289 | 
            -
             | 
| 290 | 
            -
                test 'should not output timestamps if reproducible attribute is set in HTML 5' do
         | 
| 291 | 
            -
                  doc = document_from_string 'text', :backend => :html5, :attributes => { 'reproducible' => '' }
         | 
| 292 | 
            -
                  result = doc.convert
         | 
| 293 | 
            -
                  assert doc.attr?('docdate')
         | 
| 294 | 
            -
                  assert doc.attr?('reproducible')
         | 
| 295 | 
            -
                  assert_xpath '//div[@id="footer-text" and contains(string(.//text()), "Last updated")]', result, 0
         | 
| 296 | 
            -
                end
         | 
| 297 | 
            -
             | 
| 298 | 
            -
                test 'should not output timestamps if reproducible attribute is set in DocBook' do
         | 
| 299 | 
            -
                  doc = document_from_string 'text', :backend => :docbook, :attributes => { 'reproducible' => '' }
         | 
| 300 | 
            -
                  result = doc.convert
         | 
| 301 | 
            -
                  assert doc.attr?('docdate')
         | 
| 302 | 
            -
                  assert doc.attr?('reproducible')
         | 
| 303 | 
            -
                  assert_xpath '/article/info/date', result, 0
         | 
| 304 | 
            -
                end
         | 
| 305 | 
            -
             | 
| 306 | 
            -
                test 'should not modify options argument' do
         | 
| 307 | 
            -
                  options = {
         | 
| 308 | 
            -
                    :safe => Asciidoctor::SafeMode::SAFE
         | 
| 309 | 
            -
                  }
         | 
| 310 | 
            -
                  options.freeze
         | 
| 311 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 312 | 
            -
                  begin
         | 
| 313 | 
            -
                    Asciidoctor.load_file sample_input_path, options
         | 
| 314 | 
            -
                  rescue
         | 
| 315 | 
            -
                    flunk %(options argument should not be modified)
         | 
| 316 | 
            -
                  end
         | 
| 317 | 
            -
                end
         | 
| 318 | 
            -
             | 
| 319 | 
            -
                test 'should not modify attributes Hash argument' do
         | 
| 320 | 
            -
                  attributes = {}
         | 
| 321 | 
            -
                  attributes.freeze
         | 
| 322 | 
            -
                  options = {
         | 
| 323 | 
            -
                    :safe => Asciidoctor::SafeMode::SAFE,
         | 
| 324 | 
            -
                    :attributes => attributes
         | 
| 325 | 
            -
                  }
         | 
| 326 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 327 | 
            -
                  begin
         | 
| 328 | 
            -
                    Asciidoctor.load_file sample_input_path, options
         | 
| 329 | 
            -
                  rescue
         | 
| 330 | 
            -
                    flunk %(attributes argument should not be modified)
         | 
| 331 | 
            -
                  end
         | 
| 332 | 
            -
                end
         | 
| 333 | 
            -
             | 
| 334 | 
            -
                test 'should track file and line information with blocks if sourcemap option is set' do
         | 
| 335 | 
            -
                  doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :sourcemap => true
         | 
| 336 | 
            -
             | 
| 337 | 
            -
                  section_1 = doc.sections[0]
         | 
| 338 | 
            -
                  assert_equal 'Section A', section_1.title
         | 
| 339 | 
            -
                  refute_nil section_1.source_location
         | 
| 340 | 
            -
                  assert_equal 'sample.asciidoc', section_1.file
         | 
| 341 | 
            -
                  assert_equal 10, section_1.lineno
         | 
| 342 | 
            -
             | 
| 343 | 
            -
                  section_2 = doc.sections[1]
         | 
| 344 | 
            -
                  assert_equal 'Section B', section_2.title
         | 
| 345 | 
            -
                  refute_nil section_2.source_location
         | 
| 346 | 
            -
                  assert_equal 'sample.asciidoc', section_2.file
         | 
| 347 | 
            -
                  assert_equal 18, section_2.lineno
         | 
| 348 | 
            -
             | 
| 349 | 
            -
                  last_block = section_2.blocks[-1]
         | 
| 350 | 
            -
                  assert_equal :ulist, last_block.context
         | 
| 351 | 
            -
                  refute_nil last_block.source_location
         | 
| 352 | 
            -
                  assert_equal 'sample.asciidoc', last_block.file
         | 
| 353 | 
            -
                  assert_equal 23, last_block.lineno
         | 
| 354 | 
            -
             | 
| 355 | 
            -
                  doc = Asciidoctor.load_file fixture_path('master.adoc'), :sourcemap => true, :safe => :safe
         | 
| 356 | 
            -
             | 
| 357 | 
            -
                  section_1 = doc.sections[0]
         | 
| 358 | 
            -
                  assert_equal 'Chapter A', section_1.title
         | 
| 359 | 
            -
                  refute_nil section_1.source_location
         | 
| 360 | 
            -
                  assert_equal fixture_path('chapter-a.adoc'), section_1.file
         | 
| 361 | 
            -
                  assert_equal 1, section_1.lineno
         | 
| 362 | 
            -
                end
         | 
| 363 | 
            -
             | 
| 364 | 
            -
                test 'should assign correct source location if section occurs on last line of input' do
         | 
| 365 | 
            -
                  input = <<-EOS
         | 
| 366 | 
            -
            = Document Title
         | 
| 367 | 
            -
             | 
| 368 | 
            -
            == Section A
         | 
| 369 | 
            -
             | 
| 370 | 
            -
            content
         | 
| 371 | 
            -
             | 
| 372 | 
            -
            == Section B
         | 
| 373 | 
            -
                  EOS
         | 
| 374 | 
            -
             | 
| 375 | 
            -
                  doc = document_from_string input, :sourcemap => true
         | 
| 376 | 
            -
                  assert_equal [1, 3, 7], (doc.find_by :context => :section).map(&:lineno)
         | 
| 377 | 
            -
                end
         | 
| 378 | 
            -
             | 
| 379 | 
            -
                test 'should allow sourcemap option on document to be modified' do
         | 
| 380 | 
            -
                  doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :parse => false
         | 
| 381 | 
            -
                  doc.sourcemap = true
         | 
| 382 | 
            -
                  doc = doc.parse
         | 
| 383 | 
            -
             | 
| 384 | 
            -
                  section_1 = doc.sections[0]
         | 
| 385 | 
            -
                  assert_equal 'Section A', section_1.title
         | 
| 386 | 
            -
                  refute_nil section_1.source_location
         | 
| 387 | 
            -
                  assert_equal 'sample.asciidoc', section_1.file
         | 
| 388 | 
            -
                  assert_equal 10, section_1.lineno
         | 
| 389 | 
            -
                end
         | 
| 390 | 
            -
             | 
| 391 | 
            -
                test 'find_by should return Array of blocks anywhere in document tree that match criteria' do
         | 
| 392 | 
            -
                  input = <<-EOS
         | 
| 393 | 
            -
            = Document Title
         | 
| 394 | 
            -
             | 
| 395 | 
            -
            preamble
         | 
| 396 | 
            -
             | 
| 397 | 
            -
            == Section A
         | 
| 398 | 
            -
             | 
| 399 | 
            -
            paragraph
         | 
| 400 | 
            -
             | 
| 401 | 
            -
            --
         | 
| 402 | 
            -
            Exhibit A::
         | 
| 403 | 
            -
            +
         | 
| 404 | 
            -
            [#tiger.animal]
         | 
| 405 | 
            -
            image::tiger.png[Tiger]
         | 
| 406 | 
            -
            --
         | 
| 407 | 
            -
             | 
| 408 | 
            -
            image::shoe.png[Shoe]
         | 
| 409 | 
            -
             | 
| 410 | 
            -
            == Section B
         | 
| 411 | 
            -
             | 
| 412 | 
            -
            paragraph
         | 
| 413 | 
            -
                  EOS
         | 
| 414 | 
            -
             | 
| 415 | 
            -
                  doc = Asciidoctor.load input
         | 
| 416 | 
            -
                  result = doc.find_by :context => :image
         | 
| 417 | 
            -
                  assert_equal 2, result.size
         | 
| 418 | 
            -
                  assert_equal :image, result[0].context
         | 
| 419 | 
            -
                  assert_equal 'tiger.png', result[0].attr('target')
         | 
| 420 | 
            -
                  assert_equal :image, result[1].context
         | 
| 421 | 
            -
                  assert_equal 'shoe.png', result[1].attr('target')
         | 
| 422 | 
            -
                end
         | 
| 423 | 
            -
             | 
| 424 | 
            -
                test 'find_by should return an empty Array if no matches are found' do
         | 
| 425 | 
            -
                  input = <<-EOS
         | 
| 426 | 
            -
            paragraph
         | 
| 427 | 
            -
                  EOS
         | 
| 428 | 
            -
                  doc = Asciidoctor.load input
         | 
| 429 | 
            -
                  result = doc.find_by :context => :section
         | 
| 430 | 
            -
                  refute_nil result
         | 
| 431 | 
            -
                  assert_equal 0, result.size
         | 
| 432 | 
            -
                end
         | 
| 433 | 
            -
             | 
| 434 | 
            -
                test 'find_by should return Array of blocks that match style criteria' do
         | 
| 435 | 
            -
                  input = <<-EOS
         | 
| 436 | 
            -
            [square]
         | 
| 437 | 
            -
            * one
         | 
| 438 | 
            -
            * two
         | 
| 439 | 
            -
            * three
         | 
| 440 | 
            -
             | 
| 441 | 
            -
            ---
         | 
| 442 | 
            -
             | 
| 443 | 
            -
            * apples
         | 
| 444 | 
            -
            * bananas
         | 
| 445 | 
            -
            * pears
         | 
| 446 | 
            -
                  EOS
         | 
| 447 | 
            -
             | 
| 448 | 
            -
                  doc = Asciidoctor.load input
         | 
| 449 | 
            -
                  result = doc.find_by :context => :ulist, :style => 'square'
         | 
| 450 | 
            -
                  assert_equal 1, result.size
         | 
| 451 | 
            -
                  assert_equal :ulist, result[0].context
         | 
| 452 | 
            -
                end
         | 
| 453 | 
            -
             | 
| 454 | 
            -
                test 'find_by should return Array of blocks that match role criteria' do
         | 
| 455 | 
            -
                  input = <<-EOS
         | 
| 456 | 
            -
            [#tiger.animal]
         | 
| 457 | 
            -
            image::tiger.png[Tiger]
         | 
| 458 | 
            -
             | 
| 459 | 
            -
            image::shoe.png[Shoe]
         | 
| 460 | 
            -
                  EOS
         | 
| 461 | 
            -
             | 
| 462 | 
            -
                  doc = Asciidoctor.load input
         | 
| 463 | 
            -
                  result = doc.find_by :context => :image, :role => 'animal'
         | 
| 464 | 
            -
                  assert_equal 1, result.size
         | 
| 465 | 
            -
                  assert_equal :image, result[0].context
         | 
| 466 | 
            -
                  assert_equal 'tiger.png', result[0].attr('target')
         | 
| 467 | 
            -
                end
         | 
| 468 | 
            -
             | 
| 469 | 
            -
                test 'find_by should return the document title section if context selector is :section' do
         | 
| 470 | 
            -
                  input = <<-EOS
         | 
| 471 | 
            -
            = Document Title
         | 
| 472 | 
            -
             | 
| 473 | 
            -
            preamble
         | 
| 474 | 
            -
             | 
| 475 | 
            -
            == Section One
         | 
| 476 | 
            -
             | 
| 477 | 
            -
            content
         | 
| 478 | 
            -
                  EOS
         | 
| 479 | 
            -
                  doc = Asciidoctor.load input
         | 
| 480 | 
            -
                  result = doc.find_by :context => :section
         | 
| 481 | 
            -
                  refute_nil result
         | 
| 482 | 
            -
                  assert_equal 2, result.size
         | 
| 483 | 
            -
                  assert_equal :section, result[0].context
         | 
| 484 | 
            -
                  assert_equal 'Document Title', result[0].title
         | 
| 485 | 
            -
                end
         | 
| 486 | 
            -
             | 
| 487 | 
            -
                test 'find_by should only return results for which the block argument yields true' do
         | 
| 488 | 
            -
                  input = <<-EOS
         | 
| 489 | 
            -
            == Section
         | 
| 490 | 
            -
             | 
| 491 | 
            -
            content
         | 
| 492 | 
            -
             | 
| 493 | 
            -
            === Subsection
         | 
| 494 | 
            -
             | 
| 495 | 
            -
            content
         | 
| 496 | 
            -
                  EOS
         | 
| 497 | 
            -
                  doc = Asciidoctor.load input
         | 
| 498 | 
            -
                  result = doc.find_by(:context => :section) {|sect| sect.level == 1 }
         | 
| 499 | 
            -
                  refute_nil result
         | 
| 500 | 
            -
                  assert_equal 1, result.size
         | 
| 501 | 
            -
                  assert_equal :section, result[0].context
         | 
| 502 | 
            -
                  assert_equal 'Section', result[0].title
         | 
| 503 | 
            -
                end
         | 
| 504 | 
            -
             | 
| 505 | 
            -
                test 'find_by should only return one result when matching by id' do
         | 
| 506 | 
            -
                  input = <<-EOS
         | 
| 507 | 
            -
            == Section
         | 
| 508 | 
            -
             | 
| 509 | 
            -
            content
         | 
| 510 | 
            -
             | 
| 511 | 
            -
            [#subsection]
         | 
| 512 | 
            -
            === Subsection
         | 
| 513 | 
            -
             | 
| 514 | 
            -
            content
         | 
| 515 | 
            -
                  EOS
         | 
| 516 | 
            -
                  doc = Asciidoctor.load input
         | 
| 517 | 
            -
                  result = doc.find_by(:context => :section, :id => 'subsection')
         | 
| 518 | 
            -
                  refute_nil result
         | 
| 519 | 
            -
                  assert_equal 1, result.size
         | 
| 520 | 
            -
                  assert_equal :section, result[0].context
         | 
| 521 | 
            -
                  assert_equal 'Subsection', result[0].title
         | 
| 522 | 
            -
                end
         | 
| 523 | 
            -
             | 
| 524 | 
            -
                test 'find_by should return an empty Array if the id criteria matches but the block argument yields false' do
         | 
| 525 | 
            -
                  input = <<-EOS
         | 
| 526 | 
            -
            == Section
         | 
| 527 | 
            -
             | 
| 528 | 
            -
            content
         | 
| 529 | 
            -
             | 
| 530 | 
            -
            [#subsection]
         | 
| 531 | 
            -
            === Subsection
         | 
| 532 | 
            -
             | 
| 533 | 
            -
            content
         | 
| 534 | 
            -
                  EOS
         | 
| 535 | 
            -
                  doc = Asciidoctor.load input
         | 
| 536 | 
            -
                  result = doc.find_by(:context => :section, :id => 'subsection') {|sect| false }
         | 
| 537 | 
            -
                  refute_nil result
         | 
| 538 | 
            -
                  assert_equal 0, result.size
         | 
| 539 | 
            -
                end
         | 
| 540 | 
            -
             | 
| 541 | 
            -
                test 'find_by should not crash if dlist entry does not have description' do
         | 
| 542 | 
            -
                  input = <<-EOS
         | 
| 543 | 
            -
            term without description::
         | 
| 544 | 
            -
                  EOS
         | 
| 545 | 
            -
                  doc = Asciidoctor.load input
         | 
| 546 | 
            -
                  result = doc.find_by
         | 
| 547 | 
            -
                  refute_nil result
         | 
| 548 | 
            -
                  assert_equal 3, result.size
         | 
| 549 | 
            -
                  assert_kind_of Asciidoctor::Document, result[0]
         | 
| 550 | 
            -
                  assert_kind_of Asciidoctor::List, result[1]
         | 
| 551 | 
            -
                  assert_kind_of Asciidoctor::ListItem, result[2]
         | 
| 552 | 
            -
                end
         | 
| 553 | 
            -
              end
         | 
| 554 | 
            -
             | 
| 555 | 
            -
              context 'Convert APIs' do
         | 
| 556 | 
            -
                test 'should convert source document to string when to_file is false' do
         | 
| 557 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 558 | 
            -
             | 
| 559 | 
            -
                  output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
         | 
| 560 | 
            -
                  refute_empty output
         | 
| 561 | 
            -
                  assert_xpath '/html', output, 1
         | 
| 562 | 
            -
                  assert_xpath '/html/head', output, 1
         | 
| 563 | 
            -
                  assert_xpath '/html/body', output, 1
         | 
| 564 | 
            -
                  assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
         | 
| 565 | 
            -
                  assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
         | 
| 566 | 
            -
                end
         | 
| 567 | 
            -
             | 
| 568 | 
            -
                test 'lines in output should be separated by line feed' do
         | 
| 569 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 570 | 
            -
             | 
| 571 | 
            -
                  output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
         | 
| 572 | 
            -
                  refute_empty output
         | 
| 573 | 
            -
                  lines = output.split("\n")
         | 
| 574 | 
            -
                  assert_equal lines.size, output.split(/\r\n|\r|\n/).size
         | 
| 575 | 
            -
                  raw_lengths = lines.map(&:length)
         | 
| 576 | 
            -
                  trimmed_lengths = lines.map {|line| line.rstrip.length }
         | 
| 577 | 
            -
                  assert_equal raw_lengths, trimmed_lengths
         | 
| 578 | 
            -
                end
         | 
| 579 | 
            -
             | 
| 580 | 
            -
                test 'should accept attributes as array' do
         | 
| 581 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 582 | 
            -
                  output = Asciidoctor.convert_file sample_input_path, :attributes => %w(sectnums idprefix idseparator=-), :to_file => false
         | 
| 583 | 
            -
                  assert_css '#section-a', output, 1
         | 
| 584 | 
            -
                end
         | 
| 585 | 
            -
             | 
| 586 | 
            -
                test 'should accept attributes as string' do
         | 
| 587 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 588 | 
            -
                  output = Asciidoctor.convert_file sample_input_path, :attributes => 'sectnums idprefix idseparator=-', :to_file => false
         | 
| 589 | 
            -
                  assert_css '#section-a', output, 1
         | 
| 590 | 
            -
                end
         | 
| 591 | 
            -
             | 
| 592 | 
            -
                test 'should link to default stylesheet by default when safe mode is SECURE or greater' do
         | 
| 593 | 
            -
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 594 | 
            -
                  output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
         | 
| 595 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
         | 
| 596 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
         | 
| 597 | 
            -
                end
         | 
| 598 | 
            -
             | 
| 599 | 
            -
                test 'should embed default stylesheet by default if SafeMode is less than SECURE' do
         | 
| 600 | 
            -
                  input = <<-EOS
         | 
| 601 | 
            -
            = Document Title
         | 
| 602 | 
            -
             | 
| 603 | 
            -
            text
         | 
| 604 | 
            -
                  EOS
         | 
| 605 | 
            -
             | 
| 606 | 
            -
                  output = Asciidoctor.render(input, :safe => Asciidoctor::SafeMode::SERVER, :header_footer => true)
         | 
| 607 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
         | 
| 608 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
         | 
| 609 | 
            -
                  stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
         | 
| 610 | 
            -
                  styles = stylenode.content
         | 
| 611 | 
            -
                  refute_nil styles
         | 
| 612 | 
            -
                  refute_empty styles.strip
         | 
| 613 | 
            -
                end
         | 
| 614 | 
            -
             | 
| 615 | 
            -
                test 'should link to default stylesheet by default even if linkcss is unset in document' do
         | 
| 616 | 
            -
                  input = <<-EOS
         | 
| 617 | 
            -
            = Document Title
         | 
| 618 | 
            -
            :linkcss!:
         | 
| 619 | 
            -
             | 
| 620 | 
            -
            text
         | 
| 621 | 
            -
                  EOS
         | 
| 622 | 
            -
             | 
| 623 | 
            -
                  output = Asciidoctor.render(input, :header_footer => true)
         | 
| 624 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
         | 
| 625 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
         | 
| 626 | 
            -
                end
         | 
| 627 | 
            -
             | 
| 628 | 
            -
                test 'should link to default stylesheet by default if linkcss is unset' do
         | 
| 629 | 
            -
                  input = <<-EOS
         | 
| 630 | 
            -
            = Document Title
         | 
| 631 | 
            -
             | 
| 632 | 
            -
            text
         | 
| 633 | 
            -
                  EOS
         | 
| 634 | 
            -
             | 
| 635 | 
            -
                  output = Asciidoctor.render(input, :header_footer => true, :attributes => {'linkcss!' => ''})
         | 
| 636 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
         | 
| 637 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
         | 
| 638 | 
            -
                end
         | 
| 639 | 
            -
             | 
| 640 | 
            -
                test 'should embed default stylesheet if safe mode is less than secure and linkcss is unset' do
         | 
| 641 | 
            -
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 642 | 
            -
                  output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false,
         | 
| 643 | 
            -
                      :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss!' => ''}
         | 
| 644 | 
            -
                  assert_css 'html:root > head > style', output, 1
         | 
| 645 | 
            -
                  stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
         | 
| 646 | 
            -
                  styles = stylenode.content
         | 
| 647 | 
            -
                  refute_nil styles
         | 
| 648 | 
            -
                  refute_empty styles.strip
         | 
| 649 | 
            -
                end
         | 
| 650 | 
            -
             | 
| 651 | 
            -
                test 'should not link to stylesheet if stylesheet is unset' do
         | 
| 652 | 
            -
                  input = <<-EOS
         | 
| 653 | 
            -
            = Document Title
         | 
| 654 | 
            -
             | 
| 655 | 
            -
            text
         | 
| 656 | 
            -
                  EOS
         | 
| 657 | 
            -
             | 
| 658 | 
            -
                  output = Asciidoctor.render(input, :header_footer => true, :attributes => {'stylesheet!' => ''})
         | 
| 659 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 0
         | 
| 660 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"]', output, 0
         | 
| 661 | 
            -
                end
         | 
| 662 | 
            -
             | 
| 663 | 
            -
                test 'should link to custom stylesheet if specified in stylesheet attribute' do
         | 
| 664 | 
            -
                  input = <<-EOS
         | 
| 665 | 
            -
            = Document Title
         | 
| 666 | 
            -
             | 
| 667 | 
            -
            text
         | 
| 668 | 
            -
                  EOS
         | 
| 669 | 
            -
             | 
| 670 | 
            -
                  output = Asciidoctor.render(input, :header_footer => true, :attributes => {'stylesheet' => './custom.css'})
         | 
| 671 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 0
         | 
| 672 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href="./custom.css"]', output, 1
         | 
| 673 | 
            -
             | 
| 674 | 
            -
                  output = Asciidoctor.render(input, :header_footer => true, :attributes => {'stylesheet' => 'file:///home/username/custom.css'})
         | 
| 675 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href="file:///home/username/custom.css"]', output, 1
         | 
| 676 | 
            -
                end
         | 
| 677 | 
            -
             | 
| 678 | 
            -
                test 'should resolve custom stylesheet relative to stylesdir' do
         | 
| 679 | 
            -
                  input = <<-EOS
         | 
| 680 | 
            -
            = Document Title
         | 
| 681 | 
            -
             | 
| 682 | 
            -
            text
         | 
| 683 | 
            -
                  EOS
         | 
| 684 | 
            -
             | 
| 685 | 
            -
                  output = Asciidoctor.render(input, :header_footer => true, :attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets'})
         | 
| 686 | 
            -
                  assert_css 'html:root > head > link[rel="stylesheet"][href="./stylesheets/custom.css"]', output, 1
         | 
| 687 | 
            -
                end
         | 
| 688 | 
            -
             | 
| 689 | 
            -
                test 'should resolve custom stylesheet to embed relative to stylesdir' do
         | 
| 690 | 
            -
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 691 | 
            -
                  output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :safe => Asciidoctor::SafeMode::SAFE, :to_file => false,
         | 
| 692 | 
            -
                      :attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets', 'linkcss!' => ''}
         | 
| 693 | 
            -
                  stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
         | 
| 694 | 
            -
                  styles = stylenode.content
         | 
| 695 | 
            -
                  refute_nil styles
         | 
| 696 | 
            -
                  refute_empty styles.strip
         | 
| 697 | 
            -
                end
         | 
| 698 | 
            -
             | 
| 699 | 
            -
                test 'should convert source file and write result to adjacent file by default' do
         | 
| 700 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 701 | 
            -
                  sample_output_path = fixture_path('sample.html')
         | 
| 702 | 
            -
                  begin
         | 
| 703 | 
            -
                    Asciidoctor.convert_file sample_input_path
         | 
| 704 | 
            -
                    assert File.exist?(sample_output_path)
         | 
| 705 | 
            -
                    output = IO.read(sample_output_path)
         | 
| 706 | 
            -
                    refute_empty output
         | 
| 707 | 
            -
                    assert_xpath '/html', output, 1
         | 
| 708 | 
            -
                    assert_xpath '/html/head', output, 1
         | 
| 709 | 
            -
                    assert_xpath '/html/body', output, 1
         | 
| 710 | 
            -
                    assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
         | 
| 711 | 
            -
                    assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
         | 
| 712 | 
            -
                  ensure
         | 
| 713 | 
            -
                    FileUtils.rm(sample_output_path)
         | 
| 714 | 
            -
                  end
         | 
| 715 | 
            -
                end
         | 
| 716 | 
            -
             | 
| 717 | 
            -
                test 'should convert source file and write to specified file' do
         | 
| 718 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 719 | 
            -
                  sample_output_path = fixture_path('result.html')
         | 
| 720 | 
            -
                  begin
         | 
| 721 | 
            -
                    Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path
         | 
| 722 | 
            -
                    assert File.exist?(sample_output_path)
         | 
| 723 | 
            -
                    output = IO.read(sample_output_path)
         | 
| 724 | 
            -
                    refute_empty output
         | 
| 725 | 
            -
                    assert_xpath '/html', output, 1
         | 
| 726 | 
            -
                    assert_xpath '/html/head', output, 1
         | 
| 727 | 
            -
                    assert_xpath '/html/body', output, 1
         | 
| 728 | 
            -
                    assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
         | 
| 729 | 
            -
                    assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
         | 
| 730 | 
            -
                  ensure
         | 
| 731 | 
            -
                    FileUtils.rm(sample_output_path)
         | 
| 732 | 
            -
                  end
         | 
| 733 | 
            -
                end
         | 
| 734 | 
            -
             | 
| 735 | 
            -
                test 'should convert source file and write to specified file in base_dir' do
         | 
| 736 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 737 | 
            -
                  sample_output_path = fixture_path('result.html')
         | 
| 738 | 
            -
                  fixture_dir = fixture_path('')
         | 
| 739 | 
            -
                  begin
         | 
| 740 | 
            -
                    Asciidoctor.convert_file sample_input_path, :to_file => 'result.html', :base_dir => fixture_dir
         | 
| 741 | 
            -
                    assert File.exist?(sample_output_path)
         | 
| 742 | 
            -
                    output = IO.read(sample_output_path)
         | 
| 743 | 
            -
                    refute_empty output
         | 
| 744 | 
            -
                    assert_xpath '/html', output, 1
         | 
| 745 | 
            -
                    assert_xpath '/html/head', output, 1
         | 
| 746 | 
            -
                    assert_xpath '/html/body', output, 1
         | 
| 747 | 
            -
                    assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
         | 
| 748 | 
            -
                    assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
         | 
| 749 | 
            -
                  rescue => e
         | 
| 750 | 
            -
                    flunk e.message
         | 
| 751 | 
            -
                  ensure
         | 
| 752 | 
            -
                    FileUtils.rm(sample_output_path, :force => true)
         | 
| 753 | 
            -
                  end
         | 
| 754 | 
            -
                end
         | 
| 755 | 
            -
             | 
| 756 | 
            -
                test 'in_place option is ignored when to_file is specified' do
         | 
| 757 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 758 | 
            -
                  sample_output_path = fixture_path('result.html')
         | 
| 759 | 
            -
                  begin
         | 
| 760 | 
            -
                    Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path, :in_place => true
         | 
| 761 | 
            -
                    assert File.exist?(sample_output_path)
         | 
| 762 | 
            -
                  ensure
         | 
| 763 | 
            -
                    FileUtils.rm(sample_output_path) if File.exist? sample_output_path
         | 
| 764 | 
            -
                  end
         | 
| 765 | 
            -
                end
         | 
| 766 | 
            -
             | 
| 767 | 
            -
                test 'in_place option is ignored when to_dir is specified' do
         | 
| 768 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 769 | 
            -
                  sample_output_path = fixture_path('sample.html')
         | 
| 770 | 
            -
                  begin
         | 
| 771 | 
            -
                    Asciidoctor.convert_file sample_input_path, :to_dir => File.dirname(sample_output_path), :in_place => true
         | 
| 772 | 
            -
                    assert File.exist?(sample_output_path)
         | 
| 773 | 
            -
                  ensure
         | 
| 774 | 
            -
                    FileUtils.rm(sample_output_path) if File.exist? sample_output_path
         | 
| 775 | 
            -
                  end
         | 
| 776 | 
            -
                end
         | 
| 777 | 
            -
             | 
| 778 | 
            -
                test 'output should be relative to to_dir option' do
         | 
| 779 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 780 | 
            -
                  output_dir = File.join(File.dirname(sample_input_path), 'test_output')
         | 
| 781 | 
            -
                  Dir.mkdir output_dir if !File.exist? output_dir
         | 
| 782 | 
            -
                  sample_output_path = File.join(output_dir, 'sample.html')
         | 
| 783 | 
            -
                  begin
         | 
| 784 | 
            -
                    Asciidoctor.convert_file sample_input_path, :to_dir => output_dir
         | 
| 785 | 
            -
                    assert File.exist? sample_output_path
         | 
| 786 | 
            -
                  ensure
         | 
| 787 | 
            -
                    FileUtils.rm(sample_output_path) if File.exist? sample_output_path
         | 
| 788 | 
            -
                    FileUtils.rmdir output_dir
         | 
| 789 | 
            -
                  end
         | 
| 790 | 
            -
                end
         | 
| 791 | 
            -
             | 
| 792 | 
            -
                test 'missing directories should be created if mkdirs is enabled' do
         | 
| 793 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 794 | 
            -
                  output_dir = File.join(File.join(File.dirname(sample_input_path), 'test_output'), 'subdir')
         | 
| 795 | 
            -
                  sample_output_path = File.join(output_dir, 'sample.html')
         | 
| 796 | 
            -
                  begin
         | 
| 797 | 
            -
                    Asciidoctor.convert_file sample_input_path, :to_dir => output_dir, :mkdirs => true
         | 
| 798 | 
            -
                    assert File.exist? sample_output_path
         | 
| 799 | 
            -
                  ensure
         | 
| 800 | 
            -
                    FileUtils.rm(sample_output_path) if File.exist? sample_output_path
         | 
| 801 | 
            -
                    FileUtils.rmdir output_dir
         | 
| 802 | 
            -
                    FileUtils.rmdir File.dirname(output_dir)
         | 
| 803 | 
            -
                  end
         | 
| 804 | 
            -
                end
         | 
| 805 | 
            -
             | 
| 806 | 
            -
                # TODO need similar test for when to_dir is specified
         | 
| 807 | 
            -
                test 'should raise exception if an attempt is made to overwrite input file' do
         | 
| 808 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 809 | 
            -
             | 
| 810 | 
            -
                  assert_raises IOError do
         | 
| 811 | 
            -
                    Asciidoctor.convert_file sample_input_path, :attributes => { 'outfilesuffix' => '.asciidoc' }
         | 
| 812 | 
            -
                  end
         | 
| 813 | 
            -
                end
         | 
| 814 | 
            -
             | 
| 815 | 
            -
                test 'to_file should be relative to to_dir when both given' do
         | 
| 816 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 817 | 
            -
                  base_dir = File.dirname(sample_input_path)
         | 
| 818 | 
            -
                  sample_rel_output_path = File.join('test_output', 'result.html')
         | 
| 819 | 
            -
                  output_dir = File.dirname(File.join(base_dir, sample_rel_output_path))
         | 
| 820 | 
            -
                  Dir.mkdir output_dir if !File.exist? output_dir
         | 
| 821 | 
            -
                  sample_output_path = File.join(base_dir, sample_rel_output_path)
         | 
| 822 | 
            -
                  begin
         | 
| 823 | 
            -
                    Asciidoctor.convert_file sample_input_path, :to_dir => base_dir, :to_file => sample_rel_output_path
         | 
| 824 | 
            -
                    assert File.exist? sample_output_path
         | 
| 825 | 
            -
                  ensure
         | 
| 826 | 
            -
                    FileUtils.rm(sample_output_path) if File.exist? sample_output_path
         | 
| 827 | 
            -
                    FileUtils.rmdir output_dir
         | 
| 828 | 
            -
                  end
         | 
| 829 | 
            -
                end
         | 
| 830 | 
            -
             | 
| 831 | 
            -
                test 'should not modify options argument' do
         | 
| 832 | 
            -
                  options = {
         | 
| 833 | 
            -
                    :safe => Asciidoctor::SafeMode::SAFE,
         | 
| 834 | 
            -
                    :to_file => false
         | 
| 835 | 
            -
                  }
         | 
| 836 | 
            -
                  options.freeze
         | 
| 837 | 
            -
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 838 | 
            -
                  begin
         | 
| 839 | 
            -
                    Asciidoctor.convert_file sample_input_path, options
         | 
| 840 | 
            -
                  rescue
         | 
| 841 | 
            -
                    flunk %(options argument should not be modified)
         | 
| 842 | 
            -
                  end
         | 
| 843 | 
            -
                end
         | 
| 844 | 
            -
              end
         | 
| 845 | 
            -
             | 
| 846 134 | 
             
              context 'Docinfo files' do
         | 
| 847 135 | 
             
                test 'should include docinfo files for html backend' do
         | 
| 848 136 | 
             
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| @@ -1048,18 +336,17 @@ text | |
| 1048 336 |  | 
| 1049 337 | 
             
                test 'should substitute attributes in docinfo files by default' do
         | 
| 1050 338 | 
             
                  sample_input_path = fixture_path 'subs.adoc'
         | 
| 1051 | 
            -
                   | 
| 339 | 
            +
                  using_memory_logger do |logger|
         | 
| 1052 340 | 
             
                    output = Asciidoctor.convert_file sample_input_path,
         | 
| 1053 341 | 
             
                        :to_file => false,
         | 
| 1054 342 | 
             
                        :header_footer => true,
         | 
| 1055 343 | 
             
                        :safe => :server,
         | 
| 1056 344 | 
             
                        :attributes => { 'docinfo' => '', 'bootstrap-version' => nil, 'linkcss' => '', 'attribute-missing' => 'drop-line' }
         | 
| 1057 | 
            -
                     | 
| 345 | 
            +
                    refute_empty output
         | 
| 346 | 
            +
                    assert_css 'script', output, 0
         | 
| 347 | 
            +
                    assert_xpath %(//meta[@name="copyright"][@content="(C) OpenDevise"]), output, 1
         | 
| 348 | 
            +
                    assert_message logger, :WARN, 'dropping line containing reference to missing attribute: bootstrap-version'
         | 
| 1058 349 | 
             
                  end
         | 
| 1059 | 
            -
                  refute_empty output
         | 
| 1060 | 
            -
                  assert_css 'script', output, 0
         | 
| 1061 | 
            -
                  assert_xpath %(//meta[@name="copyright"][@content="(C) OpenDevise"]), output, 1
         | 
| 1062 | 
            -
                  assert_includes warnings, 'dropping line containing reference to missing attribute'
         | 
| 1063 350 | 
             
                end
         | 
| 1064 351 |  | 
| 1065 352 | 
             
                test 'should apply explicit substitutions to docinfo files' do
         | 
| @@ -1134,9 +421,9 @@ text | |
| 1134 421 | 
             
                    '/img/favicon.png' => %w(/img/favicon.png image/png)
         | 
| 1135 422 | 
             
                  }.each {|val, (href, type)|
         | 
| 1136 423 | 
             
                    result = render_string %(= Untitled), :attributes => { 'favicon' => val }
         | 
| 1137 | 
            -
                    assert_css 'link[rel=" | 
| 1138 | 
            -
                    assert_css %(link[rel=" | 
| 1139 | 
            -
                    assert_css %(link[rel=" | 
| 424 | 
            +
                    assert_css 'link[rel="icon"]', result, 1
         | 
| 425 | 
            +
                    assert_css %(link[rel="icon"][href="#{href}"]), result, 1
         | 
| 426 | 
            +
                    assert_css %(link[rel="icon"][type="#{type}"]), result, 1
         | 
| 1140 427 | 
             
                  }
         | 
| 1141 428 | 
             
                end
         | 
| 1142 429 | 
             
              end
         | 
| @@ -1302,7 +589,25 @@ Block content | |
| 1302 589 | 
             
                 assert doc.has_header?
         | 
| 1303 590 | 
             
                 assert_equal 'Document Title', doc.header.title
         | 
| 1304 591 | 
             
                 assert_equal 'Document Title', doc.first_section.title
         | 
| 1305 | 
            -
                 assert_xpath '//*[@id="preamble"]//p[text()="Document Title"]', doc. | 
| 592 | 
            +
                 assert_xpath '//*[@id="preamble"]//p[text()="Document Title"]', doc.convert, 1
         | 
| 593 | 
            +
                end
         | 
| 594 | 
            +
             | 
| 595 | 
            +
                test 'document with blank title attribute entry overrides doctitle' do
         | 
| 596 | 
            +
                 input = <<-EOS
         | 
| 597 | 
            +
            = Document Title
         | 
| 598 | 
            +
            :title:
         | 
| 599 | 
            +
             | 
| 600 | 
            +
            {doctitle}
         | 
| 601 | 
            +
             | 
| 602 | 
            +
            == First Section
         | 
| 603 | 
            +
                 EOS
         | 
| 604 | 
            +
                 doc = document_from_string input
         | 
| 605 | 
            +
                 assert_equal '', doc.doctitle
         | 
| 606 | 
            +
                 assert_equal '', doc.title
         | 
| 607 | 
            +
                 assert doc.has_header?
         | 
| 608 | 
            +
                 assert_equal 'Document Title', doc.header.title
         | 
| 609 | 
            +
                 assert_equal 'Document Title', doc.first_section.title
         | 
| 610 | 
            +
                 assert_xpath '//*[@id="preamble"]//p[text()="Document Title"]', doc.convert, 1
         | 
| 1306 611 | 
             
                end
         | 
| 1307 612 |  | 
| 1308 613 | 
             
                test 'document with title attribute entry overrides doctitle attribute entry' do
         | 
| @@ -1322,7 +627,7 @@ Block content | |
| 1322 627 | 
             
                 assert doc.has_header?
         | 
| 1323 628 | 
             
                 assert_equal 'doctitle', doc.header.title
         | 
| 1324 629 | 
             
                 assert_equal 'doctitle', doc.first_section.title
         | 
| 1325 | 
            -
                 assert_xpath '//*[@id="preamble"]//p[text()="Document Title, doctitle"]', doc. | 
| 630 | 
            +
                 assert_xpath '//*[@id="preamble"]//p[text()="Document Title, doctitle"]', doc.convert, 1
         | 
| 1326 631 | 
             
                end
         | 
| 1327 632 |  | 
| 1328 633 | 
             
                test 'document with doctitle attribute entry overrides header title and doctitle' do
         | 
| @@ -1337,11 +642,11 @@ Block content | |
| 1337 642 | 
             
                 EOS
         | 
| 1338 643 | 
             
                 doc = document_from_string input
         | 
| 1339 644 | 
             
                 assert_equal 'Override', doc.doctitle
         | 
| 1340 | 
            -
                 assert_nil doc.title
         | 
| 645 | 
            +
                 assert_nil doc.attributes['title']
         | 
| 1341 646 | 
             
                 assert doc.has_header?
         | 
| 1342 647 | 
             
                 assert_equal 'Override', doc.header.title
         | 
| 1343 648 | 
             
                 assert_equal 'Override', doc.first_section.title
         | 
| 1344 | 
            -
                 assert_xpath '//*[@id="preamble"]//p[text()="Document Title, Override"]', doc. | 
| 649 | 
            +
                 assert_xpath '//*[@id="preamble"]//p[text()="Document Title, Override"]', doc.convert, 1
         | 
| 1345 650 | 
             
                end
         | 
| 1346 651 |  | 
| 1347 652 | 
             
                test 'doctitle attribute entry above header overrides header title and doctitle' do
         | 
| @@ -1355,11 +660,11 @@ Block content | |
| 1355 660 | 
             
                 EOS
         | 
| 1356 661 | 
             
                 doc = document_from_string input
         | 
| 1357 662 | 
             
                 assert_equal 'Override', doc.doctitle
         | 
| 1358 | 
            -
                 assert_nil doc.title
         | 
| 663 | 
            +
                 assert_nil doc.attributes['title']
         | 
| 1359 664 | 
             
                 assert doc.has_header?
         | 
| 1360 665 | 
             
                 assert_equal 'Override', doc.header.title
         | 
| 1361 666 | 
             
                 assert_equal 'Override', doc.first_section.title
         | 
| 1362 | 
            -
                 assert_xpath '//*[@id="preamble"]//p[text()="Override"]', doc. | 
| 667 | 
            +
                 assert_xpath '//*[@id="preamble"]//p[text()="Override"]', doc.convert, 1
         | 
| 1363 668 | 
             
                end
         | 
| 1364 669 |  | 
| 1365 670 | 
             
                test 'should recognize document title when preceded by blank lines' do
         | 
| @@ -1568,6 +873,18 @@ content | |
| 1568 873 | 
             
                  assert_xpath '//meta[@name="author"][@content="Ze Product team"]', output, 1
         | 
| 1569 874 | 
             
                end
         | 
| 1570 875 |  | 
| 876 | 
            +
                test 'should not double escape ampersand in author attribute' do
         | 
| 877 | 
            +
                  input = <<-EOS
         | 
| 878 | 
            +
            = Document Title
         | 
| 879 | 
            +
            R&D Lab
         | 
| 880 | 
            +
             | 
| 881 | 
            +
            {author}
         | 
| 882 | 
            +
                  EOS
         | 
| 883 | 
            +
             | 
| 884 | 
            +
                  output = render_string input
         | 
| 885 | 
            +
                  assert_includes output, 'R&D Lab', 2
         | 
| 886 | 
            +
                end
         | 
| 887 | 
            +
             | 
| 1571 888 | 
             
                test 'should include multiple authors in HTML output' do
         | 
| 1572 889 | 
             
                  input = <<-EOS
         | 
| 1573 890 | 
             
            = Document Title
         | 
| @@ -1605,6 +922,19 @@ content | |
| 1605 922 | 
             
                  assert_xpath '//articleinfo/authorgroup/author[2]/firstname[text() = "Junior"]', output, 1
         | 
| 1606 923 | 
             
                end
         | 
| 1607 924 |  | 
| 925 | 
            +
                test 'with author defined by indexed attribute name' do
         | 
| 926 | 
            +
                  input = <<-EOS
         | 
| 927 | 
            +
            = Document Title
         | 
| 928 | 
            +
            :author_1: Doc Writer
         | 
| 929 | 
            +
             | 
| 930 | 
            +
            {author}
         | 
| 931 | 
            +
                  EOS
         | 
| 932 | 
            +
             | 
| 933 | 
            +
                  doc = document_from_string input
         | 
| 934 | 
            +
                  assert_equal 'Doc Writer', (doc.attr 'author')
         | 
| 935 | 
            +
                  assert_equal 'Doc Writer', (doc.attr 'author_1')
         | 
| 936 | 
            +
                end
         | 
| 937 | 
            +
             | 
| 1608 938 | 
             
                test 'with authors defined using attribute entry to DocBook' do
         | 
| 1609 939 | 
             
                  input = <<-EOS
         | 
| 1610 940 | 
             
            = Document Title
         | 
| @@ -1625,10 +955,50 @@ content | |
| 1625 955 | 
             
                  assert_xpath '(//articleinfo/authorgroup/author)[2]/email[text() = "junior@asciidoc.org"]', output, 1
         | 
| 1626 956 | 
             
                end
         | 
| 1627 957 |  | 
| 958 | 
            +
                test 'should populate copyright element in DocBook output if copyright attribute is defined' do
         | 
| 959 | 
            +
                  input = <<-EOS
         | 
| 960 | 
            +
            = Jet Bike
         | 
| 961 | 
            +
            :copyright: ACME, Inc.
         | 
| 962 | 
            +
             | 
| 963 | 
            +
            Essential for catching road runners.
         | 
| 964 | 
            +
                  EOS
         | 
| 965 | 
            +
                  output = render_string input, :backend => 'docbook5'
         | 
| 966 | 
            +
                  assert_xpath '/article/info/copyright', output, 1
         | 
| 967 | 
            +
                  assert_xpath '/article/info/copyright/holder[text()="ACME, Inc."]', output, 1
         | 
| 968 | 
            +
                end
         | 
| 969 | 
            +
             | 
| 970 | 
            +
                test 'should populate copyright element in DocBook output if copyright attribute is defined with year' do
         | 
| 971 | 
            +
                  input = <<-EOS
         | 
| 972 | 
            +
            = Jet Bike
         | 
| 973 | 
            +
            :copyright: ACME, Inc. 1956
         | 
| 974 | 
            +
             | 
| 975 | 
            +
            Essential for catching road runners.
         | 
| 976 | 
            +
                  EOS
         | 
| 977 | 
            +
                  output = render_string input, :backend => 'docbook5'
         | 
| 978 | 
            +
                  assert_xpath '/article/info/copyright', output, 1
         | 
| 979 | 
            +
                  assert_xpath '/article/info/copyright/holder[text()="ACME, Inc."]', output, 1
         | 
| 980 | 
            +
                  assert_xpath '/article/info/copyright/year', output, 1
         | 
| 981 | 
            +
                  assert_xpath '/article/info/copyright/year[text()="1956"]', output, 1
         | 
| 982 | 
            +
                end
         | 
| 983 | 
            +
             | 
| 984 | 
            +
                test 'should populate copyright element in DocBook output if copyright attribute is defined with year range' do
         | 
| 985 | 
            +
                  input = <<-EOS
         | 
| 986 | 
            +
            = Jet Bike
         | 
| 987 | 
            +
            :copyright: ACME, Inc. 1956-2018
         | 
| 988 | 
            +
             | 
| 989 | 
            +
            Essential for catching road runners.
         | 
| 990 | 
            +
                  EOS
         | 
| 991 | 
            +
                  output = render_string input, :backend => 'docbook5'
         | 
| 992 | 
            +
                  assert_xpath '/article/info/copyright', output, 1
         | 
| 993 | 
            +
                  assert_xpath '/article/info/copyright/holder[text()="ACME, Inc."]', output, 1
         | 
| 994 | 
            +
                  assert_xpath '/article/info/copyright/year', output, 1
         | 
| 995 | 
            +
                  assert_xpath '/article/info/copyright/year[text()="1956-2018"]', output, 1
         | 
| 996 | 
            +
                end
         | 
| 997 | 
            +
             | 
| 1628 998 | 
             
                test 'with header footer' do
         | 
| 1629 999 | 
             
                  doc = document_from_string "= Title\n\nparagraph"
         | 
| 1630 1000 | 
             
                  refute doc.attr?('embedded')
         | 
| 1631 | 
            -
                  result = doc. | 
| 1001 | 
            +
                  result = doc.convert
         | 
| 1632 1002 | 
             
                  assert_xpath '/html', result, 1
         | 
| 1633 1003 | 
             
                  assert_xpath '//*[@id="header"]', result, 1
         | 
| 1634 1004 | 
             
                  assert_xpath '//*[@id="header"]/h1', result, 1
         | 
| @@ -1649,7 +1019,7 @@ content | |
| 1649 1019 |  | 
| 1650 1020 | 
             
                test 'can disable last updated in footer' do
         | 
| 1651 1021 | 
             
                  doc = document_from_string "= Document Title\n\npreamble", :attributes => {'last-update-label!' => ''}
         | 
| 1652 | 
            -
                  result = doc. | 
| 1022 | 
            +
                  result = doc.convert
         | 
| 1653 1023 | 
             
                  assert_xpath '//*[@id="footer-text"]', result, 1
         | 
| 1654 1024 | 
             
                  assert_xpath '//*[@id="footer-text"][normalize-space(text())=""]', result, 1
         | 
| 1655 1025 | 
             
                end
         | 
| @@ -1657,7 +1027,7 @@ content | |
| 1657 1027 | 
             
                test 'no header footer' do
         | 
| 1658 1028 | 
             
                  doc = document_from_string "= Document Title\n\ncontent", :header_footer => false
         | 
| 1659 1029 | 
             
                  assert doc.attr?('embedded')
         | 
| 1660 | 
            -
                  result = doc. | 
| 1030 | 
            +
                  result = doc.convert
         | 
| 1661 1031 | 
             
                  assert_xpath '/html', result, 0
         | 
| 1662 1032 | 
             
                  assert_xpath '/h1', result, 0
         | 
| 1663 1033 | 
             
                  assert_xpath '/*[@id="header"]', result, 0
         | 
| @@ -1726,13 +1096,13 @@ finally a reference to the second footnote footnoteref:[note2]. | |
| 1726 1096 | 
             
                  output = render_string input
         | 
| 1727 1097 | 
             
                  assert_css '#footnotes', output, 1
         | 
| 1728 1098 | 
             
                  assert_css '#footnotes .footnote', output, 2
         | 
| 1729 | 
            -
                  assert_css '#footnotes .footnote# | 
| 1730 | 
            -
                  assert_xpath '//div[@id="footnotes"]/div[@id=" | 
| 1731 | 
            -
                  text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id=" | 
| 1099 | 
            +
                  assert_css '#footnotes .footnote#_footnotedef_1', output, 1
         | 
| 1100 | 
            +
                  assert_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
         | 
| 1101 | 
            +
                  text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_1"]/text()', output
         | 
| 1732 1102 | 
             
                  assert_equal '. An example footnote.', text.text.strip
         | 
| 1733 | 
            -
                  assert_css '#footnotes .footnote# | 
| 1734 | 
            -
                  assert_xpath '//div[@id="footnotes"]/div[@id=" | 
| 1735 | 
            -
                  text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id=" | 
| 1103 | 
            +
                  assert_css '#footnotes .footnote#_footnotedef_2', output, 1
         | 
| 1104 | 
            +
                  assert_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_2"]/a[@href="#_footnoteref_2"][text()="2"]', output, 1
         | 
| 1105 | 
            +
                  text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_2"]/text()', output
         | 
| 1736 1106 | 
             
                  assert_equal '. Second footnote.', text.text.strip
         | 
| 1737 1107 | 
             
                end
         | 
| 1738 1108 |  | 
| @@ -1744,9 +1114,9 @@ Text that has supporting information{empty}footnote:[An example footnote.]. | |
| 1744 1114 | 
             
                  output = render_embedded_string input
         | 
| 1745 1115 | 
             
                  assert_css '#footnotes', output, 1
         | 
| 1746 1116 | 
             
                  assert_css '#footnotes .footnote', output, 1
         | 
| 1747 | 
            -
                  assert_css '#footnotes .footnote# | 
| 1748 | 
            -
                  assert_xpath '/div[@id="footnotes"]/div[@id=" | 
| 1749 | 
            -
                  text = xmlnodes_at_xpath '/div[@id="footnotes"]/div[@id=" | 
| 1117 | 
            +
                  assert_css '#footnotes .footnote#_footnotedef_1', output, 1
         | 
| 1118 | 
            +
                  assert_xpath '/div[@id="footnotes"]/div[@id="_footnotedef_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
         | 
| 1119 | 
            +
                  text = xmlnodes_at_xpath '/div[@id="footnotes"]/div[@id="_footnotedef_1"]/text()', output
         | 
| 1750 1120 | 
             
                  assert_equal '. An example footnote.', text.text.strip
         | 
| 1751 1121 | 
             
                end
         | 
| 1752 1122 |  | 
| @@ -1776,12 +1146,29 @@ content{blank}footnote:[commentary] | |
| 1776 1146 |  | 
| 1777 1147 | 
             
                  doc = document_from_string input
         | 
| 1778 1148 | 
             
                  refute_nil doc.catalog
         | 
| 1779 | 
            -
                  assert_equal [:footnotes, :ids, :images, :includes, :indexterms, :links, :refs].to_set, doc.catalog.keys.to_set
         | 
| 1149 | 
            +
                  assert_equal [:footnotes, :ids, :images, :includes, :indexterms, :links, :refs, :callouts].to_set, doc.catalog.keys.to_set
         | 
| 1780 1150 | 
             
                  assert_same doc.catalog, doc.references
         | 
| 1781 1151 | 
             
                  assert_same doc.catalog[:footnotes], doc.references[:footnotes]
         | 
| 1782 1152 | 
             
                  assert_same doc.catalog[:ids], doc.references[:ids]
         | 
| 1783 1153 | 
             
                  assert_equal 'Section A', doc.references[:ids]['_section_a']
         | 
| 1784 1154 | 
             
                end
         | 
| 1155 | 
            +
             | 
| 1156 | 
            +
                test 'should catalog assets inside nested document' do
         | 
| 1157 | 
            +
                  input = <<-EOS
         | 
| 1158 | 
            +
            image::outer.png[]
         | 
| 1159 | 
            +
             | 
| 1160 | 
            +
            |===
         | 
| 1161 | 
            +
            a|
         | 
| 1162 | 
            +
            image::inner.png[]
         | 
| 1163 | 
            +
            |===
         | 
| 1164 | 
            +
                  EOS
         | 
| 1165 | 
            +
             | 
| 1166 | 
            +
                  doc = document_from_string input, :catalog_assets => true
         | 
| 1167 | 
            +
                  images = doc.catalog[:images]
         | 
| 1168 | 
            +
                  refute_empty images
         | 
| 1169 | 
            +
                  assert_equal 2, images.size
         | 
| 1170 | 
            +
                  assert_equal images, ['outer.png', 'inner.png']
         | 
| 1171 | 
            +
                end
         | 
| 1785 1172 | 
             
              end
         | 
| 1786 1173 |  | 
| 1787 1174 | 
             
              context 'Backends and Doctypes' do
         | 
| @@ -1861,6 +1248,7 @@ content | |
| 1861 1248 | 
             
            Author Name
         | 
| 1862 1249 | 
             
            v1.0, 2001-01-01
         | 
| 1863 1250 | 
             
            :icons:
         | 
| 1251 | 
            +
            :favicon:
         | 
| 1864 1252 |  | 
| 1865 1253 | 
             
            image:tiger.png[]
         | 
| 1866 1254 |  | 
| @@ -2057,6 +1445,8 @@ section body | |
| 2057 1445 | 
             
                test 'docbook5 backend doctype manpage' do
         | 
| 2058 1446 | 
             
                  input = <<-EOS
         | 
| 2059 1447 | 
             
            = asciidoctor(1)
         | 
| 1448 | 
            +
            :mansource: Asciidoctor
         | 
| 1449 | 
            +
            :manmanual: Asciidoctor Manual
         | 
| 2060 1450 |  | 
| 2061 1451 | 
             
            == NAME
         | 
| 2062 1452 |  | 
| @@ -2079,6 +1469,8 @@ section body | |
| 2079 1469 | 
             
                  assert_xpath '/xmlns:refentry/xmlns:info/xmlns:title[text() = "asciidoctor(1)"]', result, 1
         | 
| 2080 1470 | 
             
                  assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:refentrytitle[text() = "asciidoctor"]', result, 1
         | 
| 2081 1471 | 
             
                  assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:manvolnum[text() = "1"]', result, 1
         | 
| 1472 | 
            +
                  assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="source"][text() = "Asciidoctor"]', result, 1
         | 
| 1473 | 
            +
                  assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="manual"][text() = "Asciidoctor Manual"]', result, 1
         | 
| 2082 1474 | 
             
                  assert_xpath '/xmlns:refentry/xmlns:refnamediv/xmlns:refname[text() = "asciidoctor"]', result, 1
         | 
| 2083 1475 | 
             
                  assert_xpath '/xmlns:refentry/xmlns:refnamediv/xmlns:refpurpose[text() = "Process text"]', result, 1
         | 
| 2084 1476 | 
             
                  assert_xpath '/xmlns:refentry/xmlns:refsynopsisdiv', result, 1
         | 
| @@ -2093,6 +1485,23 @@ section body | |
| 2093 1485 | 
             
                  assert_equal '_first_section', id_attr.value
         | 
| 2094 1486 | 
             
                end
         | 
| 2095 1487 |  | 
| 1488 | 
            +
                test 'should output non-breaking space for source and manual in docbook5 manpage output if absent from source' do
         | 
| 1489 | 
            +
                  input = <<-EOS
         | 
| 1490 | 
            +
            = asciidoctor(1)
         | 
| 1491 | 
            +
             | 
| 1492 | 
            +
            == NAME
         | 
| 1493 | 
            +
             | 
| 1494 | 
            +
            asciidoctor - Process text
         | 
| 1495 | 
            +
             | 
| 1496 | 
            +
            == SYNOPSIS
         | 
| 1497 | 
            +
             | 
| 1498 | 
            +
            some text
         | 
| 1499 | 
            +
                  EOS
         | 
| 1500 | 
            +
                  result = render_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5', 'doctype' => 'manpage'})
         | 
| 1501 | 
            +
                  assert_xpath %(/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="source"][text() = "#{decode_char 160}"]), result, 1
         | 
| 1502 | 
            +
                  assert_xpath %(/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="manual"][text() = "#{decode_char 160}"]), result, 1
         | 
| 1503 | 
            +
                end
         | 
| 1504 | 
            +
             | 
| 2096 1505 | 
             
                test 'docbook5 backend doctype book' do
         | 
| 2097 1506 | 
             
                  input = <<-EOS
         | 
| 2098 1507 | 
             
            = Title
         | 
| @@ -2122,6 +1531,30 @@ chapter body | |
| 2122 1531 | 
             
                  assert_equal '_first_chapter', id_attr.value
         | 
| 2123 1532 | 
             
                end
         | 
| 2124 1533 |  | 
| 1534 | 
            +
                test 'adds refname to DocBook output for each name defined in NAME section of manpage' do
         | 
| 1535 | 
            +
                  input = <<-EOS
         | 
| 1536 | 
            +
            = eve(1)
         | 
| 1537 | 
            +
            Andrew Stanton
         | 
| 1538 | 
            +
            v1.0.0
         | 
| 1539 | 
            +
            :doctype: manpage
         | 
| 1540 | 
            +
            :manmanual: EVE
         | 
| 1541 | 
            +
            :mansource: EVE
         | 
| 1542 | 
            +
             | 
| 1543 | 
            +
            == NAME
         | 
| 1544 | 
            +
             | 
| 1545 | 
            +
            eve, islifeform - analyzes an image to determine if it's a picture of a life form
         | 
| 1546 | 
            +
             | 
| 1547 | 
            +
            == SYNOPSIS
         | 
| 1548 | 
            +
             | 
| 1549 | 
            +
            *eve* ['OPTION']... 'FILE'...
         | 
| 1550 | 
            +
                  EOS
         | 
| 1551 | 
            +
             | 
| 1552 | 
            +
                  result = render_string input, :backend => 'docbook5'
         | 
| 1553 | 
            +
                  assert_xpath '/refentry/refnamediv/refname', result, 2
         | 
| 1554 | 
            +
                  assert_xpath '(/refentry/refnamediv/refname)[1][text()="eve"]', result, 1
         | 
| 1555 | 
            +
                  assert_xpath '(/refentry/refnamediv/refname)[2][text()="islifeform"]', result, 1
         | 
| 1556 | 
            +
                end
         | 
| 1557 | 
            +
             | 
| 2125 1558 | 
             
                test 'adds a front and back cover image to DocBook 5 when doctype is book' do
         | 
| 2126 1559 | 
             
                  input = <<-EOS
         | 
| 2127 1560 | 
             
            = Title
         | 
| @@ -2214,24 +1647,24 @@ preamble | |
| 2214 1647 | 
             
            asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
         | 
| 2215 1648 | 
             
                  EOS
         | 
| 2216 1649 |  | 
| 2217 | 
            -
             | 
| 2218 | 
            -
             | 
| 2219 | 
            -
             | 
| 1650 | 
            +
                  doc = document_from_string input
         | 
| 1651 | 
            +
                  assert_equal 'asciidoctor', doc.attr('mantitle')
         | 
| 1652 | 
            +
                  assert_equal '1', doc.attr('manvolnum')
         | 
| 2220 1653 | 
             
                end
         | 
| 2221 1654 |  | 
| 2222 1655 | 
             
                test 'should perform attribute substitution on mantitle in manpage doctype' do
         | 
| 2223 1656 | 
             
                  input = <<-EOS
         | 
| 2224 1657 | 
             
            = {app}(1)
         | 
| 2225 1658 | 
             
            :doctype: manpage
         | 
| 2226 | 
            -
            :app:  | 
| 1659 | 
            +
            :app: Asciidoctor
         | 
| 2227 1660 |  | 
| 2228 1661 | 
             
            == NAME
         | 
| 2229 1662 |  | 
| 2230 1663 | 
             
            asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
         | 
| 2231 1664 | 
             
                  EOS
         | 
| 2232 1665 |  | 
| 2233 | 
            -
             | 
| 2234 | 
            -
             | 
| 1666 | 
            +
                  doc = document_from_string input
         | 
| 1667 | 
            +
                  assert_equal 'asciidoctor', doc.attr('mantitle')
         | 
| 2235 1668 | 
             
                end
         | 
| 2236 1669 |  | 
| 2237 1670 | 
             
                test 'should consume name section as manname and manpurpose for manpage doctype' do
         | 
| @@ -2244,10 +1677,11 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 2244 1677 | 
             
            asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
         | 
| 2245 1678 | 
             
                  EOS
         | 
| 2246 1679 |  | 
| 2247 | 
            -
             | 
| 2248 | 
            -
             | 
| 2249 | 
            -
             | 
| 2250 | 
            -
             | 
| 1680 | 
            +
                  doc = document_from_string input
         | 
| 1681 | 
            +
                  assert_equal 'asciidoctor', doc.attr('manname')
         | 
| 1682 | 
            +
                  assert_equal 'converts AsciiDoc source files to HTML, DocBook and other formats', doc.attr('manpurpose')
         | 
| 1683 | 
            +
                  assert_equal '_name', doc.attr('manname-id')
         | 
| 1684 | 
            +
                  assert_equal 0, doc.blocks.size
         | 
| 2251 1685 | 
             
                end
         | 
| 2252 1686 |  | 
| 2253 1687 | 
             
                test 'should set docname and outfilesuffix from manname and manvolnum for manpage backend and doctype' do
         | 
| @@ -2260,9 +1694,9 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 2260 1694 | 
             
            asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
         | 
| 2261 1695 | 
             
                  EOS
         | 
| 2262 1696 |  | 
| 2263 | 
            -
             | 
| 2264 | 
            -
             | 
| 2265 | 
            -
             | 
| 1697 | 
            +
                  doc = document_from_string input, :backend => 'manpage'
         | 
| 1698 | 
            +
                  assert_equal 'asciidoctor', doc.attributes['docname']
         | 
| 1699 | 
            +
                  assert_equal '.1', doc.attributes['outfilesuffix']
         | 
| 2266 1700 | 
             
                end
         | 
| 2267 1701 |  | 
| 2268 1702 | 
             
                test 'should mark synopsis as special section in manpage doctype' do
         | 
| @@ -2279,12 +1713,12 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 2279 1713 | 
             
            *asciidoctor* ['OPTION']... 'FILE'..
         | 
| 2280 1714 | 
             
                  EOS
         | 
| 2281 1715 |  | 
| 2282 | 
            -
             | 
| 2283 | 
            -
             | 
| 2284 | 
            -
             | 
| 2285 | 
            -
             | 
| 2286 | 
            -
             | 
| 2287 | 
            -
             | 
| 1716 | 
            +
                  doc = document_from_string input
         | 
| 1717 | 
            +
                  synopsis_section = doc.blocks.first
         | 
| 1718 | 
            +
                  refute_nil synopsis_section
         | 
| 1719 | 
            +
                  assert_equal :section, synopsis_section.context
         | 
| 1720 | 
            +
                  assert synopsis_section.special
         | 
| 1721 | 
            +
                  assert_equal 'synopsis', synopsis_section.sectname
         | 
| 2288 1722 | 
             
                end
         | 
| 2289 1723 |  | 
| 2290 1724 | 
             
                test 'should output special header block in HTML for manpage doctype' do
         | 
| @@ -2305,6 +1739,7 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 2305 1739 | 
             
                  assert_css 'body.manpage', output, 1
         | 
| 2306 1740 | 
             
                  assert_xpath '//body/*[@id="header"]/h1[text()="asciidoctor(1) Manual Page"]', output, 1
         | 
| 2307 1741 | 
             
                  assert_xpath '//body/*[@id="header"]/h1/following-sibling::h2[text()="NAME"]', output, 1
         | 
| 1742 | 
            +
                  assert_xpath '//h2[@id="_name"][text()="NAME"]', output, 1
         | 
| 2308 1743 | 
             
                  assert_xpath '//h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]', output, 1
         | 
| 2309 1744 | 
             
                  assert_xpath '//h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]/p[text()="asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats"]', output, 1
         | 
| 2310 1745 | 
             
                  assert_xpath '//*[@id="content"]/*[@class="sect1"]/h2[text()="SYNOPSIS"]', output, 1
         | 
| @@ -2328,6 +1763,7 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 2328 1763 | 
             
                  output = render_embedded_string input
         | 
| 2329 1764 | 
             
                  assert_xpath '/h1[text()="asciidoctor(1) Manual Page"]', output, 1
         | 
| 2330 1765 | 
             
                  assert_xpath '/h1/following-sibling::h2[text()="NAME"]', output, 1
         | 
| 1766 | 
            +
                  assert_xpath '/h2[@id="_name"][text()="NAME"]', output, 1
         | 
| 2331 1767 | 
             
                  assert_xpath '/h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]', output, 1
         | 
| 2332 1768 | 
             
                  assert_xpath '/h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]/p[text()="asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats"]', output, 1
         | 
| 2333 1769 | 
             
                end
         | 
| @@ -2342,18 +1778,23 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 2342 1778 |  | 
| 2343 1779 | 
             
                test 'keeps naughty absolute paths from getting outside' do
         | 
| 2344 1780 | 
             
                  naughty_path = "#{disk_root}etc/passwd"
         | 
| 2345 | 
            -
                   | 
| 2346 | 
            -
             | 
| 2347 | 
            -
             | 
| 2348 | 
            -
             | 
| 1781 | 
            +
                  using_memory_logger do |logger|
         | 
| 1782 | 
            +
                    doc = empty_document
         | 
| 1783 | 
            +
                    secure_path = doc.normalize_asset_path naughty_path
         | 
| 1784 | 
            +
                    refute_equal naughty_path, secure_path
         | 
| 1785 | 
            +
                    assert_equal (::File.join doc.base_dir, 'etc/passwd'), secure_path
         | 
| 1786 | 
            +
                    assert_message logger, :WARN, 'path is outside of jail; recovering automatically'
         | 
| 1787 | 
            +
                  end
         | 
| 2349 1788 | 
             
                end
         | 
| 2350 1789 |  | 
| 2351 1790 | 
             
                test 'keeps naughty relative paths from getting outside' do
         | 
| 2352 1791 | 
             
                  naughty_path = 'safe/ok/../../../../../etc/passwd'
         | 
| 2353 | 
            -
                   | 
| 2354 | 
            -
             | 
| 2355 | 
            -
             | 
| 2356 | 
            -
             | 
| 1792 | 
            +
                  using_memory_logger do
         | 
| 1793 | 
            +
                    doc = empty_document
         | 
| 1794 | 
            +
                    secure_path = doc.normalize_asset_path naughty_path
         | 
| 1795 | 
            +
                    refute_equal naughty_path, secure_path
         | 
| 1796 | 
            +
                    assert_match(/^#{doc.base_dir}/, secure_path)
         | 
| 1797 | 
            +
                  end
         | 
| 2357 1798 | 
             
                end
         | 
| 2358 1799 |  | 
| 2359 1800 | 
             
                test 'should raise an exception when a converter cannot be resolved before conversion' do
         |