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
    
        data/test/sections_test.rb
    CHANGED
    
    | @@ -1,5 +1,8 @@ | |
| 1 1 | 
             
            # encoding: UTF-8
         | 
| 2 | 
            -
             | 
| 2 | 
            +
            unless defined? ASCIIDOCTOR_PROJECT_DIR
         | 
| 3 | 
            +
              $: << File.dirname(__FILE__); $:.uniq!
         | 
| 4 | 
            +
              require 'test_helper'
         | 
| 5 | 
            +
            end
         | 
| 3 6 |  | 
| 4 7 | 
             
            context 'Sections' do
         | 
| 5 8 | 
             
              context 'Ids' do
         | 
| @@ -19,8 +22,8 @@ context 'Sections' do | |
| 19 22 | 
             
                end
         | 
| 20 23 |  | 
| 21 24 | 
             
                test 'synthetic id removes entities' do
         | 
| 22 | 
            -
                  sec = block_from_string('== Ben & Jerry "Ice Cream Brothers"')
         | 
| 23 | 
            -
                  assert_equal ' | 
| 25 | 
            +
                  sec = block_from_string('== Ben & Jerry & Company "Ice Cream Brothers" ✾')
         | 
| 26 | 
            +
                  assert_equal '_ben_jerry_company_ice_cream_brothers', sec.id
         | 
| 24 27 | 
             
                end
         | 
| 25 28 |  | 
| 26 29 | 
             
                test 'synthetic id prefix can be customized' do
         | 
| @@ -58,12 +61,39 @@ context 'Sections' do | |
| 58 61 | 
             
                  assert_equal 'one', sec.id
         | 
| 59 62 | 
             
                end
         | 
| 60 63 |  | 
| 61 | 
            -
                test 'explicit id can be defined using an  | 
| 64 | 
            +
                test 'explicit id can be defined using an embedded anchor' do
         | 
| 62 65 | 
             
                  sec = block_from_string("== Section One [[one]] ==")
         | 
| 63 66 | 
             
                  assert_equal 'one', sec.id
         | 
| 64 67 | 
             
                  assert_equal 'Section One', sec.title
         | 
| 65 68 | 
             
                end
         | 
| 66 69 |  | 
| 70 | 
            +
                test 'explicit id can be defined using an embedded anchor with reftext' do
         | 
| 71 | 
            +
                  sec = block_from_string("== Section One [[one,Section Uno]] ==")
         | 
| 72 | 
            +
                  assert_equal 'one', sec.id
         | 
| 73 | 
            +
                  assert_equal 'Section One', sec.title
         | 
| 74 | 
            +
                  assert_equal 'Section Uno', (sec.attr 'reftext')
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                test 'id and reftext in embedded anchor cannot be quoted' do
         | 
| 78 | 
            +
                  sec = block_from_string(%(== Section One [["one","Section Uno"]] ==))
         | 
| 79 | 
            +
                  refute_equal 'one', sec.id
         | 
| 80 | 
            +
                  assert_equal 'Section One [["one","Section Uno"]]', sec.title
         | 
| 81 | 
            +
                  assert_nil(sec.attr 'reftext')
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                test 'reftext in embedded anchor may contain comma' do
         | 
| 85 | 
            +
                  sec = block_from_string(%(== Section One [[one, Section,Uno]] ==))
         | 
| 86 | 
            +
                  assert_equal 'one', sec.id
         | 
| 87 | 
            +
                  assert_equal 'Section One', sec.title
         | 
| 88 | 
            +
                  assert_equal 'Section,Uno', (sec.attr 'reftext')
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                test 'should unescape but not process inline anchor' do
         | 
| 92 | 
            +
                  sec = block_from_string(%(== Section One \\[[one]] ==))
         | 
| 93 | 
            +
                  refute_equal 'one', sec.id
         | 
| 94 | 
            +
                  assert_equal 'Section One [[one]]', sec.title
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
             | 
| 67 97 | 
             
                test 'title substitutions are applied before generating id' do
         | 
| 68 98 | 
             
                  sec = block_from_string("== Section{sp}One\n")
         | 
| 69 99 | 
             
                  assert_equal '_section_one', sec.id
         | 
| @@ -83,6 +113,34 @@ text | |
| 83 113 | 
             
                  assert_equal '_some_section', doc.blocks[0].id
         | 
| 84 114 | 
             
                  assert_equal '_some_section_2', doc.blocks[1].id
         | 
| 85 115 | 
             
                end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                test 'should use specified id and reftext when registering section reference' do
         | 
| 118 | 
            +
                  input = <<-EOS
         | 
| 119 | 
            +
            [[install,Install Procedure]]
         | 
| 120 | 
            +
            == Install
         | 
| 121 | 
            +
             | 
| 122 | 
            +
            content
         | 
| 123 | 
            +
                  EOS
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                  doc = document_from_string input
         | 
| 126 | 
            +
                  reftext = doc.references[:ids]['install']
         | 
| 127 | 
            +
                  refute_nil reftext
         | 
| 128 | 
            +
                  assert_equal 'Install Procedure', reftext
         | 
| 129 | 
            +
                end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                test 'should use specified reftext when registering section reference' do
         | 
| 132 | 
            +
                  input = <<-EOS
         | 
| 133 | 
            +
            [reftext="Install Procedure"]
         | 
| 134 | 
            +
            == Install
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            content
         | 
| 137 | 
            +
                  EOS
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                  doc = document_from_string input
         | 
| 140 | 
            +
                  reftext = doc.references[:ids]['_install']
         | 
| 141 | 
            +
                  refute_nil reftext
         | 
| 142 | 
            +
                  assert_equal 'Install Procedure', reftext
         | 
| 143 | 
            +
                end
         | 
| 86 144 | 
             
              end
         | 
| 87 145 |  | 
| 88 146 | 
             
              context "document title (level 0)" do
         | 
| @@ -173,9 +231,13 @@ preamble | |
| 173 231 | 
             
                  assert_xpath "//h2[@id='_my_title'][text() = 'My Title ===']", render_string("== My Title ===")
         | 
| 174 232 | 
             
                end
         | 
| 175 233 |  | 
| 176 | 
            -
                test "with  | 
| 234 | 
            +
                test "with XML entity" do
         | 
| 177 235 | 
             
                  assert_xpath "//h2[@id='_where_s_the_love'][text() = \"Where#{[8217].pack('U*')}s the love?\"]", render_string("== Where's the love?")
         | 
| 178 236 | 
             
                end
         | 
| 237 | 
            +
                
         | 
| 238 | 
            +
                test "with non-word character" do
         | 
| 239 | 
            +
                  assert_xpath "//h2[@id='_where_s_the_love'][text() = \"Where’s the love?\"]", render_string("== Where’s the love?")
         | 
| 240 | 
            +
                end
         | 
| 179 241 |  | 
| 180 242 | 
             
                test "with sequential non-word characters" do
         | 
| 181 243 | 
             
                  assert_xpath "//h2[@id='_what_the_is_this'][text() = 'What the \#@$ is this?']", render_string('== What the #@$ is this?')
         | 
| @@ -198,8 +260,37 @@ preamble | |
| 198 260 | 
             
            == Asciidoctor in 中文
         | 
| 199 261 | 
             
                  EOS
         | 
| 200 262 | 
             
                  output = render_string input
         | 
| 201 | 
            -
                   | 
| 263 | 
            +
                  if ::RUBY_MIN_VERSION_1_9
         | 
| 264 | 
            +
                    assert_xpath '//h2[@id="_asciidoctor_in_中文"][text()="Asciidoctor in 中文"]', output
         | 
| 265 | 
            +
                  else
         | 
| 266 | 
            +
                    assert_xpath '//h2[@id="_asciidoctor_in"][text()="Asciidoctor in 中文"]', output
         | 
| 267 | 
            +
                  end
         | 
| 202 268 | 
             
                end
         | 
| 269 | 
            +
             | 
| 270 | 
            +
                test 'with only multibyte characters' do
         | 
| 271 | 
            +
                  input = <<-EOS
         | 
| 272 | 
            +
            == 视图
         | 
| 273 | 
            +
                  EOS
         | 
| 274 | 
            +
                  output = render_embedded_string input
         | 
| 275 | 
            +
                  assert_xpath '//h2[@id="_视图"][text()="视图"]', output
         | 
| 276 | 
            +
                end if ::RUBY_MIN_VERSION_1_9
         | 
