asciidoctor 1.5.5 → 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +216 -1
- data/CONTRIBUTING.adoc +2 -2
- data/Gemfile +20 -1
- data/LICENSE.adoc +1 -1
- data/README-fr.adoc +4 -3
- data/README-jp.adoc +11 -10
- data/README-zh_CN.adoc +4 -3
- data/README.adoc +17 -202
- data/Rakefile +41 -25
- data/asciidoctor.gemspec +9 -10
- data/data/locale/attributes.adoc +216 -34
- data/data/stylesheets/asciidoctor-default.css +23 -16
- data/features/step_definitions.rb +15 -19
- data/features/xref.feature +584 -20
- data/lib/asciidoctor.rb +292 -278
- data/lib/asciidoctor/abstract_block.rb +155 -94
- data/lib/asciidoctor/abstract_node.rb +108 -94
- data/lib/asciidoctor/attribute_list.rb +30 -22
- data/lib/asciidoctor/block.rb +7 -7
- data/lib/asciidoctor/cli/invoker.rb +47 -34
- data/lib/asciidoctor/cli/options.rb +22 -11
- data/lib/asciidoctor/converter.rb +3 -3
- data/lib/asciidoctor/converter/base.rb +2 -2
- data/lib/asciidoctor/converter/composite.rb +1 -1
- data/lib/asciidoctor/converter/docbook45.rb +2 -2
- data/lib/asciidoctor/converter/docbook5.rb +132 -87
- data/lib/asciidoctor/converter/factory.rb +0 -1
- data/lib/asciidoctor/converter/html5.rb +116 -98
- data/lib/asciidoctor/converter/manpage.rb +51 -52
- data/lib/asciidoctor/converter/template.rb +47 -36
- data/lib/asciidoctor/core_ext.rb +8 -2
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +4 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +5 -0
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +1 -1
- data/lib/asciidoctor/core_ext/1.8.7/string/{limit.rb → limit_bytesize.rb} +7 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +1 -1
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +5 -5
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +3 -0
- data/lib/asciidoctor/core_ext/string/{limit.rb → limit_bytesize.rb} +2 -2
- data/lib/asciidoctor/document.rb +216 -213
- data/lib/asciidoctor/extensions.rb +318 -185
- data/lib/asciidoctor/helpers.rb +35 -35
- data/lib/asciidoctor/inline.rb +32 -1
- data/lib/asciidoctor/list.rb +22 -6
- data/lib/asciidoctor/parser.rb +1008 -1038
- data/lib/asciidoctor/path_resolver.rb +46 -50
- data/lib/asciidoctor/reader.rb +275 -251
- data/lib/asciidoctor/section.rb +86 -58
- data/lib/asciidoctor/stylesheets.rb +6 -6
- data/lib/asciidoctor/substitutors.rb +567 -649
- data/lib/asciidoctor/table.rb +163 -108
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +18 -16
- data/man/asciidoctor.adoc +15 -13
- data/test/attributes_test.rb +138 -22
- data/test/blocks_test.rb +377 -97
- data/test/converter_test.rb +13 -0
- data/test/document_test.rb +244 -34
- data/test/extensions_test.rb +409 -42
- data/test/fixtures/asciidoc_index.txt +521 -0
- data/test/fixtures/basic-docinfo-footer.html +6 -0
- data/test/fixtures/basic-docinfo-footer.xml +8 -0
- data/test/fixtures/basic-docinfo.html +1 -0
- data/test/fixtures/basic-docinfo.xml +4 -0
- data/test/fixtures/basic.asciidoc +5 -0
- data/test/fixtures/chapter-a.adoc +3 -0
- data/test/fixtures/child-include.adoc +5 -0
- data/test/fixtures/circle.svg +9 -0
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +1 -0
- data/test/fixtures/custom-docinfodir/docinfo.html +1 -0
- data/test/fixtures/docinfo-footer.html +1 -0
- data/test/fixtures/docinfo-footer.xml +9 -0
- data/test/fixtures/docinfo.html +1 -0
- data/test/fixtures/docinfo.xml +3 -0
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +13 -0
- data/test/fixtures/grandchild-include.adoc +3 -0
- data/test/fixtures/hello-asciidoctor.pdf +69 -0
- data/test/fixtures/include-file.asciidoc +24 -0
- data/test/fixtures/include-file.ml +3 -0
- data/test/fixtures/include-file.xml +5 -0
- data/test/fixtures/master.adoc +5 -0
- data/test/fixtures/mismatched-end-tag.adoc +7 -0
- data/test/fixtures/parent-include-restricted.adoc +5 -0
- data/test/fixtures/parent-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +26 -0
- data/test/fixtures/stylesheets/custom.css +3 -0
- data/test/fixtures/subs-docinfo.html +2 -0
- data/test/fixtures/subs.adoc +7 -0
- data/test/fixtures/tagged-class-enclosed.rb +26 -0
- data/test/fixtures/tagged-class.rb +23 -0
- data/test/fixtures/tip.gif +0 -0
- data/test/invoker_test.rb +82 -4
- data/test/links_test.rb +312 -37
- data/test/lists_test.rb +204 -25
- data/test/manpage_test.rb +191 -4
- data/test/options_test.rb +18 -1
- data/test/paragraphs_test.rb +32 -7
- data/test/parser_test.rb +150 -30
- data/test/paths_test.rb +47 -13
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +366 -126
- data/test/sections_test.rb +203 -56
- data/test/substitutions_test.rb +339 -131
- data/test/tables_test.rb +315 -15
- data/test/test_helper.rb +400 -0
- data/test/text_test.rb +5 -5
- metadata +110 -22
| @@ -4,20 +4,20 @@ module Asciidoctor | |
| 4 4 | 
             
              # consistent with the html5 backend from AsciiDoc Python.
         | 
| 5 5 | 
             
              class Converter::Html5Converter < Converter::BuiltIn
         | 
