asciidoctor 0.1.4 → 1.5.0
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 +209 -25
- data/{LICENSE → LICENSE.adoc} +4 -3
- data/README.adoc +392 -395
- data/Rakefile +94 -137
- data/benchmark/benchmark.rb +127 -0
- data/benchmark/sample-data/mdbasics.adoc +334 -0
- data/bin/asciidoctor +5 -8
- data/bin/asciidoctor-safe +4 -8
- data/compat/asciidoc.conf +78 -11
- data/compat/font-awesome-3-compat.css +397 -0
- data/data/stylesheets/asciidoctor-default.css +399 -0
- data/data/stylesheets/coderay-asciidoctor.css +89 -0
- data/features/open_block.feature +92 -0
- data/features/pass_block.feature +66 -0
- data/features/step_definitions.rb +42 -0
- data/features/text_formatting.feature +55 -0
- data/features/xref.feature +116 -0
- data/lib/asciidoctor.rb +1155 -605
- data/lib/asciidoctor/abstract_block.rb +157 -71
- data/lib/asciidoctor/abstract_node.rb +150 -93
- data/lib/asciidoctor/attribute_list.rb +85 -90
- data/lib/asciidoctor/block.rb +51 -24
- data/lib/asciidoctor/callouts.rb +4 -7
- data/lib/asciidoctor/cli.rb +3 -0
- data/lib/asciidoctor/cli/invoker.rb +86 -76
- data/lib/asciidoctor/cli/options.rb +111 -61
- data/lib/asciidoctor/converter.rb +232 -0
- data/lib/asciidoctor/converter/base.rb +58 -0
- data/lib/asciidoctor/converter/composite.rb +66 -0
- data/lib/asciidoctor/converter/docbook45.rb +94 -0
- data/lib/asciidoctor/converter/docbook5.rb +684 -0
- data/lib/asciidoctor/converter/factory.rb +225 -0
- data/lib/asciidoctor/converter/html5.rb +1081 -0
- data/lib/asciidoctor/converter/template.rb +296 -0
- data/lib/asciidoctor/core_ext.rb +7 -0
- data/lib/asciidoctor/core_ext/object/nil_or_empty.rb +23 -0
- data/lib/asciidoctor/core_ext/string/chr.rb +6 -0
- data/lib/asciidoctor/core_ext/symbol/length.rb +6 -0
- data/lib/asciidoctor/document.rb +590 -304
- data/lib/asciidoctor/extensions.rb +1100 -308
- data/lib/asciidoctor/helpers.rb +109 -46
- data/lib/asciidoctor/inline.rb +16 -9
- data/lib/asciidoctor/list.rb +23 -15
- data/lib/asciidoctor/opal_ext.rb +4 -0
- data/lib/asciidoctor/opal_ext/comparable.rb +38 -0
- data/lib/asciidoctor/opal_ext/dir.rb +13 -0
- data/lib/asciidoctor/opal_ext/error.rb +2 -0
- data/lib/asciidoctor/opal_ext/file.rb +125 -0
- data/lib/asciidoctor/{lexer.rb → parser.rb} +646 -455
- data/lib/asciidoctor/path_resolver.rb +141 -77
- data/lib/asciidoctor/reader.rb +257 -187
- data/lib/asciidoctor/section.rb +12 -16
- data/lib/asciidoctor/stylesheets.rb +91 -0
- data/lib/asciidoctor/substitutors.rb +1548 -0
- data/lib/asciidoctor/table.rb +73 -57
- data/lib/asciidoctor/timings.rb +39 -0
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +22 -14
- data/man/asciidoctor.adoc +18 -10
- data/test/attributes_test.rb +314 -14
- data/test/blocks_test.rb +763 -118
- data/test/converter_test.rb +352 -0
- data/test/document_test.rb +518 -199
- data/test/extensions_test.rb +273 -103
- data/test/fixtures/asciidoc_index.txt +27 -13
- data/test/fixtures/basic-docinfo.xml +1 -1
- data/test/fixtures/chapter-a.adoc +3 -0
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
- data/test/fixtures/docinfo.xml +1 -1
- data/test/fixtures/include-file.asciidoc +2 -0
- data/test/fixtures/master.adoc +5 -0
- data/test/invoker_test.rb +173 -61
- data/test/links_test.rb +97 -21
- data/test/lists_test.rb +181 -22
- data/test/options_test.rb +86 -2
- data/test/paragraphs_test.rb +47 -5
- data/test/{lexer_test.rb → parser_test.rb} +128 -57
- data/test/paths_test.rb +36 -1
- data/test/preamble_test.rb +25 -17
- data/test/reader_test.rb +404 -249
- data/test/sections_test.rb +623 -58
- data/test/substitutions_test.rb +609 -132
- data/test/tables_test.rb +198 -24
- data/test/test_helper.rb +101 -31
- data/test/text_test.rb +88 -31
- metadata +160 -64
- data/Gemfile +0 -12
- data/Guardfile +0 -18
- data/asciidoctor.gemspec +0 -143
- data/lib/asciidoctor/backends/_stylesheets.rb +0 -466
- data/lib/asciidoctor/backends/base_template.rb +0 -114
- data/lib/asciidoctor/backends/docbook45.rb +0 -774
- data/lib/asciidoctor/backends/docbook5.rb +0 -103
- data/lib/asciidoctor/backends/html5.rb +0 -1214
- data/lib/asciidoctor/renderer.rb +0 -259
- data/lib/asciidoctor/substituters.rb +0 -1083
- data/test/fixtures/asciidoc.txt +0 -105
- data/test/fixtures/ascshort.txt +0 -32
- data/test/fixtures/list_elements.asciidoc +0 -10
- data/test/renderer_test.rb +0 -162
| @@ -0,0 +1,352 @@ | |
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
            unless defined? ASCIIDOCTOR_PROJECT_DIR
         | 
| 3 | 
            +
              $: << File.dirname(__FILE__); $:.uniq!
         | 
| 4 | 
            +
              require 'test_helper'
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
            require 'tilt' unless defined? ::Tilt
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            context 'Converter' do
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              context 'View options' do
         | 
| 11 | 
            +
                test 'should set Haml format to html5 for html5 backend' do
         | 
| 12 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'haml'), :template_cache => false
         | 
| 13 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 14 | 
            +
                  selected = doc.converter.find_converter('paragraph')
         | 
| 15 | 
            +
                  assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 16 | 
            +
                  assert selected.templates['paragraph'].is_a? Tilt::HamlTemplate
         | 
| 17 | 
            +
                  assert_equal :html5, selected.templates['paragraph'].options[:format]
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                test 'should set Haml format to xhtml for docbook backend' do
         | 
| 21 | 
            +
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'haml'), :template_cache => false
         | 
| 22 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 23 | 
            +
                  selected = doc.converter.find_converter('paragraph')
         | 
| 24 | 
            +
                  assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 25 | 
            +
                  assert selected.templates['paragraph'].is_a? Tilt::HamlTemplate
         | 
| 26 | 
            +
                  assert_equal :xhtml, selected.templates['paragraph'].options[:format]
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                test 'should set Slim format to html5 for html5 backend' do
         | 
| 30 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false
         | 
| 31 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 32 | 
            +
                  selected = doc.converter.find_converter('paragraph')
         | 
| 33 | 
            +
                  assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 34 | 
            +
                  assert selected.templates['paragraph'].is_a? Slim::Template
         | 
| 35 | 
            +
                  assert_equal :html5, selected.templates['paragraph'].options[:format]
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                test 'should set Slim format to nil for docbook backend' do
         | 
| 39 | 
            +
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false
         | 
| 40 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 41 | 
            +
                  selected = doc.converter.find_converter('paragraph')
         | 
| 42 | 
            +
                  assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 43 | 
            +
                  assert selected.templates['paragraph'].is_a? Slim::Template
         | 
| 44 | 
            +
                  assert_nil selected.templates['paragraph'].options[:format]
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                test 'should support custom template engine options for known engine' do
         | 
| 48 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false, :template_engine_options => { :slim => { :pretty => true } }
         | 
| 49 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 50 | 
            +
                  selected = doc.converter.find_converter('paragraph')
         | 
| 51 | 
            +
                  assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 52 | 
            +
                  assert selected.templates['paragraph'].is_a? Slim::Template
         | 
| 53 | 
            +
                  assert_equal true, selected.templates['paragraph'].options[:pretty]
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                test 'should support custom template engine options' do
         | 
| 57 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false, :template_engine_options => { :slim => { :pretty => true } }
         | 
| 58 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 59 | 
            +
                  selected = doc.converter.find_converter('paragraph')
         | 
| 60 | 
            +
                  assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 61 | 
            +
                  assert selected.templates['paragraph'].is_a? Slim::Template
         | 
| 62 | 
            +
                  assert_equal false, selected.templates['paragraph'].options[:sort_attrs]
         | 
| 63 | 
            +
                  assert_equal true, selected.templates['paragraph'].options[:pretty]
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              context 'Custom backends' do
         | 
| 68 | 
            +
                test 'should load Haml templates for default backend' do
         | 
| 69 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'haml'), :template_cache => false
         | 
| 70 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 71 | 
            +
                  ['paragraph', 'sidebar'].each do |node_name|
         | 
| 72 | 
            +
                    selected = doc.converter.find_converter node_name
         | 
| 73 | 
            +
                    assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 74 | 
            +
                    assert selected.templates[node_name].is_a? Tilt::HamlTemplate
         | 
| 75 | 
            +
                    assert_equal %(block_#{node_name}.html.haml), File.basename(selected.templates[node_name].file)
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                test 'should set outfilesuffix according to backend info' do
         | 
| 80 | 
            +
                  doc = Asciidoctor.load 'content'
         | 
| 81 | 
            +
                  doc.render
         | 
| 82 | 
            +
                  assert_equal '.html', doc.attributes['outfilesuffix']
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  doc = Asciidoctor.load 'content', :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'haml'), :template_cache => false
         | 
| 85 | 
            +
                  doc.render
         | 
| 86 | 
            +
                  assert_equal '.html', doc.attributes['outfilesuffix']
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                test 'should not override outfilesuffix attribute if locked' do
         | 
| 90 | 
            +
                  doc = Asciidoctor.load 'content', :attributes => {'outfilesuffix' => '.foo'}
         | 
| 91 | 
            +
                  doc.render
         | 
| 92 | 
            +
                  assert_equal '.foo', doc.attributes['outfilesuffix']
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                  doc = Asciidoctor.load 'content', :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'haml'), :template_cache => false, :attributes => {'outfilesuffix' => '.foo'}
         | 
| 95 | 
            +
                  doc.render
         | 
| 96 | 
            +
                  assert_equal '.foo', doc.attributes['outfilesuffix']
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                test 'should load Haml templates for docbook45 backend' do
         | 
| 100 | 
            +
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'haml'), :template_cache => false
         | 
| 101 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 102 | 
            +
                  ['paragraph'].each do |node_name|
         | 
| 103 | 
            +
                    selected = doc.converter.find_converter node_name
         | 
| 104 | 
            +
                    assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 105 | 
            +
                    assert selected.templates[node_name].is_a? Tilt::HamlTemplate
         | 
| 106 | 
            +
                    assert_equal %(block_#{node_name}.xml.haml), File.basename(selected.templates[node_name].file)
         | 
| 107 | 
            +
                  end
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                test 'should use Haml templates in place of built-in templates' do
         | 
| 111 | 
            +
                  input = <<-EOS
         | 
| 112 | 
            +
            = Document Title
         | 
| 113 | 
            +
            Author Name
         | 
| 114 | 
            +
             | 
| 115 | 
            +
            == Section One
         | 
| 116 | 
            +
             | 
| 117 | 
            +
            Sample paragraph
         | 
| 118 | 
            +
             | 
| 119 | 
            +
            .Related
         | 
| 120 | 
            +
            ****
         | 
| 121 | 
            +
            Sidebar content
         | 
| 122 | 
            +
            ****
         | 
| 123 | 
            +
                  EOS
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                  output = render_embedded_string input, :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'haml'), :template_cache => false
         | 
| 126 | 
            +
                  assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p', output, 1
         | 
| 127 | 
            +
                  assert_xpath '//aside', output, 1
         | 
| 128 | 
            +
                  assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p/following-sibling::aside', output, 1
         | 
| 129 | 
            +
                  assert_xpath '//aside/header/h1[text()="Related"]', output, 1
         | 
| 130 | 
            +
                  assert_xpath '//aside/header/following-sibling::p[text()="Sidebar content"]', output, 1
         | 
| 131 | 
            +
                end
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                test 'should use built-in global cache to cache templates' do
         | 
| 134 | 
            +
                  begin
         | 
| 135 | 
            +
                    # clear out any cache, just to be sure
         | 
| 136 | 
            +
                    Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                    template_dir = File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'haml')
         | 
| 139 | 
            +
                    doc = Asciidoctor::Document.new [], :template_dir => template_dir
         | 
| 140 | 
            +
                    doc.converter
         | 
| 141 | 
            +
                    caches = Asciidoctor::Converter::TemplateConverter.caches
         | 
| 142 | 
            +
                    if defined? ::ThreadSafe::Cache
         | 
| 143 | 
            +
                      assert caches[:templates].is_a?(::ThreadSafe::Cache)
         | 
| 144 | 
            +
                      assert !caches[:templates].empty?
         | 
| 145 | 
            +
                      paragraph_template_before = caches[:templates].values.find {|t| File.basename(t.file) == 'block_paragraph.html.haml' }
         | 
| 146 | 
            +
                      assert !paragraph_template_before.nil?
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                      # should use cache
         | 
| 149 | 
            +
                      doc = Asciidoctor::Document.new [], :template_dir => template_dir
         | 
| 150 | 
            +
                      template_converter = doc.converter.find_converter('paragraph')
         | 
