asciidoctor 1.5.5 → 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +216 -1
- data/CONTRIBUTING.adoc +2 -2
- data/Gemfile +20 -1
- data/LICENSE.adoc +1 -1
- data/README-fr.adoc +4 -3
- data/README-jp.adoc +11 -10
- data/README-zh_CN.adoc +4 -3
- data/README.adoc +17 -202
- data/Rakefile +41 -25
- data/asciidoctor.gemspec +9 -10
- data/data/locale/attributes.adoc +216 -34
- data/data/stylesheets/asciidoctor-default.css +23 -16
- data/features/step_definitions.rb +15 -19
- data/features/xref.feature +584 -20
- data/lib/asciidoctor.rb +292 -278
- data/lib/asciidoctor/abstract_block.rb +155 -94
- data/lib/asciidoctor/abstract_node.rb +108 -94
- data/lib/asciidoctor/attribute_list.rb +30 -22
- data/lib/asciidoctor/block.rb +7 -7
- data/lib/asciidoctor/cli/invoker.rb +47 -34
- data/lib/asciidoctor/cli/options.rb +22 -11
- data/lib/asciidoctor/converter.rb +3 -3
- data/lib/asciidoctor/converter/base.rb +2 -2
- data/lib/asciidoctor/converter/composite.rb +1 -1
- data/lib/asciidoctor/converter/docbook45.rb +2 -2
- data/lib/asciidoctor/converter/docbook5.rb +132 -87
- data/lib/asciidoctor/converter/factory.rb +0 -1
- data/lib/asciidoctor/converter/html5.rb +116 -98
- data/lib/asciidoctor/converter/manpage.rb +51 -52
- data/lib/asciidoctor/converter/template.rb +47 -36
- data/lib/asciidoctor/core_ext.rb +8 -2
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +4 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +5 -0
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +1 -1
- data/lib/asciidoctor/core_ext/1.8.7/string/{limit.rb → limit_bytesize.rb} +7 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +1 -1
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +5 -5
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +3 -0
- data/lib/asciidoctor/core_ext/string/{limit.rb → limit_bytesize.rb} +2 -2
- data/lib/asciidoctor/document.rb +216 -213
- data/lib/asciidoctor/extensions.rb +318 -185
- data/lib/asciidoctor/helpers.rb +35 -35
- data/lib/asciidoctor/inline.rb +32 -1
- data/lib/asciidoctor/list.rb +22 -6
- data/lib/asciidoctor/parser.rb +1008 -1038
- data/lib/asciidoctor/path_resolver.rb +46 -50
- data/lib/asciidoctor/reader.rb +275 -251
- data/lib/asciidoctor/section.rb +86 -58
- data/lib/asciidoctor/stylesheets.rb +6 -6
- data/lib/asciidoctor/substitutors.rb +567 -649
- data/lib/asciidoctor/table.rb +163 -108
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +18 -16
- data/man/asciidoctor.adoc +15 -13
- data/test/attributes_test.rb +138 -22
- data/test/blocks_test.rb +377 -97
- data/test/converter_test.rb +13 -0
- data/test/document_test.rb +244 -34
- data/test/extensions_test.rb +409 -42
- data/test/fixtures/asciidoc_index.txt +521 -0
- data/test/fixtures/basic-docinfo-footer.html +6 -0
- data/test/fixtures/basic-docinfo-footer.xml +8 -0
- data/test/fixtures/basic-docinfo.html +1 -0
- data/test/fixtures/basic-docinfo.xml +4 -0
- data/test/fixtures/basic.asciidoc +5 -0
- data/test/fixtures/chapter-a.adoc +3 -0
- data/test/fixtures/child-include.adoc +5 -0
- data/test/fixtures/circle.svg +9 -0
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +1 -0
- data/test/fixtures/custom-docinfodir/docinfo.html +1 -0
- data/test/fixtures/docinfo-footer.html +1 -0
- data/test/fixtures/docinfo-footer.xml +9 -0
- data/test/fixtures/docinfo.html +1 -0
- data/test/fixtures/docinfo.xml +3 -0
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +13 -0
- data/test/fixtures/grandchild-include.adoc +3 -0
- data/test/fixtures/hello-asciidoctor.pdf +69 -0
- data/test/fixtures/include-file.asciidoc +24 -0
- data/test/fixtures/include-file.ml +3 -0
- data/test/fixtures/include-file.xml +5 -0
- data/test/fixtures/master.adoc +5 -0
- data/test/fixtures/mismatched-end-tag.adoc +7 -0
- data/test/fixtures/parent-include-restricted.adoc +5 -0
- data/test/fixtures/parent-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +26 -0
- data/test/fixtures/stylesheets/custom.css +3 -0
- data/test/fixtures/subs-docinfo.html +2 -0
- data/test/fixtures/subs.adoc +7 -0
- data/test/fixtures/tagged-class-enclosed.rb +26 -0
- data/test/fixtures/tagged-class.rb +23 -0
- data/test/fixtures/tip.gif +0 -0
- data/test/invoker_test.rb +82 -4
- data/test/links_test.rb +312 -37
- data/test/lists_test.rb +204 -25
- data/test/manpage_test.rb +191 -4
- data/test/options_test.rb +18 -1
- data/test/paragraphs_test.rb +32 -7
- data/test/parser_test.rb +150 -30
- data/test/paths_test.rb +47 -13
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +366 -126
- data/test/sections_test.rb +203 -56
- data/test/substitutions_test.rb +339 -131
- data/test/tables_test.rb +315 -15
- data/test/test_helper.rb +400 -0
- data/test/text_test.rb +5 -5
- metadata +110 -22
    
        data/test/converter_test.rb
    CHANGED
    
    | @@ -26,6 +26,19 @@ context 'Converter' do | |