| 277 | 
            +
             | 
| 278 | 
            +
                test 'multiline syntax with only multibyte characters' do
         | 
| 279 | 
            +
                  input = <<-EOS
         | 
| 280 | 
            +
            视图
         | 
| 281 | 
            +
            --
         | 
| 282 | 
            +
             | 
| 283 | 
            +
            content
         | 
| 284 | 
            +
             | 
| 285 | 
            +
            连接器
         | 
| 286 | 
            +
            ---
         | 
| 287 | 
            +
             | 
| 288 | 
            +
            content
         | 
| 289 | 
            +
                  EOS
         | 
| 290 | 
            +
                  output = render_embedded_string input
         | 
| 291 | 
            +
                  assert_xpath '//h2[@id="_视图"][text()="视图"]', output
         | 
| 292 | 
            +
                  assert_xpath '//h2[@id="_连接器"][text()="连接器"]', output
         | 
| 293 | 
            +
                end if ::RUBY_MIN_VERSION_1_9
         | 
| 203 294 | 
             
              end
         | 
| 204 295 |  | 
| 205 296 | 
             
              context "level 2" do 
         | 
| @@ -280,15 +371,15 @@ blah blah | |
| 280 371 | 
             
                test 'should create floating title if style is float' do
         | 
| 281 372 | 
             
                  input = <<-EOS
         | 
| 282 373 | 
             
            [float]
         | 
| 283 | 
            -
            =  | 
| 374 | 
            +
            = Independent Heading!
         | 
| 284 375 |  | 
| 285 376 | 
             
            not in section
         | 
| 286 377 | 
             
                  EOS
         | 
| 287 378 |  | 
| 288 379 | 
             
                  output = render_embedded_string input
         | 
| 289 | 
            -
                  assert_xpath '/h1[@id=" | 
| 380 | 
            +
                  assert_xpath '/h1[@id="_independent_heading"]', output, 1
         | 
| 290 381 | 
             
                  assert_xpath '/h1[@class="float"]', output, 1
         | 
