asciidoctor 2.0.10 → 2.0.11
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.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +89 -5
- data/LICENSE +1 -1
- data/README-de.adoc +4 -4
- data/README-fr.adoc +4 -4
- data/README-jp.adoc +4 -4
- data/README-zh_CN.adoc +6 -6
- data/README.adoc +14 -10
- data/asciidoctor.gemspec +3 -3
- data/data/locale/attributes-ar.adoc +4 -3
- 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 +6 -5
- data/data/locale/attributes-hu.adoc +4 -3
- data/data/locale/attributes-id.adoc +4 -3
- data/data/locale/attributes-it.adoc +4 -3
- 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 +4 -3
- 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-tr.adoc +4 -3
- data/data/locale/attributes-uk.adoc +6 -5
- data/data/locale/attributes-zh_CN.adoc +4 -3
- data/data/locale/attributes-zh_TW.adoc +4 -3
- data/data/stylesheets/asciidoctor-default.css +22 -20
- data/lib/asciidoctor.rb +33 -7
- data/lib/asciidoctor/abstract_block.rb +9 -4
- data/lib/asciidoctor/abstract_node.rb +16 -6
- data/lib/asciidoctor/attribute_list.rb +59 -67
- data/lib/asciidoctor/cli/invoker.rb +2 -0
- data/lib/asciidoctor/cli/options.rb +3 -3
- data/lib/asciidoctor/convert.rb +167 -162
- data/lib/asciidoctor/converter.rb +13 -12
- data/lib/asciidoctor/converter/docbook5.rb +3 -7
- data/lib/asciidoctor/converter/html5.rb +59 -42
- data/lib/asciidoctor/converter/manpage.rb +12 -11
- data/lib/asciidoctor/converter/template.rb +3 -0
- data/lib/asciidoctor/document.rb +23 -38
- data/lib/asciidoctor/extensions.rb +2 -2
- data/lib/asciidoctor/helpers.rb +17 -9
- data/lib/asciidoctor/load.rb +101 -101
- data/lib/asciidoctor/parser.rb +26 -23
- data/lib/asciidoctor/path_resolver.rb +14 -12
- data/lib/asciidoctor/reader.rb +14 -7
- data/lib/asciidoctor/rx.rb +5 -4
- data/lib/asciidoctor/substitutors.rb +57 -38
- data/lib/asciidoctor/syntax_highlighter.rb +8 -5
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +1 -1
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +12 -4
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +7 -4
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +2 -3
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +15 -7
- data/lib/asciidoctor/table.rb +49 -20
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +6 -6
- data/man/asciidoctor.adoc +3 -3
- metadata +8 -8
@@ -85,23 +85,24 @@ module Converter
|
|
85
85
|
# Public: Derive backend traits (basebackend, filetype, outfilesuffix, htmlsyntax) from the given backend.
|
86
86
|
#
|
87
87
|
# backend - the String backend from which to derive the traits
|
88
|
+
# basebackend - the String basebackend to use in favor of deriving one from the backend (optional, default: nil)
|
88
89
|
#
|
89
90
|
# Returns the backend traits for the given backend as a [Hash].
|
90
|
-
def self.derive_backend_traits backend
|
91
|
+
def self.derive_backend_traits backend, basebackend = nil
|
91
92
|
return {} unless backend
|
92
|
-
if (
|
93
|
-
|
93
|
+
if (outfilesuffix = DEFAULT_EXTENSIONS[(basebackend ||= backend.sub TrailingDigitsRx, '')])
|
94
|
+
filetype = outfilesuffix.slice 1, outfilesuffix.length
|
94
95
|
else
|
95
|
-
|
96
|
+
outfilesuffix = %(.#{filetype = basebackend})
|
96
97
|
end
|
97
|
-
|
98
|
-
{ basebackend:
|
99
|
-
{ basebackend:
|
98
|
+
filetype == 'html' ?
|
99
|
+
{ basebackend: basebackend, filetype: filetype, htmlsyntax: 'html', outfilesuffix: outfilesuffix } :
|
100
|
+
{ basebackend: basebackend, filetype: filetype, outfilesuffix: outfilesuffix }
|
100
101
|
end
|
101
102
|
|
102
103
|
module BackendTraits
|
103
104
|
def basebackend value = nil
|
104
|
-
value ? (backend_traits[:basebackend] = value) : backend_traits[:basebackend]
|
105
|
+
value ? ((backend_traits value)[:basebackend] = value) : backend_traits[:basebackend]
|
105
106
|
end
|
106
107
|
|
107
108
|
def filetype value = nil
|
@@ -128,15 +129,15 @@ module Converter
|
|
128
129
|
@backend_traits = value || {}
|
129
130
|
end
|
130
131
|
|
131
|
-
def backend_traits
|
132
|
-
@backend_traits ||= Converter.derive_backend_traits @backend
|
132
|
+
def backend_traits basebackend = nil
|
133
|
+
@backend_traits ||= Converter.derive_backend_traits @backend, basebackend
|
133
134
|
end
|
134
135
|
|
135
136
|
alias backend_info backend_traits
|
136
137
|
|
137
138
|
# Deprecated: Use {Converter.derive_backend_traits} instead.
|
138
|
-
def self.derive_backend_traits backend
|
139
|
-
Converter.derive_backend_traits backend
|
139
|
+
def self.derive_backend_traits backend, basebackend = nil
|
140
|
+
Converter.derive_backend_traits backend, basebackend
|
140
141
|
end
|
141
142
|
end
|
142
143
|
|
@@ -371,9 +371,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
371
371
|
has_body = false
|
372
372
|
result = []
|
373
373
|
pgwide_attribute = (node.option? 'pgwide') ? ' pgwide="1"' : ''
|
374
|
-
if (frame = node.attr 'frame', 'all', 'table-frame') == 'ends'
|
375
|
-
frame = 'topbot'
|
376
|
-
end
|
374
|
+
frame = 'topbot' if (frame = node.attr 'frame', 'all', 'table-frame') == 'ends'
|
377
375
|
grid = node.attr 'grid', nil, 'table-grid'
|
378
376
|
result << %(<#{tag_name = node.title? ? 'table' : 'informaltable'}#{common_attributes node.id, node.role, node.reftext}#{pgwide_attribute} frame="#{frame}" rowsep="#{['none', 'cols'].include?(grid) ? 0 : 1}" colsep="#{['none', 'rows'].include?(grid) ? 0 : 1}"#{(node.attr? 'orientation', 'landscape', 'table-orientation') ? ' orient="land"' : ''}>)
|
379
377
|
if (node.option? 'unbreakable')
|
@@ -401,12 +399,10 @@ class Converter::DocBook5Converter < Converter::Base
|
|
401
399
|
rows.each do |row|
|
402
400
|
result << '<row>'
|
403
401
|
row.each do |cell|
|
404
|
-
halign_attribute = (cell.attr? 'halign') ? %( align="#{cell.attr 'halign'}") : ''
|
405
|
-
valign_attribute = (cell.attr? 'valign') ? %( valign="#{cell.attr 'valign'}") : ''
|
406
402
|
colspan_attribute = cell.colspan ? %( namest="col_#{colnum = cell.column.attr 'colnumber'}" nameend="col_#{colnum + cell.colspan - 1}") : ''
|
407
403
|
rowspan_attribute = cell.rowspan ? %( morerows="#{cell.rowspan - 1}") : ''
|
408
404
|
# NOTE <entry> may not have whitespace (e.g., line breaks) as a direct descendant according to DocBook rules
|
409
|
-
entry_start = %(<entry#{
|
405
|
+
entry_start = %(<entry align="#{cell.attr 'halign'}" valign="#{cell.attr 'valign'}"#{colspan_attribute}#{rowspan_attribute}>)
|
410
406
|
if tsec == :head
|
411
407
|
cell_content = cell.text
|
412
408
|
else
|
@@ -487,7 +483,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
487
483
|
when :link
|
488
484
|
%(<link xl:href="#{node.target}">#{node.text}</link>)
|
489
485
|
when :bibref
|
490
|
-
%(<anchor#{common_attributes node.id, nil, "[#{node.reftext || node.id}]"}/>#{text})
|
486
|
+
%(<anchor#{common_attributes node.id, nil, (text = "[#{node.reftext || node.id}]")}/>#{text})
|
491
487
|
else
|
492
488
|
logger.warn %(unknown anchor type: #{node.type.inspect})
|
493
489
|
nil
|
@@ -21,15 +21,15 @@ class Converter::Html5Converter < Converter::Base
|
|
21
21
|
#latexmath: INLINE_MATH_DELIMITERS[:latexmath] + [false],
|
22
22
|
}).default = ['', '']
|
23
23
|
|
24
|
-
DropAnchorRx = /<(?:a[
|
24
|
+
DropAnchorRx = /<(?: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
|
|
@@ -96,6 +96,7 @@ class Converter::Html5Converter < Converter::Base
|
|
96
96
|
end
|
97
97
|
cdn_base_url = %(#{asset_uri_scheme}//cdnjs.cloudflare.com/ajax/libs)
|
98
98
|
linkcss = node.attr? 'linkcss'
|
99
|
+
max_width_attr = (node.attr? 'max-width') ? %( style="max-width: #{node.attr 'max-width'};") : ''
|
99
100
|
result = ['<!DOCTYPE html>']
|
100
101
|
lang_attribute = (node.attr? 'nolang') ? '' : %( lang="#{node.attr 'lang', 'en'}")
|
101
102
|
result << %(<html#{@xml_mode ? ' xmlns="http://www.w3.org/1999/xhtml"' : ''}#{lang_attribute}>)
|
@@ -138,7 +139,7 @@ class Converter::Html5Converter < Converter::Base
|
|
138
139
|
result << %(<link rel="stylesheet" href="#{node.normalize_web_path((node.attr 'stylesheet'), (node.attr 'stylesdir', ''))}"#{slash}>)
|
139
140
|
else
|
140
141
|
result << %(<style>
|
141
|
-
#{node.
|
142
|
+
#{node.read_contents (node.attr 'stylesheet'), start: (node.attr 'stylesdir'), warn_on_failure: true, label: 'stylesheet'}
|
142
143
|
</style>)
|
143
144
|
end
|
144
145
|
end
|
@@ -152,8 +153,8 @@ class Converter::Html5Converter < Converter::Base
|
|
152
153
|
end
|
153
154
|
end
|
154
155
|
|
155
|
-
if (syntax_hl = node.syntax_highlighter)
|
156
|
-
result << (
|
156
|
+
if (syntax_hl = node.syntax_highlighter)
|
157
|
+
result << (syntax_hl_docinfo_head_idx = result.size)
|
157
158
|
end
|
158
159
|
|
159
160
|
unless (docinfo_content = node.docinfo).empty?
|
@@ -161,29 +162,27 @@ class Converter::Html5Converter < Converter::Base
|
|
161
162
|
end
|
162
163
|
|
163
164
|
result << '</head>'
|
164
|
-
|
165
|
+
id_attr = node.id ? %( id="#{node.id}") : ''
|
165
166
|
if (sectioned = node.sections?) && (node.attr? 'toc-class') && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
|
166
167
|
classes = [node.doctype, (node.attr 'toc-class'), %(toc-#{node.attr 'toc-position', 'header'})]
|
167
168
|
else
|
168
169
|
classes = [node.doctype]
|
169
170
|
end
|
170
171
|
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 ' '}>)
|
172
|
+
result << %(<body#{id_attr} class="#{classes.join ' '}">)
|
174
173
|
|
175
174
|
unless (docinfo_content = node.docinfo :header).empty?
|
176
175
|
result << docinfo_content
|
177
176
|
end
|
178
177
|
|
179
178
|
unless node.noheader
|
180
|
-
result <<
|
179
|
+
result << %(<div id="header"#{max_width_attr}>)
|
181
180
|
if node.doctype == 'manpage'
|
182
181
|
result << %(<h1>#{node.doctitle} Manual Page</h1>)
|
183
182
|
if sectioned && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
|
184
183
|
result << %(<div id="toc" class="#{node.attr 'toc-class', 'toc'}">
|
185
184
|
<div id="toctitle">#{node.attr 'toc-title'}</div>
|
186
|
-
#{
|
185
|
+
#{node.converter.convert node, 'outline'}
|
187
186
|
</div>)
|
188
187
|
end
|
189
188
|
result << (generate_manname_section node) if node.attr? 'manpurpose'
|
@@ -216,19 +215,19 @@ class Converter::Html5Converter < Converter::Base
|
|
216
215
|
if sectioned && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
|
217
216
|
result << %(<div id="toc" class="#{node.attr 'toc-class', 'toc'}">
|
218
217
|
<div id="toctitle">#{node.attr 'toc-title'}</div>
|
219
|
-
#{
|
218
|
+
#{node.converter.convert node, 'outline'}
|
220
219
|
</div>)
|
221
220
|
end
|
222
221
|
end
|
223
222
|
result << '</div>'
|
224
223
|
end
|
225
224
|
|
226
|
-
result << %(<div id="content">
|
225
|
+
result << %(<div id="content"#{max_width_attr}>
|
227
226
|
#{node.content}
|
228
227
|
</div>)
|
229
228
|
|
230
229
|
if node.footnotes? && !(node.attr? 'nofootnotes')
|
231
|
-
result << %(<div id="footnotes">
|
230
|
+
result << %(<div id="footnotes"#{max_width_attr}>
|
232
231
|
<hr#{slash}>)
|
233
232
|
node.footnotes.each do |footnote|
|
234
233
|
result << %(<div class="footnote" id="_footnotedef_#{footnote.index}">
|
@@ -239,7 +238,7 @@ class Converter::Html5Converter < Converter::Base
|
|
239
238
|
end
|
240
239
|
|
241
240
|
unless node.nofooter
|
242
|
-
result <<
|
241
|
+
result << %(<div id="footer"#{max_width_attr}>)
|
243
242
|
result << '<div id="footer-text">'
|
244
243
|
result << %(#{node.attr 'version-label'} #{node.attr 'revnumber'}#{br}) if node.attr? 'revnumber'
|
245
244
|
result << %(#{node.attr 'last-update-label'} #{node.attr 'docdatetime'}) if (node.attr? 'last-update-label') && !(node.attr? 'reproducible')
|
@@ -250,8 +249,15 @@ class Converter::Html5Converter < Converter::Base
|
|
250
249
|
# JavaScript (and auxiliary stylesheets) loaded at the end of body for performance reasons
|
251
250
|
# See http://www.html5rocks.com/en/tutorials/speed/script-loading/
|
252
251
|
|
253
|
-
if syntax_hl
|
254
|
-
|
252
|
+
if syntax_hl
|
253
|
+
if syntax_hl.docinfo? :head
|
254
|
+
result[syntax_hl_docinfo_head_idx] = syntax_hl.docinfo :head, node, cdn_base_url: cdn_base_url, linkcss: linkcss, self_closing_tag_slash: slash
|
255
|
+
else
|
256
|
+
result.delete_at syntax_hl_docinfo_head_idx
|
257
|
+
end
|
258
|
+
if syntax_hl.docinfo? :footer
|
259
|
+
result << (syntax_hl.docinfo :footer, node, cdn_base_url: cdn_base_url, linkcss: linkcss, self_closing_tag_slash: slash)
|
260
|
+
end
|
255
261
|
end
|
256
262
|
|
257
263
|
if node.attr? 'stem'
|
@@ -275,7 +281,7 @@ MathJax.Hub.Config({
|
|
275
281
|
})
|
276
282
|
MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
|
277
283
|
MathJax.InputJax.AsciiMath.postfilterHooks.Add(function (data, node) {
|
278
|
-
if ((node = data.script.parentNode) && (node = node.parentNode) && node.classList.contains(
|
284
|
+
if ((node = data.script.parentNode) && (node = node.parentNode) && node.classList.contains("stemblock")) {
|
279
285
|
data.math.root.display = "block"
|
280
286
|
}
|
281
287
|
return data
|
@@ -311,7 +317,7 @@ MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
|
|
311
317
|
if node.sections? && (node.attr? 'toc') && (toc_p = node.attr 'toc-placement') != 'macro' && toc_p != 'preamble'
|
312
318
|
result << %(<div id="toc" class="toc">
|
313
319
|
<div id="toctitle">#{node.attr 'toc-title'}</div>
|
314
|
-
#{
|
320
|
+
#{node.converter.convert node, 'outline'}
|
315
321
|
</div>)
|
316
322
|
end
|
317
323
|
|
@@ -628,9 +634,7 @@ Your browser does not support the audio tag.
|
|
628
634
|
end
|
629
635
|
end
|
630
636
|
img ||= %(<img src="#{node.image_uri target}" alt="#{encode_attribute_value node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>)
|
631
|
-
if node.attr? 'link'
|
632
|
-
img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>)
|
633
|
-
end
|
637
|
+
img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>) if node.attr? 'link'
|
634
638
|
id_attr = node.id ? %( id="#{node.id}") : ''
|
635
639
|
classes = ['imageblock']
|
636
640
|
classes << (node.attr 'float') if node.attr? 'float'
|
@@ -689,8 +693,8 @@ Your browser does not support the audio tag.
|
|
689
693
|
open, close = BLOCK_MATH_DELIMITERS[style = node.style.to_sym]
|
690
694
|
if (equation = node.content)
|
691
695
|
if style == :asciimath && (equation.include? LF)
|
692
|
-
br = %(<br#{@void_element_slash}
|
693
|
-
equation = equation.gsub(StemBreakRx) { %(#{close}#{br * ($&.count LF)}#{open}) }
|
696
|
+
br = %(#{LF}<br#{@void_element_slash}>)
|
697
|
+
equation = equation.gsub(StemBreakRx) { %(#{close}#{br * (($&.count LF) - 1)}#{LF}#{open}) }
|
694
698
|
end
|
695
699
|
unless (equation.start_with? open) && (equation.end_with? close)
|
696
700
|
equation = %(#{open}#{equation}#{close})
|
@@ -796,7 +800,7 @@ Your browser does not support the audio tag.
|
|
796
800
|
toc = %(
|
797
801
|
<div id="toc" class="#{doc.attr 'toc-class', 'toc'}">
|
798
802
|
<div id="toctitle">#{doc.attr 'toc-title'}</div>
|
799
|
-
#{
|
803
|
+
#{doc.converter.convert doc, 'outline'}
|
800
804
|
</div>)
|
801
805
|
else
|
802
806
|
toc = ''
|
@@ -848,7 +852,8 @@ Your browser does not support the audio tag.
|
|
848
852
|
def convert_table node
|
849
853
|
result = []
|
850
854
|
id_attribute = node.id ? %( id="#{node.id}") : ''
|
851
|
-
|
855
|
+
frame = 'ends' if (frame = node.attr 'frame', 'all', 'table-frame') == 'topbot'
|
856
|
+
classes = ['tableblock', %(frame-#{frame}), %(grid-#{node.attr 'grid', 'all', 'table-grid'})]
|
852
857
|
if (stripes = node.attr 'stripes', nil, 'table-stripes')
|
853
858
|
classes << %(stripes-#{stripes})
|
854
859
|
end
|
@@ -934,7 +939,7 @@ Your browser does not support the audio tag.
|
|
934
939
|
|
935
940
|
%(<div#{id_attr} class="#{role}">
|
936
941
|
<div#{title_id_attr} class="title">#{title}</div>
|
937
|
-
#{
|
942
|
+
#{doc.converter.convert doc, 'outline', toclevels: levels}
|
938
943
|
</div>)
|
939
944
|
end
|
940
945
|
|
@@ -1089,7 +1094,7 @@ Your browser does not support the audio tag.
|
|
1089
1094
|
time_anchor = (start_t || end_t) ? %(#t=#{start_t || ''}#{end_t ? ",#{end_t}" : ''}) : ''
|
1090
1095
|
%(<div#{id_attribute}#{class_attribute}>#{title_element}
|
1091
1096
|
<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}>
|
1097
|
+
<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
1098
|
Your browser does not support the video tag.
|
1094
1099
|
</video>
|
1095
1100
|
</div>
|
@@ -1107,8 +1112,13 @@ Your browser does not support the video tag.
|
|
1107
1112
|
attrs = node.role ? %( class="#{node.role}") : ''
|
1108
1113
|
unless (text = node.text)
|
1109
1114
|
refid = node.attributes['refid']
|
1110
|
-
if AbstractNode === (ref = (@refs ||= node.document.catalog[:refs])[refid])
|
1111
|
-
text =
|
1115
|
+
if AbstractNode === (ref = (@refs ||= node.document.catalog[:refs])[refid]) && (@resolving_xref ||= (outer = true)) && outer
|
1116
|
+
if !(text = ref.xreftext node.attr 'xrefstyle', nil, true)
|
1117
|
+
text = %([#{refid}])
|
1118
|
+
elsif text.include? '<a'
|
1119
|
+
text = text.gsub DropAnchorRx, ''
|
1120
|
+
end
|
1121
|
+
@resolving_xref = nil
|
1112
1122
|
else
|
1113
1123
|
text = %([#{refid}])
|
1114
1124
|
end
|
@@ -1144,8 +1154,10 @@ Your browser does not support the video tag.
|
|
1144
1154
|
elsif node.document.attr? 'icons'
|
1145
1155
|
src = node.icon_uri("callouts/#{node.text}")
|
1146
1156
|
%(<img src="#{src}" alt="#{node.text}"#{@void_element_slash}>)
|
1157
|
+
elsif ::Array === (guard = node.attributes['guard'])
|
1158
|
+
%(<!--<b class="conum">(#{node.text})</b>-->)
|
1147
1159
|
else
|
1148
|
-
%(#{
|
1160
|
+
%(#{guard}<b class="conum">(#{node.text})</b>)
|
1149
1161
|
end
|
1150
1162
|
end
|
1151
1163
|
|
@@ -1186,9 +1198,7 @@ Your browser does not support the video tag.
|
|
1186
1198
|
end
|
1187
1199
|
img ||= %(<img src="#{type == 'icon' ? (node.icon_uri target) : (node.image_uri target)}" alt="#{encode_attribute_value node.alt}"#{attrs}#{@void_element_slash}>)
|
1188
1200
|
end
|
1189
|
-
if node.attr? 'link'
|
1190
|
-
img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>)
|
1191
|
-
end
|
1201
|
+
img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>) if node.attr? 'link'
|
1192
1202
|
if (role = node.role)
|
1193
1203
|
if node.attr? 'float'
|
1194
1204
|
class_attr_val = %(#{type} #{node.attr 'float'} #{role})
|
@@ -1252,15 +1262,22 @@ Your browser does not support the video tag.
|
|
1252
1262
|
|
1253
1263
|
# NOTE expose read_svg_contents for Bespoke converter
|
1254
1264
|
def read_svg_contents node, target
|
1255
|
-
if (svg = node.read_contents target, start: (node.document.attr 'imagesdir'), normalize: true, label: 'SVG')
|
1265
|
+
if (svg = node.read_contents target, start: (node.document.attr 'imagesdir'), normalize: true, label: 'SVG', warn_if_empty: true)
|
1266
|
+
return if svg.empty?
|
1256
1267
|
svg = svg.sub SvgPreambleRx, '' unless svg.start_with? '<svg'
|
1257
|
-
old_start_tag = new_start_tag = nil
|
1268
|
+
old_start_tag = new_start_tag = start_tag_match = nil
|
1258
1269
|
# NOTE width, height and style attributes are removed if either width or height is specified
|
1259
1270
|
['width', 'height'].each do |dim|
|
1260
1271
|
if node.attr? dim
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1272
|
+
unless new_start_tag
|
1273
|
+
next if (start_tag_match ||= (svg.match SvgStartTagRx) || :no_match) == :no_match
|
1274
|
+
new_start_tag = (old_start_tag = start_tag_match[0]).gsub DimensionAttributeRx, ''
|
1275
|
+
end
|
1276
|
+
unless (dim_val = node.attr dim).end_with? '%'
|
1277
|
+
# QUESTION should we add px since it's already the default?
|
1278
|
+
dim_val += 'px'
|
1279
|
+
end
|
1280
|
+
new_start_tag = %(#{new_start_tag.chop} #{dim}="#{dim_val}">)
|
1264
1281
|
end
|
1265
1282
|
end
|
1266
1283
|
svg = %(#{new_start_tag}#{svg[old_start_tag.length..-1]}) if new_start_tag
|
@@ -15,7 +15,7 @@ class Converter::ManPageConverter < Converter::Base
|
|
15
15
|
ESC_BS = %(#{ESC}\\) # escaped backslash (indicates troff formatting sequence)
|
16
16
|
ESC_FS = %(#{ESC}.) # escaped full stop (indicates troff macro)
|
17
17
|
|
18
|
-
LiteralBackslashRx =
|
18
|
+
LiteralBackslashRx = /\A\\|(#{ESC})?\\/
|
19
19
|
LeadingPeriodRx = /^\./
|
20
20
|
EscapedMacroRx = /^(?:#{ESC}\\c\n)?#{ESC}\.((?:URL|MTO) "#{CC_ANY}*?" "#{CC_ANY}*?" )( |[^\s]*)(#{CC_ANY}*?)(?: *#{ESC}\\c)?$/
|
21
21
|
MockBoundaryRx = /<\/?BOUNDARY>/
|
@@ -247,7 +247,9 @@ r lw(\n(.lu*75u/100u).'
|
|
247
247
|
result << %(.sp
|
248
248
|
.if n .RS 4
|
249
249
|
.nf
|
250
|
+
.fam C
|
250
251
|
#{manify node.content, whitespace: :preserve}
|
252
|
+
.fam
|
251
253
|
.fi
|
252
254
|
.if n .RE)
|
253
255
|
result.join LF
|
@@ -261,7 +263,9 @@ r lw(\n(.lu*75u/100u).'
|
|
261
263
|
result << %(.sp
|
262
264
|
.if n .RS 4
|
263
265
|
.nf
|
266
|
+
.fam C
|
264
267
|
#{manify node.content, whitespace: :preserve}
|
268
|
+
.fam
|
265
269
|
.fi
|
266
270
|
.if n .RE)
|
267
271
|
result.join LF
|
@@ -284,15 +288,16 @@ r lw(\n(.lu*75u/100u).'
|
|
284
288
|
.B #{manify node.title}
|
285
289
|
.br) if node.title?
|
286
290
|
|
291
|
+
start = (node.attr 'start', 1).to_i
|
287
292
|
node.items.each_with_index do |item, idx|
|
288
293
|
result << %(.sp
|
289
294
|
.RS 4
|
290
295
|
.ie n \\{\\
|
291
|
-
\\h'-04' #{idx +
|
296
|
+
\\h'-04' #{numeral = idx + start}.\\h'+01'\\c
|
292
297
|
.\\}
|
293
298
|
.el \\{\\
|
294
299
|
. sp -1
|
295
|
-
. IP " #{
|
300
|
+
. IP " #{numeral}." 4.2
|
296
301
|
.\\}
|
297
302
|
#{manify item.text, whitespace: :normalize})
|
298
303
|
result << item.content if item.blocks?
|
@@ -580,11 +585,7 @@ allbox tab(:);'
|
|
580
585
|
when :xref
|
581
586
|
unless (text = node.text)
|
582
587
|
refid = node.attributes['refid']
|
583
|
-
|
584
|
-
text = (ref.xreftext node.attr('xrefstyle', nil, true)) || %([#{refid}])
|
585
|
-
else
|
586
|
-
text = %([#{refid}])
|
587
|
-
end
|
588
|
+
text = %([#{refid}]) unless AbstractNode === (ref = (@refs ||= node.document.catalog[:refs])[refid]) && (@resolving_xref ||= outer = true) && outer && (text = ref.xreftext node.attr 'xrefstyle', nil, true)
|
588
589
|
end
|
589
590
|
text
|
590
591
|
when :ref, :bibref
|
@@ -699,7 +700,8 @@ allbox tab(:);'
|
|
699
700
|
str = str.tr_s WHITESPACE, ' '
|
700
701
|
end
|
701
702
|
str = str.
|
702
|
-
gsub(LiteralBackslashRx
|
703
|
+
gsub(LiteralBackslashRx) { $1 ? $& : '\\(rs' }. # literal backslash (not a troff escape sequence)
|
704
|
+
gsub(EllipsisCharRefRx, '...'). # horizontal ellipsis
|
703
705
|
gsub(LeadingPeriodRx, '\\\&.'). # leading . is used in troff for macro call or other formatting; replace with \&.
|
704
706
|
# drop orphaned \c escape lines, unescape troff macro, quote adjacent character, isolate macro line
|
705
707
|
gsub(EscapedMacroRx) { (rest = $3.lstrip).empty? ? %(.#$1"#$2") : %(.#$1"#$2"#{LF}#{rest}) }.
|
@@ -717,13 +719,12 @@ allbox tab(:);'
|
|
717
719
|
gsub('’', '\(cq'). # right single quotation mark
|
718
720
|
gsub('“', '\(lq'). # left double quotation mark
|
719
721
|
gsub('”', '\(rq'). # right double quotation mark
|
720
|
-
gsub(EllipsisCharRefRx, '...'). # horizontal ellipsis
|
721
722
|
gsub('←', '\(<-'). # leftwards arrow
|
722
723
|
gsub('→', '\(->'). # rightwards arrow
|
723
724
|
gsub('⇐', '\(lA'). # leftwards double arrow
|
724
725
|
gsub('⇒', '\(rA'). # rightwards double arrow
|
725
726
|
gsub('​', '\:'). # zero width space
|
726
|
-
gsub('&','&').
|
727
|
+
gsub('&', '&'). # literal ampersand (NOTE must take place after any other replacement that includes &)
|
727
728
|
gsub('\'', '\(aq'). # apostrophe-quote
|
728
729
|
gsub(MockBoundaryRx, ''). # mock boundary
|
729
730
|
gsub(ESC_BS, '\\'). # unescape troff backslash (NOTE update if more escapes are added)
|
@@ -257,6 +257,9 @@ class Converter::TemplateConverter < Converter::Base
|
|
257
257
|
if !name || name == 'erb'
|
258
258
|
require 'erb' unless defined? ::ERB.version
|
259
259
|
[::Tilt::ERBTemplate, {}]
|
260
|
+
elsif name == 'erubi'
|
261
|
+
Helpers.require_library 'erubi' unless defined? ::Erubis::Engine
|
262
|
+
[::Tilt::ErubiTemplate, {}]
|
260
263
|
elsif name == 'erubis'
|
261
264
|
Helpers.require_library 'erubis' unless defined? ::Erubis::FastEruby
|
262
265
|
[::Tilt::ErubisTemplate, { engine_class: ::Erubis::FastEruby }]
|
data/lib/asciidoctor/document.rb
CHANGED
@@ -326,7 +326,7 @@ class Document < AbstractBlock
|
|
326
326
|
@sourcemap = options[:sourcemap]
|
327
327
|
@timings = options.delete :timings
|
328
328
|
@path_resolver = PathResolver.new
|
329
|
-
initialize_extensions = (defined? ::Asciidoctor::Extensions) ?
|
329
|
+
initialize_extensions = (defined? ::Asciidoctor::Extensions) || (options.key? :extensions) ? ::Asciidoctor::Extensions : nil
|
330
330
|
@extensions = nil # initialize furthur down if initialize_extensions is true
|
331
331
|
options[:standalone] = options[:header_footer] if (options.key? :header_footer) && !(options.key? :standalone)
|
332
332
|
end
|
@@ -339,51 +339,36 @@ class Document < AbstractBlock
|
|
339
339
|
(@options = options).freeze
|
340
340
|
|
341
341
|
attrs = @attributes
|
342
|
-
|
343
|
-
attrs['
|
344
|
-
attrs
|
342
|
+
attrs['attribute-undefined'] = Compliance.attribute_undefined
|
343
|
+
attrs['attribute-missing'] = Compliance.attribute_missing
|
344
|
+
attrs.update DEFAULT_ATTRIBUTES
|
345
|
+
# TODO if lang attribute is set, @safe mode < SafeMode::SERVER, and !parent_doc,
|
346
|
+
# load attributes from data/locale/attributes-<lang>.adoc
|
347
|
+
|
345
348
|
if standalone
|
346
|
-
attrs['copycss'] = ''
|
347
349
|
# sync embedded attribute with :standalone option value
|
348
350
|
attr_overrides['embedded'] = nil
|
351
|
+
attrs['copycss'] = ''
|
352
|
+
attrs['iconfont-remote'] = ''
|
353
|
+
attrs['stylesheet'] = ''
|
354
|
+
attrs['webfonts'] = ''
|
349
355
|
else
|
350
|
-
attrs['notitle'] = ''
|
351
356
|
# sync embedded attribute with :standalone option value
|
352
357
|
attr_overrides['embedded'] = ''
|
358
|
+
if (attr_overrides.key? 'showtitle') && (attr_overrides.keys & %w(notitle showtitle))[-1] == 'showtitle'
|
359
|
+
attr_overrides['notitle'] = { nil => '', false => '@', '@' => false}[attr_overrides['showtitle']]
|
360
|
+
elsif attr_overrides.key? 'notitle'
|
361
|
+
attr_overrides['showtitle'] = { nil => '', false => '@', '@' => false}[attr_overrides['notitle']]
|
362
|
+
else
|
363
|
+
attrs['notitle'] = ''
|
364
|
+
end
|
353
365
|
end
|
354
|
-
attrs['stylesheet'] = ''
|
355
|
-
attrs['webfonts'] = ''
|
356
|
-
attrs['prewrap'] = ''
|
357
|
-
attrs['attribute-undefined'] = Compliance.attribute_undefined
|
358
|
-
attrs['attribute-missing'] = Compliance.attribute_missing
|
359
|
-
attrs['iconfont-remote'] = ''
|
360
|
-
|
361
|
-
# language strings
|
362
|
-
# TODO load these based on language settings
|
363
|
-
attrs['caution-caption'] = 'Caution'
|
364
|
-
attrs['important-caption'] = 'Important'
|
365
|
-
attrs['note-caption'] = 'Note'
|
366
|
-
attrs['tip-caption'] = 'Tip'
|
367
|
-
attrs['warning-caption'] = 'Warning'
|
368
|
-
attrs['example-caption'] = 'Example'
|
369
|
-
attrs['figure-caption'] = 'Figure'
|
370
|
-
#attrs['listing-caption'] = 'Listing'
|
371
|
-
attrs['table-caption'] = 'Table'
|
372
|
-
attrs['toc-title'] = 'Table of Contents'
|
373
|
-
#attrs['preface-title'] = 'Preface'
|
374
|
-
attrs['section-refsig'] = 'Section'
|
375
|
-
attrs['part-refsig'] = 'Part'
|
376
|
-
attrs['chapter-refsig'] = 'Chapter'
|
377
|
-
attrs['appendix-caption'] = attrs['appendix-refsig'] = 'Appendix'
|
378
|
-
attrs['untitled-label'] = 'Untitled'
|
379
|
-
attrs['version-label'] = 'Version'
|
380
|
-
attrs['last-update-label'] = 'Last updated'
|
381
366
|
|
382
367
|
attr_overrides['asciidoctor'] = ''
|
383
368
|
attr_overrides['asciidoctor-version'] = ::Asciidoctor::VERSION
|
384
369
|
|
385
370
|
attr_overrides['safe-mode-name'] = (safe_mode_name = SafeMode.name_for_value @safe)
|
386
|
-
attr_overrides[
|
371
|
+
attr_overrides[%(safe-mode-#{safe_mode_name})] = ''
|
387
372
|
attr_overrides['safe-mode-level'] = @safe
|
388
373
|
|
389
374
|
# the only way to set the max-include-depth attribute is via the API; default to 64 like AsciiDoc Python
|
@@ -505,10 +490,10 @@ class Document < AbstractBlock
|
|
505
490
|
::AsciidoctorJ::Extensions::ExtensionRegistry === ext_registry)
|
506
491
|
@extensions = ext_registry.activate self
|
507
492
|
end
|
508
|
-
elsif
|
493
|
+
elsif (ext_block = options[:extensions]).nil?
|
494
|
+
@extensions = Extensions::Registry.new.activate self unless Extensions.groups.empty?
|
495
|
+
elsif ::Proc === ext_block
|
509
496
|
@extensions = Extensions.create(&ext_block).activate self
|
510
|
-
elsif !Extensions.groups.empty?
|
511
|
-
@extensions = Extensions::Registry.new.activate self
|
512
497
|
end
|
513
498
|
end
|
514
499
|
|
@@ -772,7 +757,7 @@ class Document < AbstractBlock
|
|
772
757
|
end
|
773
758
|
|
774
759
|
def notitle
|
775
|
-
|
760
|
+
@attributes.key? 'notitle'
|
776
761
|
end
|
777
762
|
|
778
763
|
def noheader
|