| 151 | 
            +
                      paragraph_template_after = template_converter.templates['paragraph']
         | 
| 152 | 
            +
                      assert !paragraph_template_after.nil?
         | 
| 153 | 
            +
                      assert paragraph_template_before.eql?(paragraph_template_after)
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                      # should not use cache
         | 
| 156 | 
            +
                      doc = Asciidoctor::Document.new [], :template_dir => template_dir, :template_cache => false
         | 
| 157 | 
            +
                      template_converter = doc.converter.find_converter('paragraph')
         | 
| 158 | 
            +
                      paragraph_template_after = template_converter.templates['paragraph']
         | 
| 159 | 
            +
                      assert !paragraph_template_after.nil?
         | 
| 160 | 
            +
                      assert !paragraph_template_before.eql?(paragraph_template_after)
         | 
| 161 | 
            +
                    else
         | 
| 162 | 
            +
                      assert caches.empty?
         | 
| 163 | 
            +
                    end
         | 
| 164 | 
            +
                  ensure
         | 
| 165 | 
            +
                    # clean up
         | 
| 166 | 
            +
                    Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
         | 
| 167 | 
            +
                  end
         | 
| 168 | 
            +
                end
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                test 'should use custom cache to cache templates' do
         | 
| 171 | 
            +
                  template_dir = File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'haml')
         | 
| 172 | 
            +
                  Asciidoctor::PathResolver.new.system_path(File.join(template_dir, 'html5', 'block_paragraph.html.haml'), nil)
         | 
| 173 | 
            +
                  caches = { :scans => {}, :templates => {} }
         | 
| 174 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => template_dir, :template_cache => caches
         | 
| 175 | 
            +
                  doc.converter
         | 
| 176 | 
            +
                  assert !caches[:scans].empty?
         | 
| 177 | 
            +
                  assert !caches[:templates].empty?
         | 
| 178 | 
            +
                  paragraph_template = caches[:templates].values.find {|t| File.basename(t.file) == 'block_paragraph.html.haml' }
         | 
| 179 | 
            +
                  assert !paragraph_template.nil?
         | 
| 180 | 
            +
                  assert paragraph_template.is_a? ::Tilt::HamlTemplate
         | 
| 181 | 
            +
                end
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                test 'should be able to disable template cache' do
         | 
| 184 | 
            +
                  begin
         | 
| 185 | 
            +
                    # clear out any cache, just to be sure
         | 
| 186 | 
            +
                    Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                    doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'haml'),
         | 
| 189 | 
            +
                        :template_cache => false
         | 
| 190 | 
            +
                    doc.converter
         | 
| 191 | 
            +
                    caches = Asciidoctor::Converter::TemplateConverter.caches
         | 
| 192 | 
            +
                    assert caches.empty? || caches[:scans].empty?
         | 
| 193 | 
            +
                    assert caches.empty? || caches[:templates].empty?
         | 
| 194 | 
            +
                  ensure
         | 
| 195 | 
            +
                    # clean up
         | 
| 196 | 
            +
                    Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
         | 
| 197 | 
            +
                  end
         | 
| 198 | 
            +
                end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                test 'should load ERB templates using ERBTemplate if eruby is not set' do
         | 
| 201 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'erb'), :template_cache => false
         | 
| 202 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 203 | 
            +
                  ['paragraph'].each do |node_name|
         | 
| 204 | 
            +
                    selected = doc.converter.find_converter node_name
         | 
| 205 | 
            +
                    assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 206 | 
            +
                    template = selected.templates[node_name]
         | 
| 207 | 
            +
                    assert template.is_a? Tilt::ERBTemplate
         | 
| 208 | 
            +
                    assert !(template.is_a? Tilt::ErubisTemplate)
         | 
| 209 | 
            +
                    assert template.instance_variable_get('@engine').is_a? ::ERB
         | 
| 210 | 
            +
                    assert_equal %(block_#{node_name}.html.erb), File.basename(selected.templates[node_name].file)
         | 
| 211 | 
            +
                  end
         | 
| 212 | 
            +
                end
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                test 'should load ERB templates using ErubisTemplate if eruby is set to erubis' do
         | 
| 215 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'erb'), :template_cache => false, :eruby => 'erubis'
         | 
| 216 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 217 | 
            +
                  ['paragraph'].each do |node_name|
         | 
| 218 | 
            +
                    selected = doc.converter.find_converter node_name
         | 
| 219 | 
            +
                    assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 220 | 
            +
                    template = selected.templates[node_name]
         | 
| 221 | 
            +
                    assert template.is_a? Tilt::ERBTemplate
         | 
| 222 | 
            +
                    assert template.is_a? Tilt::ErubisTemplate
         | 
| 223 | 
            +
                    assert template.instance_variable_get('@engine').is_a? ::Erubis::FastEruby
         | 