| 26 26 | 
             
                  assert_equal :xhtml, selected.templates['paragraph'].options[:format]
         | 
| 27 27 | 
             
                end
         | 
| 28 28 |  | 
| 29 | 
            +
                test 'should configure Slim to resolve includes in specified template dirs' do
         | 
| 30 | 
            +
                  template_dirs = [
         | 
| 31 | 
            +
                    File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'),
         | 
| 32 | 
            +
                    File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim-overrides'),
         | 
| 33 | 
            +
                  ]
         | 
| 34 | 
            +
                  doc = Asciidoctor::Document.new [], :template_dirs => template_dirs, :template_cache => false
         | 
| 35 | 
            +
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
| 36 | 
            +
                  selected = doc.converter.find_converter('paragraph')
         | 
| 37 | 
            +
                  assert selected.is_a? Asciidoctor::Converter::TemplateConverter
         | 
| 38 | 
            +
                  assert selected.templates['paragraph'].is_a? Slim::Template
         | 
| 39 | 
            +
                  assert_equal template_dirs.reverse.map {|dir| File.expand_path dir }, selected.templates['paragraph'].options[:include_dirs]
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 29 42 | 
             
                test 'should set Slim format to html for html5 backend' do
         | 
| 30 43 | 
             
                  doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false
         | 
| 31 44 | 
             
                  assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
         | 
    
        data/test/document_test.rb
    CHANGED
    
    | @@ -13,6 +13,9 @@ context 'Document' do | |
| 13 13 | 
             
                  doc = example_document(:asciidoc_index)
         | 
| 14 14 | 
             
                  assert_equal 'AsciiDoc Home Page', doc.doctitle
         | 
| 15 15 | 
             
                  assert_equal 'AsciiDoc Home Page', doc.name
         | 
| 16 | 
            +
                  refute_nil doc.header
         | 
| 17 | 
            +
                  assert_equal :section, doc.header.context
         | 
| 18 | 
            +
                  assert_equal 'header', doc.header.sectname
         | 
| 16 19 | 
             
                  assert_equal 14, doc.blocks.size
         | 
| 17 20 | 
             
                  assert_equal :preamble, doc.blocks[0].context
         | 
| 18 21 | 
             
                  assert doc.blocks[1].context == :section
         | 
| @@ -106,6 +109,18 @@ context 'Document' do | |
| 106 109 | 
             
                  assert !doc.attr?('sectnums')
         | 
| 107 110 | 
             
                end
         | 
| 108 111 |  | 
| 112 | 
            +
                test 'noheader attribute should suppress info element when converting to DocBook' do
         | 
| 113 | 
            +
                  input = <<-EOS
         | 
| 114 | 
            +
            = Document Title
         | 
| 115 | 
            +
            :noheader:
         | 
| 116 | 
            +
             | 
| 117 | 
            +
            content
         | 
| 118 | 
            +
                  EOS
         | 
| 119 | 
            +
                  result = render_string input, :backend => 'docbook'
         | 
| 120 | 
            +
                  assert_xpath '/article', result, 1
         | 
| 121 | 
            +
                  assert_xpath '/article/info', result, 0
         | 
| 122 | 
            +
                end
         | 
| 123 | 
            +
             | 
| 109 124 | 
             
                test 'should be able to disable section numbering using numbered attribute in document header for DocBook backend' do
         | 
| 110 125 | 
             
                  input = <<-EOS
         | 
| 111 126 | 
             
            = Document Title
         | 
| @@ -119,10 +134,11 @@ context 'Document' do | |
| 119 134 | 
             
              context 'Load APIs' do
         | 
| 120 135 | 
             
                test 'should load input file' do
         | 
| 121 136 | 
             
                  sample_input_path = fixture_path('sample.asciidoc')
         | 
| 122 | 
            -
                  doc =  | 
| 137 | 
            +
                  doc = File.open(sample_input_path) {|file| Asciidoctor.load file, :safe => Asciidoctor::SafeMode::SAFE }
         | 
| 123 138 | 
             
                  assert_equal 'Document Title', doc.doctitle
         | 
| 124 139 | 
             
                  assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
         | 
| 125 140 | 
             
                  assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
         | 
| 141 | 
            +
                  assert_equal '.asciidoc', doc.attr('docfilesuffix')
         | 
| 126 142 | 
             
                end
         | 
| 127 143 |  | 
| 128 144 | 
             
                test 'should load input file from filename' do
         | 
| @@ -131,6 +147,7 @@ context 'Document' do | |
| 131 147 | 
             
                  assert_equal 'Document Title', doc.doctitle
         | 
| 132 148 | 
             
                  assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
         | 
| 133 149 | 
             
                  assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
         | 
| 150 | 
            +
                  assert_equal '.asciidoc', doc.attr('docfilesuffix')
         | 
| 134 151 | 
             
                end
         | 
| 135 152 |  | 
| 136 153 | 
             
                test 'should not load invalid file' do
         | 
| @@ -204,8 +221,10 @@ preamble | |
| 204 221 | 
             
                end
         | 
| 205 222 |  | 
| 206 223 | 
             
                test 'should accept attributes as string' do
         | 
| 207 | 
            -
             | 
| 208 | 
            -
             | 
