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/man/asciidoctor.adoc
    CHANGED
    
    | @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            = asciidoctor(1)
         | 
| 2 | 
            -
            Dan Allen; Ryan Waldron
         | 
| 2 | 
            +
            Dan Allen; Sarah White; Ryan Waldron
         | 
| 3 3 | 
             
            :doctype: manpage
         | 
| 4 4 | 
             
            :man manual: Asciidoctor Manual
         | 
| 5 | 
            -
            :man source: Asciidoctor  | 
| 6 | 
            -
            : | 
| 5 | 
            +
            :man source: Asciidoctor 1.5.0
         | 
| 6 | 
            +
            :page-layout: base
         | 
| 7 7 |  | 
| 8 8 | 
             
            == NAME
         | 
| 9 9 |  | 
| @@ -17,7 +17,7 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats | |
| 17 17 |  | 
| 18 18 | 
             
            == DESCRIPTION
         | 
| 19 19 |  | 
| 20 | 
            -
            The asciidoctor(1) command converts the AsciiDoc source file(s) 'FILE' to  | 
| 20 | 
            +
            The asciidoctor(1) command converts the AsciiDoc source file(s) 'FILE' to HTML5,
         | 
| 21 21 | 
             
            DocBook 4.5, DocBook 5.0 and other custom output formats.
         | 
| 22 22 |  | 
| 23 23 | 
             
            If 'FILE' is '-' then the AsciiDoc source is read from standard input.
         | 
| @@ -62,7 +62,7 @@ This option may be specified more than once. | |
| 62 62 | 
             
            *-b, --backend*='BACKEND'::
         | 
| 63 63 | 
             
                Backend output file format: 'html5', 'docbook45' and 'docbook5' supported
         | 
| 64 64 | 
             
                out of the box. You can also use the backend alias names 'html' (aliased to
         | 
| 65 | 
            -
                'html5') or 'docbook' (aliased to ' | 
| 65 | 
            +
                'html5') or 'docbook' (aliased to 'docbook5'). Defaults to 'html5'. Other
         | 
| 66 66 | 
             
                options can be passed, but if Asciidoctor cannot find the backend, it will
         | 
| 67 67 | 
             
                fail during rendering.
         | 
| 68 68 |  | 
| @@ -79,7 +79,7 @@ This option may be specified more than once. | |
| 79 79 | 
             
            === Rendering Control
         | 
| 80 80 |  | 
| 81 81 | 
             
            *-C, --compact*::
         | 
| 82 | 
            -
                Compact the output by removing blank lines.  | 
| 82 | 
            +
                Compact the output by removing blank lines. (No longer in use).
         | 
| 83 83 |  | 
| 84 84 | 
             
            *-D, --destination-dir*='DIR'::
         | 
| 85 85 | 
             
                Destination output directory. Defaults to the directory containing the
         | 
| @@ -89,10 +89,12 @@ This option may be specified more than once. | |
| 89 89 | 
             
            *-E, --template-engine*='NAME'::
         | 
| 90 90 | 
             
                Template engine to use for the custom render templates. The gem with the
         | 
| 91 91 | 
             
                same name as the engine will be loaded automatically. This name is also
         | 
| 92 | 
            -
                used to build the full path to the custom templates.
         | 
| 92 | 
            +
                used to build the full path to the custom templates. If a template engine
         | 
| 93 | 
            +
                is not specified, it will be auto-detected based on the file extension
         | 
| 94 | 
            +
                of the custom templates found.
         | 
| 93 95 |  | 
| 94 96 | 
             
            *-e, --eruby*::
         | 
| 95 | 
            -
                Specifies the eRuby implementation to use for rendering the  | 
| 97 | 
            +
                Specifies the eRuby implementation to use for rendering the custom ERB
         | 
| 96 98 | 
             
                templates. Supported values are 'erb' and 'erubis'. Defaults to 'erb'.
         | 
| 97 99 |  | 
| 98 100 | 
             
            *-n, --section-numbers*::
         | 
| @@ -122,6 +124,9 @@ subsequent directories override ones previously discovered. | |
| 122 124 |  | 
| 123 125 | 
             
            === Processing Information
         | 
| 124 126 |  | 
| 127 | 
            +
            *-q, --quiet*::
         | 
| 128 | 
            +
                Silence warnings.
         | 
| 129 | 
            +
             | 
| 125 130 | 
             
            *--trace*::
         | 
| 126 131 | 
             
                Include backtrace information on errors. Not enabled by default.
         | 