| 224 | 
            +
                    assert_equal %(block_#{node_name}.html.erb), File.basename(selected.templates[node_name].file)
         | 
| 225 | 
            +
                  end
         | 
| 226 | 
            +
                end
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                test 'should load Slim templates for default backend' do
         | 
| 229 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false
         | 
| 230 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 231 | 
            +
                  ['paragraph', 'sidebar'].each do |node_name|
         | 
| 232 | 
            +
                    selected = doc.converter.find_converter node_name
         | 
| 233 | 
            +
                    assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 234 | 
            +
                    assert selected.templates[node_name].is_a? Slim::Template
         | 
| 235 | 
            +
                    assert_equal %(block_#{node_name}.html.slim), File.basename(selected.templates[node_name].file)
         | 
| 236 | 
            +
                  end
         | 
| 237 | 
            +
                end
         | 
| 238 | 
            +
             | 
| 239 | 
            +
                test 'should load Slim templates for docbook45 backend' do
         | 
| 240 | 
            +
                  doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false
         | 
| 241 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 242 | 
            +
                  ['paragraph'].each do |node_name|
         | 
| 243 | 
            +
                    selected = doc.converter.find_converter node_name
         | 
| 244 | 
            +
                    assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 245 | 
            +
                    assert selected.templates[node_name].is_a? Slim::Template
         | 
| 246 | 
            +
                    assert_equal %(block_#{node_name}.xml.slim), File.basename(selected.templates[node_name].file)
         | 
| 247 | 
            +
                  end
         | 
| 248 | 
            +
                end
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                test 'should use Slim templates in place of built-in templates' do
         | 
| 251 | 
            +
                  input = <<-EOS
         | 
| 252 | 
            +
            = Document Title
         | 
| 253 | 
            +
            Author Name
         | 
| 254 | 
            +
             | 
| 255 | 
            +
            == Section One
         | 
| 256 | 
            +
             | 
| 257 | 
            +
            Sample paragraph
         | 
| 258 | 
            +
             | 
| 259 | 
            +
            .Related
         | 
| 260 | 
            +
            ****
         | 
| 261 | 
            +
            Sidebar content
         | 
| 262 | 
            +
            ****
         | 
| 263 | 
            +
                  EOS
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                  output = render_embedded_string input, :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false
         | 
| 266 | 
            +
                  assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p', output, 1
         | 
| 267 | 
            +
                  assert_xpath '//aside', output, 1
         | 
| 268 | 
            +
                  assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p/following-sibling::aside', output, 1
         | 
| 269 | 
            +
                  assert_xpath '//aside/header/h1[text()="Related"]', output, 1
         | 
| 270 | 
            +
                  assert_xpath '//aside/header/following-sibling::p[text()="Sidebar content"]', output, 1
         | 
| 271 | 
            +
                end
         | 
| 272 | 
            +
             | 
| 273 | 
            +
                test 'should use custom converter if specified' do
         | 
| 274 | 
            +
                  input = <<-EOS
         | 
| 275 | 
            +
            = Document Title
         | 
| 276 | 
            +
             | 
| 277 | 
            +
            preamble
         | 
| 278 | 
            +
             | 
| 279 | 
            +
            == Section
         | 
| 280 | 
            +
             | 
| 281 | 
            +
            content
         | 
| 282 | 
            +
                  EOS
         | 
| 283 | 
            +
             | 
| 284 | 
            +
                  class CustomConverterA
         | 
| 285 | 
            +
                    def initialize backend, opts = {}
         | 
| 286 | 
            +
                    end
         | 
| 287 | 
            +
             | 
| 288 | 
            +
                    def convert node, name = nil
         | 
| 289 | 
            +
                      'document'
         | 
| 290 | 
            +
                    end
         | 
| 291 | 
            +
             | 
| 292 | 
            +
                    def self.converts? backend
         | 
| 293 | 
            +
                      true
         | 
| 294 | 
            +
                    end
         | 
| 295 | 
            +
                  end
         | 
| 296 | 
            +
             | 
| 297 | 
            +
                  output = render_string input, :converter => CustomConverterA
         | 
| 298 | 
            +
                  assert 'document', output
         | 
| 299 | 
            +
                end
         | 
| 300 | 
            +
             | 
| 301 | 
            +
                test 'should use converter registered for backend' do
         | 
| 302 | 
            +
                  input = <<-EOS
         | 
| 303 | 
            +
            content
         | 
| 304 | 
            +
                  EOS
         | 
| 305 | 
            +
             | 
| 306 | 
            +
                  begin
         | 
| 307 | 
            +
                    Asciidoctor::Converter::Factory.unregister_all 
         | 
| 308 | 
            +
             | 
| 309 | 
            +
                    class CustomConverterB
         | 
| 310 | 
            +
                      include Asciidoctor::Converter
         | 
| 311 | 
            +
                      register_for 'foobar'
         | 
| 312 | 
            +
                      def convert node, name = nil
         | 
| 313 | 
            +
                        'foobar content'
         | 
| 314 | 
            +
                      end
         | 
| 315 | 
            +
                    end
         | 
| 316 | 
            +
             | 
| 317 | 
            +
                    converters = Asciidoctor::Converter::Factory.converters
         | 
| 318 | 
            +
                    assert converters.size == 1
         | 
| 319 | 
            +
                    assert converters['foobar'] == CustomConverterB
         | 
| 320 | 
            +
                    output = render_string input, :backend => 'foobar'
         | 
| 321 | 
            +
                    assert 'foobar content', output
         | 
| 322 | 
            +
                  ensure
         | 
| 323 | 
            +
                    Asciidoctor::Converter::Factory.unregister_all 
         | 
| 324 | 
            +
                  end
         | 
| 325 | 
            +
                end
         | 
| 326 | 
            +
             | 
| 327 | 
            +
                test 'should fall back to catch all converter' do
         | 
| 328 | 
            +
                  input = <<-EOS
         | 
| 329 | 
            +
            content
         | 
| 330 | 
            +
                  EOS
         | 
| 331 | 
            +
             | 
| 332 | 
            +
                  begin
         | 
| 333 | 
            +
                    Asciidoctor::Converter::Factory.unregister_all 
         | 
| 334 | 
            +
             | 
| 335 | 
            +
                    class CustomConverterC
         | 
| 336 | 
            +
                      include Asciidoctor::Converter
         | 
| 337 | 
            +
                      register_for '*'
         | 
| 338 | 
            +
                      def convert node, name = nil
         | 
| 339 | 
            +
                        'foobaz content'
         | 
| 340 | 
            +
                      end
         | 
| 341 | 
            +
                    end
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                    converters = Asciidoctor::Converter::Factory.converters
         | 
| 344 | 
            +
                    assert converters['*'] == CustomConverterC
         | 
| 345 | 
            +
                    output = render_string input, :backend => 'foobaz'
         | 
| 346 | 
            +
                    assert 'foobaz content', output
         | 
| 347 | 
            +
                  ensure
         | 
| 348 | 
            +
                    Asciidoctor::Converter::Factory.unregister_all 
         | 
| 349 | 
            +
                  end
         | 
| 350 | 
            +
                end
         | 
| 351 | 
            +
              end
         | 
| 352 | 
            +
            end
         | 
    
        data/test/document_test.rb
    CHANGED
    
    | @@ -1,4 +1,10 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
            unless defined? ASCIIDOCTOR_PROJECT_DIR
         | 
| 3 | 
            +
              $: << File.dirname(__FILE__); $:.uniq!
         | 
| 4 | 
            +
              require 'test_helper'
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            BUILT_IN_ELEMENTS = %w(admonition audio colist dlist document embedded example floating_title image inline_anchor inline_break inline_button inline_callout inline_footnote inline_image inline_indexterm inline_kbd inline_menu inline_quoted listing literal stem olist open page_break paragraph pass preamble quote section sidebar table thematic_break toc ulist verse video)
         | 
| 2 8 |  | 
| 3 9 | 
             
            context 'Document' do
         | 
| 4 10 |  | 
| @@ -9,42 +15,46 @@ context 'Document' do | |
| 9 15 | 
             
                  assert_equal 'AsciiDoc Home Page', doc.name
         | 
| 10 16 | 
             
                  assert_equal 14, doc.blocks.size
         | 
| 11 17 | 
             
                  assert_equal :preamble, doc.blocks[0].context
         | 
| 12 | 
            -
                  assert doc.blocks[1]. | 
| 18 | 
            +
                  assert doc.blocks[1].context == :section
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  # verify compat-mode is set when atx-style doctitle is used
         | 
| 21 | 
            +
                  result = doc.blocks[0].convert
         | 
| 22 | 
            +
                  assert_xpath %q(//em[text()="Stuart Rackham"]), result, 1
         | 
| 13 23 | 
             
                end
         | 
| 14 24 | 
             
              end
         | 
| 15 25 |  | 
| 16 26 | 
             
              context 'Default settings' do
         | 
| 17 27 | 
             
                test 'safe mode level set to SECURE by default' do
         | 
| 18 | 
            -
                  doc =  | 
| 28 | 
            +
                  doc = empty_document
         | 
| 19 29 | 
             
                  assert_equal Asciidoctor::SafeMode::SECURE, doc.safe
         | 
| 20 30 | 
             
                end
         | 
| 21 31 |  | 
| 22 32 | 
             
                test 'safe mode level set using string' do
         | 
| 23 | 
            -
                  doc =  | 
| 33 | 
            +
                  doc = empty_document :safe => 'server'
         | 
| 24 34 | 
             
                  assert_equal Asciidoctor::SafeMode::SERVER, doc.safe
         | 
| 25 35 |  | 
| 26 | 
            -
                  doc =  | 
| 36 | 
            +
                  doc = empty_document :safe => 'foo'
         | 
| 27 37 | 
             
                  assert_equal Asciidoctor::SafeMode::SECURE, doc.safe
         | 
| 28 38 | 
             
                end
         | 
| 29 39 |  | 
| 30 40 | 
             
                test 'safe mode level set using symbol' do
         | 
| 31 | 
            -
                  doc =  | 
| 41 | 
            +
                  doc = empty_document :safe => :server
         | 
| 32 42 | 
             
                  assert_equal Asciidoctor::SafeMode::SERVER, doc.safe
         | 
| 33 43 |  | 
| 34 | 
            -
                  doc =  | 
| 44 | 
            +
                  doc = empty_document :safe => :foo
         | 
| 35 45 | 
             
                  assert_equal Asciidoctor::SafeMode::SECURE, doc.safe
         | 
| 36 46 | 
             
                end
         | 
| 37 47 |  | 
| 38 48 | 
             
                test 'safe mode level set using integer' do
         | 
| 39 | 
            -
                  doc =  | 
| 49 | 
            +
                  doc = empty_document :safe => 10
         | 
| 40 50 | 
             
                  assert_equal Asciidoctor::SafeMode::SERVER, doc.safe
         | 
| 41 51 |  | 
| 42 | 
            -
                  doc =  | 
| 52 | 
            +
                  doc = empty_document :safe => 100
         | 
| 43 53 | 
             
                  assert_equal 100, doc.safe
         | 
| 44 54 | 
             
                end
         | 
| 45 55 |  | 
| 46 56 | 
             
                test 'safe mode attributes are set on document' do
         | 
| 47 | 
            -
                  doc =  | 
| 57 | 
            +
                  doc = empty_document
         | 
| 48 58 | 
             
                  assert_equal Asciidoctor::SafeMode::SECURE, doc.attr('safe-mode-level')
         | 
| 49 59 | 
             
                  assert_equal 'secure', doc.attr('safe-mode-name')
         | 
| 50 60 | 
             
                  assert doc.attr?('safe-mode-secure')
         | 
| @@ -59,7 +69,7 @@ context 'Document' do | |
| 59 69 | 
             
                end
         | 
| 60 70 |  | 
| 61 71 | 
             
                test 'safe model level cannot be modified' do
         | 
| 62 | 
            -
                  doc =  | 
| 72 | 
            +
                  doc = empty_document
         | 
| 63 73 | 
             
                  begin
         | 
| 64 74 | 
             
                    doc.safe = Asciidoctor::SafeMode::UNSAFE
         | 
| 65 75 | 
             
                    flunk 'safe mode property of Asciidoctor::Document should not be writable!' 
         | 
| @@ -67,21 +77,30 @@ context 'Document' do | |
| 67 77 | 
             
                  end
         | 
| 68 78 | 
             
                end
         | 
| 69 79 |  | 
| 70 | 
            -
                test 'toc and  | 
| 71 | 
            -
                  doc =  | 
| 80 | 
            +
                test 'toc and sectnums should be enabled by default for DocBook backend' do
         | 
| 81 | 
            +
                  doc = empty_document :backend => 'docbook', :parse => true
         | 
| 72 82 | 
             
                  assert doc.attr?('toc')
         | 
| 73 | 
            -
                  assert doc.attr?(' | 
| 83 | 
            +
                  assert doc.attr?('sectnums')
         | 
| 74 84 | 
             
                end
         | 
| 75 85 |  | 
| 76 | 
            -
                test 'should be able to disable toc and  | 
| 86 | 
            +
                test 'should be able to disable toc and sectnums in document header for DocBook backend' do
         | 
| 77 87 | 
             
                  input = <<-EOS
         | 
| 78 88 | 
             
            = Document Title
         | 
| 79 89 | 
             
            :toc!:
         | 
| 80 | 
            -
            : | 
| 90 | 
            +
            :sectnums!:
         | 
| 81 91 | 
             
                  EOS
         | 
| 82 92 | 
             
                  doc = document_from_string input, :backend => 'docbook'
         | 
| 83 93 | 
             
                  assert !doc.attr?('toc')
         | 
| 84 | 
            -
                  assert !doc.attr?(' | 
| 94 | 
            +
                  assert !doc.attr?('sectnums')
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                test 'should be able to disable section numbering using numbered attribute in document header for DocBook backend' do
         | 
| 98 | 
            +
                  input = <<-EOS
         | 
| 99 | 
            +
            = Document Title
         | 
| 100 | 
            +
            :numbered!:
         | 
| 101 | 
            +
                  EOS
         | 
| 102 | 
            +
                  doc = document_from_string input, :backend => 'docbook'
         | 
| 103 | 
            +
                  assert !doc.attr?('sectnums')
         | 
| 85 104 | 
             
                end
         | 
| 86 105 | 
             
              end
         | 
| 87 106 |  | 
| @@ -143,12 +162,12 @@ preamble | |
| 143 162 |  | 
| 144 163 | 
             
                test 'should accept attributes as array' do
         | 
| 145 164 | 
             
            	  # NOTE there's a tab character before idseparator
         | 
| 146 | 
            -
                  doc = Asciidoctor.load('text', :attributes => %w(toc  | 
| 165 | 
            +
                  doc = Asciidoctor.load('text', :attributes => %w(toc sectnums   source-highlighter=coderay idprefix	idseparator=-))
         | 
| 147 166 | 
             
                  assert doc.attributes.is_a?(Hash)
         | 
| 148 167 | 
             
                  assert doc.attr?('toc')
         | 
| 149 168 | 
             
                  assert_equal '', doc.attr('toc')
         | 
| 150 | 
            -
                  assert doc.attr?(' | 
| 151 | 
            -
                  assert_equal '', doc.attr(' | 
| 169 | 
            +
                  assert doc.attr?('sectnums')
         | 
| 170 | 
            +
                  assert_equal '', doc.attr('sectnums')
         | 
| 152 171 | 
             
                  assert doc.attr?('source-highlighter')
         | 
| 153 172 | 
             
                  assert_equal 'coderay', doc.attr('source-highlighter')
         | 
| 154 173 | 
             
                  assert doc.attr?('idprefix')
         | 
| @@ -164,12 +183,12 @@ preamble | |
| 164 183 |  | 
| 165 184 | 
             
                test 'should accept attributes as string' do
         | 
| 166 185 | 
             
            	  # NOTE there's a tab character before idseparator
         | 
| 167 | 
            -
                  doc = Asciidoctor.load('text', :attributes => 'toc  | 
| 186 | 
            +
                  doc = Asciidoctor.load('text', :attributes => 'toc sectnums  source-highlighter=coderay idprefix	idseparator=-')
         | 
| 168 187 | 
             
                  assert doc.attributes.is_a?(Hash)
         | 
| 169 188 | 
             
                  assert doc.attr?('toc')
         | 
| 170 189 | 
             
                  assert_equal '', doc.attr('toc')
         | 
| 171 | 
            -
                  assert doc.attr?(' | 
| 172 | 
            -
                  assert_equal '', doc.attr(' | 
| 190 | 
            +
                  assert doc.attr?('sectnums')
         | 
| 191 | 
            +
                  assert_equal '', doc.attr('sectnums')
         | 
| 173 192 | 
             
                  assert doc.attr?('source-highlighter')
         | 
| 174 193 | 
             
                  assert_equal 'coderay', doc.attr('source-highlighter')
         | 
| 175 194 | 
             
                  assert doc.attr?('idprefix')
         | 
| @@ -219,13 +238,104 @@ preamble | |
| 219 238 | 
             
                  assert doc.attributes.is_a?(Hash)
         | 
| 220 239 | 
             
                  assert doc.attributes.has_key?('toc')
         | 
| 221 240 | 
             
                end
         | 
| 241 | 
            +
             | 
| 242 | 
            +
                test 'should not modify options argument' do
         | 
| 243 | 
            +
                  options = {
         | 
| 244 | 
            +
                    :safe => Asciidoctor::SafeMode::SAFE
         | 
| 245 | 
            +
                  }
         | 
| 246 | 
            +
                  options.freeze
         | 
| 247 | 
            +
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 248 | 
            +
                  begin
         | 
| 249 | 
            +
                    Asciidoctor.load_file sample_input_path, options
         | 
| 250 | 
            +
                  rescue
         | 
| 251 | 
            +
                    flunk %(options argument should not be modified)
         | 
| 252 | 
            +
                  end
         | 
| 253 | 
            +
                end
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                test 'should not modify attributes Hash argument' do
         | 
| 256 | 
            +
                  attributes = {}
         | 
| 257 | 
            +
                  attributes.freeze
         | 
| 258 | 
            +
                  options = {
         | 
| 259 | 
            +
                    :safe => Asciidoctor::SafeMode::SAFE,
         | 
| 260 | 
            +
                    :attributes => attributes
         | 
| 261 | 
            +
                  }
         | 
| 262 | 
            +
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 263 | 
            +
                  begin
         | 
| 264 | 
            +
                    Asciidoctor.load_file sample_input_path, options
         | 
| 265 | 
            +
                  rescue
         | 
| 266 | 
            +
                    flunk %(attributes argument should not be modified)
         | 
| 267 | 
            +
                  end
         | 
| 268 | 
            +
                end
         | 
| 269 | 
            +
             | 
| 270 | 
            +
                test 'should track file and line information with blocks if sourcemap option is set' do
         | 
| 271 | 
            +
                  doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :sourcemap => true
         | 
| 272 | 
            +
             | 
| 273 | 
            +
                  section_1 = doc.sections[0]
         | 
| 274 | 
            +
                  assert_equal 'Section A', section_1.title
         | 
| 275 | 
            +
                  refute_nil section_1.source_location
         | 
| 276 | 
            +
                  assert_equal 'sample.asciidoc', section_1.file
         | 
| 277 | 
            +
                  assert_equal 10, section_1.lineno
         | 
| 278 | 
            +
             | 
| 279 | 
            +
                  section_2 = doc.sections[1]
         | 
| 280 | 
            +
                  assert_equal 'Section B', section_2.title
         | 
| 281 | 
            +
                  refute_nil section_2.source_location
         | 
| 282 | 
            +
                  assert_equal 'sample.asciidoc', section_2.file
         | 
| 283 | 
            +
                  assert_equal 18, section_2.lineno
         | 
| 284 | 
            +
             | 
| 285 | 
            +
                  last_block = section_2.blocks[-1] 
         | 
| 286 | 
            +
                  assert_equal :ulist, last_block.context
         | 
| 287 | 
            +
                  refute_nil last_block.source_location
         | 
| 288 | 
            +
                  assert_equal 'sample.asciidoc', last_block.file
         | 
| 289 | 
            +
                  assert_equal 23, last_block.lineno
         | 
| 290 | 
            +
             | 
| 291 | 
            +
                  doc = Asciidoctor.load_file fixture_path('master.adoc'), :sourcemap => true, :safe => :safe
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                  section_1 = doc.sections[0]
         | 
| 294 | 
            +
                  assert_equal 'Chapter A', section_1.title
         | 
| 295 | 
            +
                  refute_nil section_1.source_location
         | 
| 296 | 
            +
                  assert_equal fixture_path('chapter-a.adoc'), section_1.file
         | 
| 297 | 
            +
                  assert_equal 1, section_1.lineno
         | 
| 298 | 
            +
                end
         | 
| 299 | 
            +
             | 
| 300 | 
            +
                test 'find_by should return Array of blocks that match criteria' do
         | 
| 301 | 
            +
                  input = <<-EOS
         | 
| 302 | 
            +
            = Document Title
         | 
| 303 | 
            +
             | 
| 304 | 
            +
            preamble
         | 
| 305 | 
            +
             | 
| 306 | 
            +
            == Section A
         | 
| 307 | 
            +
             | 
| 308 | 
            +
            paragraph
         | 
| 309 | 
            +
             | 
| 310 | 
            +
            --
         | 
| 311 | 
            +
            Exhibit A::
         | 
| 312 | 
            +
            +
         | 
| 313 | 
            +
            [#tiger.animal]
         | 
| 314 | 
            +
            image::tiger.png[Tiger]
         | 
| 315 | 
            +
            --
         | 
| 316 | 
            +
             | 
| 317 | 
            +
            image::cat.png[Cat]
         | 
| 318 | 
            +
             | 
| 319 | 
            +
            == Section B
         | 
| 320 | 
            +
             | 
| 321 | 
            +
            paragraph
         | 
| 322 | 
            +
                  EOS
         | 
| 323 | 
            +
             | 
| 324 | 
            +
                  doc = Asciidoctor.load input
         | 
| 325 | 
            +
                  result = doc.find_by :context => :image
         | 
| 326 | 
            +
                  assert_equal 2, result.size
         | 
| 327 | 
            +
                  assert_equal :image, result[0].context
         | 
| 328 | 
            +
                  assert_equal 'tiger.png', result[0].attr('target')
         | 
| 329 | 
            +
                  assert_equal :image, result[1].context
         | 
| 330 | 
            +
                  assert_equal 'cat.png', result[1].attr('target')
         | 
| 331 | 
            +
                end
         | 
| 222 332 | 
             
              end
         | 
| 223 333 |  | 
| 224 | 
            -
              context ' | 
| 225 | 
            -
                test 'should  | 
| 334 | 
            +
              context 'Convert APIs' do
         | 
| 335 | 
            +
                test 'should convert source document to string when to_file is false' do
         | 
| 226 336 | 
             
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 227 337 |  | 
| 228 | 
            -
                  output = Asciidoctor. | 
| 338 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
         | 
| 229 339 | 
             
                  assert !output.empty?
         | 
| 230 340 | 
             
                  assert_xpath '/html', output, 1
         | 
| 231 341 | 
             
                  assert_xpath '/html/head', output, 1
         | 
| @@ -236,19 +346,19 @@ preamble | |
| 236 346 |  | 
| 237 347 | 
             
                test 'should accept attributes as array' do
         | 
| 238 348 | 
             
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 239 | 
            -
                  output = Asciidoctor. | 
| 349 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :attributes => %w(sectnums idprefix idseparator=-), :to_file => false
         | 
| 240 350 | 
             
                  assert_css '#section-a', output, 1
         | 
| 241 351 | 
             
                end
         | 
| 242 352 |  | 
| 243 353 | 
             
                test 'should accept attributes as string' do
         | 
| 244 354 | 
             
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 245 | 
            -
                  output = Asciidoctor. | 
| 355 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :attributes => 'sectnums idprefix idseparator=-', :to_file => false
         | 
| 246 356 | 
             
                  assert_css '#section-a', output, 1
         | 
| 247 357 | 
             
                end
         | 
| 248 358 |  | 
| 249 359 | 
             
                test 'should link to default stylesheet by default when safe mode is SECURE or greater' do
         | 
| 250 360 | 
             
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 251 | 
            -
                  output = Asciidoctor. | 
| 361 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
         | 
| 252 362 | 
             
                  assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
         | 
| 253 363 | 
             
                end
         | 
| 254 364 |  | 
| @@ -267,7 +377,7 @@ text | |
| 267 377 | 
             
                  assert !styles.strip.empty?
         | 
| 268 378 | 
             
                end
         | 
| 269 379 |  | 
| 270 | 
            -
                test 'should link to default stylesheet by default if linkcss is unset in document' do
         | 
| 380 | 
            +
                test 'should link to default stylesheet by default even if linkcss is unset in document' do
         | 
| 271 381 | 
             
                  input = <<-EOS
         | 
| 272 382 | 
             
            = Document Title
         | 
| 273 383 | 
             
            :linkcss!:
         | 
| @@ -292,8 +402,8 @@ text | |
| 292 402 |  | 
| 293 403 | 
             
                test 'should embed default stylesheet if safe mode is less than secure and linkcss is unset' do
         | 
| 294 404 | 
             
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 295 | 
            -
                  output = Asciidoctor. | 
| 296 | 
            -
                      :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss!' => ''} | 
| 405 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false,
         | 
| 406 | 
            +
                      :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss!' => ''}
         | 
| 297 407 | 
             
                  assert_css 'html:root > head > style', output, 1
         | 
| 298 408 | 
             
                  stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
         | 
| 299 409 | 
             
                  styles = stylenode.first.content
         | 
| @@ -336,19 +446,19 @@ text | |
| 336 446 |  | 
| 337 447 | 
             
                test 'should resolve custom stylesheet to embed relative to stylesdir' do
         | 
| 338 448 | 
             
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 339 | 
            -
                  output = Asciidoctor. | 
| 340 | 
            -
                      :attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets', 'linkcss!' => ''} | 
| 449 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :safe => Asciidoctor::SafeMode::SAFE, :to_file => false,
         | 
| 450 | 
            +
                      :attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets', 'linkcss!' => ''}
         | 
| 341 451 | 
             
                  stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
         | 
| 342 452 | 
             
                  styles = stylenode.first.content
         | 
| 343 453 | 
             
                  assert !styles.nil?
         | 
| 344 454 | 
             
                  assert !styles.strip.empty?
         | 
| 345 455 | 
             
                end
         | 
| 346 456 |  | 
| 347 | 
            -
                test 'should  | 
| 457 | 
            +
                test 'should convert source file and write result to adjacent file by default' do
         | 
| 348 458 | 
             
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 349 459 | 
             
                  sample_output_path = fixture_path('sample.html')
         | 
| 350 460 | 
             
                  begin
         | 
| 351 | 
            -
                    Asciidoctor. | 
| 461 | 
            +
                    Asciidoctor.convert_file sample_input_path
         | 
| 352 462 | 
             
                    assert File.exist?(sample_output_path)
         | 
| 353 463 | 
             
                    output = File.read(sample_output_path)
         | 
| 354 464 | 
             
                    assert !output.empty?
         | 
| @@ -358,15 +468,15 @@ text | |
| 358 468 | 
             
                    assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
         | 
| 359 469 | 
             
                    assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
         | 
| 360 470 | 
             
                  ensure
         | 
| 361 | 
            -
                    FileUtils | 
| 471 | 
            +
                    FileUtils.rm(sample_output_path)
         | 
| 362 472 | 
             
                  end
         | 
| 363 473 | 
             
                end
         | 
| 364 474 |  | 
| 365 | 
            -
                test 'should  | 
| 475 | 
            +
                test 'should convert source file and write to specified file' do
         | 
| 366 476 | 
             
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 367 477 | 
             
                  sample_output_path = fixture_path('result.html')
         | 
| 368 478 | 
             
                  begin
         | 
| 369 | 
            -
                    Asciidoctor. | 
| 479 | 
            +
                    Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path
         | 
| 370 480 | 
             
                    assert File.exist?(sample_output_path)
         | 
| 371 481 | 
             
                    output = File.read(sample_output_path)
         | 
| 372 482 | 
             
                    assert !output.empty?
         | 
| @@ -376,16 +486,16 @@ text | |
| 376 486 | 
             
                    assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
         | 
| 377 487 | 
             
                    assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
         | 
| 378 488 | 
             
                  ensure
         | 
| 379 | 
            -
                    FileUtils | 
| 489 | 
            +
                    FileUtils.rm(sample_output_path)
         | 
| 380 490 | 
             
                  end
         | 
| 381 491 | 
             
                end
         | 
| 382 492 |  | 
| 383 | 
            -
                test 'should  | 
| 493 | 
            +
                test 'should convert source file and write to specified file in base_dir' do
         | 
| 384 494 | 
             
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 385 495 | 
             
                  sample_output_path = fixture_path('result.html')
         | 
| 386 496 | 
             
                  fixture_dir = fixture_path('')
         | 
| 387 497 | 
             
                  begin
         | 
| 388 | 
            -
                    Asciidoctor. | 
| 498 | 
            +
                    Asciidoctor.convert_file sample_input_path, :to_file => 'result.html', :base_dir => fixture_dir
         | 
| 389 499 | 
             
                    assert File.exist?(sample_output_path)
         | 
| 390 500 | 
             
                    output = File.read(sample_output_path)
         | 
| 391 501 | 
             
                    assert !output.empty?
         | 
| @@ -397,45 +507,43 @@ text | |
| 397 507 | 
             
                  rescue => e
         | 
| 398 508 | 
             
                    flunk e.message
         | 
| 399 509 | 
             
                  ensure
         | 
| 400 | 
            -
                    FileUtils | 
| 510 | 
            +
                    FileUtils.rm(sample_output_path, :force => true)
         | 
| 401 511 | 
             
                  end
         | 
| 402 512 | 
             
                end
         | 
| 403 513 |  | 
| 404 | 
            -
                test 'in_place option  | 
| 514 | 
            +
                test 'in_place option is ignored when to_file is specified' do
         | 
| 405 515 | 
             
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 406 516 | 
             
                  sample_output_path = fixture_path('result.html')
         | 
| 407 | 
            -
                   | 
| 408 | 
            -
                     | 
| 409 | 
            -
             | 
| 410 | 
            -
             | 
| 411 | 
            -
             | 
| 412 | 
            -
                    end
         | 
| 517 | 
            +
                  begin
         | 
| 518 | 
            +
                    Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path, :in_place => true
         | 
| 519 | 
            +
                    assert File.exist?(sample_output_path)
         | 
| 520 | 
            +
                  ensure
         | 
| 521 | 
            +
                    FileUtils.rm(sample_output_path) if File.exist? sample_output_path
         | 
| 413 522 | 
             
                  end
         | 
| 414 523 | 
             
                end
         | 
| 415 524 |  | 
| 416 | 
            -
                test 'in_place option  | 
| 525 | 
            +
                test 'in_place option is ignored when to_dir is specified' do
         | 
| 417 526 | 
             
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 418 | 
            -
                  sample_output_path = fixture_path(' | 
| 419 | 
            -
                   | 
| 420 | 
            -
                     | 
| 421 | 
            -
             | 
| 422 | 
            -
             | 
| 423 | 
            -
             | 
| 424 | 
            -
                    end
         | 
| 527 | 
            +
                  sample_output_path = fixture_path('sample.html')
         | 
| 528 | 
            +
                  begin
         | 
| 529 | 
            +
                    Asciidoctor.convert_file sample_input_path, :to_dir => File.dirname(sample_output_path), :in_place => true
         | 
| 530 | 
            +
                    assert File.exist?(sample_output_path)
         | 
| 531 | 
            +
                  ensure
         | 
| 532 | 
            +
                    FileUtils.rm(sample_output_path) if File.exist? sample_output_path
         | 
| 425 533 | 
             
                  end
         | 
| 426 534 | 
             
                end
         | 
| 427 535 |  | 
| 428 536 | 
             
                test 'output should be relative to to_dir option' do
         | 
| 429 537 | 
             
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 430 538 | 
             
                  output_dir = File.join(File.dirname(sample_input_path), 'test_output')
         | 
| 431 | 
            -
                  Dir.mkdir output_dir if !File. | 
| 539 | 
            +
                  Dir.mkdir output_dir if !File.exist? output_dir
         | 
| 432 540 | 
             
                  sample_output_path = File.join(output_dir, 'sample.html')
         | 
| 433 541 | 
             
                  begin
         | 
| 434 | 
            -
                    Asciidoctor. | 
| 435 | 
            -
                    assert File. | 
| 542 | 
            +
                    Asciidoctor.convert_file sample_input_path, :to_dir => output_dir
         | 
| 543 | 
            +
                    assert File.exist? sample_output_path
         | 
| 436 544 | 
             
                  ensure
         | 
| 437 | 
            -
                    FileUtils | 
| 438 | 
            -
                    FileUtils | 
| 545 | 
            +
                    FileUtils.rm(sample_output_path) if File.exist? sample_output_path
         | 
| 546 | 
            +
                    FileUtils.rmdir output_dir
         | 
| 439 547 | 
             
                  end
         | 
| 440 548 | 
             
                end
         | 
| 441 549 |  | 
| @@ -444,12 +552,21 @@ text | |
| 444 552 | 
             
                  output_dir = File.join(File.join(File.dirname(sample_input_path), 'test_output'), 'subdir')
         | 
| 445 553 | 
             
                  sample_output_path = File.join(output_dir, 'sample.html')
         | 
| 446 554 | 
             
                  begin
         | 
| 447 | 
            -
                    Asciidoctor. | 
| 448 | 
            -
                    assert File. | 
| 555 | 
            +
                    Asciidoctor.convert_file sample_input_path, :to_dir => output_dir, :mkdirs => true
         | 
| 556 | 
            +
                    assert File.exist? sample_output_path
         | 
| 449 557 | 
             
                  ensure
         | 
| 450 | 
            -
                    FileUtils | 
| 451 | 
            -
                    FileUtils | 
| 452 | 
            -
                    FileUtils | 
| 558 | 
            +
                    FileUtils.rm(sample_output_path) if File.exist? sample_output_path
         | 
| 559 | 
            +
                    FileUtils.rmdir output_dir
         | 
| 560 | 
            +
                    FileUtils.rmdir File.dirname(output_dir)
         | 
| 561 | 
            +
                  end
         | 
| 562 | 
            +
                end
         | 
| 563 | 
            +
             | 
| 564 | 
            +
                # TODO need similar test for when to_dir is specified
         | 
| 565 | 
            +
                test 'should raise exception if an attempt is made to overwrite input file' do
         | 
| 566 | 
            +
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 567 | 
            +
             | 
| 568 | 
            +
                  assert_raises IOError do
         | 
| 569 | 
            +
                    Asciidoctor.convert_file sample_input_path, :attributes => { 'outfilesuffix' => '.asciidoc' }
         | 
| 453 570 | 
             
                  end
         | 
| 454 571 | 
             
                end
         | 
| 455 572 |  | 
| @@ -458,14 +575,28 @@ text | |
| 458 575 | 
             
                  base_dir = File.dirname(sample_input_path)
         | 
| 459 576 | 
             
                  sample_rel_output_path = File.join('test_output', 'result.html')
         | 
| 460 577 | 
             
                  output_dir = File.dirname(File.join(base_dir, sample_rel_output_path))
         | 
| 461 | 
            -
                  Dir.mkdir output_dir if !File. | 
| 578 | 
            +
                  Dir.mkdir output_dir if !File.exist? output_dir
         | 
| 462 579 | 
             
                  sample_output_path = File.join(base_dir, sample_rel_output_path)
         | 
| 463 580 | 
             
                  begin
         | 
| 464 | 
            -
                    Asciidoctor. | 
| 465 | 
            -
                    assert File. | 
| 581 | 
            +
                    Asciidoctor.convert_file sample_input_path, :to_dir => base_dir, :to_file => sample_rel_output_path
         | 
| 582 | 
            +
                    assert File.exist? sample_output_path
         | 
| 466 583 | 
             
                  ensure
         | 
| 467 | 
            -
                    FileUtils | 
| 468 | 
            -
                    FileUtils | 
| 584 | 
            +
                    FileUtils.rm(sample_output_path) if File.exist? sample_output_path
         | 
| 585 | 
            +
                    FileUtils.rmdir output_dir
         | 
| 586 | 
            +
                  end
         | 
| 587 | 
            +
                end
         | 
| 588 | 
            +
             | 
| 589 | 
            +
                test 'should not modify options argument' do
         | 
| 590 | 
            +
                  options = {
         | 
| 591 | 
            +
                    :safe => Asciidoctor::SafeMode::SAFE,
         | 
| 592 | 
            +
                    :to_file => false
         | 
| 593 | 
            +
                  }
         | 
| 594 | 
            +
                  options.freeze
         | 
| 595 | 
            +
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 596 | 
            +
                  begin
         | 
| 597 | 
            +
                    Asciidoctor.convert_file sample_input_path, options
         | 
| 598 | 
            +
                  rescue
         | 
| 599 | 
            +
                    flunk %(options argument should not be modified)
         | 
| 469 600 | 
             
                  end
         | 
| 470 601 | 
             
                end
         | 
| 471 602 | 
             
              end
         | 
| @@ -474,20 +605,20 @@ text | |
| 474 605 | 
             
                test 'should include docinfo files for html backend' do
         | 
| 475 606 | 
             
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 476 607 |  | 
| 477 | 
            -
                  output = Asciidoctor. | 
| 478 | 
            -
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''} | 
| 608 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 609 | 
            +
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''}
         | 
| 479 610 | 
             
                  assert !output.empty?
         | 
| 480 611 | 
             
                  assert_css 'script[src="modernizr.js"]', output, 1
         | 
| 481 612 | 
             
                  assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
         | 
| 482 613 |  | 
| 483 | 
            -
                  output = Asciidoctor. | 
| 484 | 
            -
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''} | 
| 614 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 615 | 
            +
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''}
         | 
| 485 616 | 
             
                  assert !output.empty?
         | 
| 486 617 | 
             
                  assert_css 'script[src="modernizr.js"]', output, 0
         | 
| 487 618 | 
             
                  assert_css 'meta[http-equiv="imagetoolbar"]', output, 1
         | 
| 488 619 |  | 
| 489 | 
            -
                  output = Asciidoctor. | 
| 490 | 
            -
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''} | 
| 620 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 621 | 
            +
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''}
         | 
| 491 622 | 
             
                  assert !output.empty?
         | 
| 492 623 | 
             
                  assert_css 'script[src="modernizr.js"]', output, 1
         | 
| 493 624 | 
             
                  assert_css 'meta[http-equiv="imagetoolbar"]', output, 1
         | 
| @@ -496,24 +627,26 @@ text | |
| 496 627 | 
             
                test 'should include docinfo files for docbook backend' do
         | 
| 497 628 | 
             
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 498 629 |  | 
| 499 | 
            -
                  output = Asciidoctor. | 
| 500 | 
            -
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''} | 
| 630 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 631 | 
            +
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''}
         | 
| 501 632 | 
             
                  assert !output.empty?
         | 
| 502 633 | 
             
                  assert_css 'productname', output, 0
         | 
| 503 634 | 
             
                  assert_css 'copyright', output, 1
         | 
| 504 635 |  | 
| 505 | 
            -
                  output = Asciidoctor. | 
| 506 | 
            -
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''} | 
| 636 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 637 | 
            +
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''}
         | 
| 507 638 | 
             
                  assert !output.empty?
         | 
| 508 639 | 
             
                  assert_css 'productname', output, 1
         | 
| 640 | 
            +
                  assert_xpath '//xmlns:productname[text()="Asciidoctor™"]', output, 1
         | 
| 509 641 | 
             
                  assert_css 'edition', output, 1
         | 
| 510 642 | 
             
                  assert_xpath '//xmlns:edition[text()="1.0"]', output, 1 # verifies substitutions are performed
         | 
| 511 643 | 
             
                  assert_css 'copyright', output, 0
         | 
| 512 644 |  | 
| 513 | 
            -
                  output = Asciidoctor. | 
| 514 | 
            -
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''} | 
| 645 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 646 | 
            +
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''}
         | 
| 515 647 | 
             
                  assert !output.empty?
         | 
| 516 648 | 
             
                  assert_css 'productname', output, 1
         | 
| 649 | 
            +
                  assert_xpath '//xmlns:productname[text()="Asciidoctor™"]', output, 1
         | 
| 517 650 | 
             
                  assert_css 'edition', output, 1
         | 
| 518 651 | 
             
                  assert_xpath '//xmlns:edition[text()="1.0"]', output, 1 # verifies substitutions are performed
         | 
| 519 652 | 
             
                  assert_css 'copyright', output, 1
         | 
| @@ -522,20 +655,20 @@ text | |
| 522 655 | 
             
                test 'should include docinfo footer files for html backend' do
         | 
| 523 656 | 
             
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 524 657 |  | 
| 525 | 
            -
                  output = Asciidoctor. | 
| 526 | 
            -
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''} | 
| 658 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 659 | 
            +
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''}
         | 
| 527 660 | 
             
                  assert !output.empty?
         | 
| 528 661 | 
             
                  assert_css 'body script', output, 1
         | 
| 529 662 | 
             
                  assert_css 'a#top', output, 0
         | 
| 530 663 |  | 
| 531 | 
            -
                  output = Asciidoctor. | 
| 532 | 
            -
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''} | 
| 664 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 665 | 
            +
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''}
         | 