| 6 6 | 
             
                (QUOTE_TAGS = {
         | 
| 7 | 
            +
                  :monospaced  => ['<code>',   '</code>',   true],
         | 
| 7 8 | 
             
                  :emphasis    => ['<em>',     '</em>',     true],
         | 
| 8 9 | 
             
                  :strong      => ['<strong>', '</strong>', true],
         | 
| 9 | 
            -
                  :monospaced  => ['<code>',   '</code>',   true],
         | 
| 10 | 
            -
                  :superscript => ['<sup>',    '</sup>',    true],
         | 
| 11 | 
            -
                  :subscript   => ['<sub>',    '</sub>',    true],
         | 
| 12 10 | 
             
                  :double      => ['“',  '”',   false],
         | 
| 13 11 | 
             
                  :single      => ['‘',  '’',   false],
         | 
| 14 12 | 
             
                  :mark        => ['<mark>',   '</mark>',   true],
         | 
| 15 | 
            -
                  : | 
| 16 | 
            -
                  : | 
| 13 | 
            +
                  :superscript => ['<sup>',    '</sup>',    true],
         | 
| 14 | 
            +
                  :subscript   => ['<sub>',    '</sub>',    true],
         | 
| 15 | 
            +
                  :asciimath   => ['\$',       '\$',        false],
         | 
| 16 | 
            +
                  :latexmath   => ['\(',       '\)',        false]
         | 
| 17 17 | 
             
                  # Opal can't resolve these constants when referenced here
         | 
| 18 18 | 
             
                  #:asciimath   => INLINE_MATH_DELIMITERS[:asciimath] + [false],
         | 
| 19 19 | 
             
                  #:latexmath   => INLINE_MATH_DELIMITERS[:latexmath] + [false]
         | 
| 20 | 
            -
                }).default = [ | 
| 20 | 
            +
                }).default = ['', '', false]
         | 
| 21 21 |  | 
| 22 22 | 
             
                SvgPreambleRx = /\A.*?(?=<svg\b)/m
         | 
| 23 23 | 
             
                SvgStartTagRx = /\A<svg[^>]*>/
         | 
| @@ -30,7 +30,6 @@ module Asciidoctor | |
| 30 30 | 
             
                end
         | 
| 31 31 |  | 
| 32 32 | 
             
                def document node
         | 
| 33 | 
            -
                  result = []
         | 
| 34 33 | 
             
                  slash = @void_element_slash
         | 