| 127 132 |  | 
| @@ -129,6 +134,9 @@ subsequent directories override ones previously discovered. | |
| 129 134 | 
             
                Verbosely print processing information and configuration file checks to
         | 
| 130 135 | 
             
                stderr.
         | 
| 131 136 |  | 
| 137 | 
            +
            *-t, --timings*::
         | 
| 138 | 
            +
                Display timings information (time to read, parse and convert)
         | 
| 139 | 
            +
             | 
| 132 140 | 
             
            === Program Information
         | 
| 133 141 |  | 
| 134 142 | 
             
            *-h, --help*::
         | 
| @@ -168,14 +176,14 @@ Git source repository on GitHub: <**https://github.com/asciidoctor/asciidoctor** | |
| 168 176 |  | 
| 169 177 | 
             
            Project web site: <**http://asciidoctor.org**>
         | 
| 170 178 |  | 
| 171 | 
            -
            GitHub organization: <** | 
| 179 | 
            +
            GitHub organization: <**https://github.com/asciidoctor**>
         | 
| 172 180 |  | 
| 173 181 | 
             
            Mailinglist / forum: <**http://discuss.asciidoctor.org**>
         | 
| 174 182 |  | 
| 175 183 |  | 
| 176 184 | 
             
            == COPYING
         | 
| 177 185 |  | 
| 178 | 
            -
            Copyright \(C) 2012- | 
| 186 | 
            +
            Copyright \(C) 2012-2014 Dan Allen, Ryan Waldron and the Asciidoctor Project. Free use of this
         | 
| 179 187 | 
             
            software is granted under the terms of the MIT License.
         | 
| 180 188 |  | 
| 181 189 | 
             
            // vim: tw=80
         | 
    
        data/test/attributes_test.rb
    CHANGED
    
    | @@ -1,4 +1,8 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
            unless defined? ASCIIDOCTOR_PROJECT_DIR
         | 
| 3 | 
            +
              $: << File.dirname(__FILE__); $:.uniq!
         | 
| 4 | 
            +
              require 'test_helper'
         | 
| 5 | 
            +
            end
         | 
| 2 6 |  | 
| 3 7 | 
             
            context 'Attributes' do
         | 
| 4 8 | 
             
              context 'Assignment' do
         | 
| @@ -12,7 +16,7 @@ context 'Attributes' do | |
| 12 16 | 
             
                  assert_equal nil, doc.attributes['foo']
         | 
| 13 17 | 
             
                end
         | 
| 14 18 |  | 
| 15 | 
            -
                test 'creates an attribute by fusing a multi-line value' do
         | 
| 19 | 
            +
                test 'creates an attribute by fusing a legacy multi-line value' do
         | 
| 16 20 | 
             
                  str = <<-EOS
         | 
| 17 21 | 
             
            :description: This is the first      +
         | 
| 18 22 | 
             
                          Ruby implementation of +
         | 
| @@ -22,6 +26,26 @@ context 'Attributes' do | |
| 22 26 | 
             
                  assert_equal 'This is the first Ruby implementation of AsciiDoc.', doc.attributes['description']
         | 
| 23 27 | 
             
                end
         | 
| 24 28 |  | 
| 29 | 
            +
                test 'creates an attribute by fusing a multi-line value' do
         | 
| 30 | 
            +
                  str = <<-EOS
         | 
| 31 | 
            +
            :description: This is the first \\
         | 
| 32 | 
            +
                          Ruby implementation of \\
         | 
| 33 | 
            +
                          AsciiDoc.
         | 
| 34 | 
            +
                  EOS
         | 
| 35 | 
            +
                  doc = document_from_string(str)
         | 
| 36 | 
            +
                  assert_equal 'This is the first Ruby implementation of AsciiDoc.', doc.attributes['description']
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                test 'honors line break characters in multi-line values' do
         | 
| 40 | 
            +
                  str = <<-EOS
         | 
| 41 | 
            +
            :signature: Linus Torvalds + \\
         | 
| 42 | 
            +
            Linux Hacker + \\
         | 
| 43 | 
            +
            linus.torvalds@example.com
         | 
| 44 | 
            +
                  EOS
         | 
| 45 | 
            +
                  doc = document_from_string(str)
         | 
| 46 | 
            +
                  assert_equal %(Linus Torvalds +\nLinux Hacker +\nlinus.torvalds@example.com), doc.attributes['signature']
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 25 49 | 
             
                test 'should delete an attribute that ends with !' do
         | 
| 26 50 | 
             
                  doc = document_from_string(":frog: Tanglefoot\n:frog!:")
         | 