| 533 666 | 
             
                  assert !output.empty?
         | 
| 534 667 | 
             
                  assert_css 'body script', output, 0
         | 
| 535 668 | 
             
                  assert_css 'a#top', output, 1
         | 
| 536 669 |  | 
| 537 | 
            -
                  output = Asciidoctor. | 
| 538 | 
            -
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''} | 
| 670 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 671 | 
            +
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''}
         | 
| 539 672 | 
             
                  assert !output.empty?
         | 
| 540 673 | 
             
                  assert_css 'body script', output, 1
         | 
| 541 674 | 
             
                  assert_css 'a#top', output, 1
         | 
| @@ -544,38 +677,69 @@ text | |
| 544 677 | 
             
                test 'should include docinfo footer files for docbook backend' do
         | 
| 545 678 | 
             
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 546 679 |  | 
| 547 | 
            -
                  output = Asciidoctor. | 
| 548 | 
            -
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''} | 
| 680 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 681 | 
            +
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''}
         | 
| 549 682 | 
             
                  assert !output.empty?
         | 
| 550 683 | 
             
                  assert_css 'article > revhistory', output, 1
         | 
| 551 684 | 
             
                  assert_xpath '/xmlns:article/xmlns:revhistory/xmlns:revision/xmlns:revnumber[text()="1.0"]', output, 1 # verifies substitutions are performed
         | 