| 35 34 | 
             
                  br = %(<br#{slash}>)
         | 
| 36 35 | 
             
                  unless (asset_uri_scheme = (node.attr 'asset-uri-scheme', 'https')).empty?
         | 
| @@ -38,7 +37,7 @@ module Asciidoctor | |
| 38 37 | 
             
                  end
         | 
| 39 38 | 
             
                  cdn_base = %(#{asset_uri_scheme}//cdnjs.cloudflare.com/ajax/libs)
         | 
| 40 39 | 
             
                  linkcss = node.safe >= SafeMode::SECURE || (node.attr? 'linkcss')
         | 
| 41 | 
            -
                  result  | 
| 40 | 
            +
                  result = ['<!DOCTYPE html>']
         | 
| 42 41 | 
             
                  lang_attribute = (node.attr? 'nolang') ? nil : %( lang="#{node.attr 'lang', 'en'}")
         | 
| 43 42 | 
             
                  result << %(<html#{@xml_mode ? ' xmlns="http://www.w3.org/1999/xhtml"' : nil}#{lang_attribute}>)
         | 
| 44 43 | 
             
                  result << %(<head>
         | 
| @@ -49,8 +48,16 @@ module Asciidoctor | |
| 49 48 | 
             
                  result << %(<meta name="application-name" content="#{node.attr 'app-name'}"#{slash}>) if node.attr? 'app-name'
         | 
| 50 49 | 
             
                  result << %(<meta name="description" content="#{node.attr 'description'}"#{slash}>) if node.attr? 'description'
         | 
| 51 50 | 
             
                  result << %(<meta name="keywords" content="#{node.attr 'keywords'}"#{slash}>) if node.attr? 'keywords'
         | 
| 52 | 
            -
                  result << %(<meta name="author" content="#{node.attr 'authors'}"#{slash}>) if node.attr? 'authors'
         | 
| 51 | 
            +
                  result << %(<meta name="author" content="#{((authors = node.attr 'authors').include? '<') ? (authors.gsub XmlSanitizeRx, '') : authors}"#{slash}>) if node.attr? 'authors'
         | 
| 53 52 | 
             
                  result << %(<meta name="copyright" content="#{node.attr 'copyright'}"#{slash}>) if node.attr? 'copyright'
         | 
| 53 | 
            +
                  if node.attr? 'favicon'
         | 
| 54 | 
            +
                    if (icon_href = node.attr 'favicon').empty?
         | 
| 55 | 
            +
                      icon_href, icon_type = 'favicon.ico', 'image/x-icon'
         | 
| 56 | 
            +
                    else
         | 
| 57 | 
            +
                      icon_type = (icon_ext = ::File.extname icon_href) == '.ico' ? 'image/x-icon' : %(image/#{icon_ext[1..-1]})
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                    result << %(<link rel="shortcut icon" type="#{icon_type}" href="#{icon_href}">)
         | 
| 60 | 
            +
                  end
         | 
| 54 61 | 
             
                  result << %(<title>#{node.doctitle :sanitize => true, :use_fallback => true}</title>)
         | 
| 55 62 |  | 
| 56 63 | 
             
                  if DEFAULT_STYLESHEET_KEYS.include?(node.attr 'stylesheet')
         | 
| @@ -67,7 +74,7 @@ module Asciidoctor | |
| 67 74 | 
             
                      result << %(<link rel="stylesheet" href="#{node.normalize_web_path((node.attr 'stylesheet'), (node.attr 'stylesdir', ''))}"#{slash}>)
         | 
| 68 75 | 
             
                    else
         | 
| 69 76 | 
             
                      result << %(<style>
         | 
| 70 | 
            -
            #{node.read_asset node.normalize_system_path((node.attr 'stylesheet'), (node.attr 'stylesdir', '')), :warn_on_failure => true}
         | 
| 77 | 
            +
            #{node.read_asset node.normalize_system_path((node.attr 'stylesheet'), (node.attr 'stylesdir', '')), :warn_on_failure => true, :label => 'stylesheet'}
         | 
| 71 78 | 
             
            </style>)
         | 
| 72 79 | 
             
                    end
         | 
| 73 80 | 
             
                  end
         | 
| @@ -207,7 +214,7 @@ module Asciidoctor | |
| 207 214 | 
             
                  # See http://www.html5rocks.com/en/tutorials/speed/script-loading/
         | 
| 208 215 | 
             
                  case highlighter
         | 
| 209 216 | 
             
                  when 'highlightjs', 'highlight.js'
         | 
| 210 | 
            -
                    highlightjs_path = node.attr 'highlightjsdir', %(#{cdn_base}/highlight.js/ | 
| 217 | 
            +
                    highlightjs_path = node.attr 'highlightjsdir', %(#{cdn_base}/highlight.js/9.12.0)
         | 
| 211 218 | 
             
                    result << %(<link rel="stylesheet" href="#{highlightjs_path}/styles/#{node.attr 'highlightjs-theme', 'github'}.min.css"#{slash}>)
         | 
| 212 219 | 
             
                    result << %(<script src="#{highlightjs_path}/highlight.min.js"></script>
         | 
| 213 220 | 
             
            <script>hljs.initHighlighting()</script>)
         | 
| @@ -243,7 +250,7 @@ MathJax.Hub.Config({ | |
| 243 250 |  | 
| 244 251 | 
             
                  result << '</body>'
         | 
| 245 252 | 
             
                  result << '</html>'
         | 
| 246 | 
            -
                  result *  | 
| 253 | 
            +
                  result * LF
         | 
| 247 254 | 
             
                end
         | 
| 248 255 |  | 
| 249 256 | 
             
                def embedded node
         | 
| @@ -286,38 +293,39 @@ MathJax.Hub.Config({ | |
| 286 293 | 
             
                    result << '</div>'
         | 
| 287 294 | 
             
                  end
         | 
| 288 295 |  | 
| 289 | 
            -
                  result *  | 
| 296 | 
            +
                  result * LF
         | 
| 290 297 | 
             
                end
         | 
| 291 298 |  | 
| 292 299 | 
             
                def outline node, opts = {}
         | 
| 293 300 | 
             
                  return unless node.sections?
         | 
| 294 301 | 
             
                  sectnumlevels = opts[:sectnumlevels] || (node.document.attr 'sectnumlevels', 3).to_i
         | 
| 295 302 | 
             
                  toclevels = opts[:toclevels] || (node.document.attr 'toclevels', 2).to_i
         | 
| 296 | 
            -
                  result = []
         | 
| 297 303 | 
             
                  sections = node.sections
         | 
| 298 | 
            -
                  # FIXME  | 
| 299 | 
            -
                   | 
| 300 | 
            -
                  slevel = (first_section = sections[0]).level
         | 
| 301 | 
            -
                  slevel = 1 if slevel == 0 && first_section.special
         | 
| 302 | 
            -
                  result << %(<ul class="sectlevel#{slevel}">)
         | 
| 304 | 
            +
                  # FIXME top level is incorrect if a multipart book starts with a special section defined at level 0
         | 
| 305 | 
            +
                  result = [%(<ul class="sectlevel#{sections[0].level}">)]
         | 
| 303 306 | 
             
                  sections.each do |section|
         | 
| 304 | 
            -
                     | 
| 305 | 
            -
                    if section. | 
| 306 | 
            -
                       | 
| 307 | 
            +
                    slevel = section.level
         | 
| 308 | 
            +
                    if section.caption
         | 
| 309 | 
            +
                      stitle = section.captioned_title
         | 
| 310 | 
            +
                    elsif section.numbered && slevel <= sectnumlevels
         | 
| 311 | 
            +
                      stitle = %(#{section.sectnum} #{section.title})
         | 
| 312 | 
            +
                    else
         | 
| 313 | 
            +
                      stitle = section.title
         | 
| 314 | 
            +
                    end
         | 
| 315 | 
            +
                    if slevel < toclevels && (child_toc_level = outline section, :toclevels => toclevels, :secnumlevels => sectnumlevels)
         | 
| 316 | 
            +
                      result << %(<li><a href="##{section.id}">#{stitle}</a>)
         | 
| 307 317 | 
             
                      result << child_toc_level
         | 
| 308 318 | 
             
                      result << '</li>'
         | 
| 309 319 | 
             
                    else
         | 
| 310 | 
            -
                      result << %(<li><a href="##{section.id}">#{ | 
| 320 | 
            +
                      result << %(<li><a href="##{section.id}">#{stitle}</a></li>)
         | 
| 311 321 | 
             
                    end
         | 
| 312 322 | 
             
                  end
         | 
| 313 323 | 
             
                  result << '</ul>'
         | 
| 314 | 
            -
                  result *  | 
| 324 | 
            +
                  result * LF
         | 
| 315 325 | 
             
                end
         | 
| 316 326 |  | 
| 317 327 | 
             
                def section node
         | 
| 318 328 | 
             
                  slevel = node.level
         | 
| 319 | 
            -
                  # QUESTION should the check for slevel be done in section?
         | 
| 320 | 
            -
                  slevel = 1 if slevel == 0 && node.special
         | 
| 321 329 | 
             
                  htag = %(h#{slevel + 1})
         | 
| 322 330 | 
             
                  id_attr = anchor = link_start = link_end = nil
         | 
| 323 331 | 
             
                  if node.id
         | 
| @@ -356,20 +364,20 @@ MathJax.Hub.Config({ | |
| 356 364 | 
             
                  id_attr = node.id ? %( id="#{node.id}") : nil
         | 
| 357 365 | 
             
                  name = node.attr 'name'
         | 
| 358 366 | 
             
                  title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : nil
         | 
| 359 | 
            -
                   | 
| 367 | 
            +
                  if node.document.attr? 'icons'
         | 
| 360 368 | 
             
                    if (node.document.attr? 'icons', 'font') && !(node.attr? 'icon')
         | 
| 361 | 
            -
                      %(<i class="fa icon-#{name}" title="#{node. | 
| 369 | 
            +
                      label = %(<i class="fa icon-#{name}" title="#{node.attr 'textlabel'}"></i>)
         | 
| 362 370 | 
             
                    else
         | 
| 363 | 
            -
                      %(<img src="#{node.icon_uri name}" alt="#{node. | 
| 371 | 
            +
                      label = %(<img src="#{node.icon_uri name}" alt="#{node.attr 'textlabel'}"#{@void_element_slash}>)
         | 
| 364 372 | 
             
                    end
         | 
| 365 373 | 
             
                  else
         | 
| 366 | 
            -
                    %(<div class="title">#{node. | 
| 374 | 
            +
                    label = %(<div class="title">#{node.attr 'textlabel'}</div>)
         | 
| 367 375 | 
             
                  end
         | 
| 368 376 | 
             
                  %(<div#{id_attr} class="admonitionblock #{name}#{(role = node.role) && " #{role}"}">
         | 
| 369 377 | 
             
            <table>
         | 
| 370 378 | 
             
            <tr>
         | 
| 371 379 | 
             
            <td class="icon">
         | 
| 372 | 
            -
            #{ | 
| 380 | 
            +
            #{label}
         | 
| 373 381 | 
             
            </td>
         | 
| 374 382 | 
             
            <td class="content">
         | 
| 375 383 | 
             
            #{title_element}#{node.content}
         | 
| @@ -384,10 +392,13 @@ MathJax.Hub.Config({ | |
| 384 392 | 
             
                  id_attribute = node.id ? %( id="#{node.id}") : nil
         | 
| 385 393 | 
             
                  classes = ['audioblock', node.role].compact
         | 
| 386 394 | 
             
                  class_attribute = %( class="#{classes * ' '}")
         | 
| 387 | 
            -
                  title_element = node.title? ? %(<div class="title">#{node. | 
| 395 | 
            +
                  title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : nil
         | 
| 396 | 
            +
                  start_t = node.attr 'start', nil, false
         | 
| 397 | 
            +
                  end_t = node.attr 'end', nil, false
         | 
| 398 | 
            +
                  time_anchor = (start_t || end_t) ? %(#t=#{start_t}#{end_t ? ',' : nil}#{end_t}) : nil
         | 
| 388 399 | 
             
                  %(<div#{id_attribute}#{class_attribute}>
         | 
| 389 400 | 
             
            #{title_element}<div class="content">
         | 
| 390 | 
            -
            <audio src="#{node.media_uri(node.attr 'target')}"#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : nil}#{(node.option? 'nocontrols') ? nil : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : nil}>
         | 
| 401 | 
            +
            <audio src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : nil}#{(node.option? 'nocontrols') ? nil : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : nil}>
         | 
| 391 402 | 
             
            Your browser does not support the audio tag.
         | 
| 392 403 | 
             
            </audio>
         | 
| 393 404 | 
             
            </div>
         | 
| @@ -405,34 +416,32 @@ Your browser does not support the audio tag. | |
| 405 416 |  | 
| 406 417 | 
             
                  if node.document.attr? 'icons'
         | 
| 407 418 | 
             
                    result << '<table>'
         | 
| 408 | 
            -
             | 
| 409 | 
            -
                     | 
| 410 | 
            -
             | 
| 411 | 
            -
                       | 
| 412 | 
            -
             | 
| 413 | 
            -
                        %(<i class="conum" data-value="#{num}"></i><b>#{num}</b>)
         | 
| 419 | 
            +
                    font_icons, num = (node.document.attr? 'icons', 'font'), 0
         | 
| 420 | 
            +
                    node.items.each do |item|
         | 
| 421 | 
            +
                      num += 1
         | 
| 422 | 
            +
                      if font_icons
         | 
| 423 | 
            +
                        num_label = %(<i class="conum" data-value="#{num}"></i><b>#{num}</b>)
         | 
| 414 424 | 
             
                      else
         | 
| 415 | 
            -
                        %(<img src="#{node.icon_uri "callouts/#{num}"}" alt="#{num}"#{@void_element_slash}>)
         | 
| 425 | 
            +
                        num_label = %(<img src="#{node.icon_uri "callouts/#{num}"}" alt="#{num}"#{@void_element_slash}>)
         | 
| 416 426 | 
             
                      end
         | 
| 417 427 | 
             
                      result << %(<tr>
         | 
| 418 | 
            -
            <td>#{ | 
| 419 | 
            -
            <td>#{item.text}</td>
         | 
| 428 | 
            +
            <td>#{num_label}</td>
         | 
| 429 | 
            +
            <td>#{item.text}#{item.blocks? ? LF + item.content : ''}</td>
         | 
| 420 430 | 
             
            </tr>)
         | 
| 421 431 | 
             
                    end
         | 
| 422 | 
            -
             | 
| 423 432 | 
             
                    result << '</table>'
         | 
| 424 433 | 
             
                  else
         | 
| 425 434 | 
             
                    result << '<ol>'
         | 
| 426 435 | 
             
                    node.items.each do |item|
         | 
| 427 436 | 
             
                      result << %(<li>
         | 
| 428 | 
            -
            <p>#{item.text}</p | 
| 437 | 
            +
            <p>#{item.text}</p>#{item.blocks? ? LF + item.content : ''}
         | 
| 429 438 | 
             
            </li>)
         | 
| 430 439 | 
             
                    end
         | 
| 431 440 | 
             
                    result << '</ol>'
         | 
| 432 441 | 
             
                  end
         | 
| 433 442 |  | 
| 434 443 | 
             
                  result << '</div>'
         | 
| 435 | 
            -
                  result *  | 
| 444 | 
            +
                  result * LF
         | 
| 436 445 | 
             
                end
         | 
| 437 446 |  | 
| 438 447 | 
             
                def dlist node
         | 
| @@ -515,14 +524,14 @@ Your browser does not support the audio tag. | |
| 515 524 | 
             
                  end
         | 
| 516 525 |  | 
| 517 526 | 
             
                  result << '</div>'
         | 
| 518 | 
            -
                  result *  | 
| 527 | 
            +
                  result * LF
         | 
| 519 528 | 
             
                end
         | 
| 520 529 |  | 
| 521 530 | 
             
                def example node
         | 
| 522 531 | 
             
                  id_attribute = node.id ? %( id="#{node.id}") : nil
         | 
| 523 532 | 
             
                  title_element = node.title? ? %(<div class="title">#{node.captioned_title}</div>\n) : nil
         | 
| 524 533 |  | 
| 525 | 
            -
                  %(<div#{id_attribute} class="#{(role = node.role)  | 
| 534 | 
            +
                  %(<div#{id_attribute} class="exampleblock#{(role = node.role) && " #{role}"}">
         | 
| 526 535 | 
             
            #{title_element}<div class="content">
         | 
| 527 536 | 
             
            #{node.content}
         | 
| 528 537 | 
             
            </div>
         | 
| @@ -543,15 +552,16 @@ Your browser does not support the audio tag. | |
| 543 552 | 
             
                  if ((node.attr? 'format', 'svg', false) || (target.include? '.svg')) && node.document.safe < SafeMode::SECURE &&
         | 
| 544 553 | 
             
                      ((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
         | 
| 545 554 | 
             
                    if svg
         | 
| 546 | 
            -
                      img = (read_svg_contents node, target) || %(<span class="alt">#{node. | 
| 555 | 
            +
                      img = (read_svg_contents node, target) || %(<span class="alt">#{node.alt}</span>)
         | 
| 547 556 | 
             
                    elsif obj
         | 
| 548 | 
            -
                      fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri(node.attr 'fallback')}" alt="#{node. | 
| 557 | 
            +
                      fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri(node.attr 'fallback')}" alt="#{encode_quotes node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>) : %(<span class="alt">#{node.alt}</span>)
         | 
| 549 558 | 
             
                      img = %(<object type="image/svg+xml" data="#{node.image_uri target}"#{width_attr}#{height_attr}>#{fallback}</object>)
         | 
| 550 559 | 
             
                    end
         | 
| 551 560 | 
             
                  end
         | 
| 552 | 
            -
                  img ||= %(<img src="#{node.image_uri target}" alt="#{node. | 
| 553 | 
            -
                  if  | 
| 554 | 
            -
                     | 
| 561 | 
            +
                  img ||= %(<img src="#{node.image_uri target}" alt="#{encode_quotes node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>)
         | 
| 562 | 
            +
                  if node.attr? 'link'
         | 
| 563 | 
            +
                    window_attr = %( target="#{window = node.attr 'window'}"#{window == '_blank' || (node.option? 'noopener') ? ' rel="noopener"' : ''}) if node.attr? 'window'
         | 
| 564 | 
            +
                    img = %(<a class="image" href="#{node.attr 'link'}"#{window_attr}>#{img}</a>)
         | 
| 555 565 | 
             
                  end
         | 
| 556 566 | 
             
                  id_attr = node.id ? %( id="#{node.id}") : nil
         | 
| 557 567 | 
             
                  classes = ['imageblock', node.role].compact
         | 
| @@ -583,9 +593,9 @@ Your browser does not support the audio tag. | |
| 583 593 | 
             
                      pre_class = %( class="pygments highlight#{nowrap ? ' nowrap' : nil}")
         | 
| 584 594 | 
             
                    when 'highlightjs', 'highlight.js'
         | 
| 585 595 | 
             
                      pre_class = %( class="highlightjs highlight#{nowrap ? ' nowrap' : nil}")
         | 
| 586 | 
            -
                      code_attrs = %( class="language-#{language}"#{code_attrs}) if language
         | 
| 596 | 
            +
                      code_attrs = %( class="language-#{language} hljs"#{code_attrs}) if language
         | 
| 587 597 | 
             
                    when 'prettify'
         | 
| 588 | 
            -
                      pre_class = %( class="prettyprint highlight#{nowrap ? ' nowrap' : nil}#{(node.attr? 'linenums') ? ' linenums' : nil}")
         | 
| 598 | 
            +
                      pre_class = %( class="prettyprint highlight#{nowrap ? ' nowrap' : nil}#{(node.attr? 'linenums', nil, false) ? ' linenums' : nil}")
         | 
| 589 599 | 
             
                      code_attrs = %( class="language-#{language}"#{code_attrs}) if language
         | 
| 590 600 | 
             
                    when 'html-pipeline'
         | 
| 591 601 | 
             
                      pre_class = language ? %( lang="#{language}") : nil
         | 
| @@ -630,7 +640,7 @@ Your browser does not support the audio tag. | |
| 630 640 | 
             
                    equation = %(#{open}#{equation}#{close})
         | 
| 631 641 | 
             
                  end
         | 
| 632 642 |  | 
| 633 | 
            -
                  %(<div#{id_attribute} class="#{(role = node.role)  | 
| 643 | 
            +
                  %(<div#{id_attribute} class="stemblock#{(role = node.role) && " #{role}"}">
         | 
| 634 644 | 
             
            #{title_element}<div class="content">
         | 
| 635 645 | 
             
            #{equation}
         | 
| 636 646 | 
             
            </div>
         | 
| @@ -660,7 +670,7 @@ Your browser does not support the audio tag. | |
| 660 670 |  | 
| 661 671 | 
             
                  result << '</ol>'
         | 
| 662 672 | 
             
                  result << '</div>'
         | 
| 663 | 
            -
                  result *  | 
| 673 | 
            +
                  result * LF
         | 
| 664 674 | 
             
                end
         | 
| 665 675 |  | 
| 666 676 | 
             
                def open node
         | 
| @@ -758,7 +768,7 @@ Your browser does not support the audio tag. | |
| 758 768 | 
             
                def sidebar node
         | 
| 759 769 | 
             
                  id_attribute = node.id ? %( id="#{node.id}") : nil
         | 
| 760 770 | 
             
                  title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : nil
         | 
| 761 | 
            -
                  %(<div#{id_attribute} class="#{(role = node.role)  | 
| 771 | 
            +
                  %(<div#{id_attribute} class="sidebarblock#{(role = node.role) && " #{role}"}">
         | 
| 762 772 | 
             
            <div class="content">
         | 
| 763 773 | 
             
            #{title_element}#{node.content}
         | 
| 764 774 | 
             
            </div>
         | 
| @@ -800,9 +810,10 @@ Your browser does not support the audio tag. | |
| 800 810 | 
             
                      end
         | 
| 801 811 | 
             
                    end
         | 
| 802 812 | 
             
                    result << '</colgroup>'
         | 
| 803 | 
            -
                     | 
| 813 | 
            +
                    node.rows.by_section.each do |tsec, rows|
         | 
| 814 | 
            +
                      next if rows.empty?
         | 
| 804 815 | 
             
                      result << %(<t#{tsec}>)
         | 
| 805 | 
            -
                       | 
| 816 | 
            +
                      rows.each do |row|
         | 
| 806 817 | 
             
                        result << '<tr>'
         | 
| 807 818 | 
             
                        row.each do |cell|
         | 
| 808 819 | 
             
                          if tsec == :head
         | 
| @@ -816,10 +827,8 @@ Your browser does not support the audio tag. | |
| 816 827 | 
             
                            when :literal
         | 
| 817 828 | 
             
                              cell_content = %(<div class="literal"><pre>#{cell.text}</pre></div>)
         | 
| 818 829 | 
             
                            else
         | 
| 819 | 
            -
                              cell_content = ''
         | 
| 820 | 
            -
             | 
| 821 | 
            -
                                cell_content = %(#{cell_content}<p class="tableblock">#{text}</p>)
         | 
| 822 | 
            -
                              end
         | 
| 830 | 
            +
                              cell_content = (cell_content = cell.content).empty? ? '' : %(<p class="tableblock">#{cell_content * '</p>
         | 
| 831 | 
            +
            <p class="tableblock">'}</p>)
         | 
| 823 832 | 
             
                            end
         | 
| 824 833 | 
             
                          end
         | 
| 825 834 |  | 
| @@ -836,7 +845,7 @@ Your browser does not support the audio tag. | |
| 836 845 | 
             
                    end
         | 
| 837 846 | 
             
                  end
         | 
| 838 847 | 
             
                  result << '</table>'
         | 
| 839 | 
            -
                  result *  | 
| 848 | 
            +
                  result * LF
         | 
| 840 849 | 
             
                end
         | 
| 841 850 |  | 
| 842 851 | 
             
                def toc node
         | 
| @@ -868,7 +877,7 @@ Your browser does not support the audio tag. | |
| 868 877 | 
             
                  marker_checked = nil
         | 
| 869 878 | 
             
                  marker_unchecked = nil
         | 
| 870 879 | 
             
                  if (checklist = node.option? 'checklist')
         | 
| 871 | 
            -
                    div_classes. | 
| 880 | 
            +
                    div_classes.unshift div_classes.shift, 'checklist'
         | 
| 872 881 | 
             
                    ul_class_attribute = ' class="checklist"'
         | 
| 873 882 | 
             
                    if node.option? 'interactive'
         | 
| 874 883 | 
             
                      if @xml_mode
         | 
| @@ -907,7 +916,7 @@ Your browser does not support the audio tag. | |
| 907 916 |  | 
| 908 917 | 
             
                  result << '</ul>'
         | 
| 909 918 | 
             
                  result << '</div>'
         | 
| 910 | 
            -
                  result *  | 
| 919 | 
            +
                  result * LF
         | 
| 911 920 | 
             
                end
         | 
| 912 921 |  | 
| 913 922 | 
             
                def verse node
         | 
| @@ -935,7 +944,7 @@ Your browser does not support the audio tag. | |
| 935 944 | 
             
                  id_attribute = node.id ? %( id="#{node.id}") : nil
         | 
| 936 945 | 
             
                  classes = ['videoblock', node.role].compact
         | 
| 937 946 | 
             
                  class_attribute = %( class="#{classes * ' '}")
         | 
| 938 | 
            -
                  title_element = node.title? ? %(\n<div class="title">#{node. | 
| 947 | 
            +
                  title_element = node.title? ? %(\n<div class="title">#{node.title}</div>) : nil
         | 
| 939 948 | 
             
                  width_attribute = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : nil
         | 
| 940 949 | 
             
                  height_attribute = (node.attr? 'height') ? %( height="#{node.attr 'height'}") : nil
         | 
| 941 950 | 
             
                  case node.attr 'poster'
         | 
| @@ -998,13 +1007,14 @@ Your browser does not support the audio tag. | |
| 998 1007 | 
             
            </div>
         | 
| 999 1008 | 
             
            </div>)
         | 
| 1000 1009 | 
             
                  else
         | 
| 1001 | 
            -
                    poster_attribute =  | 
| 1010 | 
            +
                    poster_attribute = (val = node.attr 'poster', nil, false).nil_or_empty? ? nil : %( poster="#{node.media_uri val}")
         | 
| 1011 | 
            +
                    preload_attribute = (val = node.attr 'preload', nil, false).nil_or_empty? ? nil : %( preload="#{val}")
         | 
| 1002 1012 | 
             
                    start_t = node.attr 'start', nil, false
         | 
| 1003 1013 | 
             
                    end_t = node.attr 'end', nil, false
         | 
| 1004 1014 | 
             
                    time_anchor = (start_t || end_t) ? %(#t=#{start_t}#{end_t ? ',' : nil}#{end_t}) : nil
         | 
| 1005 1015 | 
             
                    %(<div#{id_attribute}#{class_attribute}>#{title_element}
         | 
| 1006 1016 | 
             
            <div class="content">
         | 
| 1007 | 
            -
            <video src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{width_attribute}#{height_attribute}#{poster_attribute}#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : nil}#{(node.option? 'nocontrols') ? nil : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : nil}>
         | 
| 1017 | 
            +
            <video src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{width_attribute}#{height_attribute}#{poster_attribute}#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : nil}#{(node.option? 'nocontrols') ? nil : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : nil}#{preload_attribute}>
         | 
| 1008 1018 | 
             
            Your browser does not support the video tag.
         | 
| 1009 1019 | 
             
            </video>
         | 
| 1010 1020 | 
             
            </div>
         | 
| @@ -1013,27 +1023,29 @@ Your browser does not support the video tag. | |
| 1013 1023 | 
             
                end
         | 
| 1014 1024 |  | 
| 1015 1025 | 
             
                def inline_anchor node
         | 
| 1016 | 
            -
                  target = node.target
         | 
| 1017 1026 | 
             
                  case node.type
         | 
| 1018 1027 | 
             
                  when :xref
         | 
| 1019 | 
            -
                     | 
| 1020 | 
            -
             | 
| 1021 | 
            -
             | 
| 1022 | 
            -
             | 
| 1023 | 
            -
             | 
| 1028 | 
            +
                    unless (text = node.text)
         | 
| 1029 | 
            +
                      if AbstractNode === (ref = node.document.catalog[:refs][refid = node.attributes['refid']])
         | 
| 1030 | 
            +
                        text = ref.xreftext((@xrefstyle ||= node.document.attributes['xrefstyle'])) || %([#{refid}])
         | 
| 1031 | 
            +
                      else
         | 
| 1032 | 
            +
                        text = %([#{refid}])
         | 
| 1033 | 
            +
                      end
         | 
| 1034 | 
            +
                    end
         | 
| 1035 | 
            +
                    %(<a href="#{node.target}">#{text}</a>)
         | 
| 1024 1036 | 
             
                  when :ref
         | 
| 1025 | 
            -
                    %(<a id="#{ | 
| 1037 | 
            +
                    %(<a id="#{node.id}"></a>)
         | 
| 1026 1038 | 
             
                  when :link
         | 
| 1027 | 
            -
                    attrs = []
         | 
| 1028 | 
            -
                    attrs << %( id="#{node.id}") if node.id
         | 
| 1039 | 
            +
                    attrs = node.id ? [%( id="#{node.id}")] : []
         | 
| 1029 1040 | 
             
                    if (role = node.role)
         | 
| 1030 1041 | 
             
                      attrs << %( class="#{role}")
         | 
| 1031 1042 | 
             
                    end
         | 
| 1032 1043 | 
             
                    attrs << %( title="#{node.attr 'title'}") if node.attr? 'title', nil, false
         | 
| 1033 | 
            -
                    attrs << %( target="#{node.attr 'window'}") if node.attr? 'window', nil, false
         | 
| 1034 | 
            -
                    %(<a href="#{target}"#{attrs.join}>#{node.text}</a>)
         | 
| 1044 | 
            +
                    attrs << %( target="#{window = node.attr 'window'}"#{window == '_blank' || (node.option? 'noopener') ? ' rel="noopener"' : ''}) if node.attr? 'window', nil, false
         | 
| 1045 | 
            +
                    %(<a href="#{node.target}"#{attrs.join}>#{node.text}</a>)
         | 
| 1035 1046 | 
             
                  when :bibref
         | 
| 1036 | 
            -
                     | 
| 1047 | 
            +
                    # NOTE technically node.text should be node.reftext, but subs have already been applied to text
         | 
| 1048 | 
            +
                    %(<a id="#{node.id}"></a>#{node.text})
         | 
| 1037 1049 | 
             
                  else
         | 
| 1038 1050 | 
             
                    warn %(asciidoctor: WARNING: unknown anchor type: #{node.type.inspect})
         | 
| 1039 1051 | 
             
                  end
         | 
| @@ -1059,7 +1071,7 @@ Your browser does not support the video tag. | |
| 1059 1071 | 
             
                end
         | 
| 1060 1072 |  | 
| 1061 1073 | 
             
                def inline_footnote node
         | 
| 1062 | 
            -
                  if (index = node.attr 'index')
         | 
| 1074 | 
            +
                  if (index = node.attr 'index', nil, false)
         | 
| 1063 1075 | 
             
                    if node.type == :xref
         | 
| 1064 1076 | 
             
                      %(<sup class="footnoteref">[<a class="footnote" href="#_footnote_#{index}" title="View footnote.">#{index}</a>]</sup>)
         | 
| 1065 1077 | 
             
                    else
         | 
| @@ -1080,23 +1092,23 @@ Your browser does not support the video tag. | |
| 1080 1092 | 
             
                    title_attr = (node.attr? 'title') ? %( title="#{node.attr 'title'}") : nil
         | 
| 1081 1093 | 
             
                    img = %(<i class="#{class_attr_val}"#{title_attr}></i>)
         | 
| 1082 1094 | 
             
                  elsif type == 'icon' && !(node.document.attr? 'icons')
         | 
| 1083 | 
            -
                    img = %([#{node. | 
| 1095 | 
            +
                    img = %([#{node.alt}])
         | 
| 1084 1096 | 
             
                  else
         | 
| 1085 1097 | 
             
                    target = node.target
         | 
| 1086 1098 | 
             
                    attrs = ['width', 'height', 'title'].map {|name| (node.attr? name) ? %( #{name}="#{node.attr name}") : nil }.join
         | 
| 1087 1099 | 
             
                    if type != 'icon' && ((node.attr? 'format', 'svg', false) || (target.include? '.svg')) &&
         | 
| 1088 1100 | 
             
                        node.document.safe < SafeMode::SECURE && ((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
         | 
| 1089 1101 | 
             
                      if svg
         | 
| 1090 | 
            -
                        img = (read_svg_contents node, target) || %(<span class="alt">#{node. | 
| 1102 | 
            +
                        img = (read_svg_contents node, target) || %(<span class="alt">#{node.alt}</span>)
         | 
| 1091 1103 | 
             
                      elsif obj
         | 
| 1092 | 
            -
                        fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri(node.attr 'fallback')}" alt="#{node. | 
| 1104 | 
            +
                        fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri(node.attr 'fallback')}" alt="#{encode_quotes node.alt}"#{attrs}#{@void_element_slash}>) : %(<span class="alt">#{node.alt}</span>)
         | 
| 1093 1105 | 
             
                        img = %(<object type="image/svg+xml" data="#{node.image_uri target}"#{attrs}>#{fallback}</object>)
         | 
| 1094 1106 | 
             
                      end
         | 
| 1095 1107 | 
             
                    end
         | 
| 1096 | 
            -
                    img ||= %(<img src="#{type == 'icon' ? (node.icon_uri target) : (node.image_uri target)}" alt="#{node. | 
| 1108 | 
            +
                    img ||= %(<img src="#{type == 'icon' ? (node.icon_uri target) : (node.image_uri target)}" alt="#{encode_quotes node.alt}"#{attrs}#{@void_element_slash}>)
         | 
| 1097 1109 | 
             
                  end
         | 
| 1098 1110 | 
             
                  if node.attr? 'link'
         | 
| 1099 | 
            -
                    window_attr = (node.attr | 
| 1111 | 
            +
                    window_attr = %( target="#{window = node.attr 'window'}"#{window == '_blank' || (node.option? 'noopener') ? ' rel="noopener"' : ''}) if node.attr? 'window'
         | 
| 1100 1112 | 
             
                    img = %(<a class="image" href="#{node.attr 'link'}"#{window_attr}>#{img}</a>)
         | 
| 1101 1113 | 
             
                  end
         | 
| 1102 1114 | 
             
                  class_attr_val = (role = node.role) ? %(#{type} #{role}) : type
         | 
| @@ -1112,30 +1124,32 @@ Your browser does not support the video tag. | |
| 1112 1124 | 
             
                  if (keys = node.attr 'keys').size == 1
         | 
| 1113 1125 | 
             
                    %(<kbd>#{keys[0]}</kbd>)
         | 
| 1114 1126 | 
             
                  else
         | 
| 1115 | 
            -
                     | 
| 1116 | 
            -
                    %(<span class="keyseq">#{key_combo}</span>)
         | 
| 1127 | 
            +
                    %(<span class="keyseq"><kbd>#{keys * '</kbd>+<kbd>'}</kbd></span>)
         | 
| 1117 1128 | 
             
                  end
         | 
| 1118 1129 | 
             
                end
         | 
| 1119 1130 |  | 
| 1120 1131 | 
             
                def inline_menu node
         | 
| 1132 | 
            +
                  caret = (node.document.attr? 'icons', 'font') ? ' <i class="fa fa-angle-right caret"></i> ' : ' <b class="caret">›</b> '
         | 
| 1133 | 
            +
                  submenu_joiner = %(</b>#{caret}<b class="submenu">)
         | 
| 1121 1134 | 
             
                  menu = node.attr 'menu'
         | 
| 1122 | 
            -
                  if  | 
| 1123 | 
            -
                     | 
| 1124 | 
            -
             | 
| 1125 | 
            -
             | 
| 1126 | 
            -
             | 
| 1135 | 
            +
                  if (submenus = node.attr 'submenus').empty?
         | 
| 1136 | 
            +
                    if (menuitem = node.attr 'menuitem', nil, false)
         | 
| 1137 | 
            +
                      %(<span class="menuseq"><b class="menu">#{menu}</b>#{caret}<b class="menuitem">#{menuitem}</b></span>)
         | 
| 1138 | 
            +
                    else
         | 
| 1139 | 
            +
                      %(<b class="menuref">#{menu}</b>)
         | 
| 1140 | 
            +
                    end
         | 
| 1127 1141 | 
             
                  else
         | 
| 1128 | 
            -
                    %(<span class="menu">#{menu}</span>)
         | 
| 1142 | 
            +
                    %(<span class="menuseq"><b class="menu">#{menu}</b>#{caret}<b class="submenu">#{submenus * submenu_joiner}</b>#{caret}<b class="menuitem">#{node.attr 'menuitem'}</b></span>)
         | 
| 1129 1143 | 
             
                  end
         | 
| 1130 1144 | 
             
                end
         | 
| 1131 1145 |  | 
| 1132 1146 | 
             
                def inline_quoted node
         | 
| 1133 1147 | 
             
                  open, close, is_tag = QUOTE_TAGS[node.type]
         | 
| 1134 | 
            -
                  if  | 
| 1148 | 
            +
                  if node.role
         | 
| 1135 1149 | 
             
                    if is_tag
         | 
| 1136 | 
            -
                      quoted_text = %(#{open.chop} class="#{role}">#{node.text}#{close})
         | 
| 1150 | 
            +
                      quoted_text = %(#{open.chop} class="#{node.role}">#{node.text}#{close})
         | 
| 1137 1151 | 
             
                    else
         | 
| 1138 | 
            -
                      quoted_text = %(<span class="#{role}">#{open}#{node.text}#{close}</span>)
         | 
| 1152 | 
            +
                      quoted_text = %(<span class="#{node.role}">#{open}#{node.text}#{close}</span>)
         | 
| 1139 1153 | 
             
                    end
         | 
| 1140 1154 | 
             
                  else
         | 
| 1141 1155 | 
             
                    quoted_text = %(#{open}#{node.text}#{close})
         | 
| @@ -1148,6 +1162,10 @@ Your browser does not support the video tag. | |
| 1148 1162 | 
             
                  xml ? %( #{name}="#{name}") : %( #{name})
         | 
| 1149 1163 | 
             
                end
         | 
| 1150 1164 |  | 
| 1165 | 
            +
                def encode_quotes val
         | 
| 1166 | 
            +
                  (val.include? '"') ? (val.gsub '"', '"') : val
         | 
| 1167 | 
            +
                end
         | 
| 1168 | 
            +
             | 
| 1151 1169 | 
             
                def read_svg_contents node, target
         | 
| 1152 1170 | 
             
                  if (svg = node.read_contents target, :start => (node.document.attr 'imagesdir'), :normalize => true, :label => 'SVG')
         | 
| 1153 1171 | 
             
                    svg = svg.sub SvgPreambleRx, '' unless svg.start_with? '<svg'
         |