| 27 51 | 
             
                  assert_equal nil, doc.attributes['frog']
         | 
| @@ -72,6 +96,34 @@ context 'Attributes' do | |
| 72 96 | 
             
                  assert_equal '', doc.attributes['release']
         | 
| 73 97 | 
             
                end
         | 
| 74 98 |  | 
| 99 | 
            +
                test 'resolves user-home attribute if safe mode is less than SERVER' do
         | 
| 100 | 
            +
                  input = <<-EOS
         | 
| 101 | 
            +
            :imagesdir: {user-home}/etc/images
         | 
| 102 | 
            +
             | 
| 103 | 
            +
            {imagesdir}
         | 
| 104 | 
            +
            EOS
         | 
| 105 | 
            +
                  output = render_embedded_string input, :doctype => :inline, :safe => :safe
         | 
| 106 | 
            +
                  if RUBY_VERSION >= '1.9'
         | 
| 107 | 
            +
                    assert_equal %(#{Dir.home}/etc/images), output
         | 
| 108 | 
            +
                  else
         | 
| 109 | 
            +
                    assert_equal %(#{ENV['HOME']}/etc/images), output
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                test 'user-home attribute resolves to . if safe mode is SERVER or greater' do
         | 
| 114 | 
            +
                  input = <<-EOS
         | 
| 115 | 
            +
            :imagesdir: {user-home}/etc/images
         | 
| 116 | 
            +
             | 
| 117 | 
            +
            {imagesdir}
         | 
| 118 | 
            +
            EOS
         | 
| 119 | 
            +
                  output = render_embedded_string input, :doctype => :inline, :safe => :server
         | 
| 120 | 
            +
                  if RUBY_VERSION >= '1.9'
         | 
| 121 | 
            +
                    assert_equal %(./etc/images), output
         | 
| 122 | 
            +
                  else
         | 
| 123 | 
            +
                    assert_equal %(./etc/images), output
         | 
| 124 | 
            +
                  end
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 75 127 | 
             
                test "apply custom substitutions to text in passthrough macro and assign to attribute" do
         | 
| 76 128 | 
             
                  doc = document_from_string(":xml-busters: pass:[<>&]")
         | 
| 77 129 | 
             
                  assert_equal '<>&', doc.attributes['xml-busters']
         | 
| @@ -117,12 +169,97 @@ endif::holygrail[] | |
| 117 169 | 
             
                  assert_equal nil, doc.attributes['cash']
         | 
| 118 170 | 
             
                end
         | 
| 119 171 |  | 
| 172 | 
            +
                test 'backend and doctype attributes are set by default in default configuration' do
         | 
| 173 | 
            +
                  input = <<-EOS
         | 
| 174 | 
            +
            = Document Title
         | 
| 175 | 
            +
            Author Name
         | 
| 176 | 
            +
             | 
| 177 | 
            +
            content
         | 
| 178 | 
            +
                  EOS
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                  doc = document_from_string input
         | 
| 181 | 
            +
                  expect = {
         | 
| 182 | 
            +
                    'backend' => 'html5',
         | 
| 183 | 
            +
                    'backend-html5' => '',
         | 
| 184 | 
            +
                    'backend-html5-doctype-article' => '',
         | 
| 185 | 
            +
                    'outfilesuffix' => '.html',
         | 
| 186 | 
            +
                    'basebackend' => 'html',
         | 
| 187 | 
            +
                    'basebackend-html' => '',
         | 
| 188 | 
            +
                    'basebackend-html-doctype-article' => '',
         | 
| 189 | 
            +
                    'doctype' => 'article',
         | 
| 190 | 
            +
                    'doctype-article' => '',
         | 
| 191 | 
            +
                    'filetype' => 'html',
         | 
| 192 | 
            +
                    'filetype-html' => ''
         | 
| 193 | 
            +
                  }
         | 
| 194 | 
            +
                  expect.each do |key, val|
         | 
| 195 | 
            +
                    assert doc.attributes.key? key
         | 
| 196 | 
            +
                    assert_equal val, doc.attributes[key]
         | 
| 197 | 
            +
                  end
         | 
| 198 | 
            +
                end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                test 'backend and doctype attributes are set by default in custom configuration' do
         | 
| 201 | 
            +
                  input = <<-EOS
         | 
| 202 | 
            +
            = Document Title
         | 
| 203 | 
            +
            Author Name
         | 
| 204 | 
            +
             | 
| 205 | 
            +
            content
         | 
| 206 | 
            +
                  EOS
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                  doc = document_from_string input, :doctype => 'book', :backend => 'docbook'
         | 
| 209 | 
            +
                  expect = {
         | 
| 210 | 
            +
                    'backend' => 'docbook5',
         | 
| 211 | 
            +
                    'backend-docbook5' => '',
         | 
| 212 | 
            +
                    'backend-docbook5-doctype-book' => '',
         | 
| 213 | 
            +
                    'outfilesuffix' => '.xml',
         | 
| 214 | 
            +
                    'basebackend' => 'docbook',
         | 
| 215 | 
            +
                    'basebackend-docbook' => '',
         | 
| 216 | 
            +
                    'basebackend-docbook-doctype-book' => '',
         | 
| 217 | 
            +
                    'doctype' => 'book',
         | 
| 218 | 
            +
                    'doctype-book' => '',
         | 
| 219 | 
            +
                    'filetype' => 'xml',
         | 
| 220 | 
            +
                    'filetype-xml' => ''
         | 
| 221 | 
            +
                  }
         | 
| 222 | 
            +
                  expect.each do |key, val|
         | 
| 223 | 
            +
                    assert doc.attributes.key? key
         | 
| 224 | 
            +
                    assert_equal val, doc.attributes[key]
         | 
| 225 | 
            +
                  end
         | 
| 226 | 
            +
                end
         | 
| 227 | 
            +
             | 
| 120 228 | 
             
                test 'backend attributes are updated if backend attribute is defined in document and safe mode is less than SERVER' do
         | 
| 121 | 
            -
                   | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 229 | 
            +
                  input = <<-EOS
         | 
| 230 | 
            +
            = Document Title
         | 
| 231 | 
            +
            Author Name
         | 
| 232 | 
            +
            :backend: docbook
         | 
| 233 | 
            +
            :doctype: book
         | 
| 234 | 
            +
             | 
| 235 | 
            +
            content
         | 
| 236 | 
            +
                  EOS
         | 
| 237 | 
            +
             | 
| 238 | 
            +
                  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE
         | 
| 239 | 
            +
                  expect = {
         | 
| 240 | 
            +
                    'backend' => 'docbook5',
         | 
| 241 | 
            +
                    'backend-docbook5' => '',
         | 
| 242 | 
            +
                    'backend-docbook5-doctype-book' => '',
         | 
| 243 | 
            +
                    'outfilesuffix' => '.xml',
         | 
| 244 | 
            +
                    'basebackend' => 'docbook',
         | 
| 245 | 
            +
                    'basebackend-docbook' => '',
         | 
| 246 | 
            +
                    'basebackend-docbook-doctype-book' => '',
         | 
| 247 | 
            +
                    'doctype' => 'book',
         | 
| 248 | 
            +
                    'doctype-book' => '',
         | 
| 249 | 
            +
                    'filetype' => 'xml',
         | 
| 250 | 
            +
                    'filetype-xml' => ''
         | 
| 251 | 
            +
                  }
         | 
| 252 | 
            +
                  expect.each do |key, val|
         | 
| 253 | 
            +
                    assert doc.attributes.key?(key)
         | 
| 254 | 
            +
                    assert_equal val, doc.attributes[key]
         | 
| 255 | 
            +
                  end
         | 
| 256 | 
            +
             | 
| 257 | 
            +
                  assert !doc.attributes.key?('backend-html5')
         | 
| 258 | 
            +
                  assert !doc.attributes.key?('backend-html5-doctype-article')
         | 
| 259 | 
            +
                  assert !doc.attributes.key?('basebackend-html')
         | 
| 260 | 
            +
                  assert !doc.attributes.key?('basebackend-html-doctype-article')
         | 
| 261 | 
            +
                  assert !doc.attributes.key?('doctype-article')
         | 
| 262 | 
            +
                  assert !doc.attributes.key?('filetype-html')
         | 
| 126 263 | 
             
                end
         | 
| 127 264 |  | 
| 128 265 | 
             
                test 'backend attributes defined in document options overrides backend attribute in document' do
         | 
| @@ -133,6 +270,50 @@ endif::holygrail[] | |
| 133 270 | 
             
                  assert doc.attributes.has_key? 'basebackend-html'
         | 
| 134 271 | 
             
                end
         | 
| 135 272 |  | 
| 273 | 
            +
                test 'set_attr should not overwrite existing key if overwrite is false' do
         | 
| 274 | 
            +
                  node = Asciidoctor::Block.new nil, :paragraph, :attributes => { 'foo' => 'bar' }
         | 
| 275 | 
            +
                  assert_equal 'bar', (node.attr 'foo')
         | 
| 276 | 
            +
                  node.set_attr 'foo', 'baz', false
         | 
| 277 | 
            +
                  assert_equal 'bar', (node.attr 'foo')
         | 
| 278 | 
            +
                end
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                test 'set_attr should overwrite existing key by default' do
         | 
| 281 | 
            +
                  node = Asciidoctor::Block.new nil, :paragraph, :attributes => { 'foo' => 'bar' }
         | 
| 282 | 
            +
                  assert_equal 'bar', (node.attr 'foo')
         | 
| 283 | 
            +
                  node.set_attr 'foo', 'baz'
         | 
| 284 | 
            +
                  assert_equal 'baz', (node.attr 'foo')
         | 
| 285 | 
            +
                end
         | 
| 286 | 
            +
             | 
| 287 | 
            +
                test 'verify toc attribute matrix' do
         | 
| 288 | 
            +
                  expected_data = <<-EOS
         | 
| 289 | 
            +
            #attributes                               |toc|toc-position|toc-placement|toc-class
         | 
| 290 | 
            +
            toc                                       |   |nil         |auto         |nil
         | 
| 291 | 
            +
            toc=header                                |   |nil         |auto         |nil
         | 
| 292 | 
            +
            toc=beeboo                                |   |nil         |auto         |nil
         | 
| 293 | 
            +
            toc=left                                  |   |left        |auto         |toc2
         | 
| 294 | 
            +
            toc2                                      |   |left        |auto         |toc2
         | 
| 295 | 
            +
            toc=right                                 |   |right       |auto         |toc2
         | 
| 296 | 
            +
            toc=preamble                              |   |content     |preamble     |nil
         | 
| 297 | 
            +
            toc=macro                                 |   |content     |macro        |nil
         | 
| 298 | 
            +
            toc toc-placement=macro toc-position=left |   |content     |macro        |nil
         | 
| 299 | 
            +
            toc toc-placement!                        |   |content     |macro        |nil
         | 
| 300 | 
            +
                  EOS
         | 
| 301 | 
            +
             | 
| 302 | 
            +
                  expected = expected_data.strip.lines.map {|l|
         | 
| 303 | 
            +
                    next if l.start_with? '#'
         | 
| 304 | 
            +
                    l.split('|').map {|e| (e = e.strip) == 'nil' ? nil : e }
         | 
| 305 | 
            +
                  }.compact
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                  expected.each do |expect|
         | 
| 308 | 
            +
                    raw_attrs, toc, toc_position, toc_placement, toc_class = expect
         | 
| 309 | 
            +
                    attrs = Hash[*(raw_attrs.split ' ').map {|e| e.include?('=') ? e.split('=') : [e, ''] }.flatten]
         | 
| 310 | 
            +
                    doc = document_from_string '', :attributes => attrs
         | 
| 311 | 
            +
                    toc ? (assert doc.attr?('toc', toc)) : (assert !doc.attr?('toc')) 
         | 
| 312 | 
            +
                    toc_position ? (assert doc.attr?('toc-position', toc_position)) : (assert !doc.attr?('toc-position')) 
         | 
| 313 | 
            +
                    toc_placement ? (assert doc.attr?('toc-placement', toc_placement)) : (assert !doc.attr?('toc-placement')) 
         | 
| 314 | 
            +
                    toc_class ? (assert doc.attr?('toc-class', toc_class)) : (assert !doc.attr?('toc-class')) 
         | 
| 315 | 
            +
                  end
         | 
| 316 | 
            +
                end
         | 
| 136 317 | 
             
              end
         | 
| 137 318 |  | 
| 138 319 | 
             
              context 'Interpolation' do
         | 
| @@ -184,7 +365,7 @@ all there is. | |
| 184 365 | 
             
                  EOS
         | 
| 185 366 | 
             
                  html = render_embedded_string input
         | 
| 186 367 | 
             
                  result = Nokogiri::HTML(html)
         | 
| 187 | 
            -
                   | 
| 368 | 
            +
                  refute_match(/blah blah/m, result.css("p").first.content.strip)
         | 
| 188 369 | 
             
                end
         | 
| 189 370 |  | 
| 190 371 | 
             
                test "attribute value gets interpretted when rendering" do
         | 
| @@ -204,7 +385,7 @@ Line 2: Oh no, a {bogus-attribute}! This line should not appear in the output. | |
| 204 385 |  | 
| 205 386 | 
             
                  output = render_embedded_string input
         | 
| 206 387 | 
             
                  assert_match(/Line 1/, output)
         | 
| 207 | 
            -
                   | 
| 388 | 
            +
                  refute_match(/Line 2/, output)
         | 
| 208 389 | 
             
                end
         | 
| 209 390 |  | 
| 210 391 | 
             
                test 'should not drop line with reference to missing attribute by default' do
         | 
| @@ -229,7 +410,7 @@ Line 2: {set:a!}This line should not appear in the output. | |
| 229 410 |  | 
| 230 411 | 
             
                  output = render_embedded_string input
         | 
| 231 412 | 
             
                  assert_match(/Line 1/, output)
         | 
| 232 | 
            -
                   | 
| 413 | 
            +
                  refute_match(/Line 2/, output)
         | 
| 233 414 | 
             
                end
         | 
| 234 415 |  | 
| 235 416 | 
             
                test 'should not drop line with attribute unassignment if attribute-undefined is drop' do
         | 
| @@ -244,7 +425,7 @@ Line 2: {set:a!}This line should not appear in the output. | |
| 244 425 | 
             
                  output = render_embedded_string input
         | 
| 245 426 | 
             
                  assert_match(/Line 1/, output)
         | 
| 246 427 | 
             
                  assert_match(/Line 2/, output)
         | 
| 247 | 
            -
                   | 
| 428 | 
            +
                  refute_match(/\{set:a!\}/, output)
         | 
| 248 429 | 
             
                end
         | 
| 249 430 |  | 
| 250 431 | 
             
                test "substitutes inside unordered list items" do
         | 
| @@ -328,6 +509,15 @@ v1.0, 2010-01-01: First release! | |
| 328 509 | 
             
            :gem_name: asciidoctor
         | 
| 329 510 |  | 
| 330 511 | 
             
            .Require the +{gem_name}+ gem
         | 
| 512 | 
            +
            To use {gem_name}, the first thing to do is to import it in your Ruby source file.
         | 
| 513 | 
            +
                  EOS
         | 
| 514 | 
            +
                  output = render_embedded_string input, :attributes => {'compat-mode' => ''}
         | 
| 515 | 
            +
                  assert_xpath '//*[@class="title"]/code[text()="asciidoctor"]', output, 1
         | 
| 516 | 
            +
             | 
| 517 | 
            +
                  input = <<-EOS
         | 
| 518 | 
            +
            :gem_name: asciidoctor
         | 
| 519 | 
            +
             | 
| 520 | 
            +
            .Require the `{gem_name}` gem
         | 
| 331 521 | 
             
            To use {gem_name}, the first thing to do is to import it in your Ruby source file.
         | 
| 332 522 | 
             
                  EOS
         | 
| 333 523 | 
             
                  output = render_embedded_string input
         | 
| @@ -349,6 +539,30 @@ Belly up to the {foo}. | |
| 349 539 | 
             
                  assert_xpath '//p[text()="Belly up to the bar."]', output, 0
         | 
| 350 540 | 
             
                end
         | 
| 351 541 |  | 
| 542 | 
            +
                test 'should allow compat-mode to be set and unset in middle of document' do
         | 
| 543 | 
            +
                  input = <<-EOS
         | 
| 544 | 
            +
            :foo: bar
         | 
| 545 | 
            +
             | 
| 546 | 
            +
            [[paragraph-a]]
         | 
| 547 | 
            +
            `{foo}`
         | 
| 548 | 
            +
             | 
| 549 | 
            +
            :compat-mode!:
         | 
| 550 | 
            +
             | 
| 551 | 
            +
            [[paragraph-b]]
         | 
| 552 | 
            +
            `{foo}`
         | 
| 553 | 
            +
             | 
| 554 | 
            +
            :compat-mode:
         | 
| 555 | 
            +
             | 
| 556 | 
            +
            [[paragraph-c]]
         | 
| 557 | 
            +
            `{foo}`
         | 
| 558 | 
            +
                  EOS
         | 
| 559 | 
            +
             | 
| 560 | 
            +
                  result = render_embedded_string input, :attributes => {'compat-mode' => '@'}
         | 
| 561 | 
            +
                  assert_xpath '/*[@id="paragraph-a"]//code[text()="{foo}"]', result, 1
         | 
| 562 | 
            +
                  assert_xpath '/*[@id="paragraph-b"]//code[text()="bar"]', result, 1
         | 
| 563 | 
            +
                  assert_xpath '/*[@id="paragraph-c"]//code[text()="{foo}"]', result, 1
         | 
| 564 | 
            +
                end
         | 
| 565 | 
            +
             | 
| 352 566 | 
             
                test 'does not disturb attribute-looking things escaped with backslash' do
         | 
| 353 567 | 
             
                  html = render_string(":foo: bar\nThis is a \\{foo} day.")
         | 
| 354 568 | 
             
                  result = Nokogiri::HTML(html)
         | 
| @@ -450,7 +664,7 @@ of the attribute named foo in your document. | |
| 450 664 | 
             
              context "Intrinsic attributes" do
         | 
| 451 665 |  | 
| 452 666 | 
             
                test "substitute intrinsics" do
         | 
| 453 | 
            -
                  Asciidoctor:: | 
| 667 | 
            +
                  Asciidoctor::INTRINSIC_ATTRIBUTES.each_pair do |key, value|
         | 
| 454 668 | 
             
                    html = render_string("Look, a {#{key}} is here")
         | 
| 455 669 | 
             
                    # can't use Nokogiri because it interprets the HTML entities and we can't match them
         | 
| 456 670 | 
             
                    assert_match(/Look, a #{Regexp.escape(value)} is here/, html)
         | 
| @@ -539,10 +753,42 @@ of the attribute named foo in your document. | |
| 539 753 | 
             
                  assert_xpath '//p[text()="A"]', output, 2
         | 
| 540 754 | 
             
                end
         | 
| 541 755 |  | 
| 756 | 
            +
                test 'counter uses 0 as seed value if seed attribute is nil' do
         | 
| 757 | 
            +
                  input = <<-EOS
         | 
| 758 | 
            +
            :mycounter:
         | 
| 759 | 
            +
             | 
| 760 | 
            +
            {counter:mycounter}
         | 
| 761 | 
            +
             | 
| 762 | 
            +
            {mycounter}
         | 
| 763 | 
            +
                  EOS
         | 
| 764 | 
            +
             | 
| 765 | 
            +
                  doc = document_from_string input
         | 
| 766 | 
            +
                  output = doc.render :header_footer => false
         | 
| 767 | 
            +
                  assert_equal 1, doc.attributes['mycounter']
         | 
| 768 | 
            +
                  assert_xpath '//p[text()="1"]', output, 2
         | 
| 769 | 
            +
                end
         | 
| 770 | 
            +
             | 
| 771 | 
            +
                test 'counter value can be reset by attribute entry' do
         | 
| 772 | 
            +
                  input = <<-EOS
         | 
| 773 | 
            +
            :mycounter:
         | 
| 774 | 
            +
             | 
| 775 | 
            +
            before: {counter:mycounter} {counter:mycounter} {counter:mycounter}
         | 
| 776 | 
            +
             | 
| 777 | 
            +
            :mycounter!:
         | 
| 778 | 
            +
             | 
| 779 | 
            +
            after: {counter:mycounter}
         | 
| 780 | 
            +
                  EOS
         | 
| 781 | 
            +
             | 
| 782 | 
            +
                  doc = document_from_string input
         | 
| 783 | 
            +
                  output = doc.render :header_footer => false
         | 
| 784 | 
            +
                  assert_equal 1, doc.attributes['mycounter']
         | 
| 785 | 
            +
                  assert_xpath '//p[text()="before: 1 2 3"]', output, 1
         | 
| 786 | 
            +
                  assert_xpath '//p[text()="after: 1"]', output, 1
         | 
| 787 | 
            +
                end
         | 
| 542 788 | 
             
              end
         | 
| 543 789 |  | 
| 544 790 | 
             
              context 'Block attributes' do
         | 
| 545 | 
            -
                test ' | 
| 791 | 
            +
                test 'positional attributes assigned to block' do
         | 
| 546 792 | 
             
                  input = <<-EOS
         | 
| 547 793 | 
             
            [quote, author, source]
         | 
| 548 794 | 
             
            ____
         | 
| @@ -558,7 +804,7 @@ ____ | |
| 558 804 | 
             
                  assert_equal 'source', qb.attributes['citetitle']
         | 
| 559 805 | 
             
                end
         | 
| 560 806 |  | 
| 561 | 
            -
                test ' | 
| 807 | 
            +
                test 'normal substitutions are performed on single-quoted positional attribute' do
         | 
| 562 808 | 
             
                  input = <<-EOS
         | 
| 563 809 | 
             
            [quote, author, 'http://wikipedia.org[source]']
         | 
| 564 810 | 
             
            ____
         | 
| @@ -574,6 +820,31 @@ ____ | |
| 574 820 | 
             
                  assert_equal '<a href="http://wikipedia.org">source</a>', qb.attributes['citetitle']
         | 
| 575 821 | 
             
                end
         | 
| 576 822 |  | 
| 823 | 
            +
                test 'normal substitutions are performed on single-quoted named attribute' do
         | 
| 824 | 
            +
                  input = <<-EOS
         | 
| 825 | 
            +
            [quote, author, citetitle='http://wikipedia.org[source]']
         | 
| 826 | 
            +
            ____
         | 
| 827 | 
            +
            A famous quote.
         | 
| 828 | 
            +
            ____
         | 
| 829 | 
            +
                  EOS
         | 
| 830 | 
            +
                  doc = document_from_string(input)
         | 
| 831 | 
            +
                  qb = doc.blocks.first
         | 
| 832 | 
            +
                  assert_equal 'quote', qb.style
         | 
| 833 | 
            +
                  assert_equal 'author', qb.attr('attribution')
         | 
| 834 | 
            +
                  assert_equal 'author', qb.attr(:attribution)
         | 
| 835 | 
            +
                  assert_equal 'author', qb.attributes['attribution']
         | 
| 836 | 
            +
                  assert_equal '<a href="http://wikipedia.org">source</a>', qb.attributes['citetitle']
         | 
| 837 | 
            +
                end
         | 
| 838 | 
            +
             | 
| 839 | 
            +
                test 'normal substitutions are performed once on single-quoted named title attribute' do
         | 
| 840 | 
            +
                  input = <<-EOS
         | 
| 841 | 
            +
            [title='*title*']
         | 
| 842 | 
            +
            content
         | 
| 843 | 
            +
                  EOS
         | 
| 844 | 
            +
                  output = render_embedded_string input
         | 
| 845 | 
            +
                  assert_xpath '//*[@class="title"]/strong[text()="title"]', output, 1
         | 
| 846 | 
            +
                end
         | 
| 847 | 
            +
             | 
| 577 848 | 
             
                test 'attribute list may begin with space' do
         | 
| 578 849 | 
             
                  input = <<-EOS
         | 
| 579 850 | 
             
            [ quote]
         | 
| @@ -634,6 +905,17 @@ ____ | |
| 634 905 | 
             
                  assert_equal 'famous', qb.attributes['role']
         | 
| 635 906 | 
             
                end
         | 
| 636 907 |  | 
| 908 | 
            +
                test 'attribute with value None without quotes is ignored' do
         | 
| 909 | 
            +
                  input = <<-EOS
         | 
| 910 | 
            +
            [id=None]
         | 
| 911 | 
            +
            paragraph
         | 
| 912 | 
            +
                  EOS
         | 
| 913 | 
            +
             | 
| 914 | 
            +
                  doc = document_from_string input
         | 
| 915 | 
            +
                  para = doc.blocks.first
         | 
| 916 | 
            +
                  assert !para.attributes.has_key?('id')
         | 
| 917 | 
            +
                end
         | 
| 918 | 
            +
             | 
| 637 919 | 
             
                test 'role? returns true if role is assigned' do
         | 
| 638 920 | 
             
                  input = <<-EOS
         | 
| 639 921 | 
             
            [role="lead"]
         | 
| @@ -754,6 +1036,24 @@ Content. | |
| 754 1036 | 
             
                  assert_xpath '/div[@class="sect1 small"]/h2[@id="dedication"]', output, 1
         | 
| 755 1037 | 
             
                end
         | 
| 756 1038 |  | 
| 1039 | 
            +
                test 'id attribute specified using shorthand syntax should not create a special section' do
         | 
| 1040 | 
            +
                  input = <<-EOS
         | 
| 1041 | 
            +
            [#idname]
         | 
| 1042 | 
            +
            == Section
         | 
| 1043 | 
            +
             | 
| 1044 | 
            +
            content
         | 
| 1045 | 
            +
                  EOS
         | 
| 1046 | 
            +
             | 
| 1047 | 
            +
                  doc = document_from_string input, :backend => 'docbook45'
         | 
| 1048 | 
            +
                  section = doc.blocks[0]
         | 
| 1049 | 
            +
                  refute_nil section
         | 
| 1050 | 
            +
                  assert_equal :section, section.context
         | 
| 1051 | 
            +
                  assert !section.special
         | 
| 1052 | 
            +
                  output = doc.convert
         | 
| 1053 | 
            +
                  assert_css 'section', output, 1
         | 
| 1054 | 
            +
                  assert_css 'section#idname', output, 1
         | 
| 1055 | 
            +
                end
         | 
| 1056 | 
            +
             | 
| 757 1057 | 
             
                test "Block attributes are additive" do
         | 
| 758 1058 | 
             
                  input = <<-EOS
         | 
| 759 1059 | 
             
            [id='foo']
         |