| 552 685 | 
             
                  assert_css 'glossary#_glossary', output, 0
         | 
| 553 686 |  | 
| 554 | 
            -
                  output = Asciidoctor. | 
| 555 | 
            -
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''} | 
| 687 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 688 | 
            +
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''}
         | 
| 556 689 | 
             
                  assert !output.empty?
         | 
| 557 690 | 
             
                  assert_css 'article > revhistory', output, 0
         | 
| 558 691 | 
             
                  assert_css 'glossary#_glossary', output, 1
         | 
| 559 692 |  | 
| 560 | 
            -
                  output = Asciidoctor. | 
| 561 | 
            -
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''} | 
| 693 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 694 | 
            +
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''}
         | 
| 562 695 | 
             
                  assert !output.empty?
         | 
| 563 696 | 
             
                  assert_css 'article > revhistory', output, 1
         | 
| 564 697 | 
             
                  assert_xpath '/xmlns:article/xmlns:revhistory/xmlns:revision/xmlns:revnumber[text()="1.0"]', output, 1 # verifies substitutions are performed
         | 
| 565 698 | 
             
                  assert_css 'glossary#_glossary', output, 1
         | 
| 566 699 | 
             
                end
         | 
| 567 700 |  | 
| 701 | 
            +
                # WARNING this test manipulates runtime settings; should probably be run in forked process
         | 
| 702 | 
            +
                test 'should force encoding of docinfo files to UTF-8' do
         | 
| 703 | 
            +
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 704 | 
            +
             | 
| 705 | 
            +
                  if RUBY_VERSION >= '1.9'
         | 
| 706 | 
            +
                    default_external_old = Encoding.default_external
         | 
| 707 | 
            +
                    force_encoding_old = Asciidoctor::FORCE_ENCODING
         | 
| 708 | 
            +
                    verbose_old = $VERBOSE
         | 
| 709 | 
            +
                  end
         | 
| 710 | 
            +
                  begin
         | 
| 711 | 
            +
                    if RUBY_VERSION >= '1.9'
         | 
| 712 | 
            +
                      $VERBOSE = nil # disable warnings since we have to modify constants
         | 
| 713 | 
            +
                      Encoding.default_external = 'US-ASCII'
         | 
| 714 | 
            +
                      Asciidoctor::FORCE_ENCODING = true
         | 
| 715 | 
            +
                    end
         | 
| 716 | 
            +
                    output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 717 | 
            +
                        :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''}
         | 
| 718 | 
            +
                    assert !output.empty?
         | 
| 719 | 
            +
                    assert_css 'productname', output, 1
         | 
| 720 | 
            +
                    assert_css 'edition', output, 1
         | 
| 721 | 
            +
                    assert_xpath '//xmlns:edition[text()="1.0"]', output, 1 # verifies substitutions are performed
         | 
| 722 | 
            +
                    assert_css 'copyright', output, 1
         | 
| 723 | 
            +
                  ensure
         | 
| 724 | 
            +
                    if RUBY_VERSION >= '1.9'
         | 
| 725 | 
            +
                      Encoding.default_external = default_external_old
         | 
| 726 | 
            +
                      Asciidoctor::FORCE_ENCODING = force_encoding_old
         | 
| 727 | 
            +
                      $VERBOSE = verbose_old
         | 
| 728 | 
            +
                    end
         | 
| 729 | 
            +
                  end
         | 
| 730 | 
            +
                end
         | 
| 731 | 
            +
             | 
| 568 732 | 
             
                test 'should not include docinfo files by default' do
         | 
| 569 733 | 
             
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 570 734 |  | 
| 571 | 
            -
                  output = Asciidoctor. | 
| 572 | 
            -
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER | 
| 735 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 736 | 
            +
                      :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER
         | 
| 573 737 | 
             
                  assert !output.empty?
         | 
| 574 738 | 
             
                  assert_css 'script[src="modernizr.js"]', output, 0
         | 
| 575 739 | 
             
                  assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
         | 
| 576 740 |  | 
| 577 | 
            -
                  output = Asciidoctor. | 
| 578 | 
            -
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER | 
| 741 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 742 | 
            +
                      :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER
         | 
| 579 743 | 
             
                  assert !output.empty?
         | 
| 580 744 | 
             
                  assert_css 'productname', output, 0
         | 
| 581 745 | 
             
                  assert_css 'copyright', output, 0
         | 
| @@ -584,93 +748,67 @@ text | |
| 584 748 | 
             
                test 'should not include docinfo files if safe mode is SECURE or greater' do
         | 
| 585 749 | 
             
                  sample_input_path = fixture_path('basic.asciidoc')
         | 
| 586 750 |  | 
| 587 | 
            -
                  output = Asciidoctor. | 
| 588 | 
            -
                      :header_footer => true, :attributes => {'docinfo2' => ''} | 
| 751 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 752 | 
            +
                      :header_footer => true, :attributes => {'docinfo2' => ''}
         | 
| 589 753 | 
             
                  assert !output.empty?
         | 
| 590 754 | 
             
                  assert_css 'script[src="modernizr.js"]', output, 0
         | 
| 591 755 | 
             
                  assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
         | 
| 592 756 |  | 
| 593 | 
            -
                  output = Asciidoctor. | 
| 594 | 
            -
                      :header_footer => true, :backend => 'docbook', :attributes => {'docinfo2' => ''} | 
| 757 | 
            +
                  output = Asciidoctor.convert_file sample_input_path, :to_file => false,
         | 
| 758 | 
            +
                      :header_footer => true, :backend => 'docbook', :attributes => {'docinfo2' => ''}
         | 
| 595 759 | 
             
                  assert !output.empty?
         | 
| 596 760 | 
             
                  assert_css 'productname', output, 0
         | 
| 597 761 | 
             
                  assert_css 'copyright', output, 0
         | 
| 598 762 | 
             
                end
         | 
| 599 763 | 
             
              end
         | 
| 600 764 |  | 
| 601 | 
            -
              context ' | 
| 765 | 
            +
              context 'MathJax' do
         | 
| 766 | 
            +
                test 'should add MathJax script to HTML head if stem attribute is set' do
         | 
| 767 | 
            +
                  output = render_string '', :attributes => {'stem' => ''}
         | 
| 768 | 
            +
                  assert_match('<script type="text/x-mathjax-config">', output)
         | 
| 769 | 
            +
                end
         | 
| 770 | 
            +
              end
         | 
| 771 | 
            +
             | 
| 772 | 
            +
              context 'Converter' do
         | 
| 602 773 | 
             
                test 'built-in HTML5 views are registered by default' do
         | 
| 603 774 | 
             
                  doc = document_from_string ''
         | 
| 604 775 | 
             
                  assert_equal 'html5', doc.attributes['backend']
         | 
| 605 776 | 
             
                  assert doc.attributes.has_key? 'backend-html5'
         | 
| 606 777 | 
             
                  assert_equal 'html', doc.attributes['basebackend']
         | 
| 607 778 | 
             
                  assert doc.attributes.has_key? 'basebackend-html'
         | 
| 608 | 
            -
                   | 
| 609 | 
            -
                  assert  | 
| 610 | 
            -
                   | 
| 611 | 
            -
             | 
| 612 | 
            -
                   | 
