asciidoctor 2.0.10 → 2.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +294 -30
- data/LICENSE +1 -1
- data/README-de.adoc +16 -20
- data/README-fr.adoc +15 -22
- data/README-jp.adoc +15 -26
- data/README-zh_CN.adoc +21 -25
- data/README.adoc +161 -138
- data/asciidoctor.gemspec +6 -13
- data/data/locale/attributes-ar.adoc +4 -3
- data/data/locale/attributes-be.adoc +23 -0
- data/data/locale/attributes-bg.adoc +4 -3
- data/data/locale/attributes-ca.adoc +6 -5
- data/data/locale/attributes-cs.adoc +4 -3
- data/data/locale/attributes-da.adoc +6 -5
- data/data/locale/attributes-de.adoc +4 -4
- data/data/locale/attributes-en.adoc +4 -4
- data/data/locale/attributes-es.adoc +6 -5
- data/data/locale/attributes-fa.adoc +4 -3
- data/data/locale/attributes-fi.adoc +4 -3
- data/data/locale/attributes-fr.adoc +8 -7
- data/data/locale/attributes-hu.adoc +4 -3
- data/data/locale/attributes-id.adoc +4 -3
- data/data/locale/attributes-it.adoc +6 -5
- data/data/locale/attributes-ja.adoc +4 -3
- data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
- data/data/locale/attributes-nb.adoc +4 -3
- data/data/locale/attributes-nl.adoc +6 -5
- data/data/locale/attributes-nn.adoc +4 -3
- data/data/locale/attributes-pl.adoc +8 -7
- data/data/locale/attributes-pt.adoc +6 -5
- data/data/locale/attributes-pt_BR.adoc +6 -5
- data/data/locale/attributes-ro.adoc +4 -3
- data/data/locale/attributes-ru.adoc +6 -5
- data/data/locale/attributes-sr.adoc +4 -4
- data/data/locale/attributes-sr_Latn.adoc +4 -4
- data/data/locale/attributes-sv.adoc +4 -4
- data/data/locale/attributes-th.adoc +23 -0
- data/data/locale/attributes-tr.adoc +4 -3
- data/data/locale/attributes-uk.adoc +6 -5
- data/data/locale/attributes-vi.adoc +23 -0
- data/data/locale/attributes-zh_CN.adoc +4 -3
- data/data/locale/attributes-zh_TW.adoc +4 -3
- data/data/reference/syntax.adoc +14 -7
- data/data/stylesheets/asciidoctor-default.css +76 -76
- data/data/stylesheets/coderay-asciidoctor.css +9 -9
- data/lib/asciidoctor/abstract_block.rb +20 -13
- data/lib/asciidoctor/abstract_node.rb +23 -12
- data/lib/asciidoctor/attribute_list.rb +64 -72
- data/lib/asciidoctor/block.rb +6 -6
- data/lib/asciidoctor/cli/invoker.rb +3 -2
- data/lib/asciidoctor/cli/options.rb +32 -31
- data/lib/asciidoctor/convert.rb +168 -162
- data/lib/asciidoctor/converter/docbook5.rb +49 -34
- data/lib/asciidoctor/converter/html5.rb +180 -139
- data/lib/asciidoctor/converter/manpage.rb +118 -90
- data/lib/asciidoctor/converter/template.rb +15 -13
- data/lib/asciidoctor/converter.rb +19 -16
- data/lib/asciidoctor/core_ext/hash/merge.rb +1 -1
- data/lib/asciidoctor/document.rb +77 -86
- data/lib/asciidoctor/extensions.rb +22 -16
- data/lib/asciidoctor/helpers.rb +20 -15
- data/lib/asciidoctor/list.rb +2 -6
- data/lib/asciidoctor/load.rb +103 -101
- data/lib/asciidoctor/logging.rb +10 -8
- data/lib/asciidoctor/parser.rb +211 -220
- data/lib/asciidoctor/path_resolver.rb +17 -15
- data/lib/asciidoctor/reader.rb +87 -79
- data/lib/asciidoctor/rx.rb +9 -7
- data/lib/asciidoctor/section.rb +7 -0
- data/lib/asciidoctor/substitutors.rb +167 -148
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +3 -2
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +13 -5
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +7 -4
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +19 -11
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +35 -20
- data/lib/asciidoctor/syntax_highlighter.rb +16 -16
- data/lib/asciidoctor/table.rb +70 -43
- data/lib/asciidoctor/timings.rb +3 -3
- data/lib/asciidoctor/version.rb +1 -1
- data/lib/asciidoctor.rb +45 -19
- data/man/asciidoctor.1 +29 -31
- data/man/asciidoctor.adoc +35 -29
- metadata +17 -70
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
3
|
# A built-in {Converter} implementation that generates HTML 5 output
|
4
|
-
# consistent with the html5 backend from AsciiDoc
|
4
|
+
# consistent with the html5 backend from AsciiDoc.py.
|
5
5
|
class Converter::Html5Converter < Converter::Base
|
6
6
|
register_for 'html5'
|
7
7
|
|
@@ -21,15 +21,15 @@ class Converter::Html5Converter < Converter::Base
|
|
21
21
|
#latexmath: INLINE_MATH_DELIMITERS[:latexmath] + [false],
|
22
22
|
}).default = ['', '']
|
23
23
|
|
24
|
-
DropAnchorRx =
|
24
|
+
DropAnchorRx = %r(<(?:a\b[^>]*|/a)>)
|
25
25
|
StemBreakRx = / *\\\n(?:\\?\n)*|\n\n+/
|
26
26
|
if RUBY_ENGINE == 'opal'
|
27
27
|
# NOTE In JavaScript, ^ matches the start of the string when the m flag is not set
|
28
|
-
SvgPreambleRx = /^#{CC_ALL}*?(?=<svg\
|
29
|
-
SvgStartTagRx = /^<svg[^>]
|
28
|
+
SvgPreambleRx = /^#{CC_ALL}*?(?=<svg[\s>])/
|
29
|
+
SvgStartTagRx = /^<svg(?:\s[^>]*)?>/
|
30
30
|
else
|
31
|
-
SvgPreambleRx = /\A.*?(?=<svg\
|
32
|
-
SvgStartTagRx = /\A<svg[^>]
|
31
|
+
SvgPreambleRx = /\A.*?(?=<svg[\s>])/m
|
32
|
+
SvgStartTagRx = /\A<svg(?:\s[^>]*)?>/
|
33
33
|
end
|
34
34
|
DimensionAttributeRx = /\s(?:width|height|style)=(["'])#{CC_ANY}*?\1/
|
35
35
|
|
@@ -48,44 +48,45 @@ class Converter::Html5Converter < Converter::Base
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def convert node, transform = node.node_name, opts = nil
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
51
|
+
case transform
|
52
|
+
when 'inline_quoted' then convert_inline_quoted node
|
53
|
+
when 'paragraph' then convert_paragraph node
|
54
|
+
when 'inline_anchor' then convert_inline_anchor node
|
55
|
+
when 'section' then convert_section node
|
56
|
+
when 'listing' then convert_listing node
|
57
|
+
when 'literal' then convert_literal node
|
58
|
+
when 'ulist' then convert_ulist node
|
59
|
+
when 'olist' then convert_olist node
|
60
|
+
when 'dlist' then convert_dlist node
|
61
|
+
when 'admonition' then convert_admonition node
|
62
|
+
when 'colist' then convert_colist node
|
63
|
+
when 'embedded' then convert_embedded node
|
64
|
+
when 'example' then convert_example node
|
65
|
+
when 'floating_title' then convert_floating_title node
|
66
|
+
when 'image' then convert_image node
|
67
|
+
when 'inline_break' then convert_inline_break node
|
68
|
+
when 'inline_button' then convert_inline_button node
|
69
|
+
when 'inline_callout' then convert_inline_callout node
|
70
|
+
when 'inline_footnote' then convert_inline_footnote node
|
71
|
+
when 'inline_image' then convert_inline_image node
|
72
|
+
when 'inline_indexterm' then convert_inline_indexterm node
|
73
|
+
when 'inline_kbd' then convert_inline_kbd node
|
74
|
+
when 'inline_menu' then convert_inline_menu node
|
75
|
+
when 'open' then convert_open node
|
76
|
+
when 'page_break' then convert_page_break node
|
77
|
+
when 'preamble' then convert_preamble node
|
78
|
+
when 'quote' then convert_quote node
|
79
|
+
when 'sidebar' then convert_sidebar node
|
80
|
+
when 'stem' then convert_stem node
|
81
|
+
when 'table' then convert_table node
|
82
|
+
when 'thematic_break' then convert_thematic_break node
|
83
|
+
when 'verse' then convert_verse node
|
84
|
+
when 'video' then convert_video node
|
85
|
+
when 'document' then convert_document node
|
86
|
+
when 'toc' then convert_toc node
|
87
|
+
when 'pass' then convert_pass node
|
88
|
+
when 'audio' then convert_audio node
|
89
|
+
else; super
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
@@ -96,6 +97,7 @@ class Converter::Html5Converter < Converter::Base
|
|
96
97
|
end
|
97
98
|
cdn_base_url = %(#{asset_uri_scheme}//cdnjs.cloudflare.com/ajax/libs)
|
98
99
|
linkcss = node.attr? 'linkcss'
|
100
|
+
max_width_attr = (node.attr? 'max-width') ? %( style="max-width: #{node.attr 'max-width'};") : ''
|
99
101
|
result = ['<!DOCTYPE html>']
|
100
102
|
lang_attribute = (node.attr? 'nolang') ? '' : %( lang="#{node.attr 'lang', 'en'}")
|
101
103
|
result << %(<html#{@xml_mode ? ' xmlns="http://www.w3.org/1999/xhtml"' : ''}#{lang_attribute}>)
|
@@ -138,7 +140,7 @@ class Converter::Html5Converter < Converter::Base
|
|
138
140
|
result << %(<link rel="stylesheet" href="#{node.normalize_web_path((node.attr 'stylesheet'), (node.attr 'stylesdir', ''))}"#{slash}>)
|
139
141
|
else
|
140
142
|
result << %(<style>
|
141
|
-
#{node.
|
143
|
+
#{node.read_contents (node.attr 'stylesheet'), start: (node.attr 'stylesdir'), warn_on_failure: true, label: 'stylesheet'}
|
142
144
|
</style>)
|
143
145
|
end
|
144
146
|
end
|
@@ -152,8 +154,8 @@ class Converter::Html5Converter < Converter::Base
|
|
152
154
|
end
|
153
155
|
end
|
154
156
|
|
155
|
-
if (syntax_hl = node.syntax_highlighter)
|
156
|
-
result << (
|
157
|
+
if (syntax_hl = node.syntax_highlighter)
|
158
|
+
result << (syntax_hl_docinfo_head_idx = result.size)
|
157
159
|
end
|
158
160
|
|
159
161
|
unless (docinfo_content = node.docinfo).empty?
|
@@ -161,29 +163,27 @@ class Converter::Html5Converter < Converter::Base
|
|
161
163
|
end
|
162
164
|
|
163
165
|
result << '</head>'
|
164
|
-
|
166
|
+
id_attr = node.id ? %( id="#{node.id}") : ''
|
165
167
|
if (sectioned = node.sections?) && (node.attr? 'toc-class') && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
|
166
168
|
classes = [node.doctype, (node.attr 'toc-class'), %(toc-#{node.attr 'toc-position', 'header'})]
|
167
169
|
else
|
168
170
|
classes = [node.doctype]
|
169
171
|
end
|
170
172
|
classes << node.role if node.role?
|
171
|
-
|
172
|
-
body_attrs << %(style="max-width: #{node.attr 'max-width'};") if node.attr? 'max-width'
|
173
|
-
result << %(<body #{body_attrs.join ' '}>)
|
173
|
+
result << %(<body#{id_attr} class="#{classes.join ' '}">)
|
174
174
|
|
175
175
|
unless (docinfo_content = node.docinfo :header).empty?
|
176
176
|
result << docinfo_content
|
177
177
|
end
|
178
178
|
|
179
179
|
unless node.noheader
|
180
|
-
result <<
|
180
|
+
result << %(<div id="header"#{max_width_attr}>)
|
181
181
|
if node.doctype == 'manpage'
|
182
182
|
result << %(<h1>#{node.doctitle} Manual Page</h1>)
|
183
183
|
if sectioned && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
|
184
184
|
result << %(<div id="toc" class="#{node.attr 'toc-class', 'toc'}">
|
185
185
|
<div id="toctitle">#{node.attr 'toc-title'}</div>
|
186
|
-
#{
|
186
|
+
#{node.converter.convert node, 'outline'}
|
187
187
|
</div>)
|
188
188
|
end
|
189
189
|
result << (generate_manname_section node) if node.attr? 'manpurpose'
|
@@ -216,19 +216,19 @@ class Converter::Html5Converter < Converter::Base
|
|
216
216
|
if sectioned && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
|
217
217
|
result << %(<div id="toc" class="#{node.attr 'toc-class', 'toc'}">
|
218
218
|
<div id="toctitle">#{node.attr 'toc-title'}</div>
|
219
|
-
#{
|
219
|
+
#{node.converter.convert node, 'outline'}
|
220
220
|
</div>)
|
221
221
|
end
|
222
222
|
end
|
223
223
|
result << '</div>'
|
224
224
|
end
|
225
225
|
|
226
|
-
result << %(<div id="content">
|
226
|
+
result << %(<div id="content"#{max_width_attr}>
|
227
227
|
#{node.content}
|
228
228
|
</div>)
|
229
229
|
|
230
230
|
if node.footnotes? && !(node.attr? 'nofootnotes')
|
231
|
-
result << %(<div id="footnotes">
|
231
|
+
result << %(<div id="footnotes"#{max_width_attr}>
|
232
232
|
<hr#{slash}>)
|
233
233
|
node.footnotes.each do |footnote|
|
234
234
|
result << %(<div class="footnote" id="_footnotedef_#{footnote.index}">
|
@@ -239,7 +239,7 @@ class Converter::Html5Converter < Converter::Base
|
|
239
239
|
end
|
240
240
|
|
241
241
|
unless node.nofooter
|
242
|
-
result <<
|
242
|
+
result << %(<div id="footer"#{max_width_attr}>)
|
243
243
|
result << '<div id="footer-text">'
|
244
244
|
result << %(#{node.attr 'version-label'} #{node.attr 'revnumber'}#{br}) if node.attr? 'revnumber'
|
245
245
|
result << %(#{node.attr 'last-update-label'} #{node.attr 'docdatetime'}) if (node.attr? 'last-update-label') && !(node.attr? 'reproducible')
|
@@ -250,8 +250,15 @@ class Converter::Html5Converter < Converter::Base
|
|
250
250
|
# JavaScript (and auxiliary stylesheets) loaded at the end of body for performance reasons
|
251
251
|
# See http://www.html5rocks.com/en/tutorials/speed/script-loading/
|
252
252
|
|
253
|
-
if syntax_hl
|
254
|
-
|
253
|
+
if syntax_hl
|
254
|
+
if syntax_hl.docinfo? :head
|
255
|
+
result[syntax_hl_docinfo_head_idx] = syntax_hl.docinfo :head, node, cdn_base_url: cdn_base_url, linkcss: linkcss, self_closing_tag_slash: slash
|
256
|
+
else
|
257
|
+
result.delete_at syntax_hl_docinfo_head_idx
|
258
|
+
end
|
259
|
+
if syntax_hl.docinfo? :footer
|
260
|
+
result << (syntax_hl.docinfo :footer, node, cdn_base_url: cdn_base_url, linkcss: linkcss, self_closing_tag_slash: slash)
|
261
|
+
end
|
255
262
|
end
|
256
263
|
|
257
264
|
if node.attr? 'stem'
|
@@ -275,7 +282,7 @@ MathJax.Hub.Config({
|
|
275
282
|
})
|
276
283
|
MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
|
277
284
|
MathJax.InputJax.AsciiMath.postfilterHooks.Add(function (data, node) {
|
278
|
-
if ((node = data.script.parentNode) && (node = node.parentNode) && node.classList.contains(
|
285
|
+
if ((node = data.script.parentNode) && (node = node.parentNode) && node.classList.contains("stemblock")) {
|
279
286
|
data.math.root.display = "block"
|
280
287
|
}
|
281
288
|
return data
|
@@ -311,7 +318,7 @@ MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
|
|
311
318
|
if node.sections? && (node.attr? 'toc') && (toc_p = node.attr 'toc-placement') != 'macro' && toc_p != 'preamble'
|
312
319
|
result << %(<div id="toc" class="toc">
|
313
320
|
<div id="toctitle">#{node.attr 'toc-title'}</div>
|
314
|
-
#{
|
321
|
+
#{node.converter.convert node, 'outline'}
|
315
322
|
</div>)
|
316
323
|
end
|
317
324
|
|
@@ -344,9 +351,10 @@ MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
|
|
344
351
|
stitle = section.captioned_title
|
345
352
|
elsif section.numbered && slevel <= sectnumlevels
|
346
353
|
if slevel < 2 && node.document.doctype == 'book'
|
347
|
-
|
354
|
+
case section.sectname
|
355
|
+
when 'chapter'
|
348
356
|
stitle = %(#{(signifier = node.document.attributes['chapter-signifier']) ? "#{signifier} " : ''}#{section.sectnum} #{section.title})
|
349
|
-
|
357
|
+
when 'part'
|
350
358
|
stitle = %(#{(signifier = node.document.attributes['part-signifier']) ? "#{signifier} " : ''}#{section.sectnum nil, ':'} #{section.title})
|
351
359
|
else
|
352
360
|
stitle = %(#{section.sectnum} #{section.title})
|
@@ -377,9 +385,10 @@ MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
|
|
377
385
|
title = node.captioned_title
|
378
386
|
elsif node.numbered && level <= (doc_attrs['sectnumlevels'] || 3).to_i
|
379
387
|
if level < 2 && node.document.doctype == 'book'
|
380
|
-
|
388
|
+
case node.sectname
|
389
|
+
when 'chapter'
|
381
390
|
title = %(#{(signifier = doc_attrs['chapter-signifier']) ? "#{signifier} " : ''}#{node.sectnum} #{node.title})
|
382
|
-
|
391
|
+
when 'part'
|
383
392
|
title = %(#{(signifier = doc_attrs['part-signifier']) ? "#{signifier} " : ''}#{node.sectnum nil, ':'} #{node.title})
|
384
393
|
else
|
385
394
|
title = %(#{node.sectnum} #{node.title})
|
@@ -507,16 +516,16 @@ Your browser does not support the audio tag.
|
|
507
516
|
result = []
|
508
517
|
id_attribute = node.id ? %( id="#{node.id}") : ''
|
509
518
|
|
510
|
-
|
519
|
+
case node.style
|
511
520
|
when 'qanda'
|
512
|
-
['qlist', 'qanda', node.role]
|
521
|
+
classes = ['qlist', 'qanda', node.role]
|
513
522
|
when 'horizontal'
|
514
|
-
['hdlist', node.role]
|
523
|
+
classes = ['hdlist', node.role]
|
515
524
|
else
|
516
|
-
['dlist', node.style, node.role]
|
517
|
-
end
|
525
|
+
classes = ['dlist', node.style, node.role]
|
526
|
+
end
|
518
527
|
|
519
|
-
class_attribute = %( class="#{classes.join ' '}")
|
528
|
+
class_attribute = %( class="#{classes.compact.join ' '}")
|
520
529
|
|
521
530
|
result << %(<div#{id_attribute}#{class_attribute}>)
|
522
531
|
result << %(<div class="title">#{node.title}</div>) if node.title?
|
@@ -572,12 +581,11 @@ Your browser does not support the audio tag.
|
|
572
581
|
terms.each do |dt|
|
573
582
|
result << %(<dt#{dt_style_attribute}>#{dt.text}</dt>)
|
574
583
|
end
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
end
|
584
|
+
next unless dd
|
585
|
+
result << '<dd>'
|
586
|
+
result << %(<p>#{dd.text}</p>) if dd.text?
|
587
|
+
result << dd.content if dd.blocks?
|
588
|
+
result << '</dd>'
|
581
589
|
end
|
582
590
|
result << '</dl>'
|
583
591
|
end
|
@@ -618,19 +626,19 @@ Your browser does not support the audio tag.
|
|
618
626
|
target = node.attr 'target'
|
619
627
|
width_attr = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : ''
|
620
628
|
height_attr = (node.attr? 'height') ? %( height="#{node.attr 'height'}") : ''
|
621
|
-
if ((node.attr? 'format', 'svg') || (target.include? '.svg')) && node.document.safe < SafeMode::SECURE
|
622
|
-
|
623
|
-
if svg
|
629
|
+
if ((node.attr? 'format', 'svg') || (target.include? '.svg')) && node.document.safe < SafeMode::SECURE
|
630
|
+
if node.option? 'inline'
|
624
631
|
img = (read_svg_contents node, target) || %(<span class="alt">#{node.alt}</span>)
|
625
|
-
elsif
|
626
|
-
fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri
|
632
|
+
elsif node.option? 'interactive'
|
633
|
+
fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri node.attr 'fallback'}" alt="#{encode_attribute_value node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>) : %(<span class="alt">#{node.alt}</span>)
|
627
634
|
img = %(<object type="image/svg+xml" data="#{node.image_uri target}"#{width_attr}#{height_attr}>#{fallback}</object>)
|
635
|
+
else
|
636
|
+
img = %(<img src="#{node.image_uri target}" alt="#{encode_attribute_value node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>)
|
628
637
|
end
|
638
|
+
else
|
639
|
+
img = %(<img src="#{node.image_uri target}" alt="#{encode_attribute_value node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>)
|
629
640
|
end
|
630
|
-
img
|
631
|
-
if node.attr? 'link'
|
632
|
-
img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>)
|
633
|
-
end
|
641
|
+
img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>) if node.attr? 'link'
|
634
642
|
id_attr = node.id ? %( id="#{node.id}") : ''
|
635
643
|
classes = ['imageblock']
|
636
644
|
classes << (node.attr 'float') if node.attr? 'float'
|
@@ -689,8 +697,8 @@ Your browser does not support the audio tag.
|
|
689
697
|
open, close = BLOCK_MATH_DELIMITERS[style = node.style.to_sym]
|
690
698
|
if (equation = node.content)
|
691
699
|
if style == :asciimath && (equation.include? LF)
|
692
|
-
br = %(<br#{@void_element_slash}
|
693
|
-
equation = equation.gsub(StemBreakRx) { %(#{close}#{br * ($&.count LF)}#{open}) }
|
700
|
+
br = %(#{LF}<br#{@void_element_slash}>)
|
701
|
+
equation = equation.gsub(StemBreakRx) { %(#{close}#{br * (($&.count LF) - 1)}#{LF}#{open}) }
|
694
702
|
end
|
695
703
|
unless (equation.start_with? open) && (equation.end_with? close)
|
696
704
|
equation = %(#{open}#{equation}#{close})
|
@@ -755,8 +763,8 @@ Your browser does not support the audio tag.
|
|
755
763
|
logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
756
764
|
''
|
757
765
|
else
|
758
|
-
|
759
|
-
|
766
|
+
id_attr = node.id ? %( id="#{node.id}") : ''
|
767
|
+
title_el = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
|
760
768
|
%(<div#{id_attr} class="openblock#{style && style != 'open' ? " #{style}" : ''}#{(role = node.role) ? " #{role}" : ''}">
|
761
769
|
#{title_el}<div class="content">
|
762
770
|
#{node.content}
|
@@ -796,7 +804,7 @@ Your browser does not support the audio tag.
|
|
796
804
|
toc = %(
|
797
805
|
<div id="toc" class="#{doc.attr 'toc-class', 'toc'}">
|
798
806
|
<div id="toctitle">#{doc.attr 'toc-title'}</div>
|
799
|
-
#{
|
807
|
+
#{doc.converter.convert doc, 'outline'}
|
800
808
|
</div>)
|
801
809
|
else
|
802
810
|
toc = ''
|
@@ -848,24 +856,24 @@ Your browser does not support the audio tag.
|
|
848
856
|
def convert_table node
|
849
857
|
result = []
|
850
858
|
id_attribute = node.id ? %( id="#{node.id}") : ''
|
851
|
-
|
859
|
+
frame = 'ends' if (frame = node.attr 'frame', 'all', 'table-frame') == 'topbot'
|
860
|
+
classes = ['tableblock', %(frame-#{frame}), %(grid-#{node.attr 'grid', 'all', 'table-grid'})]
|
852
861
|
if (stripes = node.attr 'stripes', nil, 'table-stripes')
|
853
862
|
classes << %(stripes-#{stripes})
|
854
863
|
end
|
855
|
-
|
864
|
+
style_attribute = ''
|
856
865
|
if (autowidth = node.option? 'autowidth') && !(node.attr? 'width')
|
857
866
|
classes << 'fit-content'
|
858
867
|
elsif (tablewidth = node.attr 'tablepcwidth') == 100
|
859
868
|
classes << 'stretch'
|
860
869
|
else
|
861
|
-
|
870
|
+
style_attribute = %( style="width: #{tablewidth}%;")
|
862
871
|
end
|
863
872
|
classes << (node.attr 'float') if node.attr? 'float'
|
864
873
|
if (role = node.role)
|
865
874
|
classes << role
|
866
875
|
end
|
867
876
|
class_attribute = %( class="#{classes.join ' '}")
|
868
|
-
style_attribute = styles.empty? ? '' : %( style="#{styles.join ' '}")
|
869
877
|
|
870
878
|
result << %(<table#{id_attribute}#{class_attribute}#{style_attribute}>)
|
871
879
|
result << %(<caption class="title">#{node.captioned_title}</caption>) if node.title?
|
@@ -934,7 +942,7 @@ Your browser does not support the audio tag.
|
|
934
942
|
|
935
943
|
%(<div#{id_attr} class="#{role}">
|
936
944
|
<div#{title_id_attr} class="title">#{title}</div>
|
937
|
-
#{
|
945
|
+
#{doc.converter.convert doc, 'outline', toclevels: levels}
|
938
946
|
</div>)
|
939
947
|
end
|
940
948
|
|
@@ -1028,12 +1036,14 @@ Your browser does not support the audio tag.
|
|
1028
1036
|
end
|
1029
1037
|
start_anchor = (node.attr? 'start') ? %(#at=#{node.attr 'start'}) : ''
|
1030
1038
|
delimiter = ['?']
|
1039
|
+
target, hash = (node.attr 'target').split '/', 2
|
1040
|
+
hash_param = (hash ||= node.attr 'hash') ? %(#{delimiter.pop || '&'}h=#{hash}) : ''
|
1031
1041
|
autoplay_param = (node.option? 'autoplay') ? %(#{delimiter.pop || '&'}autoplay=1) : ''
|
1032
1042
|
loop_param = (node.option? 'loop') ? %(#{delimiter.pop || '&'}loop=1) : ''
|
1033
1043
|
muted_param = (node.option? 'muted') ? %(#{delimiter.pop || '&'}muted=1) : ''
|
1034
1044
|
%(<div#{id_attribute}#{class_attribute}>#{title_element}
|
1035
1045
|
<div class="content">
|
1036
|
-
<iframe#{width_attribute}#{height_attribute} src="#{asset_uri_scheme}//player.vimeo.com/video/#{
|
1046
|
+
<iframe#{width_attribute}#{height_attribute} src="#{asset_uri_scheme}//player.vimeo.com/video/#{target}#{hash_param}#{autoplay_param}#{loop_param}#{muted_param}#{start_anchor}" frameborder="0"#{(node.option? 'nofullscreen') ? '' : (append_boolean_attribute 'allowfullscreen', xml)}></iframe>
|
1037
1047
|
</div>
|
1038
1048
|
</div>)
|
1039
1049
|
when 'youtube'
|
@@ -1069,7 +1079,7 @@ Your browser does not support the audio tag.
|
|
1069
1079
|
target, playlist = target.split ',', 2
|
1070
1080
|
if (playlist ||= (node.attr 'playlist'))
|
1071
1081
|
# INFO playlist bar doesn't appear in Firefox unless showinfo=1 and modestbranding=1
|
1072
|
-
list_param = %(&playlist=#{playlist})
|
1082
|
+
list_param = %(&playlist=#{target},#{playlist})
|
1073
1083
|
else
|
1074
1084
|
# NOTE for loop to work, playlist must be specified; use VIDEO_ID if there's no explicit playlist
|
1075
1085
|
list_param = has_loop_param ? %(&playlist=#{target}) : ''
|
@@ -1089,7 +1099,7 @@ Your browser does not support the audio tag.
|
|
1089
1099
|
time_anchor = (start_t || end_t) ? %(#t=#{start_t || ''}#{end_t ? ",#{end_t}" : ''}) : ''
|
1090
1100
|
%(<div#{id_attribute}#{class_attribute}>#{title_element}
|
1091
1101
|
<div class="content">
|
1092
|
-
<video src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{width_attribute}#{height_attribute}#{poster_attribute}#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : ''}#{(node.option? 'nocontrols') ? '' : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : ''}#{preload_attribute}>
|
1102
|
+
<video src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{width_attribute}#{height_attribute}#{poster_attribute}#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : ''}#{(node.option? 'muted') ? (append_boolean_attribute 'muted', xml) : ''}#{(node.option? 'nocontrols') ? '' : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : ''}#{preload_attribute}>
|
1093
1103
|
Your browser does not support the video tag.
|
1094
1104
|
</video>
|
1095
1105
|
</div>
|
@@ -1106,9 +1116,17 @@ Your browser does not support the video tag.
|
|
1106
1116
|
else
|
1107
1117
|
attrs = node.role ? %( class="#{node.role}") : ''
|
1108
1118
|
unless (text = node.text)
|
1109
|
-
refid = node.attributes['refid']
|
1110
|
-
|
1111
|
-
|
1119
|
+
if AbstractNode === (ref = (@refs ||= node.document.catalog[:refs])[refid = node.attributes['refid']] || (refid.nil_or_empty? ? (top = get_root_document node) : nil))
|
1120
|
+
if (@resolving_xref ||= (outer = true)) && outer
|
1121
|
+
if (text = ref.xreftext node.attr 'xrefstyle', nil, true)
|
1122
|
+
text = text.gsub DropAnchorRx, '' if text.include? '<a'
|
1123
|
+
else
|
1124
|
+
text = top ? '[^top]' : %([#{refid}])
|
1125
|
+
end
|
1126
|
+
@resolving_xref = nil
|
1127
|
+
else
|
1128
|
+
text = top ? '[^top]' : %([#{refid}])
|
1129
|
+
end
|
1112
1130
|
else
|
1113
1131
|
text = %([#{refid}])
|
1114
1132
|
end
|
@@ -1144,8 +1162,10 @@ Your browser does not support the video tag.
|
|
1144
1162
|
elsif node.document.attr? 'icons'
|
1145
1163
|
src = node.icon_uri("callouts/#{node.text}")
|
1146
1164
|
%(<img src="#{src}" alt="#{node.text}"#{@void_element_slash}>)
|
1165
|
+
elsif ::Array === (guard = node.attributes['guard'])
|
1166
|
+
%(<!--<b class="conum">(#{node.text})</b>-->)
|
1147
1167
|
else
|
1148
|
-
%(#{
|
1168
|
+
%(#{guard}<b class="conum">(#{node.text})</b>)
|
1149
1169
|
end
|
1150
1170
|
end
|
1151
1171
|
|
@@ -1163,42 +1183,49 @@ Your browser does not support the video tag.
|
|
1163
1183
|
end
|
1164
1184
|
|
1165
1185
|
def convert_inline_image node
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1186
|
+
target = node.target
|
1187
|
+
if (type = node.type || 'image') == 'icon'
|
1188
|
+
if (icons = node.document.attr 'icons') == 'font'
|
1189
|
+
i_class_attr_val = %(fa fa-#{target})
|
1190
|
+
i_class_attr_val = %(#{i_class_attr_val} fa-#{node.attr 'size'}) if node.attr? 'size'
|
1191
|
+
if node.attr? 'flip'
|
1192
|
+
i_class_attr_val = %(#{i_class_attr_val} fa-flip-#{node.attr 'flip'})
|
1193
|
+
elsif node.attr? 'rotate'
|
1194
|
+
i_class_attr_val = %(#{i_class_attr_val} fa-rotate-#{node.attr 'rotate'})
|
1195
|
+
end
|
1196
|
+
attrs = (node.attr? 'title') ? %( title="#{node.attr 'title'}") : ''
|
1197
|
+
img = %(<i class="#{i_class_attr_val}"#{attrs}></i>)
|
1198
|
+
elsif icons
|
1199
|
+
attrs = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : ''
|
1200
|
+
attrs = %(#{attrs} height="#{node.attr 'height'}") if node.attr? 'height'
|
1201
|
+
attrs = %(#{attrs} title="#{node.attr 'title'}") if node.attr? 'title'
|
1202
|
+
img = %(<img src="#{node.icon_uri target}" alt="#{encode_attribute_value node.alt}"#{attrs}#{@void_element_slash}>)
|
1203
|
+
else
|
1204
|
+
img = %([#{node.alt}])
|
1170
1205
|
end
|
1171
|
-
title_attr = (node.attr? 'title') ? %( title="#{node.attr 'title'}") : ''
|
1172
|
-
img = %(<i class="#{class_attr_val}"#{title_attr}></i>)
|
1173
|
-
elsif type == 'icon' && !(node.document.attr? 'icons')
|
1174
|
-
img = %([#{node.alt}])
|
1175
1206
|
else
|
1176
|
-
|
1177
|
-
attrs =
|
1178
|
-
|
1179
|
-
|
1180
|
-
if
|
1207
|
+
attrs = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : ''
|
1208
|
+
attrs = %(#{attrs} height="#{node.attr 'height'}") if node.attr? 'height'
|
1209
|
+
attrs = %(#{attrs} title="#{node.attr 'title'}") if node.attr? 'title'
|
1210
|
+
if ((node.attr? 'format', 'svg') || (target.include? '.svg')) && node.document.safe < SafeMode::SECURE
|
1211
|
+
if node.option? 'inline'
|
1181
1212
|
img = (read_svg_contents node, target) || %(<span class="alt">#{node.alt}</span>)
|
1182
|
-
elsif
|
1183
|
-
fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri
|
1213
|
+
elsif node.option? 'interactive'
|
1214
|
+
fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri node.attr 'fallback'}" alt="#{encode_attribute_value node.alt}"#{attrs}#{@void_element_slash}>) : %(<span class="alt">#{node.alt}</span>)
|
1184
1215
|
img = %(<object type="image/svg+xml" data="#{node.image_uri target}"#{attrs}>#{fallback}</object>)
|
1216
|
+
else
|
1217
|
+
img = %(<img src="#{node.image_uri target}" alt="#{encode_attribute_value node.alt}"#{attrs}#{@void_element_slash}>)
|
1185
1218
|
end
|
1219
|
+
else
|
1220
|
+
img = %(<img src="#{node.image_uri target}" alt="#{encode_attribute_value node.alt}"#{attrs}#{@void_element_slash}>)
|
1186
1221
|
end
|
1187
|
-
img ||= %(<img src="#{type == 'icon' ? (node.icon_uri target) : (node.image_uri target)}" alt="#{encode_attribute_value node.alt}"#{attrs}#{@void_element_slash}>)
|
1188
|
-
end
|
1189
|
-
if node.attr? 'link'
|
1190
|
-
img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>)
|
1191
1222
|
end
|
1223
|
+
img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>) if node.attr? 'link'
|
1224
|
+
class_attr_val = type
|
1192
1225
|
if (role = node.role)
|
1193
|
-
|
1194
|
-
class_attr_val = %(#{type} #{node.attr 'float'} #{role})
|
1195
|
-
else
|
1196
|
-
class_attr_val = %(#{type} #{role})
|
1197
|
-
end
|
1226
|
+
class_attr_val = (node.attr? 'float') ? %(#{class_attr_val} #{node.attr 'float'} #{role}) : %(#{class_attr_val} #{role})
|
1198
1227
|
elsif node.attr? 'float'
|
1199
|
-
class_attr_val = %(#{
|
1200
|
-
else
|
1201
|
-
class_attr_val = type
|
1228
|
+
class_attr_val = %(#{class_attr_val} #{node.attr 'float'})
|
1202
1229
|
end
|
1203
1230
|
%(<span class="#{class_attr_val}">#{img}</span>)
|
1204
1231
|
end
|
@@ -1252,16 +1279,19 @@ Your browser does not support the video tag.
|
|
1252
1279
|
|
1253
1280
|
# NOTE expose read_svg_contents for Bespoke converter
|
1254
1281
|
def read_svg_contents node, target
|
1255
|
-
if (svg = node.read_contents target, start: (node.document.attr 'imagesdir'), normalize: true, label: 'SVG')
|
1282
|
+
if (svg = node.read_contents target, start: (node.document.attr 'imagesdir'), normalize: true, label: 'SVG', warn_if_empty: true)
|
1283
|
+
return if svg.empty?
|
1256
1284
|
svg = svg.sub SvgPreambleRx, '' unless svg.start_with? '<svg'
|
1257
|
-
old_start_tag = new_start_tag = nil
|
1285
|
+
old_start_tag = new_start_tag = start_tag_match = nil
|
1258
1286
|
# NOTE width, height and style attributes are removed if either width or height is specified
|
1259
1287
|
['width', 'height'].each do |dim|
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
new_start_tag =
|
1288
|
+
next unless node.attr? dim
|
1289
|
+
unless new_start_tag
|
1290
|
+
next if (start_tag_match ||= (svg.match SvgStartTagRx) || :no_match) == :no_match
|
1291
|
+
new_start_tag = (old_start_tag = start_tag_match[0]).gsub DimensionAttributeRx, ''
|
1264
1292
|
end
|
1293
|
+
# NOTE a unitless value in HTML is assumed to be px, so we can pass the value straight through
|
1294
|
+
new_start_tag = %(#{new_start_tag.chop} #{dim}="#{node.attr dim}">)
|
1265
1295
|
end
|
1266
1296
|
svg = %(#{new_start_tag}#{svg[old_start_tag.length..-1]}) if new_start_tag
|
1267
1297
|
end
|
@@ -1297,13 +1327,24 @@ Your browser does not support the video tag.
|
|
1297
1327
|
manname_id_attr = (manname_id = node.attr 'manname-id') ? %( id="#{manname_id}") : ''
|
1298
1328
|
%(<h2#{manname_id_attr}>#{manname_title}</h2>
|
1299
1329
|
<div class="sectionbody">
|
1300
|
-
<p>#{node.attr '
|
1330
|
+
<p>#{(node.attr 'mannames').join ', '} - #{node.attr 'manpurpose'}</p>
|
1301
1331
|
</div>)
|
1302
1332
|
end
|
1303
1333
|
|
1334
|
+
def get_root_document node
|
1335
|
+
while (node = node.document).nested?
|
1336
|
+
node = node.parent_document
|
1337
|
+
end
|
1338
|
+
node
|
1339
|
+
end
|
1340
|
+
|
1304
1341
|
# NOTE adapt to older converters that relied on unprefixed method names
|
1305
|
-
def method_missing id, *
|
1306
|
-
!((name = id.to_s).start_with? 'convert_') && (handles? name) ? (send %(convert_#{name}), *
|
1342
|
+
def method_missing id, *args
|
1343
|
+
!((name = id.to_s).start_with? 'convert_') && (handles? name) ? (send %(convert_#{name}), *args) : super
|
1344
|
+
end
|
1345
|
+
|
1346
|
+
def respond_to_missing? id, *options
|
1347
|
+
!((name = id.to_s).start_with? 'convert_') && (handles? name)
|
1307
1348
|
end
|
1308
1349
|
end
|
1309
1350
|
end
|