| 291 | 
            -
                  assert_xpath %(/h1[@class="float"][text()=" | 
| 382 | 
            +
                  assert_xpath %(/h1[@class="float"][text()="Independent Heading!"]), output, 1
         | 
| 292 383 | 
             
                  assert_xpath '/h1/following-sibling::*[@class="paragraph"]', output, 1
         | 
| 293 384 | 
             
                  assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p', output, 1
         | 
| 294 385 | 
             
                  assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p[text()="not in section"]', output, 1
         | 
| @@ -297,25 +388,59 @@ not in section | |
| 297 388 | 
             
                test 'should create floating title if style is discrete' do
         | 
| 298 389 | 
             
                  input = <<-EOS
         | 
| 299 390 | 
             
            [discrete]
         | 
| 300 | 
            -
            ===  | 
| 391 | 
            +
            === Independent Heading!
         | 
| 301 392 |  | 
| 302 393 | 
             
            not in section
         | 
| 303 394 | 
             
                  EOS
         | 
| 304 395 |  | 
| 305 396 | 
             
                  output = render_embedded_string input
         | 
| 306 397 | 
             
                  assert_xpath '/h3', output, 1
         | 
| 307 | 
            -
                  assert_xpath '/h3[@id=" | 
| 398 | 
            +
                  assert_xpath '/h3[@id="_independent_heading"]', output, 1
         | 
| 308 399 | 
             
                  assert_xpath '/h3[@class="discrete"]', output, 1
         | 
| 309 | 
            -
                  assert_xpath %(/h3[@class="discrete"][text()=" | 
| 400 | 
            +
                  assert_xpath %(/h3[@class="discrete"][text()="Independent Heading!"]), output, 1
         | 
| 310 401 | 
             
                  assert_xpath '/h3/following-sibling::*[@class="paragraph"]', output, 1
         | 
| 311 402 | 
             
                  assert_xpath '/h3/following-sibling::*[@class="paragraph"]/p', output, 1
         | 
| 312 403 | 
             
                  assert_xpath '/h3/following-sibling::*[@class="paragraph"]/p[text()="not in section"]', output, 1
         | 
| 313 404 | 
             
                end
         | 
| 314 405 |  | 
| 406 | 
            +
                test 'should create floating title if style is float with shorthand role and id' do
         | 
| 407 | 
            +
                  input = <<-EOS
         | 
| 408 | 
            +
            [float.independent#first]
         | 
| 409 | 
            +
            = Independent Heading!
         | 
| 410 | 
            +
             | 
| 411 | 
            +
            not in section
         | 
| 412 | 
            +
                  EOS
         | 
| 413 | 
            +
             | 
| 414 | 
            +
                  output = render_embedded_string input
         | 
| 415 | 
            +
                  assert_xpath '/h1[@id="first"]', output, 1
         | 
| 416 | 
            +
                  assert_xpath '/h1[@class="float independent"]', output, 1
         | 
| 417 | 
            +
                  assert_xpath %(/h1[@class="float independent"][text()="Independent Heading!"]), output, 1
         | 
| 418 | 
            +
                  assert_xpath '/h1/following-sibling::*[@class="paragraph"]', output, 1
         | 
| 419 | 
            +
                  assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p', output, 1
         | 
| 420 | 
            +
                  assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p[text()="not in section"]', output, 1
         | 
| 421 | 
            +
                end
         | 
| 422 | 
            +
             | 
| 423 | 
            +
                test 'should create floating title if style is discrete with shorthand role and id' do
         | 
| 424 | 
            +
                  input = <<-EOS
         | 
| 425 | 
            +
            [discrete.independent#first]
         | 
| 426 | 
            +
            = Independent Heading!
         | 
| 427 | 
            +
             | 
| 428 | 
            +
            not in section
         | 
| 429 | 
            +
                  EOS
         | 
| 430 | 
            +
             | 
| 431 | 
            +
                  output = render_embedded_string input
         | 
| 432 | 
            +
                  assert_xpath '/h1[@id="first"]', output, 1
         | 
| 433 | 
            +
                  assert_xpath '/h1[@class="discrete independent"]', output, 1
         | 
| 434 | 
            +
                  assert_xpath %(/h1[@class="discrete independent"][text()="Independent Heading!"]), output, 1
         | 
| 435 | 
            +
                  assert_xpath '/h1/following-sibling::*[@class="paragraph"]', output, 1
         | 
| 436 | 
            +
                  assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p', output, 1
         | 
| 437 | 
            +
                  assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p[text()="not in section"]', output, 1
         | 
| 438 | 
            +
                end
         | 
| 439 | 
            +
             | 
| 315 440 | 
             
                test 'floating title should be a block with context floating_title' do
         | 
| 316 441 | 
             
                  input = <<-EOS
         | 
| 317 442 | 
             
            [float]
         | 
| 318 | 
            -
            ===  | 
| 443 | 
            +
            === Independent Heading!
         | 
| 319 444 |  | 
| 320 445 | 
             
            not in section
         | 
| 321 446 | 
             
                  EOS
         | 
| @@ -323,17 +448,17 @@ not in section | |
| 323 448 | 
             
                  doc = document_from_string input
         | 
| 324 449 | 
             
                  floatingtitle = doc.blocks.first
         | 
| 325 450 | 
             
                  assert floatingtitle.is_a?(Asciidoctor::Block)
         | 
| 326 | 
            -
                  assert  | 
| 451 | 
            +
                  assert floatingtitle.context != :section
         | 
| 327 452 | 
             
                  assert_equal :floating_title, floatingtitle.context
         | 
| 328 | 
            -
                  assert_equal ' | 
| 329 | 
            -
                  assert doc.references[:ids].has_key?(' | 
| 453 | 
            +
                  assert_equal '_independent_heading', floatingtitle.id
         | 
| 454 | 
            +
                  assert doc.references[:ids].has_key?('_independent_heading')
         | 
| 330 455 | 
             
                end
         | 
| 331 456 |  | 
| 332 457 | 
             
                test 'can assign explicit id to floating title' do
         | 
| 333 458 | 
             
                  input = <<-EOS
         | 
| 334 459 | 
             
            [[unchained]]
         | 
| 335 460 | 
             
            [float]
         | 
| 336 | 
            -
            ===  | 
| 461 | 
            +
            === Independent Heading!
         | 
| 337 462 |  | 
| 338 463 | 
             
            not in section
         | 
| 339 464 | 
             
                  EOS
         | 
| @@ -365,14 +490,14 @@ not in section | |
| 365 490 | 
             
                test 'should not set id on floating title if sectids attribute is unset' do
         | 
| 366 491 | 
             
                  input = <<-EOS
         | 
| 367 492 | 
             
            [float]
         | 
| 368 | 
            -
            ===  | 
| 493 | 
            +
            === Independent Heading!
         | 
| 369 494 |  | 
| 370 495 | 
             
            not in section
         | 
| 371 496 | 
             
                  EOS
         | 
| 372 497 |  | 
| 373 498 | 
             
                  output = render_embedded_string input, :attributes => {'sectids' => nil}
         | 
| 374 499 | 
             
                  assert_xpath '/h3', output, 1
         | 
| 375 | 
            -
                  assert_xpath '/h3[@id=" | 
| 500 | 
            +
                  assert_xpath '/h3[@id="_independent_heading"]', output, 0
         | 
| 376 501 | 
             
                  assert_xpath '/h3[@class="float"]', output, 1
         | 
| 377 502 | 
             
                end
         | 
| 378 503 |  | 
| @@ -380,7 +505,7 @@ not in section | |
| 380 505 | 
             
                  input = <<-EOS
         | 
| 381 506 | 
             
            [[free]]
         | 
| 382 507 | 
             
            [float]
         | 
| 383 | 
            -
            ==  | 
| 508 | 
            +
            == Independent Heading!
         | 
| 384 509 |  | 
| 385 510 | 
             
            not in section
         | 
| 386 511 | 
             
                  EOS
         | 
| @@ -394,16 +519,46 @@ not in section | |
| 394 519 | 
             
                test 'should add role to class attribute on floating title' do
         | 
| 395 520 | 
             
                  input = <<-EOS
         | 
| 396 521 | 
             
            [float, role="isolated"]
         | 
| 397 | 
            -
            ==  | 
| 522 | 
            +
            == Independent Heading!
         | 
| 398 523 |  | 
| 399 524 | 
             
            not in section
         | 
| 400 525 | 
             
                  EOS
         | 
| 401 526 |  | 
| 402 527 | 
             
                  output = render_embedded_string input
         | 
| 403 528 | 
             
                  assert_xpath '/h2', output, 1
         | 
| 404 | 
            -
                  assert_xpath '/h2[@id=" | 
| 529 | 
            +
                  assert_xpath '/h2[@id="_independent_heading"]', output, 1
         | 
| 405 530 | 
             
                  assert_xpath '/h2[@class="float isolated"]', output, 1
         | 
| 406 531 | 
             
                end
         | 
| 532 | 
            +
             | 
| 533 | 
            +
                test 'should use specified id and reftext when registering discrete section reference' do
         | 
| 534 | 
            +
                  input = <<-EOS
         | 
| 535 | 
            +
            [[install,Install Procedure]]
         | 
| 536 | 
            +
            [discrete]
         | 
| 537 | 
            +
            == Install
         | 
| 538 | 
            +
             | 
| 539 | 
            +
            content
         | 
| 540 | 
            +
                  EOS
         | 
| 541 | 
            +
             | 
| 542 | 
            +
                  doc = document_from_string input
         | 
| 543 | 
            +
                  reftext = doc.references[:ids]['install']
         | 
| 544 | 
            +
                  refute_nil reftext
         | 
| 545 | 
            +
                  assert_equal 'Install Procedure', reftext
         | 
| 546 | 
            +
                end
         | 
| 547 | 
            +
             | 
| 548 | 
            +
                test 'should use specified reftext when registering discrete section reference' do
         | 
| 549 | 
            +
                  input = <<-EOS
         | 
| 550 | 
            +
            [reftext="Install Procedure"]
         | 
| 551 | 
            +
            [discrete]
         | 
| 552 | 
            +
            == Install
         | 
| 553 | 
            +
             | 
| 554 | 
            +
            content
         | 
| 555 | 
            +
                  EOS
         | 
| 556 | 
            +
             | 
| 557 | 
            +
                  doc = document_from_string input
         | 
| 558 | 
            +
                  reftext = doc.references[:ids]['_install']
         | 
| 559 | 
            +
                  refute_nil reftext
         | 
| 560 | 
            +
                  assert_equal 'Install Procedure', reftext
         | 
| 561 | 
            +
                end
         | 
| 407 562 | 
             
              end
         | 
| 408 563 |  | 
| 409 564 | 
             
              context 'Level offset' do
         | 
| @@ -424,9 +579,9 @@ text in standalone | |
| 424 579 | 
             
                  EOS
         | 
| 425 580 |  | 
| 426 581 | 
             
                  output, errors = nil
         | 
| 427 | 
            -
                  redirect_streams do | | 
| 582 | 
            +
                  redirect_streams do |out, err|
         | 
| 428 583 | 
             
                    output = render_string input
         | 
| 429 | 
            -
                    errors =  | 
| 584 | 
            +
                    errors = err.string
         | 
| 430 585 | 
             
                  end
         | 
| 431 586 |  | 
| 432 587 | 
             
                  assert !errors.empty?
         | 
| @@ -462,9 +617,9 @@ Master section text. | |
| 462 617 |  | 
| 463 618 | 
             
                  output = nil
         | 
| 464 619 | 
             
                  errors = nil
         | 
| 465 | 
            -
                  redirect_streams do | | 
| 620 | 
            +
                  redirect_streams do |out, err|
         | 
| 466 621 | 
             
                    output = render_string input
         | 
| 467 | 
            -
                    errors =  | 
| 622 | 
            +
                    errors = out.string
         | 
| 468 623 | 
             
                  end
         | 
| 469 624 |  | 
| 470 625 | 
             
                  assert errors.empty?
         | 
| @@ -512,6 +667,31 @@ Standalone preamble. | |
| 512 667 | 
             
                  assert_xpath '//*[@class = "sect1"]/h2[text() = "Standalone Document"]', output, 1
         | 
| 513 668 | 
             
                  assert_xpath '//*[@class = "sect1"]/h2[text() = "Level 1 Section"]', output, 1
         | 
| 514 669 | 
             
                end
         | 
| 670 | 
            +
             | 
| 671 | 
            +
                test 'should add relative offset value to current leveloffset' do
         | 
| 672 | 
            +
                  input = <<-EOS
         | 
| 673 | 
            +
            = Master Document
         | 
| 674 | 
            +
            Doc Writer
         | 
| 675 | 
            +
             | 
| 676 | 
            +
            Master preamble.
         | 
| 677 | 
            +
             | 
| 678 | 
            +
            :leveloffset: 1
         | 
| 679 | 
            +
             | 
| 680 | 
            +
            = Chapter 1
         | 
| 681 | 
            +
             | 
| 682 | 
            +
            content
         | 
| 683 | 
            +
             | 
| 684 | 
            +
            :leveloffset: +1
         | 
| 685 | 
            +
             | 
| 686 | 
            +
            = Standalone Section
         | 
| 687 | 
            +
             | 
| 688 | 
            +
            content
         | 
| 689 | 
            +
                  EOS
         | 
| 690 | 
            +
             | 
| 691 | 
            +
                  output = render_string input
         | 
| 692 | 
            +
                  assert_xpath '//*[@class = "sect1"]/h2[text() = "Chapter 1"]', output, 1
         | 
| 693 | 
            +
                  assert_xpath '//*[@class = "sect2"]/h3[text() = "Standalone Section"]', output, 1
         | 
| 694 | 
            +
                end
         | 
| 515 695 | 
             
              end
         | 
| 516 696 |  | 
| 517 697 | 
             
              context 'Section Numbering' do
         | 
| @@ -555,6 +735,45 @@ Standalone preamble. | |
| 555 735 | 
             
                  assert_equal '1:1:1', sect1_1_1.sectnum(':', false)
         | 
| 556 736 | 
             
                end
         | 
| 557 737 |  | 
| 738 | 
            +
                test 'should render section numbers when sectnums attribute is set' do
         | 
| 739 | 
            +
                  input = <<-EOS
         | 
| 740 | 
            +
            = Title
         | 
| 741 | 
            +
            :sectnums:
         | 
| 742 | 
            +
             | 
| 743 | 
            +
            == Section_1 
         | 
| 744 | 
            +
             | 
| 745 | 
            +
            text
         | 
| 746 | 
            +
             | 
| 747 | 
            +
            === Section_1_1
         | 
| 748 | 
            +
             | 
| 749 | 
            +
            text
         | 
| 750 | 
            +
             | 
| 751 | 
            +
            ==== Section_1_1_1
         | 
| 752 | 
            +
             | 
| 753 | 
            +
            text
         | 
| 754 | 
            +
             | 
| 755 | 
            +
            == Section_2
         | 
| 756 | 
            +
             | 
| 757 | 
            +
            text
         | 
| 758 | 
            +
             | 
| 759 | 
            +
            === Section_2_1
         | 
| 760 | 
            +
             | 
| 761 | 
            +
            text
         | 
| 762 | 
            +
             | 
| 763 | 
            +
            === Section_2_2
         | 
| 764 | 
            +
             | 
| 765 | 
            +
            text
         | 
| 766 | 
            +
                  EOS
         | 
| 767 | 
            +
                
         | 
| 768 | 
            +
                  output = render_string input
         | 
| 769 | 
            +
                  assert_xpath '//h2[@id="_section_1"][starts-with(text(), "1. ")]', output, 1
         | 
| 770 | 
            +
                  assert_xpath '//h3[@id="_section_1_1"][starts-with(text(), "1.1. ")]', output, 1
         | 
| 771 | 
            +
                  assert_xpath '//h4[@id="_section_1_1_1"][starts-with(text(), "1.1.1. ")]', output, 1
         | 
| 772 | 
            +
                  assert_xpath '//h2[@id="_section_2"][starts-with(text(), "2. ")]', output, 1
         | 
| 773 | 
            +
                  assert_xpath '//h3[@id="_section_2_1"][starts-with(text(), "2.1. ")]', output, 1
         | 
| 774 | 
            +
                  assert_xpath '//h3[@id="_section_2_2"][starts-with(text(), "2.2. ")]', output, 1
         | 
| 775 | 
            +
                end
         | 
| 776 | 
            +
             | 
| 558 777 | 
             
                test 'should render section numbers when numbered attribute is set' do
         | 
| 559 778 | 
             
                  input = <<-EOS
         | 
| 560 779 | 
             
            = Title
         | 
| @@ -786,19 +1005,57 @@ content | |
| 786 1005 |  | 
| 787 1006 | 
             
            = Part 1
         | 
| 788 1007 |  | 
| 789 | 
            -
            ==  | 
| 1008 | 
            +
            == Chapter 1
         | 
| 1009 | 
            +
             | 
| 1010 | 
            +
            content
         | 
| 790 1011 |  | 
| 791 1012 | 
             
            = Part 2
         | 
| 792 1013 |  | 
| 793 | 
            -
            ==  | 
| 1014 | 
            +
            == Chapter 2
         | 
| 1015 | 
            +
             | 
| 1016 | 
            +
            content
         | 
| 794 1017 | 
             
                  EOS
         | 
| 795 1018 |  | 
| 796 1019 | 
             
                  output = render_string input
         | 
| 797 1020 | 
             
                  assert_xpath '(//h1)[1][text()="Document Title"]', output, 1
         | 
| 798 1021 | 
             
                  assert_xpath '(//h1)[2][text()="Part 1"]', output, 1
         | 
| 799 1022 | 
             
                  assert_xpath '(//h1)[3][text()="Part 2"]', output, 1
         | 
| 800 | 
            -
                  assert_xpath '(//h2)[1][text()="1.  | 
| 801 | 
            -
                  assert_xpath '(//h2)[2][text()=" | 
| 1023 | 
            +
                  assert_xpath '(//h2)[1][text()="1. Chapter 1"]', output, 1
         | 
| 1024 | 
            +
                  assert_xpath '(//h2)[2][text()="2. Chapter 2"]', output, 1
         | 
| 1025 | 
            +
                end
         | 
| 1026 | 
            +
             | 
| 1027 | 
            +
                test 'should number chapters sequentially even when divided into parts' do
         | 
| 1028 | 
            +
                  input = <<-EOS
         | 
| 1029 | 
            +
            = Document Title
         | 
| 1030 | 
            +
            :doctype: book
         | 
| 1031 | 
            +
            :numbered:
         | 
| 1032 | 
            +
             | 
| 1033 | 
            +
            == Chapter 1
         | 
| 1034 | 
            +
             | 
| 1035 | 
            +
            content
         | 
| 1036 | 
            +
             | 
| 1037 | 
            +
            = Part 1
         | 
| 1038 | 
            +
             | 
| 1039 | 
            +
            == Chapter 2
         | 
| 1040 | 
            +
             | 
| 1041 | 
            +
            content
         | 
| 1042 | 
            +
             | 
| 1043 | 
            +
            = Part 2
         | 
| 1044 | 
            +
             | 
| 1045 | 
            +
            == Chapter 3
         | 
| 1046 | 
            +
             | 
| 1047 | 
            +
            content
         | 
| 1048 | 
            +
             | 
| 1049 | 
            +
            == Chapter 4
         | 
| 1050 | 
            +
             | 
| 1051 | 
            +
            content
         | 
| 1052 | 
            +
                  EOS
         | 
| 1053 | 
            +
             | 
| 1054 | 
            +
                  result = render_string input
         | 
| 1055 | 
            +
                  (1..4).each do |num|
         | 
| 1056 | 
            +
                    assert_xpath %(//h2[@id="_chapter_#{num}"]), result, 1
         | 
| 1057 | 
            +
                    assert_xpath %(//h2[@id="_chapter_#{num}"][text()="#{num}. Chapter #{num}"]), result, 1
         | 
| 1058 | 
            +
                  end
         | 
| 802 1059 | 
             
                end
         | 
| 803 1060 | 
             
              end
         | 
| 804 1061 |  | 
| @@ -870,6 +1127,49 @@ Details | |
| 870 1127 | 
             
                  assert_xpath '//h2[text()="Appendix A: Attribute Options"]', output, 1
         | 
| 871 1128 | 
             
                end
         | 
| 872 1129 |  | 
| 1130 | 
            +
                test 'should prefix appendix title by label and letter only when numbered is enabled' do
         | 
| 1131 | 
            +
                  input = <<-EOS
         | 
| 1132 | 
            +
            :numbered:
         | 
| 1133 | 
            +
             | 
| 1134 | 
            +
            [appendix]
         | 
| 1135 | 
            +
            == Attribute Options
         | 
| 1136 | 
            +
             | 
| 1137 | 
            +
            Details
         | 
| 1138 | 
            +
                  EOS
         | 
| 1139 | 
            +
             | 
| 1140 | 
            +
                  output = render_embedded_string input
         | 
| 1141 | 
            +
                  assert_xpath '//h2[text()="Appendix A: Attribute Options"]', output, 1
         | 
| 1142 | 
            +
                end
         | 
| 1143 | 
            +
             | 
| 1144 | 
            +
                test 'should use custom appendix caption if specified' do
         | 
| 1145 | 
            +
                  input = <<-EOS
         | 
| 1146 | 
            +
            :appendix-caption: App
         | 
| 1147 | 
            +
             | 
| 1148 | 
            +
            [appendix]
         | 
| 1149 | 
            +
            == Attribute Options
         | 
| 1150 | 
            +
             | 
| 1151 | 
            +
            Details
         | 
| 1152 | 
            +
                  EOS
         | 
| 1153 | 
            +
             | 
| 1154 | 
            +
                  output = render_embedded_string input
         | 
| 1155 | 
            +
                  assert_xpath '//h2[text()="App A: Attribute Options"]', output, 1
         | 
| 1156 | 
            +
                end
         | 
| 1157 | 
            +
             | 
| 1158 | 
            +
                test 'should only assign letter to appendix when numbered is enabled and appendix caption is empty' do
         | 
| 1159 | 
            +
                  input = <<-EOS
         | 
| 1160 | 
            +
            :numbered:
         | 
| 1161 | 
            +
            :appendix-caption:
         | 
| 1162 | 
            +
             | 
| 1163 | 
            +
            [appendix]
         | 
| 1164 | 
            +
            == Attribute Options
         | 
| 1165 | 
            +
             | 
| 1166 | 
            +
            Details
         | 
| 1167 | 
            +
                  EOS
         | 
| 1168 | 
            +
             | 
| 1169 | 
            +
                  output = render_embedded_string input
         | 
| 1170 | 
            +
                  assert_xpath '//h2[text()="A. Attribute Options"]', output, 1
         | 
| 1171 | 
            +
                end
         | 
| 1172 | 
            +
             | 
| 873 1173 | 
             
                test 'should increment appendix number for each appendix section' do
         | 
| 874 1174 | 
             
                  input = <<-EOS
         | 
| 875 1175 | 
             
            [appendix]
         | 
| @@ -888,9 +1188,72 @@ Details | |
| 888 1188 | 
             
                  assert_xpath '(//h2)[2][text()="Appendix B: Migration"]', output, 1
         | 
| 889 1189 | 
             
                end
         | 
| 890 1190 |  | 
| 891 | 
            -
                test 'should  | 
| 1191 | 
            +
                test 'should continue numbering after appendix' do
         | 
| 1192 | 
            +
                  input = <<-EOS
         | 
| 1193 | 
            +
            :numbered:
         | 
| 1194 | 
            +
             | 
| 1195 | 
            +
            == First Section
         | 
| 1196 | 
            +
             | 
| 1197 | 
            +
            content
         | 
| 1198 | 
            +
             | 
| 1199 | 
            +
            [appendix]
         | 
| 1200 | 
            +
            == Attribute Options
         | 
| 1201 | 
            +
             | 
| 1202 | 
            +
            content
         | 
| 1203 | 
            +
             | 
| 1204 | 
            +
            == Migration
         | 
| 1205 | 
            +
             | 
| 1206 | 
            +
            content
         | 
| 1207 | 
            +
                  EOS
         | 
| 1208 | 
            +
             | 
| 1209 | 
            +
                  output = render_embedded_string input
         | 
| 1210 | 
            +
                  assert_xpath '(//h2)[1][text()="1. First Section"]', output, 1
         | 
| 1211 | 
            +
                  assert_xpath '(//h2)[2][text()="Appendix A: Attribute Options"]', output, 1
         | 
| 1212 | 
            +
                  assert_xpath '(//h2)[3][text()="2. Migration"]', output, 1
         | 
| 1213 | 
            +
                end
         | 
| 1214 | 
            +
             | 
| 1215 | 
            +
                test 'should number appendix subsections using appendix letter' do
         | 
| 1216 | 
            +
                  input = <<-EOS
         | 
| 1217 | 
            +
            :numbered:
         | 
| 1218 | 
            +
             | 
| 1219 | 
            +
            [appendix]
         | 
| 1220 | 
            +
            == Attribute Options
         | 
| 1221 | 
            +
             | 
| 1222 | 
            +
            Details
         | 
| 1223 | 
            +
             | 
| 1224 | 
            +
            === Optional Attributes
         | 
| 1225 | 
            +
             | 
| 1226 | 
            +
            Details
         | 
| 1227 | 
            +
                  EOS
         | 
| 1228 | 
            +
             | 
| 1229 | 
            +
                  output = render_embedded_string input
         | 
| 1230 | 
            +
                  assert_xpath '(//h2)[1][text()="Appendix A: Attribute Options"]', output, 1
         | 
| 1231 | 
            +
                  assert_xpath '(//h3)[1][text()="A.1. Optional Attributes"]', output, 1
         | 
| 1232 | 
            +
                end
         | 
| 1233 | 
            +
             | 
| 1234 | 
            +
                test 'should not number level 4 section by default' do
         | 
| 1235 | 
            +
                  input = <<-EOS
         | 
| 1236 | 
            +
            :numbered:
         | 
| 1237 | 
            +
             | 
| 1238 | 
            +
            == Level_1
         | 
| 1239 | 
            +
             | 
| 1240 | 
            +
            === Level_2
         | 
| 1241 | 
            +
             | 
| 1242 | 
            +
            ==== Level_3
         | 
| 1243 | 
            +
             | 
| 1244 | 
            +
            ===== Level_4
         | 
| 1245 | 
            +
             | 
| 1246 | 
            +
            text
         | 
| 1247 | 
            +
                  EOS
         | 
| 1248 | 
            +
                  output = render_embedded_string input
         | 
| 1249 | 
            +
                  assert_xpath '//h5', output, 1
         | 
| 1250 | 
            +
                  assert_xpath '//h5[text()="Level_4"]', output, 1
         | 
| 1251 | 
            +
                end
         | 
| 1252 | 
            +
             | 
| 1253 | 
            +
                test 'should only number levels up to value defined by sectnumlevels attribute' do
         | 
| 892 1254 | 
             
                  input = <<-EOS
         | 
| 893 1255 | 
             
            :numbered:
         | 
| 1256 | 
            +
            :sectnumlevels: 2
         | 
| 894 1257 |  | 
| 895 1258 | 
             
            == Level_1
         | 
| 896 1259 |  | 
| @@ -903,6 +1266,12 @@ Details | |
| 903 1266 | 
             
            text
         | 
| 904 1267 | 
             
                  EOS
         | 
| 905 1268 | 
             
                  output = render_embedded_string input
         | 
| 1269 | 
            +
                  assert_xpath '//h2', output, 1
         | 
| 1270 | 
            +
                  assert_xpath '//h2[text()="1. Level_1"]', output, 1
         | 
| 1271 | 
            +
                  assert_xpath '//h3', output, 1
         | 
| 1272 | 
            +
                  assert_xpath '//h3[text()="1.1. Level_2"]', output, 1
         | 
| 1273 | 
            +
                  assert_xpath '//h4', output, 1
         | 
| 1274 | 
            +
                  assert_xpath '//h4[text()="Level_3"]', output, 1
         | 
| 906 1275 | 
             
                  assert_xpath '//h5', output, 1
         | 
| 907 1276 | 
             
                  assert_xpath '//h5[text()="Level_4"]', output, 1
         | 
| 908 1277 | 
             
                end
         | 
| @@ -980,6 +1349,26 @@ Terms | |
| 980 1349 | 
             
                  assert_xpath '//*[@id="toc"]/ul//li/a[text()="Glossary"]', output, 1
         | 
| 981 1350 | 
             
                end
         | 
| 982 1351 |  | 
| 1352 | 
            +
                test 'should only number sections in toc up to value defined by sectnumlevels attribute' do
         | 
| 1353 | 
            +
                  input = <<-EOS
         | 
| 1354 | 
            +
            :numbered:
         | 
| 1355 | 
            +
            :toc:
         | 
| 1356 | 
            +
            :sectnumlevels: 2
         | 
| 1357 | 
            +
            :toclevels: 3
         | 
| 1358 | 
            +
             | 
| 1359 | 
            +
            == Level 1
         | 
| 1360 | 
            +
             | 
| 1361 | 
            +
            === Level 2
         | 
| 1362 | 
            +
             | 
| 1363 | 
            +
            ==== Level 3
         | 
| 1364 | 
            +
                  EOS
         | 
| 1365 | 
            +
             | 
| 1366 | 
            +
                  output = render_string input
         | 
| 1367 | 
            +
                  assert_xpath '//*[@id="toc"]//a[@href="#_level_1"][text()="1. Level 1"]', output, 1
         | 
| 1368 | 
            +
                  assert_xpath '//*[@id="toc"]//a[@href="#_level_2"][text()="1.1. Level 2"]', output, 1
         | 
| 1369 | 
            +
                  assert_xpath '//*[@id="toc"]//a[@href="#_level_3"][text()="Level 3"]', output, 1
         | 
| 1370 | 
            +
                end
         | 
| 1371 | 
            +
             | 
| 983 1372 | 
             
                # reenable once we have :specialnumbered!: implemented
         | 
| 984 1373 | 
             
            =begin
         | 
| 985 1374 | 
             
                test 'should not number special sections or subsections' do
         | 
| @@ -1117,6 +1506,7 @@ blah blah | |
| 1117 1506 |  | 
| 1118 1507 | 
             
            = Part 2
         | 
| 1119 1508 |  | 
| 1509 | 
            +
            [partintro]
         | 
| 1120 1510 | 
             
            blah blah
         | 
| 1121 1511 |  | 
| 1122 1512 | 
             
            == Chapter 3
         | 
| @@ -1155,7 +1545,7 @@ Colophon content | |
| 1155 1545 | 
             
            = Index Title
         | 
| 1156 1546 | 
             
                  EOS
         | 
| 1157 1547 |  | 
| 1158 | 
            -
                  output = render_embedded_string input, :backend => ' | 
| 1548 | 
            +
                  output = render_embedded_string input, :backend => 'docbook45'
         | 
| 1159 1549 | 
             
                  assert_xpath '/chapter[@id="abstract_title"]', output, 1
         | 
| 1160 1550 | 
             
                  assert_xpath '/chapter[@id="abstract_title"]/title[text()="Abstract Title"]', output, 1
         | 
| 1161 1551 | 
             
                  assert_xpath '/chapter/following-sibling::dedication[@id="dedication_title"]', output, 1
         | 
| @@ -1195,7 +1585,7 @@ Colophon content | |
| 1195 1585 | 
             
            Abstract content
         | 
| 1196 1586 | 
             
                  EOS
         | 
| 1197 1587 |  | 
| 1198 | 
            -
                  output = render_embedded_string input, :backend => ' | 
| 1588 | 
            +
                  output = render_embedded_string input, :backend => 'docbook45'
         | 
| 1199 1589 | 
             
                  assert_xpath '/abstract[@id="abstract_title"]', output, 1
         | 
| 1200 1590 | 
             
                  assert_xpath '/abstract[@id="abstract_title"]/title[text()="Abstract Title"]', output, 1
         | 
| 1201 1591 | 
             
                end
         | 
| @@ -1335,13 +1725,13 @@ That's all she wrote! | |
| 1335 1725 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul', output, 1
         | 
| 1336 1726 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul[@class="sectlevel1"]', output, 1
         | 
| 1337 1727 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]//ul', output, 2
         | 
| 1338 | 
            -
                  assert_xpath '//*[@id="header"]//*[@id="toc"] | 
| 1728 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]//li', output, 4
         | 
| 1339 1729 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="Section One"]', output, 1
         | 
| 1340 1730 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul', output, 1
         | 
| 1341 1731 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul[@class="sectlevel2"]', output, 1
         | 
| 1342 1732 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li', output, 1
         | 
| 1343 1733 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li/a[@href="#_interlude"][text()="Interlude"]', output, 1
         | 
| 1344 | 
            -
                  assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[ | 
| 1734 | 
            +
                  assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[3]/a[@href="#_section_three"][text()="Section Three"]', output, 1
         | 
| 1345 1735 | 
             
                end
         | 
| 1346 1736 |  | 
| 1347 1737 | 
             
                test 'should render numbered table of contents in header if toc and numbered attributes are set' do
         | 
| @@ -1371,11 +1761,11 @@ That's all she wrote! | |
| 1371 1761 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/*[@id="toctitle"][text()="Table of Contents"]', output, 1
         | 
| 1372 1762 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul', output, 1
         | 
| 1373 1763 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]//ul', output, 2
         | 
| 1374 | 
            -
                  assert_xpath '//*[@id="header"]//*[@id="toc"] | 
| 1764 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]//li', output, 4
         | 
| 1375 1765 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
         | 
| 1376 1766 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li', output, 1
         | 
| 1377 1767 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li/a[@href="#_interlude"][text()="2.1. Interlude"]', output, 1
         | 
| 1378 | 
            -
                  assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[ | 
| 1768 | 
            +
                  assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[3]/a[@href="#_section_three"][text()="3. Section Three"]', output, 1
         | 
| 1379 1769 | 
             
                end
         | 
| 1380 1770 |  | 
| 1381 1771 | 
             
                test 'should render a table of contents that honors numbered setting at position of section in document' do
         | 
| @@ -1407,9 +1797,9 @@ That's all she wrote! | |
| 1407 1797 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/*[@id="toctitle"][text()="Table of Contents"]', output, 1
         | 
| 1408 1798 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul', output, 1
         | 
| 1409 1799 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]//ul', output, 2
         | 
| 1410 | 
            -
                  assert_xpath '//*[@id="header"]//*[@id="toc"] | 
| 1800 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]//li', output, 4
         | 
| 1411 1801 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
         | 
| 1412 | 
            -
                  assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[ | 
| 1802 | 
            +
                  assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[3]/a[@href="#_section_three"][text()="Section Three"]', output, 1
         | 
| 1413 1803 | 
             
                end
         | 
| 1414 1804 |  | 
| 1415 1805 | 
             
                test 'should not number parts in table of contents for book doctype when numbered attribute is set' do
         | 
| @@ -1440,13 +1830,13 @@ blah | |
| 1440 1830 | 
             
                  assert_xpath '//*[@id="toc"]', output, 1
         | 
| 1441 1831 | 
             
                  assert_xpath '//*[@id="toc"]/ul', output, 1
         | 
| 1442 1832 | 
             
                  assert_xpath '//*[@id="toc"]/ul[@class="sectlevel0"]', output, 1
         | 
| 1443 | 
            -
                  assert_xpath '//*[@id="toc"]/ul[@class="sectlevel0"]/li', output,  | 
| 1833 | 
            +
                  assert_xpath '//*[@id="toc"]/ul[@class="sectlevel0"]/li', output, 2
         | 
| 1444 1834 | 
             
                  assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[1]/a[text()="Part 1"]', output, 1
         | 
| 1445 | 
            -
                  assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[ | 
| 1446 | 
            -
                  assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[ | 
| 1447 | 
            -
                  assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[ | 
| 1448 | 
            -
                  assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[ | 
| 1449 | 
            -
                  assert_xpath '((//*[@id="toc"]/ul[@class="sectlevel0"]/li)[ | 
| 1835 | 
            +
                  assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[2]/a[text()="Part 2"]', output, 1
         | 
| 1836 | 
            +
                  assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[1]/ul', output, 1
         | 
| 1837 | 
            +
                  assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[1]/ul[@class="sectlevel1"]', output, 1
         | 
| 1838 | 
            +
                  assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[1]/ul/li', output, 2
         | 
| 1839 | 
            +
                  assert_xpath '((//*[@id="toc"]/ul[@class="sectlevel0"]/li)[1]/ul/li)[1]/a[text()="1. First Section of Part 1"]', output, 1
         | 
| 1450 1840 | 
             
                end
         | 
| 1451 1841 |  | 
| 1452 1842 | 
             
                test 'should render table of contents in header if toc2 attribute is set' do
         | 
| @@ -1470,10 +1860,10 @@ They couldn't believe their eyes when... | |
| 1470 1860 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
         | 
| 1471 1861 | 
             
                end
         | 
| 1472 1862 |  | 
| 1473 | 
            -
                test 'should set toc position if  | 
| 1863 | 
            +
                test 'should set toc position if toc attribute is set to position' do
         | 
| 1474 1864 | 
             
                  input = <<-EOS
         | 
| 1475 1865 | 
             
            = Article
         | 
| 1476 | 
            -
            : | 
| 1866 | 
            +
            :toc: >
         | 
| 1477 1867 | 
             
            :numbered:
         | 
| 1478 1868 |  | 
| 1479 1869 | 
             
            == Section One
         | 
| @@ -1556,6 +1946,27 @@ They couldn't believe their eyes when... | |
| 1556 1946 | 
             
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
         | 
| 1557 1947 | 
             
                end
         | 
| 1558 1948 |  | 
| 1949 | 
            +
                test 'should set toc placement to preamble if toc attribute is set to preamble' do
         | 
| 1950 | 
            +
                  input = <<-EOS
         | 
| 1951 | 
            +
            = Article
         | 
| 1952 | 
            +
            :toc: preamble
         | 
| 1953 | 
            +
             | 
| 1954 | 
            +
            Yada yada
         | 
| 1955 | 
            +
             | 
| 1956 | 
            +
            == Section One
         | 
| 1957 | 
            +
             | 
| 1958 | 
            +
            It was a dark and stormy night...
         | 
| 1959 | 
            +
             | 
| 1960 | 
            +
            == Section Two
         | 
| 1961 | 
            +
             | 
| 1962 | 
            +
            They couldn't believe their eyes when...
         | 
| 1963 | 
            +
                  EOS
         | 
| 1964 | 
            +
             | 
| 1965 | 
            +
                  output = render_string input
         | 
| 1966 | 
            +
                  assert_css '#preamble #toc', output, 1
         | 
| 1967 | 
            +
                  assert_css '#preamble .sectionbody + #toc', output, 1
         | 
| 1968 | 
            +
                end
         | 
| 1969 | 
            +
             | 
| 1559 1970 | 
             
                test 'should use document attributes toc-class, toc-title and toclevels to create toc' do
         | 
| 1560 1971 | 
             
                  input = <<-EOS
         | 
| 1561 1972 | 
             
            = Article
         | 
| @@ -1609,7 +2020,7 @@ They couldn't believe their eyes when... | |
| 1609 2020 | 
             
                  input = <<-EOS
         | 
| 1610 2021 | 
             
            = Article
         | 
| 1611 2022 | 
             
            :toc:
         | 
| 1612 | 
            -
            :toc-placement | 
| 2023 | 
            +
            :toc-placement: macro
         | 
| 1613 2024 |  | 
| 1614 2025 | 
             
            Once upon a time...
         | 
| 1615 2026 |  | 
| @@ -1633,7 +2044,7 @@ They couldn't believe their eyes when... | |
| 1633 2044 | 
             
                  input = <<-EOS
         | 
| 1634 2045 | 
             
            = Article
         | 
| 1635 2046 | 
             
            :toc:
         | 
| 1636 | 
            -
            :toc-placement | 
| 2047 | 
            +
            :toc-placement: macro
         | 
| 1637 2048 |  | 
| 1638 2049 | 
             
            Once upon a time...
         | 
| 1639 2050 |  | 
| @@ -1653,7 +2064,7 @@ They couldn't believe their eyes when... | |
| 1653 2064 | 
             
                  assert_css '#preamble:root .paragraph + #toc', output, 1
         | 
| 1654 2065 | 
             
                end
         | 
| 1655 2066 |  | 
| 1656 | 
            -
                test 'should not  | 
| 2067 | 
            +
                test 'should not activate toc macro if toc-placement is not set' do
         | 
| 1657 2068 | 
             
                  input = <<-EOS
         | 
| 1658 2069 | 
             
            = Article
         | 
| 1659 2070 | 
             
            :toc:
         | 
| @@ -1675,15 +2086,41 @@ They couldn't believe their eyes when... | |
| 1675 2086 |  | 
| 1676 2087 | 
             
                  assert_css '#toc', output, 1
         | 
| 1677 2088 | 
             
                  assert_css '#toctitle', output, 1
         | 
| 1678 | 
            -
                   | 
| 1679 | 
            -
                   | 
| 2089 | 
            +
                  assert_css '.toc', output, 1
         | 
| 2090 | 
            +
                  assert_css '#content .toc', output, 0
         | 
| 2091 | 
            +
                end
         | 
| 2092 | 
            +
             | 
| 2093 | 
            +
                test 'should only output toc at toc macro if toc is macro' do
         | 
| 2094 | 
            +
                  input = <<-EOS
         | 
| 2095 | 
            +
            = Article
         | 
| 2096 | 
            +
            :toc: macro
         | 
| 2097 | 
            +
             | 
| 2098 | 
            +
            Once upon a time...
         | 
| 2099 | 
            +
             | 
| 2100 | 
            +
            toc::[]
         | 
| 2101 | 
            +
             | 
| 2102 | 
            +
            == Section One
         | 
| 2103 | 
            +
             | 
| 2104 | 
            +
            It was a dark and stormy night...
         | 
| 2105 | 
            +
             | 
| 2106 | 
            +
            == Section Two
         | 
| 2107 | 
            +
             | 
| 2108 | 
            +
            They couldn't believe their eyes when...
         | 
| 2109 | 
            +
                  EOS
         | 
| 2110 | 
            +
             | 
| 2111 | 
            +
                  output = render_string input
         | 
| 2112 | 
            +
             | 
| 2113 | 
            +
                  assert_css '#toc', output, 1
         | 
| 2114 | 
            +
                  assert_css '#toctitle', output, 1
         | 
| 2115 | 
            +
                  assert_css '.toc', output, 1
         | 
| 2116 | 
            +
                  assert_css '#content .toc', output, 1
         | 
| 1680 2117 | 
             
                end
         | 
| 1681 2118 |  | 
| 1682 2119 | 
             
                test 'should use global attributes for toc-title, toc-class and toclevels for toc macro' do
         | 
| 1683 2120 | 
             
                  input = <<-EOS
         | 
| 1684 2121 | 
             
            = Article
         | 
| 1685 2122 | 
             
            :toc:
         | 
| 1686 | 
            -
            :toc-placement | 
| 2123 | 
            +
            :toc-placement: macro
         | 
| 1687 2124 | 
             
            :toc-title: Contents
         | 
| 1688 2125 | 
             
            :toc-class: contents
         | 
| 1689 2126 | 
             
            :toclevels: 1
         | 
| @@ -1722,7 +2159,7 @@ Fin. | |
| 1722 2159 | 
             
                  input = <<-EOS
         | 
| 1723 2160 | 
             
            = Article
         | 
| 1724 2161 | 
             
            :toc:
         | 
| 1725 | 
            -
            :toc-placement | 
| 2162 | 
            +
            :toc-placement: macro
         | 
| 1726 2163 | 
             
            :toc-title: Ignored
         | 
| 1727 2164 | 
             
            :toc-class: ignored
         | 
| 1728 2165 | 
             
            :toclevels: 5
         | 
| @@ -1760,6 +2197,40 @@ Fin. | |
| 1760 2197 | 
             
                  assert_xpath '(//*[@id="contents"]//li)[1]/a[text() = "Section 1"]', output, 1
         | 
| 1761 2198 | 
             
                  assert_xpath '(//*[@id="contents"]//li)[2]/a[text() = "Section 2"]', output, 1
         | 
| 1762 2199 | 
             
                end
         | 
| 2200 | 
            +
             | 
| 2201 | 
            +
                test 'child toc levels should not have additional bullet at parent level in html' do
         | 
| 2202 | 
            +
                  input = <<-EOS
         | 
| 2203 | 
            +
            = Article
         | 
| 2204 | 
            +
            :toc:
         | 
| 2205 | 
            +
             | 
| 2206 | 
            +
            == Section One
         | 
| 2207 | 
            +
             | 
| 2208 | 
            +
            It was a dark and stormy night...
         | 
| 2209 | 
            +
             | 
| 2210 | 
            +
            == Section Two
         | 
| 2211 | 
            +
             | 
| 2212 | 
            +
            They couldn't believe their eyes when...
         | 
| 2213 | 
            +
             | 
| 2214 | 
            +
            === Interlude
         | 
| 2215 | 
            +
             | 
| 2216 | 
            +
            While they were waiting...
         | 
| 2217 | 
            +
             | 
| 2218 | 
            +
            == Section Three
         | 
| 2219 | 
            +
             | 
| 2220 | 
            +
            That's all she wrote!
         | 
| 2221 | 
            +
                  EOS
         | 
| 2222 | 
            +
                  output = render_string input
         | 
| 2223 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc"]', output, 1
         | 
| 2224 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/*[@id="toctitle"][text()="Table of Contents"]', output, 1
         | 
| 2225 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul', output, 1
         | 
| 2226 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]//ul', output, 2
         | 
| 2227 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]//li', output, 4
         | 
| 2228 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[2]/a[@href="#_section_two"][text()="Section Two"]', output, 1
         | 
| 2229 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li', output, 1
         | 
| 2230 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[2]/ul/li', output, 1
         | 
| 2231 | 
            +
                  assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li/a[@href="#_interlude"][text()="Interlude"]', output, 1
         | 
| 2232 | 
            +
                  assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[3]/a[@href="#_section_three"][text()="Section Three"]', output, 1
         | 
| 2233 | 
            +
                end
         | 
| 1763 2234 | 
             
              end
         | 
| 1764 2235 |  | 
| 1765 2236 | 
             
              context 'article doctype' do
         | 
| @@ -1814,10 +2285,16 @@ Doc Writer | |
| 1814 2285 |  | 
| 1815 2286 | 
             
            = Chapter One
         | 
| 1816 2287 |  | 
| 2288 | 
            +
            [partintro]
         | 
| 1817 2289 | 
             
            It was a dark and stormy night...
         | 
| 1818 2290 |  | 
| 2291 | 
            +
            == Scene One
         | 
| 2292 | 
            +
             | 
| 2293 | 
            +
            Someone's gonna get axed.
         | 
| 2294 | 
            +
             | 
| 1819 2295 | 
             
            = Chapter Two
         | 
| 1820 2296 |  | 
| 2297 | 
            +
            [partintro]
         | 
| 1821 2298 | 
             
            They couldn't believe their eyes when...
         | 
| 1822 2299 |  | 
| 1823 2300 | 
             
            == Interlude
         | 
| @@ -1826,6 +2303,8 @@ While they were waiting... | |
| 1826 2303 |  | 
| 1827 2304 | 
             
            = Chapter Three
         | 
| 1828 2305 |  | 
| 2306 | 
            +
            == Scene One
         | 
| 2307 | 
            +
             | 
| 1829 2308 | 
             
            That's all she wrote!
         | 
| 1830 2309 | 
             
                  EOS
         | 
| 1831 2310 |  | 
| @@ -1835,13 +2314,97 @@ That's all she wrote! | |
| 1835 2314 | 
             
                  assert_css '#header h1', output, 1
         | 
| 1836 2315 | 
             
                  assert_css '#content h1', output, 3
         | 
| 1837 2316 | 
             
                  assert_css '#content h1.sect0', output, 3
         | 
| 1838 | 
            -
                  assert_css 'h2', output,  | 
| 1839 | 
            -
                  assert_css '#content h2', output,  | 
| 2317 | 
            +
                  assert_css 'h2', output, 3
         | 
| 2318 | 
            +
                  assert_css '#content h2', output, 3
         | 
| 1840 2319 | 
             
                  assert_xpath '//h1[@id="_chapter_one"][text() = "Chapter One"]', output, 1
         | 
| 1841 2320 | 
             
                  assert_xpath '//h1[@id="_chapter_two"][text() = "Chapter Two"]', output, 1
         | 
| 1842 2321 | 
             
                  assert_xpath '//h1[@id="_chapter_three"][text() = "Chapter Three"]', output, 1
         | 
| 1843 2322 | 
             
                end
         | 
| 1844 2323 |  | 
| 2324 | 
            +
                test 'should add partintro style to child paragraph of part' do
         | 
| 2325 | 
            +
                  input = <<-EOS
         | 
| 2326 | 
            +
            = Book
         | 
| 2327 | 
            +
            :doctype: book
         | 
| 2328 | 
            +
             | 
| 2329 | 
            +
            = Part 1
         | 
| 2330 | 
            +
             | 
| 2331 | 
            +
            part intro
         | 
| 2332 | 
            +
             | 
| 2333 | 
            +
            == Chapter 1
         | 
| 2334 | 
            +
                  EOS
         | 
| 2335 | 
            +
             | 
| 2336 | 
            +
                  doc = document_from_string input
         | 
| 2337 | 
            +
                  partintro = doc.blocks.first.blocks.first
         | 
| 2338 | 
            +
                  assert_equal :open, partintro.context
         | 
| 2339 | 
            +
                  assert_equal 'partintro', partintro.style
         | 
| 2340 | 
            +
                end
         | 
| 2341 | 
            +
             | 
| 2342 | 
            +
                test 'should add partintro style to child open block of part' do
         | 
| 2343 | 
            +
                  input = <<-EOS
         | 
| 2344 | 
            +
            = Book
         | 
| 2345 | 
            +
            :doctype: book
         | 
| 2346 | 
            +
             | 
| 2347 | 
            +
            = Part 1
         | 
| 2348 | 
            +
             | 
| 2349 | 
            +
            --
         | 
| 2350 | 
            +
            part intro
         | 
| 2351 | 
            +
            --
         | 
| 2352 | 
            +
             | 
| 2353 | 
            +
            == Chapter 1
         | 
| 2354 | 
            +
                  EOS
         | 
| 2355 | 
            +
             | 
| 2356 | 
            +
                  doc = document_from_string input
         | 
| 2357 | 
            +
                  partintro = doc.blocks.first.blocks.first
         | 
| 2358 | 
            +
                  assert_equal :open, partintro.context
         | 
| 2359 | 
            +
                  assert_equal 'partintro', partintro.style
         | 
| 2360 | 
            +
                end
         | 
| 2361 | 
            +
             | 
| 2362 | 
            +
                test 'should wrap child paragraphs of part in partintro open block' do
         | 
| 2363 | 
            +
                  input = <<-EOS
         | 
| 2364 | 
            +
            = Book
         | 
| 2365 | 
            +
            :doctype: book
         | 
| 2366 | 
            +
             | 
| 2367 | 
            +
            = Part 1
         | 
| 2368 | 
            +
             | 
| 2369 | 
            +
            part intro
         | 
| 2370 | 
            +
             | 
| 2371 | 
            +
            more part intro
         | 
| 2372 | 
            +
             | 
| 2373 | 
            +
            == Chapter 1
         | 
| 2374 | 
            +
                  EOS
         | 
| 2375 | 
            +
             | 
| 2376 | 
            +
                  doc = document_from_string input
         | 
| 2377 | 
            +
                  partintro = doc.blocks.first.blocks.first
         | 
| 2378 | 
            +
                  assert_equal :open, partintro.context
         | 
| 2379 | 
            +
                  assert_equal 'partintro', partintro.style
         | 
| 2380 | 
            +
                  assert_equal 2, partintro.blocks.size
         | 
| 2381 | 
            +
                  assert_equal :paragraph, partintro.blocks[0].context
         | 
| 2382 | 
            +
                  assert_equal :paragraph, partintro.blocks[1].context
         | 
| 2383 | 
            +
                end
         | 
| 2384 | 
            +
             | 
| 2385 | 
            +
                test 'should warn if part has no sections' do
         | 
| 2386 | 
            +
                  input = <<-EOS
         | 
| 2387 | 
            +
            = Book
         | 
| 2388 | 
            +
            :doctype: book
         | 
| 2389 | 
            +
             | 
| 2390 | 
            +
            = Part 1
         | 
| 2391 | 
            +
             | 
| 2392 | 
            +
            [partintro]
         | 
| 2393 | 
            +
            intro
         | 
| 2394 | 
            +
                  EOS
         | 
| 2395 | 
            +
             | 
| 2396 | 
            +
                  doc = nil
         | 
| 2397 | 
            +
                  warnings = nil
         | 
| 2398 | 
            +
                  redirect_streams do |out, err|
         | 
| 2399 | 
            +
                    doc = document_from_string input
         | 
| 2400 | 
            +
                    warnings = err.string
         | 
| 2401 | 
            +
                  end
         | 
| 2402 | 
            +
             | 
| 2403 | 
            +
                  refute_nil warnings
         | 
| 2404 | 
            +
                  assert !warnings.empty?
         | 
| 2405 | 
            +
                  assert_match(/ERROR:.*section/, warnings)
         | 
| 2406 | 
            +
                end
         | 
| 2407 | 
            +
             | 
| 1845 2408 | 
             
                test 'should create parts and chapters in docbook backend' do
         | 
| 1846 2409 | 
             
                  input = <<-EOS
         | 
| 1847 2410 | 
             
            = Book
         | 
| @@ -1850,6 +2413,7 @@ Doc Writer | |
| 1850 2413 |  | 
| 1851 2414 | 
             
            = Part 1
         | 
| 1852 2415 |  | 
| 2416 | 
            +
            [partintro]
         | 
| 1853 2417 | 
             
            The adventure.
         | 
| 1854 2418 |  | 
| 1855 2419 | 
             
            == Chapter One
         | 
| @@ -1862,6 +2426,7 @@ They couldn't believe their eyes when... | |
| 1862 2426 |  | 
| 1863 2427 | 
             
            = Part 2
         | 
| 1864 2428 |  | 
| 2429 | 
            +
            [partintro]
         | 
| 1865 2430 | 
             
            The return.
         | 
| 1866 2431 |  | 
| 1867 2432 | 
             
            == Chapter Three
         | 
| @@ -1916,9 +2481,9 @@ Appendix subsection content | |
| 1916 2481 |  | 
| 1917 2482 | 
             
                  output = nil
         | 
| 1918 2483 | 
             
                  errors = nil
         | 
| 1919 | 
            -
                  redirect_streams do | | 
| 2484 | 
            +
                  redirect_streams do |out, err|
         | 
| 1920 2485 | 
             
                    output = render_string input, :backend => 'docbook'
         | 
| 1921 | 
            -
                    errors =  | 
| 2486 | 
            +
                    errors = out.string
         | 
| 1922 2487 | 
             
                  end
         | 
| 1923 2488 | 
             
                  assert errors.empty?
         | 
| 1924 2489 | 
             
                  assert_xpath '/book/preface', output, 1
         |