| 613 | 
            -
                  assert views.has_key? 'document'
         | 
| 614 | 
            -
                  assert Asciidoctor.const_defined?(:HTML5)
         | 
| 615 | 
            -
                  assert Asciidoctor::HTML5.const_defined?(:DocumentTemplate)
         | 
| 779 | 
            +
                  converter = doc.converter
         | 
| 780 | 
            +
                  assert converter.is_a? Asciidoctor::Converter::Html5Converter
         | 
| 781 | 
            +
                  BUILT_IN_ELEMENTS.each do |element|
         | 
| 782 | 
            +
                    assert converter.respond_to? element
         | 
| 783 | 
            +
                  end
         | 
| 616 784 | 
             
                end
         | 
| 617 785 |  | 
| 618 786 | 
             
                test 'built-in DocBook45 views are registered when backend is docbook45' do
         | 
| 619 787 | 
             
                  doc = document_from_string '', :attributes => {'backend' => 'docbook45'}
         | 
| 620 | 
            -
                   | 
| 788 | 
            +
                  converter = doc.converter
         | 
| 621 789 | 
             
                  assert_equal 'docbook45', doc.attributes['backend']
         | 
| 622 790 | 
             
                  assert doc.attributes.has_key? 'backend-docbook45'
         | 
| 623 791 | 
             
                  assert_equal 'docbook', doc.attributes['basebackend']
         | 
| 624 792 | 
             
                  assert doc.attributes.has_key? 'basebackend-docbook'
         | 
| 625 | 
            -
                   | 
| 626 | 
            -
                   | 
| 627 | 
            -
                   | 
| 628 | 
            -
             | 
| 629 | 
            -
                   | 
| 630 | 
            -
                  assert Asciidoctor.const_defined?(:DocBook45)
         | 
| 631 | 
            -
                  assert Asciidoctor::DocBook45.const_defined?(:DocumentTemplate)
         | 
| 793 | 
            +
                  converter = doc.converter
         | 
| 794 | 
            +
                  assert converter.is_a? Asciidoctor::Converter::DocBook45Converter
         | 
| 795 | 
            +
                  BUILT_IN_ELEMENTS.each do |element|
         | 
| 796 | 
            +
                    assert converter.respond_to? element
         | 
| 797 | 
            +
                  end
         | 
| 632 798 | 
             
                end
         | 
| 633 799 |  | 
| 634 800 | 
             
                test 'built-in DocBook5 views are registered when backend is docbook5' do
         | 
| 635 801 | 
             
                  doc = document_from_string '', :attributes => {'backend' => 'docbook5'}
         | 
| 636 | 
            -
                   | 
| 802 | 
            +
                  converter = doc.converter
         | 
| 637 803 | 
             
                  assert_equal 'docbook5', doc.attributes['backend']
         | 
| 638 804 | 
             
                  assert doc.attributes.has_key? 'backend-docbook5'
         | 
| 639 805 | 
             
                  assert_equal 'docbook', doc.attributes['basebackend']
         | 
| 640 806 | 
             
                  assert doc.attributes.has_key? 'basebackend-docbook'
         | 
| 641 | 
            -
                   | 
| 642 | 
            -
                   | 
| 643 | 
            -
                   | 
| 644 | 
            -
             | 
| 645 | 
            -
                   | 
| 646 | 
            -
                  assert Asciidoctor.const_defined?(:DocBook5)
         | 
| 647 | 
            -
                  assert Asciidoctor::DocBook5.const_defined?(:DocumentTemplate)
         | 
| 648 | 
            -
                end
         | 
| 649 | 
            -
             | 
| 650 | 
            -
                test 'eRuby implementation should default to ERB' do
         | 
| 651 | 
            -
                  # intentionally use built-in templates for this test
         | 
| 652 | 
            -
                  doc = Asciidoctor::Document.new [], :header_footer => true
         | 
| 653 | 
            -
                  renderer = doc.renderer
         | 
| 654 | 
            -
                  views = renderer.views
         | 
| 655 | 
            -
                  assert !views.nil?
         | 
| 656 | 
            -
                  assert views.has_key? 'document'
         | 
| 657 | 
            -
                  assert views['document'].is_a?(Asciidoctor::HTML5::DocumentTemplate)
         | 
| 658 | 
            -
                  assert_equal 'ERB', views['document'].eruby.to_s
         | 
| 659 | 
            -
                  assert_equal 'ERB', views['document'].template.class.to_s
         | 
| 660 | 
            -
                end
         | 
| 661 | 
            -
              
         | 
| 662 | 
            -
                test 'can set erubis as eRuby implementation' do
         | 
| 663 | 
            -
                  # intentionally use built-in templates for this test
         | 
| 664 | 
            -
                  doc = Asciidoctor::Document.new [], :eruby => 'erubis', :header_footer => true
         | 
| 665 | 
            -
                  assert $LOADED_FEATURES.detect {|p| p == 'erubis.rb' || p.end_with?('/erubis.rb') }.nil?
         | 
| 666 | 
            -
                  renderer = doc.renderer
         | 
| 667 | 
            -
                  assert $LOADED_FEATURES.detect {|p| p == 'erubis.rb' || p.end_with?('/erubis.rb') }
         | 
| 668 | 
            -
                  views = renderer.views
         | 
| 669 | 
            -
                  assert !views.nil?
         | 
| 670 | 
            -
                  assert views.has_key? 'document'
         | 
| 671 | 
            -
                  assert views['document'].is_a?(Asciidoctor::HTML5::DocumentTemplate)
         | 
| 672 | 
            -
                  assert_equal 'Erubis::FastEruby', views['document'].eruby.to_s
         | 
| 673 | 
            -
                  assert_equal 'Erubis::FastEruby', views['document'].template.class.to_s
         | 
| 807 | 
            +
                  converter = doc.converter
         | 
| 808 | 
            +
                  assert converter.is_a? Asciidoctor::Converter::DocBook5Converter
         | 
| 809 | 
            +
                  BUILT_IN_ELEMENTS.each do |element|
         | 
| 810 | 
            +
                    assert converter.respond_to? element
         | 
| 811 | 
            +
                  end
         | 
| 674 812 | 
             
                end
         | 
| 675 813 | 
             
              end
         | 
| 676 814 |  | 
| @@ -683,6 +821,22 @@ text | |
| 683 821 | 
             
                  assert_nil doc.header
         | 
| 684 822 | 
             
                end
         | 
| 685 823 |  | 
| 824 | 
            +
                test 'document with subtitle' do
         | 
| 825 | 
            +
                  input = <<-EOS
         | 
| 826 | 
            +
            = Main Title: *Subtitle*
         | 
| 827 | 
            +
            Author Name
         | 
| 828 | 
            +
             | 
| 829 | 
            +
            content
         | 
| 830 | 
            +
                  EOS
         | 
| 831 | 
            +
             | 
| 832 | 
            +
                  doc = document_from_string input
         | 
| 833 | 
            +
                  title = doc.doctitle :partition => true, :sanitize => true
         | 
| 834 | 
            +
                  assert title.subtitle?
         | 
| 835 | 
            +
                  assert title.sanitized?
         | 
| 836 | 
            +
                  assert_equal 'Main Title', title.main
         | 
| 837 | 
            +
                  assert_equal 'Subtitle', title.subtitle
         | 
| 838 | 
            +
                end
         | 
| 839 | 
            +
             | 
| 686 840 | 
             
                test 'document with doctitle defined as attribute entry' do
         | 
| 687 841 | 
             
                 input = <<-EOS
         | 
| 688 842 | 
             
            :doctitle: Document Title
         | 
| @@ -825,17 +979,71 @@ content | |
| 825 979 | 
             
            = AsciiDoc
         | 
| 826 980 | 
             
            Stuart Rackham <founder@asciidoc.org>
         | 
| 827 981 | 
             
            v8.6.8, 2012-07-12: See changelog.
         | 
| 982 | 
            +
            :description: AsciiDoc user guide
         | 
| 983 | 
            +
            :keywords: asciidoc,documentation
         | 
| 984 | 
            +
            :copyright: Stuart Rackham
         | 
| 828 985 |  | 
| 829 986 | 
             
            == Version 8.6.8
         | 
| 830 987 |  | 
| 831 988 | 
             
            more info...
         | 
| 832 989 | 
             
                  EOS
         | 
| 833 990 | 
             
                  output = render_string input
         | 
| 834 | 
            -
                  assert_xpath ' | 
| 835 | 
            -
                  assert_xpath ' | 
| 836 | 
            -
                  assert_xpath ' | 
| 837 | 
            -
                  assert_xpath ' | 
| 838 | 
            -
                  assert_xpath '//*[@id="header"]/span[@id=" | 
| 991 | 
            +
                  assert_xpath '//meta[@name="author"][@content="Stuart Rackham"]', output, 1
         | 
| 992 | 
            +
                  assert_xpath '//meta[@name="description"][@content="AsciiDoc user guide"]', output, 1
         | 
| 993 | 
            +
                  assert_xpath '//meta[@name="keywords"][@content="asciidoc,documentation"]', output, 1
         | 
| 994 | 
            +
                  assert_xpath '//meta[@name="copyright"][@content="Stuart Rackham"]', output, 1
         | 
| 995 | 
            +
                  assert_xpath '//*[@id="header"]/*[@class="details"]/span[@id="author"][text() = "Stuart Rackham"]', output, 1
         | 
| 996 | 
            +
                  assert_xpath '//*[@id="header"]/*[@class="details"]/span[@id="email"]/a[@href="mailto:founder@asciidoc.org"][text() = "founder@asciidoc.org"]', output, 1
         | 
| 997 | 
            +
                  assert_xpath '//*[@id="header"]/*[@class="details"]/span[@id="revnumber"][text() = "version 8.6.8,"]', output, 1
         | 
| 998 | 
            +
                  assert_xpath '//*[@id="header"]/*[@class="details"]/span[@id="revdate"][text() = "2012-07-12"]', output, 1
         | 
| 999 | 
            +
                  assert_xpath '//*[@id="header"]/*[@class="details"]/span[@id="revremark"][text() = "See changelog."]', output, 1
         | 
| 1000 | 
            +
                end
         | 
| 1001 | 
            +
             | 
| 1002 | 
            +
                test 'should include revision history if revdate and revnumber is set' do
         | 
| 1003 | 
            +
                  input = <<-EOS
         | 
| 1004 | 
            +
            = Document Title
         | 
| 1005 | 
            +
            Author Name
         | 
| 1006 | 
            +
            :revdate: 2011-11-11
         | 
| 1007 | 
            +
            :revnumber: 1.0
         | 
| 1008 | 
            +
             | 
| 1009 | 
            +
            content
         | 
| 1010 | 
            +
                  EOS
         | 
| 1011 | 
            +
             | 
| 1012 | 
            +
                  output = render_string input, :backend => 'docbook'
         | 
| 1013 | 
            +
                  assert_css 'revhistory', output, 1
         | 
| 1014 | 
            +
                  assert_css 'revhistory > revision', output, 1
         | 
| 1015 | 
            +
                  assert_css 'revhistory > revision > date', output, 1
         | 
| 1016 | 
            +
                  assert_css 'revhistory > revision > revnumber', output, 1
         | 
| 1017 | 
            +
                end
         | 
| 1018 | 
            +
             | 
| 1019 | 
            +
                test 'should include revision history if revdate and revremark is set' do
         | 
| 1020 | 
            +
                  input = <<-EOS
         | 
| 1021 | 
            +
            = Document Title
         | 
| 1022 | 
            +
            Author Name
         | 
| 1023 | 
            +
            :revdate: 2011-11-11
         | 
| 1024 | 
            +
            :revremark: features!
         | 
| 1025 | 
            +
             | 
| 1026 | 
            +
            content
         | 
| 1027 | 
            +
                  EOS
         | 
| 1028 | 
            +
             | 
| 1029 | 
            +
                  output = render_string input, :backend => 'docbook'
         | 
| 1030 | 
            +
                  assert_css 'revhistory', output, 1
         | 
| 1031 | 
            +
                  assert_css 'revhistory > revision', output, 1
         | 
| 1032 | 
            +
                  assert_css 'revhistory > revision > date', output, 1
         | 
| 1033 | 
            +
                  assert_css 'revhistory > revision > revremark', output, 1
         | 
| 1034 | 
            +
                end
         | 
| 1035 | 
            +
             | 
| 1036 | 
            +
                test 'should not include revision history if revdate is not set' do
         | 
| 1037 | 
            +
                  input = <<-EOS
         | 
| 1038 | 
            +
            = Document Title
         | 
| 1039 | 
            +
            Author Name
         | 
| 1040 | 
            +
            :revnumber: 1.0
         | 
| 1041 | 
            +
             | 
| 1042 | 
            +
            content
         | 
| 1043 | 
            +
                  EOS
         | 
| 1044 | 
            +
             | 
| 1045 | 
            +
                  output = render_string input, :backend => 'docbook'
         | 
| 1046 | 
            +
                  assert_css 'revhistory', output, 0
         | 
| 839 1047 | 
             
                end
         | 
| 840 1048 |  | 
| 841 1049 | 
             
                test 'with metadata to DocBook45' do
         | 
| @@ -848,7 +1056,7 @@ v8.6.8, 2012-07-12: See changelog. | |
| 848 1056 |  | 
| 849 1057 | 
             
            more info...
         | 
| 850 1058 | 
             
                  EOS
         | 
| 851 | 
            -
                  output = render_string input, :backend => ' | 
| 1059 | 
            +
                  output = render_string input, :backend => 'docbook45'
         | 
| 852 1060 | 
             
                  assert_xpath '/article/articleinfo', output, 1
         | 
| 853 1061 | 
             
                  assert_xpath '/article/articleinfo/title[text() = "AsciiDoc"]', output, 1
         | 