| 224 | 
            +
                  doc = Asciidoctor.load('text', :attributes => 'toc sectnums
         | 
| 225 | 
            +
            source-highlighter=coderay
         | 
| 226 | 
            +
            idprefix
         | 
| 227 | 
            +
            idseparator=-')
         | 
| 209 228 | 
             
                  assert doc.attributes.is_a?(Hash)
         | 
| 210 229 | 
             
                  assert doc.attr?('toc')
         | 
| 211 230 | 
             
                  assert_equal '', doc.attr('toc')
         | 
| @@ -220,15 +239,14 @@ preamble | |
| 220 239 | 
             
                end
         | 
| 221 240 |  | 
| 222 241 | 
             
                test 'should accept values containing spaces in attributes string' do
         | 
| 223 | 
            -
             | 
| 224 | 
            -
                  doc = Asciidoctor.load('text', :attributes => 'idprefix idseparator=-   note-caption=Note\ to\	self: toc')
         | 
| 242 | 
            +
                  doc = Asciidoctor.load('text', :attributes => %(idprefix idseparator=-   note-caption=Note\\ to\\\tself toc))
         | 
| 225 243 | 
             
                  assert doc.attributes.is_a?(Hash)
         | 
| 226 244 | 
             
                  assert doc.attr?('idprefix')
         | 
| 227 245 | 
             
                  assert_equal '', doc.attr('idprefix')
         | 
| 228 246 | 
             
                  assert doc.attr?('idseparator')
         | 
| 229 247 | 
             
                  assert_equal '-', doc.attr('idseparator')
         | 
| 230 248 | 
             
                  assert doc.attr?('note-caption')
         | 
| 231 | 
            -
                  assert_equal "Note to | 
| 249 | 
            +
                  assert_equal "Note to\tself", doc.attr('note-caption')
         | 
| 232 250 | 
             
                end
         | 
| 233 251 |  | 
| 234 252 | 
             
                test 'should accept attributes as empty string' do
         | 
| @@ -343,6 +361,33 @@ preamble | |
| 343 361 | 
             
                  assert_equal 1, section_1.lineno
         | 
| 344 362 | 
             
                end
         | 
| 345 363 |  | 
| 364 | 
            +
                test 'should assign correct source location if section occurs on last line of input' do
         | 
| 365 | 
            +
                  input = <<-EOS
         | 
| 366 | 
            +
            = Document Title
         | 
| 367 | 
            +
             | 
| 368 | 
            +
            == Section A
         | 
| 369 | 
            +
             | 
| 370 | 
            +
            content
         | 
| 371 | 
            +
             | 
| 372 | 
            +
            == Section B
         | 
| 373 | 
            +
                  EOS
         | 
| 374 | 
            +
             | 
| 375 | 
            +
                  doc = document_from_string input, :sourcemap => true
         | 
| 376 | 
            +
                  assert_equal [1, 3, 7], (doc.find_by :context => :section).map(&:lineno)
         | 
| 377 | 
            +
                end
         | 
| 378 | 
            +
             | 
| 379 | 
            +
                test 'should allow sourcemap option on document to be modified' do
         | 
| 380 | 
            +
                  doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :parse => false
         | 
| 381 | 
            +
                  doc.sourcemap = true
         | 
| 382 | 
            +
                  doc = doc.parse
         | 
| 383 | 
            +
             | 
| 384 | 
            +
                  section_1 = doc.sections[0]
         | 
| 385 | 
            +
                  assert_equal 'Section A', section_1.title
         | 
| 386 | 
            +
                  refute_nil section_1.source_location
         | 
| 387 | 
            +
                  assert_equal 'sample.asciidoc', section_1.file
         | 
| 388 | 
            +
                  assert_equal 10, section_1.lineno
         | 
| 389 | 
            +
                end
         | 
| 390 | 
            +
             | 
| 346 391 | 
             
                test 'find_by should return Array of blocks anywhere in document tree that match criteria' do
         | 
| 347 392 | 
             
                  input = <<-EOS
         | 
| 348 393 | 
             
            = Document Title
         | 
| @@ -562,7 +607,7 @@ text | |
| 562 607 | 
             
                  assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
         | 
| 563 608 | 
             
                  assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
         | 
| 564 609 | 
             
                  stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
         | 
| 565 | 
            -
                  styles = stylenode. | 
| 610 | 
            +
                  styles = stylenode.content
         | 
| 566 611 | 
             
                  assert !styles.nil?
         | 
| 567 612 | 
             
                  assert !styles.strip.empty?
         | 
| 568 613 | 
             
                end
         | 
| @@ -598,7 +643,7 @@ text | |
| 598 643 | 
             
                      :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss!' => ''}
         | 
| 599 644 | 
             
                  assert_css 'html:root > head > style', output, 1
         | 
| 600 645 | 
             
                  stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
         | 
| 601 | 
            -
                  styles = stylenode. | 
| 646 | 
            +
                  styles = stylenode.content
         | 
| 602 647 | 
             
                  assert !styles.nil?
         | 
| 603 648 | 
             
                  assert !styles.strip.empty?
         | 
| 604 649 | 
             
                end
         | 
| @@ -646,7 +691,7 @@ text | |
| 646 691 | 
             
                  output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :safe => Asciidoctor::SafeMode::SAFE, :to_file => false,
         | 
| 647 692 | 
             
                      :attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets', 'linkcss!' => ''}
         | 
| 648 693 | 
             
                  stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
         | 
| 649 | 
            -
                  styles = stylenode. | 
| 694 | 
            +
                  styles = stylenode.content
         | 
| 650 695 | 
             
                  assert !styles.nil?
         | 
| 651 696 | 
             
                  assert !styles.strip.empty?
         | 
| 652 697 | 
             
                end
         | 
| @@ -657,7 +702,7 @@ text | |
| 657 702 | 
             
                  begin
         | 
| 658 703 | 
             
                    Asciidoctor.convert_file sample_input_path
         | 
| 659 704 | 
             
                    assert File.exist?(sample_output_path)
         | 
| 660 | 
            -
                    output =  | 
| 705 | 
            +
                    output = IO.read(sample_output_path)
         | 
| 661 706 | 
             
                    assert !output.empty?
         | 
| 662 707 | 
             
                    assert_xpath '/html', output, 1
         | 
| 663 708 | 
             
                    assert_xpath '/html/head', output, 1
         | 
| @@ -675,7 +720,7 @@ text | |
| 675 720 | 
             
                  begin
         | 
| 676 721 | 
             
                    Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path
         | 
| 677 722 | 
             
                    assert File.exist?(sample_output_path)
         | 
| 678 | 
            -
                    output =  | 
| 723 | 
            +
                    output = IO.read(sample_output_path)
         | 
| 679 724 | 
             
                    assert !output.empty?
         | 
| 680 725 | 
             
                    assert_xpath '/html', output, 1
         | 
| 681 726 | 
             
                    assert_xpath '/html/head', output, 1
         | 
| @@ -694,7 +739,7 @@ text | |
| 694 739 | 
             
                  begin
         | 
| 695 740 | 
             
                    Asciidoctor.convert_file sample_input_path, :to_file => 'result.html', :base_dir => fixture_dir
         | 
| 696 741 | 
             
                    assert File.exist?(sample_output_path)
         | 
| 697 | 
            -
                    output =  | 
| 742 | 
            +
                    output = IO.read(sample_output_path)
         | 
| 698 743 | 
             
                    assert !output.empty?
         | 
| 699 744 | 
             
                    assert_xpath '/html', output, 1
         | 
| 700 745 | 
             
                    assert_xpath '/html/head', output, 1
         | 
| @@ -1001,14 +1046,32 @@ text | |
| 1001 1046 | 
             
                  assert_css 'copyright', output, 0
         | 
| 1002 1047 | 
             
                end
         | 
| 1003 1048 |  | 
| 1004 | 
            -
                test 'should  | 
| 1005 | 
            -
                  sample_input_path = fixture_path | 
| 1049 | 
            +
                test 'should substitute attributes in docinfo files by default' do
         | 
| 1050 | 
            +
                  sample_input_path = fixture_path 'subs.adoc'
         | 
| 1051 | 
            +
                  output, warnings = redirect_streams do |_, err|
         | 
| 1052 | 
            +
                    output = Asciidoctor.convert_file sample_input_path,
         | 
| 1053 | 
            +
                        :to_file => false,
         | 
| 1054 | 
            +
                        :header_footer => true,
         | 
| 1055 | 
            +
                        :safe => :server,
         | 
| 1056 | 
            +
                        :attributes => { 'docinfo' => '', 'bootstrap-version' => nil, 'linkcss' => '', 'attribute-missing' => 'drop-line' }
         | 
| 1057 | 
            +
                    [output, err.string]
         | 
| 1058 | 
            +
                  end
         | 
| 1059 | 
            +
                  refute output.empty?
         | 
| 1060 | 
            +
                  assert_css 'script', output, 0
         | 
| 1061 | 
            +
                  assert_xpath %(//meta[@name="copyright"][@content="(C) OpenDevise"]), output, 1
         | 
| 1062 | 
            +
                  assert_includes warnings, 'dropping line containing reference to missing attribute'
         | 
| 1063 | 
            +
                end
         | 
| 1006 1064 |  | 
| 1007 | 
            -
             | 
| 1008 | 
            -
             | 
| 1009 | 
            -
                   | 
| 1065 | 
            +
                test 'should apply explicit substitutions to docinfo files' do
         | 
| 1066 | 
            +
                  sample_input_path = fixture_path 'subs.adoc'
         | 
| 1067 | 
            +
                  output = Asciidoctor.convert_file sample_input_path,
         | 
| 1068 | 
            +
                      :to_file => false,
         | 
| 1069 | 
            +
                      :header_footer => true,
         | 
| 1070 | 
            +
                      :safe => :server,
         | 
| 1071 | 
            +
                      :attributes => { 'docinfo' => '', 'docinfosubs' => 'attributes,replacements', 'linkcss' => '' }
         | 
| 1072 | 
            +
                  refute output.empty?
         | 
| 1010 1073 | 
             
                  assert_css 'script[src="bootstrap.3.2.0.min.js"]', output, 1
         | 
| 1011 | 
            -
                  assert_xpath %(//meta[@name="copyright"][@content="#{ | 
| 1074 | 
            +
                  assert_xpath %(//meta[@name="copyright"][@content="#{decode_char 169} OpenDevise"]), output, 1
         | 
| 1012 1075 | 
             
                end
         | 
| 1013 1076 | 
             
              end
         | 
| 1014 1077 |  | 
| @@ -1063,6 +1126,19 @@ text | |
| 1063 1126 | 
             
                    assert converter.respond_to? element
         | 
| 1064 1127 | 
             
                  end
         | 
| 1065 1128 | 
             
                end
         | 
| 1129 | 
            +
             | 
| 1130 | 
            +
                test 'should add favicon if favicon attribute is set' do
         | 
| 1131 | 
            +
                  {
         | 
| 1132 | 
            +
                    '' => %w(favicon.ico image/x-icon),
         | 
| 1133 | 
            +
                    '/favicon.ico' => %w(/favicon.ico image/x-icon),
         | 
| 1134 | 
            +
                    '/img/favicon.png' => %w(/img/favicon.png image/png)
         | 
| 1135 | 
            +
                  }.each {|val, (href, type)|
         | 
| 1136 | 
            +
                    result = render_string %(= Untitled), :attributes => { 'favicon' => val }
         | 
| 1137 | 
            +
                    assert_css 'link[rel="shortcut icon"]', result, 1
         | 
| 1138 | 
            +
                    assert_css %(link[rel="shortcut icon"][href="#{href}"]), result, 1
         | 
| 1139 | 
            +
                    assert_css %(link[rel="shortcut icon"][type="#{type}"]), result, 1
         | 
| 1140 | 
            +
                  }
         | 
| 1141 | 
            +
                end
         | 
| 1066 1142 | 
             
              end
         | 
| 1067 1143 |  | 
| 1068 1144 | 
             
              context 'Structure' do
         | 
| @@ -1074,6 +1150,50 @@ text | |
| 1074 1150 | 
             
                  assert_nil doc.header
         | 
| 1075 1151 | 
             
                end
         | 
| 1076 1152 |  | 
| 1153 | 
            +
                test 'should enable compat mode for document with legacy doctitle' do
         | 
| 1154 | 
            +
                  input = <<-EOS
         | 
| 1155 | 
            +
            Document Title
         | 
| 1156 | 
            +
            ==============
         | 
| 1157 | 
            +
             | 
| 1158 | 
            +
            +content+
         | 
| 1159 | 
            +
                  EOS
         | 
| 1160 | 
            +
             | 
| 1161 | 
            +
                  doc = document_from_string input
         | 
| 1162 | 
            +
                  assert(doc.attr? 'compat-mode')
         | 
| 1163 | 
            +
                  result = doc.convert
         | 
| 1164 | 
            +
                  assert_xpath '//code[text()="content"]', result, 1
         | 
| 1165 | 
            +
                end
         | 
| 1166 | 
            +
             | 
| 1167 | 
            +
                test 'should not enable compat mode for document with legacy doctitle if compat mode disable by header' do
         | 
| 1168 | 
            +
                  input = <<-EOS
         | 
| 1169 | 
            +
            Document Title
         | 
| 1170 | 
            +
            ==============
         | 
| 1171 | 
            +
            :compat-mode!:
         | 
| 1172 | 
            +
             | 
| 1173 | 
            +
            +content+
         | 
| 1174 | 
            +
                  EOS
         | 
| 1175 | 
            +
             | 
| 1176 | 
            +
                  doc = document_from_string input
         | 
| 1177 | 
            +
                  assert_nil(doc.attr 'compat-mode')
         | 
| 1178 | 
            +
                  result = doc.convert
         | 
| 1179 | 
            +
                  assert_xpath '//code[text()="content"]', result, 0
         | 
| 1180 | 
            +
                end
         | 
| 1181 | 
            +
             | 
| 1182 | 
            +
                test 'should not enable compat mode for document with legacy doctitle if compat mode is locked by API' do
         | 
| 1183 | 
            +
                  input = <<-EOS
         | 
| 1184 | 
            +
            Document Title
         | 
| 1185 | 
            +
            ==============
         | 
| 1186 | 
            +
             | 
| 1187 | 
            +
            +content+
         | 
| 1188 | 
            +
                  EOS
         | 
| 1189 | 
            +
             | 
| 1190 | 
            +
                  doc = document_from_string input, :attributes => { 'compat-mode' => nil }
         | 
| 1191 | 
            +
                  assert(doc.attribute_locked? 'compat-mode')
         | 
| 1192 | 
            +
                  assert_nil(doc.attr 'compat-mode')
         | 
| 1193 | 
            +
                  result = doc.convert
         | 
| 1194 | 
            +
                  assert_xpath '//code[text()="content"]', result, 0
         | 
| 1195 | 
            +
                end
         | 
| 1196 | 
            +
             | 
| 1077 1197 | 
             
                test 'title partition API with default separator' do
         | 
| 1078 1198 | 
             
                  title = Asciidoctor::Document::Title.new 'Main Title: And More: Subtitle'
         | 
| 1079 1199 | 
             
                  assert_equal 'Main Title: And More', title.main
         | 
| @@ -1119,6 +1239,23 @@ content | |
| 1119 1239 | 
             
                  assert_equal 'Subtitle', title.subtitle
         | 
| 1120 1240 | 
             
                end
         | 
| 1121 1241 |  | 
| 1242 | 
            +
                test 'should not honor custom separator for doctitle if attribute is locked by API' do
         | 
| 1243 | 
            +
                  input = <<-EOS
         | 
| 1244 | 
            +
            [separator=::]
         | 
| 1245 | 
            +
            = Main Title - *Subtitle*
         | 
| 1246 | 
            +
            Author Name
         | 
| 1247 | 
            +
             | 
| 1248 | 
            +
            content
         | 
| 1249 | 
            +
                  EOS
         | 
| 1250 | 
            +
             | 
| 1251 | 
            +
                  doc = document_from_string input, :attributes => { 'title-separator' => ' -' }
         | 
| 1252 | 
            +
                  title = doc.doctitle :partition => true, :sanitize => true
         | 
| 1253 | 
            +
                  assert title.subtitle?
         | 
| 1254 | 
            +
                  assert title.sanitized?
         | 
| 1255 | 
            +
                  assert_equal 'Main Title', title.main
         | 
| 1256 | 
            +
                  assert_equal 'Subtitle', title.subtitle
         | 
| 1257 | 
            +
                end
         | 
| 1258 | 
            +
             | 
| 1122 1259 | 
             
                test 'document with doctitle defined as attribute entry' do
         | 
| 1123 1260 | 
             
                 input = <<-EOS
         | 
| 1124 1261 | 
             
            :doctitle: Document Title
         | 
| @@ -1251,7 +1388,7 @@ content | |
| 1251 1388 |  | 
| 1252 1389 | 
             
                  output = render_string input
         | 
| 1253 1390 | 
             
                  assert_xpath '/html/head/title[text()="Document Title"]', output, 1
         | 
| 1254 | 
            -
                  nodes = xmlnodes_at_xpath('//*[@id="header"]/h1', output | 
| 1391 | 
            +
                  nodes = xmlnodes_at_xpath('//*[@id="header"]/h1', output)
         | 
| 1255 1392 | 
             
                  assert_equal 1, nodes.size
         | 
| 1256 1393 | 
             
                  assert_match('<h1><strong>Document</strong> <span class="image"><img src="logo.png" alt="logo"></span> <em>Title</em> <span class="image"><img src="another-logo.png" alt="another logo"></span></h1>', output)
         | 
| 1257 1394 | 
             
                end
         | 
| @@ -1404,6 +1541,18 @@ content | |
| 1404 1541 | 
             
                  assert_xpath '//articleinfo/authorinitials[text() = "DW"]', output, 1
         | 
| 1405 1542 | 
             
                end
         | 
| 1406 1543 |  | 
| 1544 | 
            +
                test 'should sanitize content of HTML meta authors tag' do
         | 
| 1545 | 
            +
                  input = <<-EOS
         | 
| 1546 | 
            +
            = Document Title
         | 
| 1547 | 
            +
            :author: pass:n[http://example.org/community/team.html[Ze *Product* team]]
         | 
| 1548 | 
            +
             | 
| 1549 | 
            +
            content
         | 
| 1550 | 
            +
                  EOS
         | 
| 1551 | 
            +
             | 
| 1552 | 
            +
                  output = render_string input
         | 
| 1553 | 
            +
                  assert_xpath '//meta[@name="author"][@content="Ze Product team"]', output, 1
         | 
| 1554 | 
            +
                end
         | 
| 1555 | 
            +
             | 
| 1407 1556 | 
             
                test 'should include multiple authors in HTML output' do
         | 
| 1408 1557 | 
             
                  input = <<-EOS
         | 
| 1409 1558 | 
             
            = Document Title
         | 
| @@ -1564,11 +1713,11 @@ finally a reference to the second footnote footnoteref:[note2]. | |
| 1564 1713 | 
             
                  assert_css '#footnotes .footnote', output, 2
         | 
| 1565 1714 | 
             
                  assert_css '#footnotes .footnote#_footnote_1', output, 1
         | 
| 1566 1715 | 
             
                  assert_xpath '//div[@id="footnotes"]/div[@id="_footnote_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
         | 
| 1567 | 
            -
                  text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnote_1"]/text()', output | 
| 1716 | 
            +
                  text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnote_1"]/text()', output
         | 
| 1568 1717 | 
             
                  assert_equal '. An example footnote.', text.text.strip
         | 
| 1569 1718 | 
             
                  assert_css '#footnotes .footnote#_footnote_2', output, 1
         | 
| 1570 1719 | 
             
                  assert_xpath '//div[@id="footnotes"]/div[@id="_footnote_2"]/a[@href="#_footnoteref_2"][text()="2"]', output, 1
         | 
| 1571 | 
            -
                  text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnote_2"]/text()', output | 
| 1720 | 
            +
                  text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnote_2"]/text()', output
         | 
| 1572 1721 | 
             
                  assert_equal '. Second footnote.', text.text.strip
         | 
| 1573 1722 | 
             
                end
         | 
| 1574 1723 |  | 
| @@ -1582,7 +1731,7 @@ Text that has supporting information{empty}footnote:[An example footnote.]. | |
| 1582 1731 | 
             
                  assert_css '#footnotes .footnote', output, 1
         | 
| 1583 1732 | 
             
                  assert_css '#footnotes .footnote#_footnote_1', output, 1
         | 
| 1584 1733 | 
             
                  assert_xpath '/div[@id="footnotes"]/div[@id="_footnote_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
         | 
| 1585 | 
            -
                  text = xmlnodes_at_xpath '/div[@id="footnotes"]/div[@id="_footnote_1"]/text()', output | 
| 1734 | 
            +
                  text = xmlnodes_at_xpath '/div[@id="footnotes"]/div[@id="_footnote_1"]/text()', output
         | 
| 1586 1735 | 
             
                  assert_equal '. An example footnote.', text.text.strip
         | 
| 1587 1736 | 
             
                end
         | 
| 1588 1737 |  | 
| @@ -1596,6 +1745,30 @@ Text that has supporting information{empty}footnote:[An example footnote.]. | |
| 1596 1745 | 
             
                end
         | 
| 1597 1746 | 
             
              end
         | 
| 1598 1747 |  | 
| 1748 | 
            +
              context 'Catalog' do
         | 
| 1749 | 
            +
                test 'document catalog is aliased as references' do
         | 
| 1750 | 
            +
                  input = <<-EOS
         | 
| 1751 | 
            +
            = Document Title
         | 
| 1752 | 
            +
             | 
| 1753 | 
            +
            == Section A
         | 
| 1754 | 
            +
             | 
| 1755 | 
            +
            content
         | 
| 1756 | 
            +
             | 
| 1757 | 
            +
            == Section B
         | 
| 1758 | 
            +
             | 
| 1759 | 
            +
            content{blank}footnote:[commentary]
         | 
| 1760 | 
            +
                  EOS
         | 
| 1761 | 
            +
             | 
| 1762 | 
            +
                  doc = document_from_string input
         | 
| 1763 | 
            +
                  refute_nil doc.catalog
         | 
| 1764 | 
            +
                  assert_equal [:footnotes, :ids, :images, :includes, :indexterms, :links, :refs].to_set, doc.catalog.keys.to_set
         | 
| 1765 | 
            +
                  assert_same doc.catalog, doc.references
         | 
| 1766 | 
            +
                  assert_same doc.catalog[:footnotes], doc.references[:footnotes]
         | 
| 1767 | 
            +
                  assert_same doc.catalog[:ids], doc.references[:ids]
         | 
| 1768 | 
            +
                  assert_equal 'Section A', doc.references[:ids]['_section_a']
         | 
| 1769 | 
            +
                end
         | 
| 1770 | 
            +
              end
         | 
| 1771 | 
            +
             | 
| 1599 1772 | 
             
              context 'Backends and Doctypes' do
         | 
| 1600 1773 | 
             
                test 'html5 backend doctype article' do
         | 
| 1601 1774 | 
             
                  result = render_string("= Title\n\nparagraph", :attributes => {'backend' => 'html5'})
         | 
| @@ -1850,14 +2023,14 @@ section body | |
| 1850 2023 | 
             
                  EOS
         | 
| 1851 2024 | 
             
                  result = render_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5'})
         | 
| 1852 2025 | 
             
                  assert_xpath '/xmlns:article', result, 1
         | 
| 1853 | 
            -
                  doc = xmlnodes_at_xpath('/xmlns:article', result, 1) | 
| 2026 | 
            +
                  doc = xmlnodes_at_xpath('/xmlns:article', result, 1)
         | 
| 1854 2027 | 
             
                  assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
         | 
| 1855 2028 | 
             
                  assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xl']
         | 
| 1856 2029 | 
             
                  assert_xpath '/xmlns:article[@version="5.0"]', result, 1
         | 
| 1857 2030 | 
             
                  assert_xpath '/xmlns:article/xmlns:info/xmlns:title[text() = "Title"]', result, 1
         | 
| 1858 2031 | 
             
                  assert_xpath '/xmlns:article/xmlns:simpara[text() = "preamble"]', result, 1
         | 
| 1859 2032 | 
             
                  assert_xpath '/xmlns:article/xmlns:section', result, 1
         | 
| 1860 | 
            -
                  section = xmlnodes_at_xpath('/xmlns:article/xmlns:section', result, 1) | 
| 2033 | 
            +
                  section = xmlnodes_at_xpath('/xmlns:article/xmlns:section', result, 1)
         | 
| 1861 2034 | 
             
                  # nokogiri can't make up its mind
         | 
| 1862 2035 | 
             
                  id_attr = section.attribute('id') || section.attribute('xml:id')
         | 
| 1863 2036 | 
             
                  refute_nil id_attr
         | 
| @@ -1884,7 +2057,7 @@ section body | |
| 1884 2057 | 
             
                  EOS
         | 
| 1885 2058 | 
             
                  result = render_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5', 'doctype' => 'manpage'})
         | 
| 1886 2059 | 
             
                  assert_xpath '/xmlns:refentry', result, 1
         | 
| 1887 | 
            -
                  doc = xmlnodes_at_xpath('/xmlns:refentry', result, 1) | 
| 2060 | 
            +
                  doc = xmlnodes_at_xpath('/xmlns:refentry', result, 1)
         | 
| 1888 2061 | 
             
                  assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
         | 
| 1889 2062 | 
             
                  assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xl']
         | 
| 1890 2063 | 
             
                  assert_xpath '/xmlns:refentry[@version="5.0"]', result, 1
         | 
| @@ -1896,7 +2069,7 @@ section body | |
| 1896 2069 | 
             
                  assert_xpath '/xmlns:refentry/xmlns:refsynopsisdiv', result, 1
         | 
| 1897 2070 | 
             
                  assert_xpath '/xmlns:refentry/xmlns:refsynopsisdiv/xmlns:simpara[text() = "some text"]', result, 1
         | 
| 1898 2071 | 
             
                  assert_xpath '/xmlns:refentry/xmlns:refsection', result, 1
         | 
| 1899 | 
            -
                  section = xmlnodes_at_xpath('/xmlns:refentry/xmlns:refsection', result, 1) | 
| 2072 | 
            +
                  section = xmlnodes_at_xpath('/xmlns:refentry/xmlns:refsection', result, 1)
         | 
| 1900 2073 | 
             
                  # nokogiri can't make up its mind
         | 
| 1901 2074 | 
             
                  id_attr = section.attribute('id') || section.attribute('xml:id')
         | 
| 1902 2075 | 
             
                  refute_nil id_attr
         | 
| @@ -1918,14 +2091,14 @@ chapter body | |
| 1918 2091 | 
             
                  EOS
         | 
| 1919 2092 | 
             
                  result = render_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5', 'doctype' => 'book'})
         | 
| 1920 2093 | 
             
                  assert_xpath '/xmlns:book', result, 1
         | 
| 1921 | 
            -
                  doc = xmlnodes_at_xpath('/xmlns:book', result, 1) | 
| 2094 | 
            +
                  doc = xmlnodes_at_xpath('/xmlns:book', result, 1)
         | 
| 1922 2095 | 
             
                  assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
         | 
| 1923 2096 | 
             
                  assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xl']
         | 
| 1924 2097 | 
             
                  assert_xpath '/xmlns:book[@version="5.0"]', result, 1
         | 
| 1925 2098 | 
             
                  assert_xpath '/xmlns:book/xmlns:info/xmlns:title[text() = "Title"]', result, 1
         | 
| 1926 2099 | 
             
                  assert_xpath '/xmlns:book/xmlns:preface/xmlns:simpara[text() = "preamble"]', result, 1
         | 
| 1927 2100 | 
             
                  assert_xpath '/xmlns:book/xmlns:chapter', result, 1
         | 
| 1928 | 
            -
                  chapter = xmlnodes_at_xpath('/xmlns:book/xmlns:chapter', result, 1) | 
| 2101 | 
            +
                  chapter = xmlnodes_at_xpath('/xmlns:book/xmlns:chapter', result, 1)
         | 
| 1929 2102 | 
             
                  # nokogiri can't make up its mind
         | 
| 1930 2103 | 
             
                  id_attr = chapter.attribute('id') || chapter.attribute('xml:id')
         | 
| 1931 2104 | 
             
                  refute_nil id_attr
         | 
| @@ -1934,6 +2107,28 @@ chapter body | |
| 1934 2107 | 
             
                  assert_equal '_first_chapter', id_attr.value
         | 
| 1935 2108 | 
             
                end
         | 
| 1936 2109 |  | 
| 2110 | 
            +
                test 'adds a front and back cover image to DocBook 5 when doctype is book' do
         | 
| 2111 | 
            +
                  input = <<-EOS
         | 
| 2112 | 
            +
            = Title
         | 
| 2113 | 
            +
            :doctype: book
         | 
| 2114 | 
            +
            :imagesdir: images
         | 
| 2115 | 
            +
            :front-cover-image: image:front-cover.jpg[scaledwidth=210mm]
         | 
| 2116 | 
            +
            :back-cover-image: image:back-cover.jpg[scaledwidth=210mm]
         | 
| 2117 | 
            +
             | 
| 2118 | 
            +
            preamble
         | 
| 2119 | 
            +
             | 
| 2120 | 
            +
            == First Chapter
         | 
| 2121 | 
            +
             | 
| 2122 | 
            +
            chapter body
         | 
| 2123 | 
            +
                  EOS
         | 
| 2124 | 
            +
             | 
| 2125 | 
            +
                  result = render_string input, :attributes => {'backend' => 'docbook5'}
         | 
| 2126 | 
            +
                  assert_xpath '//info/cover[@role="front"]', result, 1
         | 
| 2127 | 
            +
                  assert_xpath '//info/cover[@role="front"]//imagedata[@fileref="images/front-cover.jpg"]', result, 1
         | 
| 2128 | 
            +
                  assert_xpath '//info/cover[@role="back"]', result, 1
         | 
| 2129 | 
            +
                  assert_xpath '//info/cover[@role="back"]//imagedata[@fileref="images/back-cover.jpg"]', result, 1
         | 
| 2130 | 
            +
                end
         | 
| 2131 | 
            +
             | 
| 1937 2132 | 
             
                test 'should be able to set backend using :backend option key' do
         | 
| 1938 2133 | 
             
                  doc = empty_document :backend => 'html5'
         | 
| 1939 2134 | 
             
                  assert_equal 'html5', doc.attributes['backend']
         | 
| @@ -2115,7 +2310,7 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 2115 2310 | 
             
            *asciidoctor* ['OPTION']... 'FILE'..
         | 
| 2116 2311 | 
             
                  EOS
         | 
| 2117 2312 |  | 
| 2118 | 
            -
                  output =  | 
| 2313 | 
            +
                  output = render_embedded_string input
         | 
| 2119 2314 | 
             
                  assert_xpath '/h1[text()="asciidoctor(1) Manual Page"]', output, 1
         | 
| 2120 2315 | 
             
                  assert_xpath '/h1/following-sibling::h2[text()="NAME"]', output, 1
         | 
| 2121 2316 | 
             
                  assert_xpath '/h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]', output, 1
         | 
| @@ -2141,20 +2336,35 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 2141 2336 | 
             
                test 'keeps naughty relative paths from getting outside' do
         | 
| 2142 2337 | 
             
                  naughty_path = 'safe/ok/../../../../../etc/passwd'
         | 
| 2143 2338 | 
             
                  doc = empty_document
         | 
| 2144 | 
            -
                  secure_path = doc.normalize_asset_path(naughty_path)
         | 
| 2339 | 
            +
                  secure_path = redirect_streams { doc.normalize_asset_path(naughty_path) }
         | 
| 2145 2340 | 
             
                  assert naughty_path != secure_path
         | 
| 2146 2341 | 
             
                  assert_match(/^#{doc.base_dir}/, secure_path)
         | 
| 2147 2342 | 
             
                end
         | 
| 2148 2343 |  | 
| 2149 | 
            -
                test 'should raise an exception when a converter cannot be resolved' do
         | 
| 2344 | 
            +
                test 'should raise an exception when a converter cannot be resolved before conversion' do
         | 
| 2345 | 
            +
                  input = <<-EOS
         | 
| 2346 | 
            +
            = Document Title
         | 
| 2347 | 
            +
             | 
| 2348 | 
            +
            text
         | 
| 2349 | 
            +
                  EOS
         | 
| 2350 | 
            +
                  exception = assert_raises NotImplementedError do
         | 
| 2351 | 
            +
                    Asciidoctor.convert input, :backend => 'unknownBackend'
         | 
| 2352 | 
            +
                  end
         | 
| 2353 | 
            +
                  assert_includes exception.message, 'missing converter for backend \'unknownBackend\''
         | 
| 2354 | 
            +
                end
         | 
| 2355 | 
            +
             | 
| 2356 | 
            +
                test 'should raise an exception when a converter cannot be resolved while parsing' do
         | 
| 2150 2357 | 
             
                  input = <<-EOS
         | 
| 2151 2358 | 
             
            = Document Title
         | 
| 2359 | 
            +
             | 
| 2360 | 
            +
            == A _Big_ Section
         | 
| 2361 | 
            +
             | 
| 2152 2362 | 
             
            text
         | 
| 2153 2363 | 
             
                  EOS
         | 
| 2154 | 
            -
                  exception = assert_raises  | 
| 2155 | 
            -
                    Asciidoctor. | 
| 2364 | 
            +
                  exception = assert_raises NotImplementedError do
         | 
| 2365 | 
            +
                    Asciidoctor.convert input, :backend => 'unknownBackend'
         | 
| 2156 2366 | 
             
                  end
         | 
| 2157 | 
            -
                   | 
| 2367 | 
            +
                  assert_includes exception.message, 'missing converter for backend \'unknownBackend\''
         | 
| 2158 2368 | 
             
                end
         | 
| 2159 2369 | 
             
              end
         | 
| 2160 2370 |  |