| 854 1062 | 
             
                  assert_xpath '/article/articleinfo/date[text() = "2012-07-12"]', output, 1
         | 
| @@ -881,7 +1089,7 @@ more info... | |
| 881 1089 | 
             
                  assert_xpath '/article/info/author/email[text() = "founder@asciidoc.org"]', output, 1
         | 
| 882 1090 | 
             
                end
         | 
| 883 1091 |  | 
| 884 | 
            -
                test 'with author defined using attribute entry to DocBook' do
         | 
| 1092 | 
            +
                test 'with author defined using attribute entry to DocBook 4.5' do
         | 
| 885 1093 | 
             
                  input = <<-EOS
         | 
| 886 1094 | 
             
            = Document Title
         | 
| 887 1095 | 
             
            :author: Doc Writer
         | 
| @@ -890,7 +1098,7 @@ more info... | |
| 890 1098 | 
             
            content
         | 
| 891 1099 | 
             
                  EOS
         | 
| 892 1100 |  | 
| 893 | 
            -
                  output = render_string input, :backend => ' | 
| 1101 | 
            +
                  output = render_string input, :backend => 'docbook45'
         | 
| 894 1102 | 
             
                  assert_xpath '//articleinfo/author', output, 1
         | 
| 895 1103 | 
             
                  assert_xpath '//articleinfo/author/firstname[text() = "Doc"]', output, 1
         | 
| 896 1104 | 
             
                  assert_xpath '//articleinfo/author/surname[text() = "Writer"]', output, 1
         | 
| @@ -927,7 +1135,7 @@ Doc Writer <thedoctor@asciidoc.org>; Junior Writer <junior@asciidoctor.org> | |
| 927 1135 | 
             
            content
         | 
| 928 1136 | 
             
                  EOS
         | 
| 929 1137 |  | 
| 930 | 
            -
                  output = render_string input, :backend => ' | 
| 1138 | 
            +
                  output = render_string input, :backend => 'docbook45'
         | 
| 931 1139 | 
             
                  assert_xpath '//articleinfo/author', output, 0
         | 
| 932 1140 | 
             
                  assert_xpath '//articleinfo/authorgroup', output, 1
         | 
| 933 1141 | 
             
                  assert_xpath '//articleinfo/authorgroup/author', output, 2
         | 
| @@ -945,7 +1153,7 @@ content | |
| 945 1153 | 
             
            content
         | 
| 946 1154 | 
             
                  EOS
         | 
| 947 1155 |  | 
| 948 | 
            -
                  output = render_string input, :backend => ' | 
| 1156 | 
            +
                  output = render_string input, :backend => 'docbook45'
         | 
| 949 1157 | 
             
                  assert_xpath '//articleinfo/author', output, 0
         | 
| 950 1158 | 
             
                  assert_xpath '//articleinfo/authorgroup', output, 1
         | 
| 951 1159 | 
             
                  assert_xpath '//articleinfo/authorgroup/author', output, 2
         | 
| @@ -956,14 +1164,14 @@ content | |
| 956 1164 | 
             
                end
         | 
| 957 1165 |  | 
| 958 1166 | 
             
                test 'with header footer' do
         | 
| 959 | 
            -
                  doc = document_from_string "= Title\n\ | 
| 1167 | 
            +
                  doc = document_from_string "= Title\n\nparagraph"
         | 
| 960 1168 | 
             
                  assert !doc.attr?('embedded')
         | 
| 961 1169 | 
             
                  result = doc.render
         | 
| 962 1170 | 
             
                  assert_xpath '/html', result, 1
         | 
| 963 1171 | 
             
                  assert_xpath '//*[@id="header"]', result, 1
         | 
| 964 1172 | 
             
                  assert_xpath '//*[@id="header"]/h1', result, 1
         | 
| 965 1173 | 
             
                  assert_xpath '//*[@id="footer"]', result, 1
         | 
| 966 | 
            -
                  assert_xpath '//*[@id=" | 
| 1174 | 
            +
                  assert_xpath '//*[@id="content"]', result, 1
         | 
| 967 1175 | 
             
                end
         | 
| 968 1176 |  | 
| 969 1177 | 
             
                test 'can disable last updated in footer' do
         | 
| @@ -974,14 +1182,14 @@ content | |
| 974 1182 | 
             
                end
         | 
| 975 1183 |  | 
| 976 1184 | 
             
                test 'no header footer' do
         | 
| 977 | 
            -
                  doc = document_from_string "= Title\n\ | 
| 1185 | 
            +
                  doc = document_from_string "= Document Title\n\ncontent", :header_footer => false
         | 
| 978 1186 | 
             
                  assert doc.attr?('embedded')
         | 
| 979 1187 | 
             
                  result = doc.render
         | 
| 980 1188 | 
             
                  assert_xpath '/html', result, 0
         | 
| 981 1189 | 
             
                  assert_xpath '/h1', result, 0
         | 
| 982 1190 | 
             
                  assert_xpath '/*[@id="header"]', result, 0
         | 
| 983 1191 | 
             
                  assert_xpath '/*[@id="footer"]', result, 0
         | 
| 984 | 
            -
                  assert_xpath '/*[@ | 
| 1192 | 
            +
                  assert_xpath '/*[@class="paragraph"]', result, 1
         | 
| 985 1193 | 
             
                end
         | 
| 986 1194 |  | 
| 987 1195 | 
             
                test 'enable title in embedded document by unassigning notitle attribute' do
         | 
| @@ -991,14 +1199,14 @@ content | |
| 991 1199 | 
             
            content
         | 
| 992 1200 | 
             
                  EOS
         | 
| 993 1201 |  | 
| 994 | 
            -
                  result =  | 
| 1202 | 
            +
                  result = render_embedded_string input, :attributes => {'notitle!' => ''}
         | 
| 995 1203 | 
             
                  assert_xpath '/html', result, 0
         | 
| 996 1204 | 
             
                  assert_xpath '/h1', result, 1
         | 
| 997 1205 | 
             
                  assert_xpath '/*[@id="header"]', result, 0
         | 
| 998 1206 | 
             
                  assert_xpath '/*[@id="footer"]', result, 0
         | 
| 999 | 
            -
                  assert_xpath '/*[@ | 
| 1207 | 
            +
                  assert_xpath '/*[@class="paragraph"]', result, 1
         | 
| 1000 1208 | 
             
                  assert_xpath '(/*)[1]/self::h1', result, 1
         | 
| 1001 | 
            -
                  assert_xpath '(/*)[2]/self::*[@ | 
| 1209 | 
            +
                  assert_xpath '(/*)[2]/self::*[@class="paragraph"]', result, 1
         | 
| 1002 1210 | 
             
                end
         | 
| 1003 1211 |  | 
| 1004 1212 | 
             
                test 'enable title in embedded document by assigning showtitle attribute' do
         | 
| @@ -1008,14 +1216,14 @@ content | |
| 1008 1216 | 
             
            content
         | 
| 1009 1217 | 
             
                  EOS
         | 
| 1010 1218 |  | 
| 1011 | 
            -
                  result =  | 
| 1219 | 
            +
                  result = render_embedded_string input, :attributes => {'showtitle' => ''}
         | 
| 1012 1220 | 
             
                  assert_xpath '/html', result, 0
         | 
| 1013 1221 | 
             
                  assert_xpath '/h1', result, 1
         | 
| 1014 1222 | 
             
                  assert_xpath '/*[@id="header"]', result, 0
         | 
| 1015 1223 | 
             
                  assert_xpath '/*[@id="footer"]', result, 0
         | 
| 1016 | 
            -
                  assert_xpath '/*[@ | 
| 1224 | 
            +
                  assert_xpath '/*[@class="paragraph"]', result, 1
         | 
| 1017 1225 | 
             
                  assert_xpath '(/*)[1]/self::h1', result, 1
         | 
| 1018 | 
            -
                  assert_xpath '(/*)[2]/self::*[@ | 
| 1226 | 
            +
                  assert_xpath '(/*)[2]/self::*[@class="paragraph"]', result, 1
         | 
| 1019 1227 | 
             
                end
         | 
| 1020 1228 |  | 
| 1021 1229 | 
             
                test 'parse header only' do
         | 
| @@ -1060,7 +1268,7 @@ finally a reference to the second footnote footnoteref:[note2]. | |
| 1060 1268 | 
             
            Text that has supporting information{empty}footnote:[An example footnote.].
         | 
| 1061 1269 | 
             
                  EOS
         | 
| 1062 1270 |  | 
| 1063 | 
            -
                  output =  | 
| 1271 | 
            +
                  output = render_embedded_string input
         | 
| 1064 1272 | 
             
                  assert_css '#footnotes', output, 1
         | 
| 1065 1273 | 
             
                end
         | 
| 1066 1274 |  | 
| @@ -1069,26 +1277,125 @@ Text that has supporting information{empty}footnote:[An example footnote.]. | |
| 1069 1277 | 
             
            Text that has supporting information{empty}footnote:[An example footnote.].
         | 
| 1070 1278 | 
             
                  EOS
         | 
| 1071 1279 |  | 
| 1072 | 
            -
                  output =  | 
| 1280 | 
            +
                  output = render_embedded_string input, :attributes => {'nofootnotes' => ''}
         | 
| 1073 1281 | 
             
                  assert_css '#footnotes', output, 0
         | 
| 1074 1282 | 
             
                end
         | 
| 1075 1283 | 
             
              end
         | 
| 1076 1284 |  | 
| 1077 1285 | 
             
              context 'Backends and Doctypes' do 
         | 
| 1078 1286 | 
             
                test 'html5 backend doctype article' do
         | 
| 1079 | 
            -
                  result = render_string("= Title\n\ | 
| 1287 | 
            +
                  result = render_string("= Title\n\nparagraph", :attributes => {'backend' => 'html5'})
         | 
| 1080 1288 | 
             
                  assert_xpath '/html', result, 1
         | 
| 1081 1289 | 
             
                  assert_xpath '/html/body[@class="article"]', result, 1
         | 
| 1082 1290 | 
             
                  assert_xpath '/html//*[@id="header"]/h1[text() = "Title"]', result, 1
         | 
| 1083 | 
            -
                  assert_xpath '/html//*[@id=" | 
| 1291 | 
            +
                  assert_xpath '/html//*[@id="content"]//p[text() = "paragraph"]', result, 1
         | 
| 1084 1292 | 
             
                end
         | 
| 1085 1293 |  | 
| 1086 1294 | 
             
                test 'html5 backend doctype book' do
         | 
| 1087 | 
            -
                  result = render_string("= Title\n\ | 
| 1295 | 
            +
                  result = render_string("= Title\n\nparagraph", :attributes => {'backend' => 'html5', 'doctype' => 'book'})
         | 
| 1088 1296 | 
             
                  assert_xpath '/html', result, 1
         | 
| 1089 1297 | 
             
                  assert_xpath '/html/body[@class="book"]', result, 1
         | 
| 1090 1298 | 
             
                  assert_xpath '/html//*[@id="header"]/h1[text() = "Title"]', result, 1
         | 
| 1091 | 
            -
                  assert_xpath '/html//*[@id=" | 
| 1299 | 
            +
                  assert_xpath '/html//*[@id="content"]//p[text() = "paragraph"]', result, 1
         | 
| 1300 | 
            +
                end
         | 
| 1301 | 
            +
             | 
| 1302 | 
            +
                test 'xhtml5 backend should map to html5 and set htmlsyntax to xml' do
         | 
| 1303 | 
            +
                  input = <<-EOS
         | 
| 1304 | 
            +
            content
         | 
| 1305 | 
            +
                  EOS
         | 
| 1306 | 
            +
                  doc = document_from_string input, :backend => :xhtml5
         | 
| 1307 | 
            +
                  assert_equal 'html5', doc.backend
         | 
| 1308 | 
            +
                  assert_equal 'xml', (doc.attr 'htmlsyntax')
         | 
| 1309 | 
            +
                end
         | 
| 1310 | 
            +
             | 
| 1311 | 
            +
                test 'xhtml backend should map to html5 and set htmlsyntax to xml' do
         | 
| 1312 | 
            +
                  input = <<-EOS
         | 
| 1313 | 
            +
            content
         | 
| 1314 | 
            +
                  EOS
         | 
| 1315 | 
            +
                  doc = document_from_string input, :backend => :xhtml
         | 
| 1316 | 
            +
                  assert_equal 'html5', doc.backend
         | 
| 1317 | 
            +
                  assert_equal 'xml', (doc.attr 'htmlsyntax')
         | 
| 1318 | 
            +
                end
         | 
| 1319 | 
            +
             | 
| 1320 | 
            +
                test 'should close all short tags when htmlsyntax is xml' do
         | 
| 1321 | 
            +
                  input = <<-EOS
         | 
| 1322 | 
            +
            = Document Title
         | 
| 1323 | 
            +
            Author Name
         | 
| 1324 | 
            +
            v1.0, 2001-01-01
         | 
| 1325 | 
            +
            :icons:
         | 
| 1326 | 
            +
             | 
| 1327 | 
            +
            image:tiger.png[]
         | 
| 1328 | 
            +
             | 
| 1329 | 
            +
            image::tiger.png[]
         | 
| 1330 | 
            +
             | 
| 1331 | 
            +
            * [x] one
         | 
| 1332 | 
            +
            * [ ] two
         | 
| 1333 | 
            +
             | 
| 1334 | 
            +
            |===
         | 
| 1335 | 
            +
            |A |B
         | 
| 1336 | 
            +
            |===
         | 
| 1337 | 
            +
             | 
| 1338 | 
            +
            [horizontal, labelwidth="25%", itemwidth="75%"]
         | 
| 1339 | 
            +
            term:: definition
         | 
| 1340 | 
            +
             | 
| 1341 | 
            +
            NOTE: note
         | 
| 1342 | 
            +
             | 
| 1343 | 
            +
            [quote,Author,Source]
         | 
| 1344 | 
            +
            ____
         | 
| 1345 | 
            +
            Quote me.
         | 
| 1346 | 
            +
            ____
         | 
| 1347 | 
            +
             | 
| 1348 | 
            +
            [verse,Author,Source]
         | 
| 1349 | 
            +
            ____
         | 
| 1350 | 
            +
            A tall tale.
         | 
| 1351 | 
            +
            ____
         | 
| 1352 | 
            +
             | 
| 1353 | 
            +
            [options="autoplay,loop"]
         | 
| 1354 | 
            +
            video::screencast.ogg[]
         | 
| 1355 | 
            +
             | 
| 1356 | 
            +
            video::12345[vimeo]
         | 
| 1357 | 
            +
             | 
| 1358 | 
            +
            [options="autoplay,loop"]
         | 
| 1359 | 
            +
            audio::podcast.ogg[]
         | 
| 1360 | 
            +
             | 
| 1361 | 
            +
            one +
         | 
| 1362 | 
            +
            two
         | 
| 1363 | 
            +
             | 
| 1364 | 
            +
            '''
         | 
| 1365 | 
            +
                  EOS
         | 
| 1366 | 
            +
                  result = render_string input, :safe => :safe, :backend => :xhtml
         | 
| 1367 | 
            +
                  begin
         | 
| 1368 | 
            +
                    Nokogiri::XML::Document.parse(result) {|config|
         | 
| 1369 | 
            +
                      config.options = Nokogiri::XML::ParseOptions::STRICT | Nokogiri::XML::ParseOptions::NONET
         | 
| 1370 | 
            +
                    }
         | 
| 1371 | 
            +
                  rescue => e
         | 
| 1372 | 
            +
                    flunk "xhtml5 backend did not generate well-formed XML: #{e.message}\n#{result}"
         | 
| 1373 | 
            +
                  end
         | 
| 1374 | 
            +
                  #refute_match(/<meta [^>]+[^\/]>/, result)
         | 
| 1375 | 
            +
                  #refute_match(/<link [^>]+[^\/]>/, result)
         | 
| 1376 | 
            +
                  #refute_match(/<img [^>]+[^\/]>/, result)
         | 
| 1377 | 
            +
                  #refute_match(/<input [^>]+[^\/]>/, result)
         | 
| 1378 | 
            +
                  #assert_match(/<input [^>]+checked="checked"/, result)
         | 
| 1379 | 
            +
                  #assert_match(/<input [^>]+disabled="disabled"/, result)
         | 
| 1380 | 
            +
                  #refute_match(/<col [^>]+[^\/]>/, result)
         | 
| 1381 | 
            +
                  #refute_match(/<[bh]r>/, result)
         | 
| 1382 | 
            +
                  #assert_match(/video [^>]+loop="loop"/, result)
         | 
| 1383 | 
            +
                  #assert_match(/video [^>]+autoplay="autoplay"/, result)
         | 
| 1384 | 
            +
                  #assert_match(/video [^>]+controls="controls"/, result)
         | 
| 1385 | 
            +
                  #assert_match(/audio [^>]+loop="loop"/, result)
         | 
| 1386 | 
            +
                  #assert_match(/audio [^>]+autoplay="autoplay"/, result)
         | 
| 1387 | 
            +
                  #assert_match(/audio [^>]+controls="controls"/, result)
         | 
| 1388 | 
            +
                  #assert_match(/iframe [^>]+webkitallowfullscreen="webkitallowfullscreen"/i, result)
         | 
| 1389 | 
            +
                  #assert_match(/iframe [^>]+mozallowfullscreen="mozallowfullscreen"/i, result)
         | 
| 1390 | 
            +
                  #assert_match(/iframe [^>]+allowfullscreen="allowfullscreen"/i, result)
         | 
| 1391 | 
            +
                end
         | 
| 1392 | 
            +
             | 
| 1393 | 
            +
                test 'xhtml backend should emit elements in proper namespace' do
         | 
| 1394 | 
            +
                  input = <<-EOS
         | 
| 1395 | 
            +
            content
         | 
| 1396 | 
            +
                  EOS
         | 
| 1397 | 
            +
                  result = render_string input, :safe => :safe, :backend => :xhtml, :keep_namespaces => true
         | 
| 1398 | 
            +
                  assert_xpath '//*[not(namespace-uri() = "http://www.w3.org/1999/xhtml")]', result, 0
         | 
| 1092 1399 | 
             
                end
         | 
| 1093 1400 |  | 
| 1094 1401 | 
             
                test 'docbook45 backend doctype article' do
         | 
| @@ -1118,8 +1425,8 @@ section body | |
| 1118 1425 | 
             
                end
         | 
| 1119 1426 |  | 
| 1120 1427 | 
             
                test 'docbook45 backend doctype article no xmlns' do
         | 
| 1121 | 
            -
                  result = render_string('text', :keep_namespaces => true, :attributes => {'backend' => 'docbook45', 'doctype' => 'article' | 
| 1122 | 
            -
                   | 
| 1428 | 
            +
                  result = render_string('text', :keep_namespaces => true, :attributes => {'backend' => 'docbook45', 'doctype' => 'article'})
         | 
| 1429 | 
            +
                  refute_match(RE_XMLNS_ATTRIBUTE, result)
         | 
| 1123 1430 | 
             
                end
         | 
| 1124 1431 |  | 
| 1125 1432 | 
             
                test 'docbook45 backend doctype book' do
         | 
| @@ -1145,12 +1452,13 @@ chapter body | |
| 1145 1452 | 
             
                  result = render_string('text', :attributes => {'backend' => 'docbook45', 'doctype' => 'book'})
         | 
| 1146 1453 | 
             
                  assert_xpath '/book', result, 1
         | 
| 1147 1454 | 
             
                  assert_xpath '/book/bookinfo/date', result, 1
         | 
| 1148 | 
            -
                   | 
| 1455 | 
            +
                  # NOTE simpara cannot be a direct child of book, so content must be treated as a preface
         | 
| 1456 | 
            +
                  assert_xpath '/book/preface/simpara[text() = "text"]', result, 1
         | 
| 1149 1457 | 
             
                end
         | 
| 1150 1458 |  | 
| 1151 1459 | 
             
                test 'docbook45 backend doctype book no xmlns' do
         | 
| 1152 | 
            -
                  result = render_string('text', :keep_namespaces => true, :attributes => {'backend' => 'docbook45', 'doctype' => 'book' | 
| 1153 | 
            -
                   | 
| 1460 | 
            +
                  result = render_string('text', :keep_namespaces => true, :attributes => {'backend' => 'docbook45', 'doctype' => 'book'})
         | 
| 1461 | 
            +
                  refute_match(RE_XMLNS_ATTRIBUTE, result)
         | 
| 1154 1462 | 
             
                end
         | 
| 1155 1463 |  | 
| 1156 1464 | 
             
                test 'docbook45 backend parses out subtitle' do
         | 
| @@ -1189,8 +1497,8 @@ section body | |
| 1189 1497 | 
             
                  section = xmlnodes_at_xpath('/xmlns:article/xmlns:section', result, 1).first
         | 
| 1190 1498 | 
             
                  # nokogiri can't make up its mind
         | 
| 1191 1499 | 
             
                  id_attr = section.attribute('id') || section.attribute('xml:id')
         | 
| 1192 | 
            -
                   | 
| 1193 | 
            -
                   | 
| 1500 | 
            +
                  refute_nil id_attr
         | 
| 1501 | 
            +
                  refute_nil id_attr.namespace
         | 
| 1194 1502 | 
             
                  assert_equal 'xml', id_attr.namespace.prefix
         | 
| 1195 1503 | 
             
                  assert_equal '_first_section', id_attr.value
         | 
| 1196 1504 | 
             
                end
         | 
| @@ -1218,29 +1526,29 @@ chapter body | |
| 1218 1526 | 
             
                  chapter = xmlnodes_at_xpath('/xmlns:book/xmlns:chapter', result, 1).first
         | 
| 1219 1527 | 
             
                  # nokogiri can't make up its mind
         | 
| 1220 1528 | 
             
                  id_attr = chapter.attribute('id') || chapter.attribute('xml:id')
         | 
| 1221 | 
            -
                   | 
| 1222 | 
            -
                   | 
| 1529 | 
            +
                  refute_nil id_attr
         | 
| 1530 | 
            +
                  refute_nil id_attr.namespace
         | 
| 1223 1531 | 
             
                  assert_equal 'xml', id_attr.namespace.prefix
         | 
| 1224 1532 | 
             
                  assert_equal '_first_chapter', id_attr.value
         | 
| 1225 1533 | 
             
                end
         | 
| 1226 1534 |  | 
| 1227 1535 | 
             
                test 'should be able to set backend using :backend option key' do
         | 
| 1228 | 
            -
                  doc =  | 
| 1536 | 
            +
                  doc = empty_document :backend => 'html5'
         | 
| 1229 1537 | 
             
                  assert_equal 'html5', doc.attributes['backend']
         | 
| 1230 1538 | 
             
                end
         | 
| 1231 1539 |  | 
| 1232 1540 | 
             
                test ':backend option should override backend attribute' do
         | 
| 1233 | 
            -
                  doc =  | 
| 1541 | 
            +
                  doc = empty_document :backend => 'html5', :attributes => {'backend' => 'docbook45'}
         | 
| 1234 1542 | 
             
                  assert_equal 'html5', doc.attributes['backend']
         | 
| 1235 1543 | 
             
                end
         | 
| 1236 1544 |  | 
| 1237 1545 | 
             
                test 'should be able to set doctype using :doctype option key' do
         | 
| 1238 | 
            -
                  doc =  | 
| 1546 | 
            +
                  doc = empty_document :doctype => 'book'
         | 
| 1239 1547 | 
             
                  assert_equal 'book', doc.attributes['doctype']
         | 
| 1240 1548 | 
             
                end
         | 
| 1241 1549 |  | 
| 1242 1550 | 
             
                test ':doctype option should override doctype attribute' do
         | 
| 1243 | 
            -
                  doc =  | 
| 1551 | 
            +
                  doc = empty_document :doctype => 'book', :attributes => {'doctype' => 'article'}
         | 
| 1244 1552 | 
             
                  assert_equal 'book', doc.attributes['doctype']
         | 
| 1245 1553 | 
             
                end
         | 
| 1246 1554 |  | 
| @@ -1361,7 +1669,7 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 1361 1669 |  | 
| 1362 1670 | 
             
                   doc = document_from_string input
         | 
| 1363 1671 | 
             
                   synopsis_section = doc.blocks.first 
         | 
| 1364 | 
            -
                    | 
| 1672 | 
            +
                   refute_nil synopsis_section
         | 
| 1365 1673 | 
             
                   assert_equal :section, synopsis_section.context
         | 
| 1366 1674 | 
             
                   assert synopsis_section.special
         | 
| 1367 1675 | 
             
                   assert_equal 'synopsis', synopsis_section.sectname
         | 
| @@ -1393,14 +1701,14 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 1393 1701 |  | 
| 1394 1702 | 
             
              context 'Secure Asset Path' do
         | 
| 1395 1703 | 
             
                test 'allows us to specify a path relative to the current dir' do
         | 
| 1396 | 
            -
                  doc =  | 
| 1704 | 
            +
                  doc = empty_document
         | 
| 1397 1705 | 
             
                  legit_path = Dir.pwd + '/foo'
         | 
| 1398 1706 | 
             
                  assert_equal legit_path, doc.normalize_asset_path(legit_path)
         | 
| 1399 1707 | 
             
                end
         | 
| 1400 1708 |  | 
| 1401 1709 | 
             
                test 'keeps naughty absolute paths from getting outside' do
         | 
| 1402 1710 | 
             
                  naughty_path = "#{disk_root}etc/passwd"
         | 
| 1403 | 
            -
                  doc =  | 
| 1711 | 
            +
                  doc = empty_document
         | 
| 1404 1712 | 
             
                  secure_path = doc.normalize_asset_path(naughty_path)
         | 
| 1405 1713 | 
             
                  assert naughty_path != secure_path
         | 
| 1406 1714 | 
             
                  assert_match(/^#{doc.base_dir}/, secure_path)
         | 
| @@ -1408,10 +1716,21 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 1408 1716 |  | 
| 1409 1717 | 
             
                test 'keeps naughty relative paths from getting outside' do
         | 
| 1410 1718 | 
             
                  naughty_path = 'safe/ok/../../../../../etc/passwd'
         | 
| 1411 | 
            -
                  doc =  | 
| 1719 | 
            +
                  doc = empty_document
         | 
| 1412 1720 | 
             
                  secure_path = doc.normalize_asset_path(naughty_path)
         | 
| 1413 1721 | 
             
                  assert naughty_path != secure_path
         | 
| 1414 1722 | 
             
                  assert_match(/^#{doc.base_dir}/, secure_path)
         | 
| 1415 1723 | 
             
                end
         | 
| 1724 | 
            +
             | 
| 1725 | 
            +
                test 'should raise an exception when a converter cannot be resolved' do
         | 
| 1726 | 
            +
                  input = <<-EOS
         | 
| 1727 | 
            +
            = Document Title
         | 
| 1728 | 
            +
            text
         | 
| 1729 | 
            +
                  EOS
         | 
| 1730 | 
            +
                  exception = assert_raises RuntimeError do
         | 
| 1731 | 
            +
                    Asciidoctor.render(input, :backend => "unknownBackend")
         | 
| 1732 | 
            +
                  end
         | 
| 1733 | 
            +
                  assert_match(/missing converter for backend 'unknownBackend'/, exception.message)
         | 
| 1734 | 
            +
                end
         | 
| 1416 1735 | 
             
              end
         | 
| 1417 1736 | 
             
            end
         |