asciidoctor 1.5.6.2 → 1.5.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +330 -143
- data/README-fr.adoc +441 -0
- data/README-jp.adoc +418 -0
- data/README-zh_CN.adoc +430 -0
- data/README.adoc +454 -0
- data/Rakefile +57 -0
- data/asciidoctor.gemspec +7 -1
- data/data/locale/attributes-ar.adoc +22 -0
- data/data/locale/attributes-bg.adoc +22 -0
- data/data/locale/attributes-ca.adoc +22 -0
- data/data/locale/attributes-cs.adoc +22 -0
- data/data/locale/attributes-da.adoc +22 -0
- data/data/locale/attributes-de.adoc +22 -0
- data/data/locale/attributes-en.adoc +23 -0
- data/data/locale/attributes-es.adoc +22 -0
- data/data/locale/attributes-fa.adoc +22 -0
- data/data/locale/attributes-fi.adoc +22 -0
- data/data/locale/attributes-fr.adoc +22 -0
- data/data/locale/attributes-hu.adoc +22 -0
- data/data/locale/attributes-id.adoc +22 -0
- data/data/locale/attributes-it.adoc +22 -0
- data/data/locale/attributes-ja.adoc +22 -0
- data/data/locale/attributes-kr.adoc +22 -0
- data/data/locale/attributes-nb.adoc +22 -0
- data/data/locale/attributes-nl.adoc +22 -0
- data/data/locale/attributes-nn.adoc +22 -0
- data/data/locale/attributes-pl.adoc +22 -0
- data/data/locale/attributes-pt.adoc +22 -0
- data/data/locale/attributes-pt_BR.adoc +22 -0
- data/data/locale/attributes-ro.adoc +22 -0
- data/data/locale/attributes-ru.adoc +22 -0
- data/data/locale/attributes-sr.adoc +22 -0
- data/data/locale/attributes-sr_Latn.adoc +22 -0
- data/data/locale/attributes-tr.adoc +22 -0
- data/data/locale/attributes-uk.adoc +22 -0
- data/data/locale/attributes-zh_CN.adoc +22 -0
- data/data/locale/attributes-zh_TW.adoc +22 -0
- data/data/locale/attributes.adoc +8 -649
- data/data/stylesheets/asciidoctor-default.css +77 -72
- data/features/xref.feature +366 -7
- data/lib/asciidoctor.rb +107 -93
- data/lib/asciidoctor/abstract_block.rb +247 -239
- data/lib/asciidoctor/abstract_node.rb +56 -58
- data/lib/asciidoctor/block.rb +3 -3
- data/lib/asciidoctor/callouts.rb +1 -1
- data/lib/asciidoctor/cli/invoker.rb +36 -9
- data/lib/asciidoctor/cli/options.rb +63 -25
- data/lib/asciidoctor/converter.rb +23 -13
- data/lib/asciidoctor/converter/base.rb +4 -0
- data/lib/asciidoctor/converter/docbook45.rb +16 -9
- data/lib/asciidoctor/converter/docbook5.rb +115 -97
- data/lib/asciidoctor/converter/factory.rb +29 -31
- data/lib/asciidoctor/converter/html5.rb +229 -192
- data/lib/asciidoctor/converter/manpage.rb +72 -50
- data/lib/asciidoctor/converter/template.rb +12 -12
- data/lib/asciidoctor/core_ext.rb +5 -1
- data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +6 -0
- data/lib/asciidoctor/document.rb +168 -77
- data/lib/asciidoctor/extensions.rb +79 -47
- data/lib/asciidoctor/helpers.rb +33 -11
- data/lib/asciidoctor/inline.rb +3 -2
- data/lib/asciidoctor/list.rb +2 -1
- data/lib/asciidoctor/logging.rb +122 -0
- data/lib/asciidoctor/parser.rb +406 -382
- data/lib/asciidoctor/path_resolver.rb +169 -162
- data/lib/asciidoctor/reader.rb +166 -121
- data/lib/asciidoctor/section.rb +45 -28
- data/lib/asciidoctor/stylesheets.rb +13 -5
- data/lib/asciidoctor/substitutors.rb +328 -254
- data/lib/asciidoctor/table.rb +105 -48
- data/lib/asciidoctor/timings.rb +34 -6
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +41 -23
- data/man/asciidoctor.adoc +14 -8
- data/test/api_test.rb +1004 -0
- data/test/attributes_test.rb +241 -50
- data/test/blocks_test.rb +549 -124
- data/test/converter_test.rb +170 -78
- data/test/document_test.rb +208 -767
- data/test/extensions_test.rb +188 -53
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +1 -1
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +1 -1
- data/test/fixtures/file-with-missing-include.adoc +1 -0
- data/test/fixtures/include-file.jsx +8 -0
- data/test/fixtures/lists.adoc +96 -0
- data/test/fixtures/other-chapters.adoc +11 -0
- data/test/fixtures/outer-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +5 -1
- data/test/fixtures/subdir/index.adoc +3 -0
- data/test/fixtures/subdir/inner-include.adoc +3 -0
- data/test/fixtures/subdir/middle-include.adoc +5 -0
- data/test/fixtures/tagged-class-enclosed.rb +0 -1
- data/test/fixtures/unclosed-tag.adoc +3 -0
- data/test/fixtures/unexpected-end-tag.adoc +4 -0
- data/test/invoker_test.rb +101 -40
- data/test/links_test.rb +266 -72
- data/test/lists_test.rb +243 -45
- data/test/logger_test.rb +211 -0
- data/test/manpage_test.rb +124 -6
- data/test/options_test.rb +46 -1
- data/test/paragraphs_test.rb +23 -10
- data/test/parser_test.rb +30 -1
- data/test/paths_test.rb +115 -33
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +337 -81
- data/test/sections_test.rb +656 -72
- data/test/substitutions_test.rb +182 -57
- data/test/tables_test.rb +324 -57
- data/test/test_helper.rb +77 -32
- data/test/text_test.rb +7 -7
- metadata +67 -3
@@ -37,7 +37,7 @@ module Asciidoctor
|
|
37
37
|
# the registry of converters is initialized using a normal Hash.
|
38
38
|
#
|
39
39
|
# initialize_singleton - A Boolean to indicate whether the singleton should
|
40
|
-
# be
|
40
|
+
# be initialized if it has not already been created.
|
41
41
|
# If false, and a singleton has not been previously
|
42
42
|
# initialized, a fresh instance is returned.
|
43
43
|
#
|
@@ -46,10 +46,12 @@ module Asciidoctor
|
|
46
46
|
return @__default__ || new unless initialize_singleton
|
47
47
|
# FIXME this assignment is not thread_safe, may need to use a ::Threadsafe helper here
|
48
48
|
@__default__ ||= begin
|
49
|
+
# NOTE .to_s hides require from Opal
|
49
50
|
require 'thread_safe'.to_s unless defined? ::ThreadSafe
|
50
51
|
new ::ThreadSafe::Cache.new
|
51
52
|
rescue ::LoadError
|
52
|
-
|
53
|
+
include Logging unless include? Logging
|
54
|
+
logger.warn 'gem \'thread_safe\' is not installed. This gem is recommended when registering custom converters.'
|
53
55
|
new
|
54
56
|
end
|
55
57
|
end
|
@@ -183,41 +185,37 @@ module Asciidoctor
|
|
183
185
|
# Returns the [Converter] object
|
184
186
|
def create backend, opts = {}
|
185
187
|
if (converter = resolve backend)
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
require 'asciidoctor/converter/html5'.to_s
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
188
|
+
base_converter = ::Class === converter ? (converter.new backend, opts) : converter
|
189
|
+
return base_converter unless Converter::BackendInfo === base_converter && base_converter.supports_templates?
|
190
|
+
else
|
191
|
+
case backend
|
192
|
+
when 'html5'
|
193
|
+
# NOTE .to_s hides require from Opal
|
194
|
+
require 'asciidoctor/converter/html5'.to_s unless defined? ::Asciidoctor::Converter::Html5Converter
|
195
|
+
base_converter = Html5Converter.new backend, opts
|
196
|
+
when 'docbook5'
|
197
|
+
# NOTE .to_s hides require from Opal
|
198
|
+
require 'asciidoctor/converter/docbook5'.to_s unless defined? ::Asciidoctor::Converter::DocBook5Converter
|
199
|
+
base_converter = DocBook5Converter.new backend, opts
|
200
|
+
when 'docbook45'
|
201
|
+
# NOTE .to_s hides require from Opal
|
202
|
+
require 'asciidoctor/converter/docbook45'.to_s unless defined? ::Asciidoctor::Converter::DocBook45Converter
|
203
|
+
base_converter = DocBook45Converter.new backend, opts
|
204
|
+
when 'manpage'
|
205
|
+
# NOTE .to_s hides require from Opal
|
206
|
+
require 'asciidoctor/converter/manpage'.to_s unless defined? ::Asciidoctor::Converter::ManPageConverter
|
207
|
+
base_converter = ManPageConverter.new backend, opts
|
203
208
|
end
|
204
|
-
DocBook45Converter.new backend, opts
|
205
|
-
when 'manpage'
|
206
|
-
unless defined? ::Asciidoctor::Converter::ManPageConverter
|
207
|
-
require 'asciidoctor/converter/manpage'.to_s
|
208
|
-
end
|
209
|
-
ManPageConverter.new backend, opts
|
210
209
|
end
|
211
210
|
|
212
211
|
return base_converter unless opts.key? :template_dirs
|
213
212
|
|
214
|
-
|
215
|
-
|
216
|
-
end
|
217
|
-
unless defined? ::Asciidoctor::Converter::CompositeConverter
|
218
|
-
require 'asciidoctor/converter/composite'.to_s
|
219
|
-
end
|
213
|
+
# NOTE .to_s hides require from Opal
|
214
|
+
require 'asciidoctor/converter/template'.to_s unless defined? ::Asciidoctor::Converter::TemplateConverter
|
220
215
|
template_converter = TemplateConverter.new backend, opts[:template_dirs], opts
|
216
|
+
|
217
|
+
# NOTE .to_s hides require from Opal
|
218
|
+
require 'asciidoctor/converter/composite'.to_s unless defined? ::Asciidoctor::Converter::CompositeConverter
|
221
219
|
# QUESTION should we omit the composite converter if built_in_converter is nil?
|
222
220
|
CompositeConverter.new backend, template_converter, base_converter
|
223
221
|
end
|
@@ -19,6 +19,8 @@ module Asciidoctor
|
|
19
19
|
#:latexmath => INLINE_MATH_DELIMITERS[:latexmath] + [false]
|
20
20
|
}).default = ['', '', false]
|
21
21
|
|
22
|
+
DropAnchorRx = /<(?:a[^>+]+|\/a)>/
|
23
|
+
StemBreakRx = / *\\\n(?:\\?\n)*|\n\n+/
|
22
24
|
SvgPreambleRx = /\A.*?(?=<svg\b)/m
|
23
25
|
SvgStartTagRx = /\A<svg[^>]*>/
|
24
26
|
DimensionAttributeRx = /\s(?:width|height|style)=(["']).*?\1/
|
@@ -36,10 +38,10 @@ module Asciidoctor
|
|
36
38
|
asset_uri_scheme = %(#{asset_uri_scheme}:)
|
37
39
|
end
|
38
40
|
cdn_base = %(#{asset_uri_scheme}//cdnjs.cloudflare.com/ajax/libs)
|
39
|
-
linkcss = node.
|
41
|
+
linkcss = node.attr? 'linkcss'
|
40
42
|
result = ['<!DOCTYPE html>']
|
41
|
-
lang_attribute = (node.attr? 'nolang') ?
|
42
|
-
result << %(<html#{@xml_mode ? ' xmlns="http://www.w3.org/1999/xhtml"' :
|
43
|
+
lang_attribute = (node.attr? 'nolang') ? '' : %( lang="#{node.attr 'lang', 'en'}")
|
44
|
+
result << %(<html#{@xml_mode ? ' xmlns="http://www.w3.org/1999/xhtml"' : ''}#{lang_attribute}>)
|
43
45
|
result << %(<head>
|
44
46
|
<meta charset="#{node.attr 'encoding', 'UTF-8'}"#{slash}>
|
45
47
|
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"#{slash}><![endif]-->
|
@@ -56,7 +58,7 @@ module Asciidoctor
|
|
56
58
|
else
|
57
59
|
icon_type = (icon_ext = ::File.extname icon_href) == '.ico' ? 'image/x-icon' : %(image/#{icon_ext[1..-1]})
|
58
60
|
end
|
59
|
-
result << %(<link rel="
|
61
|
+
result << %(<link rel="icon" type="#{icon_type}" href="#{icon_href}"#{slash}>)
|
60
62
|
end
|
61
63
|
result << %(<title>#{node.doctitle :sanitize => true, :use_fallback => true}</title>)
|
62
64
|
|
@@ -81,7 +83,7 @@ module Asciidoctor
|
|
81
83
|
|
82
84
|
if node.attr? 'icons', 'font'
|
83
85
|
if node.attr? 'iconfont-remote'
|
84
|
-
result << %(<link rel="stylesheet" href="#{node.attr 'iconfont-cdn', %[#{cdn_base}/font-awesome/
|
86
|
+
result << %(<link rel="stylesheet" href="#{node.attr 'iconfont-cdn', %[#{cdn_base}/font-awesome/#{FONT_AWESOME_VERSION}/css/font-awesome.min.css]}"#{slash}>)
|
85
87
|
else
|
86
88
|
iconfont_stylesheet = %(#{node.attr 'iconfont-name', 'font-awesome'}.css)
|
87
89
|
result << %(<link rel="stylesheet" href="#{node.normalize_web_path iconfont_stylesheet, (node.attr 'stylesdir', ''), false}"#{slash}>)
|
@@ -113,13 +115,14 @@ module Asciidoctor
|
|
113
115
|
end
|
114
116
|
|
115
117
|
result << '</head>'
|
116
|
-
body_attrs = []
|
117
|
-
body_attrs << %(id="#{node.id}") if node.id
|
118
|
+
body_attrs = node.id ? [%(id="#{node.id}")] : []
|
118
119
|
if (sectioned = node.sections?) && (node.attr? 'toc-class') && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
|
119
|
-
|
120
|
+
classes = [node.doctype, (node.attr 'toc-class'), %(toc-#{node.attr 'toc-position', 'header'})]
|
120
121
|
else
|
121
|
-
|
122
|
+
classes = [node.doctype]
|
122
123
|
end
|
124
|
+
classes << (node.attr 'docrole') if node.attr? 'docrole'
|
125
|
+
body_attrs << %(class="#{classes * ' '}")
|
123
126
|
body_attrs << %(style="max-width: #{node.attr 'max-width'};") if node.attr? 'max-width'
|
124
127
|
result << %(<body #{body_attrs * ' '}>)
|
125
128
|
|
@@ -133,11 +136,7 @@ module Asciidoctor
|
|
133
136
|
#{outline node}
|
134
137
|
</div>)
|
135
138
|
end
|
136
|
-
|
137
|
-
result << %(<h2>#{node.attr 'manname-title'}</h2>
|
138
|
-
<div class="sectionbody">
|
139
|
-
<p>#{node.attr 'manname'} - #{node.attr 'manpurpose'}</p>
|
140
|
-
</div>)
|
139
|
+
result << (generate_manname_section node) if node.attr? 'manpurpose'
|
141
140
|
else
|
142
141
|
if node.has_header?
|
143
142
|
result << %(<h1>#{node.header.title}</h1>) unless node.notitle
|
@@ -190,7 +189,7 @@ module Asciidoctor
|
|
190
189
|
result << %(<div id="footnotes">
|
191
190
|
<hr#{slash}>)
|
192
191
|
node.footnotes.each do |footnote|
|
193
|
-
result << %(<div class="footnote" id="
|
192
|
+
result << %(<div class="footnote" id="_footnotedef_#{footnote.index}">
|
194
193
|
<a href="#_footnoteref_#{footnote.index}">#{footnote.index}</a>. #{footnote.text}
|
195
194
|
</div>)
|
196
195
|
end
|
@@ -245,7 +244,7 @@ MathJax.Hub.Config({
|
|
245
244
|
TeX: {#{eqnums_opt}}
|
246
245
|
});
|
247
246
|
</script>
|
248
|
-
<script src="#{cdn_base}/mathjax/
|
247
|
+
<script src="#{cdn_base}/mathjax/#{MATHJAX_VERSION}/MathJax.js?config=TeX-MML-AM_HTMLorMML"></script>)
|
249
248
|
end
|
250
249
|
|
251
250
|
result << '</body>'
|
@@ -258,17 +257,13 @@ MathJax.Hub.Config({
|
|
258
257
|
if node.doctype == 'manpage'
|
259
258
|
# QUESTION should notitle control the manual page title?
|
260
259
|
unless node.notitle
|
261
|
-
id_attr = node.id ? %( id="#{node.id}") :
|
260
|
+
id_attr = node.id ? %( id="#{node.id}") : ''
|
262
261
|
result << %(<h1#{id_attr}>#{node.doctitle} Manual Page</h1>)
|
263
262
|
end
|
264
|
-
|
265
|
-
result << %(<h2>#{node.attr 'manname-title'}</h2>
|
266
|
-
<div class="sectionbody">
|
267
|
-
<p>#{node.attr 'manname'} - #{node.attr 'manpurpose'}</p>
|
268
|
-
</div>)
|
263
|
+
result << (generate_manname_section node) if node.attr? 'manpurpose'
|
269
264
|
else
|
270
265
|
if node.has_header? && !node.notitle
|
271
|
-
id_attr = node.id ? %( id="#{node.id}") :
|
266
|
+
id_attr = node.id ? %( id="#{node.id}") : ''
|
272
267
|
result << %(<h1#{id_attr}>#{node.header.title}</h1>)
|
273
268
|
end
|
274
269
|
end
|
@@ -286,7 +281,7 @@ MathJax.Hub.Config({
|
|
286
281
|
result << %(<div id="footnotes">
|
287
282
|
<hr#{@void_element_slash}>)
|
288
283
|
node.footnotes.each do |footnote|
|
289
|
-
result << %(<div class="footnote" id="
|
284
|
+
result << %(<div class="footnote" id="_footnotedef_#{footnote.index}">
|
290
285
|
<a href="#_footnoteref_#{footnote.index}">#{footnote.index}</a>. #{footnote.text}
|
291
286
|
</div>)
|
292
287
|
end
|
@@ -312,6 +307,7 @@ MathJax.Hub.Config({
|
|
312
307
|
else
|
313
308
|
stitle = section.title
|
314
309
|
end
|
310
|
+
stitle = stitle.gsub DropAnchorRx, '' if stitle.include? '<a'
|
315
311
|
if slevel < toclevels && (child_toc_level = outline section, :toclevels => toclevels, :secnumlevels => sectnumlevels)
|
316
312
|
result << %(<li><a href="##{section.id}">#{stitle}</a>)
|
317
313
|
result << child_toc_level
|
@@ -325,45 +321,46 @@ MathJax.Hub.Config({
|
|
325
321
|
end
|
326
322
|
|
327
323
|
def section node
|
328
|
-
|
329
|
-
|
330
|
-
|
324
|
+
if (level = node.level) == 0
|
325
|
+
sect0 = true
|
326
|
+
title = node.numbered && level <= (node.document.attr 'sectnumlevels', 3).to_i ? %(#{node.sectnum} #{node.title}) : node.title
|
327
|
+
else
|
328
|
+
title = node.numbered && !node.caption && level <= (node.document.attr 'sectnumlevels', 3).to_i ? %(#{node.sectnum} #{node.title}) : node.captioned_title
|
329
|
+
end
|
331
330
|
if node.id
|
332
331
|
id_attr = %( id="#{id = node.id}")
|
333
|
-
if (
|
334
|
-
|
335
|
-
# possible idea - anchor icons GitHub-style
|
336
|
-
#if doc.attr? 'icons', 'font'
|
337
|
-
# anchor = %(<a class="anchor" href="##{id}"><i class="fa fa-anchor"></i></a>)
|
338
|
-
#else
|
339
|
-
# anchor = %(<a class="anchor" href="##{id}"></a>)
|
340
|
-
#end
|
332
|
+
if (doc_attrs = node.document.attributes).key? 'sectlinks'
|
333
|
+
title = %(<a class="link" href="##{id}">#{title}</a>)
|
341
334
|
end
|
342
|
-
if
|
343
|
-
|
344
|
-
|
335
|
+
if doc_attrs.key? 'sectanchors'
|
336
|
+
# QUESTION should we add a font-based icon in anchor if icons=font?
|
337
|
+
if doc_attrs['sectanchors'] == 'after'
|
338
|
+
title = %(#{title}<a class="anchor" href="##{id}"></a>)
|
339
|
+
else
|
340
|
+
title = %(<a class="anchor" href="##{id}"></a>#{title})
|
341
|
+
end
|
345
342
|
end
|
343
|
+
else
|
344
|
+
id_attr = ''
|
346
345
|
end
|
347
346
|
|
348
|
-
if
|
349
|
-
%(<h1#{id_attr} class="sect0"
|
347
|
+
if sect0
|
348
|
+
%(<h1#{id_attr} class="sect0#{(role = node.role) ? " #{role}" : ''}">#{title}</h1>
|
350
349
|
#{node.content})
|
351
350
|
else
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
<#{htag}#{id_attr}>#{anchor}#{link_start}#{sectnum}#{node.captioned_title}#{link_end}</#{htag}>
|
358
|
-
#{slevel == 1 ? %[<div class="sectionbody">\n#{node.content}\n</div>] : node.content}
|
351
|
+
%(<div class="sect#{level}#{(role = node.role) ? " #{role}" : ''}">
|
352
|
+
<h#{level + 1}#{id_attr}>#{title}</h#{level + 1}>
|
353
|
+
#{level == 1 ? %[<div class="sectionbody">
|
354
|
+
#{node.content}
|
355
|
+
</div>] : node.content}
|
359
356
|
</div>)
|
360
357
|
end
|
361
358
|
end
|
362
359
|
|
363
360
|
def admonition node
|
364
|
-
id_attr = node.id ? %( id="#{node.id}") :
|
361
|
+
id_attr = node.id ? %( id="#{node.id}") : ''
|
365
362
|
name = node.attr 'name'
|
366
|
-
title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) :
|
363
|
+
title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
|
367
364
|
if node.document.attr? 'icons'
|
368
365
|
if (node.document.attr? 'icons', 'font') && !(node.attr? 'icon')
|
369
366
|
label = %(<i class="fa icon-#{name}" title="#{node.attr 'textlabel'}"></i>)
|
@@ -373,7 +370,7 @@ MathJax.Hub.Config({
|
|
373
370
|
else
|
374
371
|
label = %(<div class="title">#{node.attr 'textlabel'}</div>)
|
375
372
|
end
|
376
|
-
%(<div#{id_attr} class="admonitionblock #{name}#{(role = node.role)
|
373
|
+
%(<div#{id_attr} class="admonitionblock #{name}#{(role = node.role) ? " #{role}" : ''}">
|
377
374
|
<table>
|
378
375
|
<tr>
|
379
376
|
<td class="icon">
|
@@ -389,16 +386,16 @@ MathJax.Hub.Config({
|
|
389
386
|
|
390
387
|
def audio node
|
391
388
|
xml = @xml_mode
|
392
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
389
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
393
390
|
classes = ['audioblock', node.role].compact
|
394
391
|
class_attribute = %( class="#{classes * ' '}")
|
395
|
-
title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) :
|
392
|
+
title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
|
396
393
|
start_t = node.attr 'start', nil, false
|
397
394
|
end_t = node.attr 'end', nil, false
|
398
|
-
time_anchor = (start_t || end_t) ? %(#t=#{start_t}#{end_t ?
|
395
|
+
time_anchor = (start_t || end_t) ? %(#t=#{start_t || ''}#{end_t ? ",#{end_t}" : ''}) : ''
|
399
396
|
%(<div#{id_attribute}#{class_attribute}>
|
400
397
|
#{title_element}<div class="content">
|
401
|
-
<audio src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) :
|
398
|
+
<audio src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : ''}#{(node.option? 'nocontrols') ? '' : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : ''}>
|
402
399
|
Your browser does not support the audio tag.
|
403
400
|
</audio>
|
404
401
|
</div>
|
@@ -407,7 +404,7 @@ Your browser does not support the audio tag.
|
|
407
404
|
|
408
405
|
def colist node
|
409
406
|
result = []
|
410
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
407
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
411
408
|
classes = ['colist', node.style, node.role].compact
|
412
409
|
class_attribute = %( class="#{classes * ' '}")
|
413
410
|
|
@@ -446,7 +443,7 @@ Your browser does not support the audio tag.
|
|
446
443
|
|
447
444
|
def dlist node
|
448
445
|
result = []
|
449
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
446
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
450
447
|
|
451
448
|
classes = case node.style
|
452
449
|
when 'qanda'
|
@@ -481,15 +478,15 @@ Your browser does not support the audio tag.
|
|
481
478
|
result << '<table>'
|
482
479
|
if (node.attr? 'labelwidth') || (node.attr? 'itemwidth')
|
483
480
|
result << '<colgroup>'
|
484
|
-
col_style_attribute = (node.attr? 'labelwidth') ? %( style="width: #{(node.attr 'labelwidth').chomp '%'}%;") :
|
481
|
+
col_style_attribute = (node.attr? 'labelwidth') ? %( style="width: #{(node.attr 'labelwidth').chomp '%'}%;") : ''
|
485
482
|
result << %(<col#{col_style_attribute}#{slash}>)
|
486
|
-
col_style_attribute = (node.attr? 'itemwidth') ? %( style="width: #{(node.attr 'itemwidth').chomp '%'}%;") :
|
483
|
+
col_style_attribute = (node.attr? 'itemwidth') ? %( style="width: #{(node.attr 'itemwidth').chomp '%'}%;") : ''
|
487
484
|
result << %(<col#{col_style_attribute}#{slash}>)
|
488
485
|
result << '</colgroup>'
|
489
486
|
end
|
490
487
|
node.items.each do |terms, dd|
|
491
488
|
result << '<tr>'
|
492
|
-
result << %(<td class="hdlist1#{(node.option? 'strong') ? ' strong' :
|
489
|
+
result << %(<td class="hdlist1#{(node.option? 'strong') ? ' strong' : ''}">)
|
493
490
|
terms_array = [*terms]
|
494
491
|
last_term = terms_array[-1]
|
495
492
|
terms_array.each do |dt|
|
@@ -508,7 +505,7 @@ Your browser does not support the audio tag.
|
|
508
505
|
result << '</table>'
|
509
506
|
else
|
510
507
|
result << '<dl>'
|
511
|
-
dt_style_attribute = node.style ?
|
508
|
+
dt_style_attribute = node.style ? '' : ' class="hdlist1"'
|
512
509
|
node.items.each do |terms, dd|
|
513
510
|
[*terms].each do |dt|
|
514
511
|
result << %(<dt#{dt_style_attribute}>#{dt.text}</dt>)
|
@@ -528,10 +525,10 @@ Your browser does not support the audio tag.
|
|
528
525
|
end
|
529
526
|
|
530
527
|
def example node
|
531
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
532
|
-
title_element = node.title? ? %(<div class="title">#{node.captioned_title}</div>\n) :
|
528
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
529
|
+
title_element = node.title? ? %(<div class="title">#{node.captioned_title}</div>\n) : ''
|
533
530
|
|
534
|
-
%(<div#{id_attribute} class="exampleblock#{(role = node.role)
|
531
|
+
%(<div#{id_attribute} class="exampleblock#{(role = node.role) ? " #{role}" : ''}">
|
535
532
|
#{title_element}<div class="content">
|
536
533
|
#{node.content}
|
537
534
|
</div>
|
@@ -540,15 +537,15 @@ Your browser does not support the audio tag.
|
|
540
537
|
|
541
538
|
def floating_title node
|
542
539
|
tag_name = %(h#{node.level + 1})
|
543
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
540
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
544
541
|
classes = [node.style, node.role].compact
|
545
542
|
%(<#{tag_name}#{id_attribute} class="#{classes * ' '}">#{node.title}</#{tag_name}>)
|
546
543
|
end
|
547
544
|
|
548
545
|
def image node
|
549
546
|
target = node.attr 'target'
|
550
|
-
width_attr = (node.attr? 'width') ? %( width="#{node.attr 'width'}") :
|
551
|
-
height_attr = (node.attr? 'height') ? %( height="#{node.attr 'height'}") :
|
547
|
+
width_attr = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : ''
|
548
|
+
height_attr = (node.attr? 'height') ? %( height="#{node.attr 'height'}") : ''
|
552
549
|
if ((node.attr? 'format', 'svg', false) || (target.include? '.svg')) && node.document.safe < SafeMode::SECURE &&
|
553
550
|
((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
|
554
551
|
if svg
|
@@ -559,18 +556,17 @@ Your browser does not support the audio tag.
|
|
559
556
|
end
|
560
557
|
end
|
561
558
|
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
|
-
|
564
|
-
img = %(<a class="image" href="#{node.attr 'link'}"#{window_attr}>#{img}</a>)
|
559
|
+
if node.attr? 'link', nil, false
|
560
|
+
img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>)
|
565
561
|
end
|
566
|
-
id_attr = node.id ? %( id="#{node.id}") :
|
562
|
+
id_attr = node.id ? %( id="#{node.id}") : ''
|
567
563
|
classes = ['imageblock', node.role].compact
|
568
564
|
class_attr = %( class="#{classes * ' '}")
|
569
565
|
styles = []
|
570
566
|
styles << %(text-align: #{node.attr 'align'}) if node.attr? 'align'
|
571
567
|
styles << %(float: #{node.attr 'float'}) if node.attr? 'float'
|
572
|
-
style_attr = styles.empty? ?
|
573
|
-
title_el = node.title? ? %(\n<div class="title">#{node.captioned_title}</div>) :
|
568
|
+
style_attr = styles.empty? ? '' : %( style="#{styles * ';'}")
|
569
|
+
title_el = node.title? ? %(\n<div class="title">#{node.captioned_title}</div>) : ''
|
574
570
|
%(<div#{id_attr}#{class_attr}#{style_attr}>
|
575
571
|
<div class="content">
|
576
572
|
#{img}
|
@@ -584,36 +580,41 @@ Your browser does not support the audio tag.
|
|
584
580
|
if (language = node.attr 'language', nil, false)
|
585
581
|
code_attrs = %( data-lang="#{language}")
|
586
582
|
else
|
587
|
-
code_attrs =
|
583
|
+
code_attrs = ''
|
588
584
|
end
|
589
585
|
case node.document.attr 'source-highlighter'
|
590
586
|
when 'coderay'
|
591
|
-
pre_class = %( class="CodeRay highlight#{nowrap ? ' nowrap' :
|
587
|
+
pre_class = %( class="CodeRay highlight#{nowrap ? ' nowrap' : ''}")
|
592
588
|
when 'pygments'
|
593
|
-
|
589
|
+
if (node.document.attr? 'pygments-css', 'inline')
|
590
|
+
@pygments_bg = @stylesheets.pygments_background(node.document.attr 'pygments-style') unless defined? @pygments_bg
|
591
|
+
pre_class = %( class="pygments highlight#{nowrap ? ' nowrap' : ''}" style="background: #{@pygments_bg}")
|
592
|
+
else
|
593
|
+
pre_class = %( class="pygments highlight#{nowrap ? ' nowrap' : ''}")
|
594
|
+
end
|
594
595
|
when 'highlightjs', 'highlight.js'
|
595
|
-
pre_class = %( class="highlightjs highlight#{nowrap ? ' nowrap' :
|
596
|
+
pre_class = %( class="highlightjs highlight#{nowrap ? ' nowrap' : ''}")
|
596
597
|
code_attrs = %( class="language-#{language} hljs"#{code_attrs}) if language
|
597
598
|
when 'prettify'
|
598
|
-
pre_class = %( class="prettyprint highlight#{nowrap ? ' nowrap' :
|
599
|
+
pre_class = %( class="prettyprint highlight#{nowrap ? ' nowrap' : ''}#{(node.attr? 'linenums', nil, false) ? ' linenums' : ''}")
|
599
600
|
code_attrs = %( class="language-#{language}"#{code_attrs}) if language
|
600
601
|
when 'html-pipeline'
|
601
|
-
pre_class = language ? %( lang="#{language}") :
|
602
|
-
code_attrs =
|
602
|
+
pre_class = language ? %( lang="#{language}") : ''
|
603
|
+
code_attrs = ''
|
603
604
|
else
|
604
|
-
pre_class = %( class="highlight#{nowrap ? ' nowrap' :
|
605
|
+
pre_class = %( class="highlight#{nowrap ? ' nowrap' : ''}")
|
605
606
|
code_attrs = %( class="language-#{language}"#{code_attrs}) if language
|
606
607
|
end
|
607
608
|
pre_start = %(<pre#{pre_class}><code#{code_attrs}>)
|
608
609
|
pre_end = '</code></pre>'
|
609
610
|
else
|
610
|
-
pre_start = %(<pre#{nowrap ? ' class="nowrap"' :
|
611
|
+
pre_start = %(<pre#{nowrap ? ' class="nowrap"' : ''}>)
|
611
612
|
pre_end = '</pre>'
|
612
613
|
end
|
613
614
|
|
614
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
615
|
-
title_element = node.title? ? %(<div class="title">#{node.captioned_title}</div>\n) :
|
616
|
-
%(<div#{id_attribute} class="listingblock#{(role = node.role)
|
615
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
616
|
+
title_element = node.title? ? %(<div class="title">#{node.captioned_title}</div>\n) : ''
|
617
|
+
%(<div#{id_attribute} class="listingblock#{(role = node.role) ? " #{role}" : ''}">
|
617
618
|
#{title_element}<div class="content">
|
618
619
|
#{pre_start}#{node.content}#{pre_end}
|
619
620
|
</div>
|
@@ -621,26 +622,32 @@ Your browser does not support the audio tag.
|
|
621
622
|
end
|
622
623
|
|
623
624
|
def literal node
|
624
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
625
|
-
title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) :
|
625
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
626
|
+
title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
|
626
627
|
nowrap = !(node.document.attr? 'prewrap') || (node.option? 'nowrap')
|
627
|
-
%(<div#{id_attribute} class="literalblock#{(role = node.role)
|
628
|
+
%(<div#{id_attribute} class="literalblock#{(role = node.role) ? " #{role}" : ''}">
|
628
629
|
#{title_element}<div class="content">
|
629
|
-
<pre#{nowrap ? ' class="nowrap"' :
|
630
|
+
<pre#{nowrap ? ' class="nowrap"' : ''}>#{node.content}</pre>
|
630
631
|
</div>
|
631
632
|
</div>)
|
632
633
|
end
|
633
634
|
|
634
635
|
def stem node
|
635
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
636
|
-
title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) :
|
637
|
-
open, close = BLOCK_MATH_DELIMITERS[node.style.to_sym]
|
636
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
637
|
+
title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
|
638
|
+
open, close = BLOCK_MATH_DELIMITERS[style = node.style.to_sym]
|
639
|
+
equation = node.content
|
640
|
+
|
641
|
+
if style == :asciimath && (equation.include? LF)
|
642
|
+
br = %(<br#{@void_element_slash}>#{LF})
|
643
|
+
equation = equation.gsub(StemBreakRx) { %(#{close}#{br * ($&.count LF)}#{open}) }
|
644
|
+
end
|
638
645
|
|
639
|
-
unless (
|
646
|
+
unless (equation.start_with? open) && (equation.end_with? close)
|
640
647
|
equation = %(#{open}#{equation}#{close})
|
641
648
|
end
|
642
649
|
|
643
|
-
%(<div#{id_attribute} class="stemblock#{(role = node.role)
|
650
|
+
%(<div#{id_attribute} class="stemblock#{(role = node.role) ? " #{role}" : ''}">
|
644
651
|
#{title_element}<div class="content">
|
645
652
|
#{equation}
|
646
653
|
</div>
|
@@ -649,16 +656,16 @@ Your browser does not support the audio tag.
|
|
649
656
|
|
650
657
|
def olist node
|
651
658
|
result = []
|
652
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
659
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
653
660
|
classes = ['olist', node.style, node.role].compact
|
654
661
|
class_attribute = %( class="#{classes * ' '}")
|
655
662
|
|
656
663
|
result << %(<div#{id_attribute}#{class_attribute}>)
|
657
664
|
result << %(<div class="title">#{node.title}</div>) if node.title?
|
658
665
|
|
659
|
-
type_attribute = (keyword = node.list_marker_keyword) ? %( type="#{keyword}") :
|
660
|
-
start_attribute = (node.attr? 'start') ? %( start="#{node.attr 'start'}") :
|
661
|
-
reversed_attribute = (node.option? 'reversed') ? (append_boolean_attribute 'reversed', @xml_mode) :
|
666
|
+
type_attribute = (keyword = node.list_marker_keyword) ? %( type="#{keyword}") : ''
|
667
|
+
start_attribute = (node.attr? 'start') ? %( start="#{node.attr 'start'}") : ''
|
668
|
+
reversed_attribute = (node.option? 'reversed') ? (append_boolean_attribute 'reversed', @xml_mode) : ''
|
662
669
|
result << %(<ol class="#{node.style}"#{type_attribute}#{start_attribute}#{reversed_attribute}>)
|
663
670
|
|
664
671
|
node.items.each do |item|
|
@@ -676,24 +683,24 @@ Your browser does not support the audio tag.
|
|
676
683
|
def open node
|
677
684
|
if (style = node.style) == 'abstract'
|
678
685
|
if node.parent == node.document && node.document.doctype == 'book'
|
679
|
-
warn '
|
686
|
+
logger.warn 'abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
|
680
687
|
''
|
681
688
|
else
|
682
|
-
id_attr = node.id ? %( id="#{node.id}") :
|
683
|
-
title_el = node.title? ? %(<div class="title">#{node.title}</div>\n) :
|
684
|
-
%(<div#{id_attr} class="quoteblock abstract#{(role = node.role)
|
689
|
+
id_attr = node.id ? %( id="#{node.id}") : ''
|
690
|
+
title_el = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
|
691
|
+
%(<div#{id_attr} class="quoteblock abstract#{(role = node.role) ? " #{role}" : ''}">
|
685
692
|
#{title_el}<blockquote>
|
686
693
|
#{node.content}
|
687
694
|
</blockquote>
|
688
695
|
</div>)
|
689
696
|
end
|
690
697
|
elsif style == 'partintro' && (node.level > 0 || node.parent.context != :section || node.document.doctype != 'book')
|
691
|
-
|
698
|
+
logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
692
699
|
''
|
693
700
|
else
|
694
|
-
id_attr = node.id ? %( id="#{node.id}") :
|
695
|
-
title_el = node.title? ? %(<div class="title">#{node.title}</div>\n) :
|
696
|
-
%(<div#{id_attr} class="openblock#{style && style != 'open' ? " #{style}" : ''}#{(role = node.role)
|
701
|
+
id_attr = node.id ? %( id="#{node.id}") : ''
|
702
|
+
title_el = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
|
703
|
+
%(<div#{id_attr} class="openblock#{style && style != 'open' ? " #{style}" : ''}#{(role = node.role) ? " #{role}" : ''}">
|
697
704
|
#{title_el}<div class="content">
|
698
705
|
#{node.content}
|
699
706
|
</div>
|
@@ -729,7 +736,7 @@ Your browser does not support the audio tag.
|
|
729
736
|
#{outline doc}
|
730
737
|
</div>)
|
731
738
|
else
|
732
|
-
toc =
|
739
|
+
toc = ''
|
733
740
|
end
|
734
741
|
|
735
742
|
%(<div id="preamble">
|
@@ -740,18 +747,18 @@ Your browser does not support the audio tag.
|
|
740
747
|
end
|
741
748
|
|
742
749
|
def quote node
|
743
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
750
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
744
751
|
classes = ['quoteblock', node.role].compact
|
745
752
|
class_attribute = %( class="#{classes * ' '}")
|
746
|
-
title_element = node.title? ? %(\n<div class="title">#{node.title}</div>) :
|
753
|
+
title_element = node.title? ? %(\n<div class="title">#{node.title}</div>) : ''
|
747
754
|
attribution = (node.attr? 'attribution') ? (node.attr 'attribution') : nil
|
748
755
|
citetitle = (node.attr? 'citetitle') ? (node.attr 'citetitle') : nil
|
749
756
|
if attribution || citetitle
|
750
|
-
cite_element = citetitle ? %(<cite>#{citetitle}</cite>) :
|
751
|
-
attribution_text = attribution ? %(— #{attribution}#{citetitle ? "<br#{@void_element_slash}>\n" :
|
757
|
+
cite_element = citetitle ? %(<cite>#{citetitle}</cite>) : ''
|
758
|
+
attribution_text = attribution ? %(— #{attribution}#{citetitle ? "<br#{@void_element_slash}>\n" : ''}) : ''
|
752
759
|
attribution_element = %(\n<div class="attribution">\n#{attribution_text}#{cite_element}\n</div>)
|
753
760
|
else
|
754
|
-
attribution_element =
|
761
|
+
attribution_element = ''
|
755
762
|
end
|
756
763
|
|
757
764
|
%(<div#{id_attribute}#{class_attribute}>#{title_element}
|
@@ -766,9 +773,9 @@ Your browser does not support the audio tag.
|
|
766
773
|
end
|
767
774
|
|
768
775
|
def sidebar node
|
769
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
770
|
-
title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) :
|
771
|
-
%(<div#{id_attribute} class="sidebarblock#{(role = node.role)
|
776
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
777
|
+
title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
|
778
|
+
%(<div#{id_attribute} class="sidebarblock#{(role = node.role) ? " #{role}" : ''}">
|
772
779
|
<div class="content">
|
773
780
|
#{title_element}#{node.content}
|
774
781
|
</div>
|
@@ -777,36 +784,36 @@ Your browser does not support the audio tag.
|
|
777
784
|
|
778
785
|
def table node
|
779
786
|
result = []
|
780
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
787
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
781
788
|
classes = ['tableblock', %(frame-#{node.attr 'frame', 'all'}), %(grid-#{node.attr 'grid', 'all'})]
|
789
|
+
if (stripes = node.attr 'stripes')
|
790
|
+
classes << %(stripes-#{stripes})
|
791
|
+
end
|
782
792
|
styles = []
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
793
|
+
if (autowidth = node.attributes['autowidth-option']) && !(node.attr? 'width', nil, false)
|
794
|
+
classes << 'fit-content'
|
795
|
+
elsif (tablewidth = node.attr 'tablepcwidth') == 100
|
796
|
+
classes << 'stretch'
|
797
|
+
else
|
798
|
+
styles << %(width: #{tablewidth}%;)
|
789
799
|
end
|
790
800
|
if (role = node.role)
|
791
801
|
classes << role
|
792
802
|
end
|
793
803
|
class_attribute = %( class="#{classes * ' '}")
|
794
804
|
styles << %(float: #{node.attr 'float'};) if node.attr? 'float'
|
795
|
-
style_attribute = styles.empty? ?
|
805
|
+
style_attribute = styles.empty? ? '' : %( style="#{styles * ' '}")
|
796
806
|
|
797
807
|
result << %(<table#{id_attribute}#{class_attribute}#{style_attribute}>)
|
798
808
|
result << %(<caption class="title">#{node.captioned_title}</caption>) if node.title?
|
799
809
|
if (node.attr 'rowcount') > 0
|
800
810
|
slash = @void_element_slash
|
801
811
|
result << '<colgroup>'
|
802
|
-
if
|
803
|
-
|
804
|
-
node.columns.size.times do
|
805
|
-
result << tag
|
806
|
-
end
|
812
|
+
if autowidth
|
813
|
+
result += (Array.new node.columns.size, %(<col#{slash}>))
|
807
814
|
else
|
808
815
|
node.columns.each do |col|
|
809
|
-
result << %(<col style="width: #{col.attr 'colpcwidth'}%;"#{slash}>)
|
816
|
+
result << (col.attributes['autowidth-option'] ? %(<col#{slash}>) : %(<col style="width: #{col.attr 'colpcwidth'}%;"#{slash}>))
|
810
817
|
end
|
811
818
|
end
|
812
819
|
result << '</colgroup>'
|
@@ -821,7 +828,7 @@ Your browser does not support the audio tag.
|
|
821
828
|
else
|
822
829
|
case cell.style
|
823
830
|
when :asciidoc
|
824
|
-
cell_content = %(<div>#{cell.content}</div>)
|
831
|
+
cell_content = %(<div class="content">#{cell.content}</div>)
|
825
832
|
when :verse
|
826
833
|
cell_content = %(<div class="verse">#{cell.text}</div>)
|
827
834
|
when :literal
|
@@ -834,9 +841,9 @@ Your browser does not support the audio tag.
|
|
834
841
|
|
835
842
|
cell_tag_name = (tsec == :head || cell.style == :header ? 'th' : 'td')
|
836
843
|
cell_class_attribute = %( class="tableblock halign-#{cell.attr 'halign'} valign-#{cell.attr 'valign'}")
|
837
|
-
cell_colspan_attribute = cell.colspan ? %( colspan="#{cell.colspan}") :
|
838
|
-
cell_rowspan_attribute = cell.rowspan ? %( rowspan="#{cell.rowspan}") :
|
839
|
-
cell_style_attribute = (node.document.attr? 'cellbgcolor') ? %( style="background-color: #{node.document.attr 'cellbgcolor'};") :
|
844
|
+
cell_colspan_attribute = cell.colspan ? %( colspan="#{cell.colspan}") : ''
|
845
|
+
cell_rowspan_attribute = cell.rowspan ? %( rowspan="#{cell.rowspan}") : ''
|
846
|
+
cell_style_attribute = (node.document.attr? 'cellbgcolor') ? %( style="background-color: #{node.document.attr 'cellbgcolor'};") : ''
|
840
847
|
result << %(<#{cell_tag_name}#{cell_class_attribute}#{cell_colspan_attribute}#{cell_rowspan_attribute}#{cell_style_attribute}>#{cell_content}</#{cell_tag_name}>)
|
841
848
|
end
|
842
849
|
result << '</tr>'
|
@@ -872,10 +879,9 @@ Your browser does not support the audio tag.
|
|
872
879
|
|
873
880
|
def ulist node
|
874
881
|
result = []
|
875
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
882
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
876
883
|
div_classes = ['ulist', node.style, node.role].compact
|
877
|
-
marker_checked =
|
878
|
-
marker_unchecked = nil
|
884
|
+
marker_checked = marker_unchecked = ''
|
879
885
|
if (checklist = node.option? 'checklist')
|
880
886
|
div_classes.unshift div_classes.shift, 'checklist'
|
881
887
|
ul_class_attribute = ' class="checklist"'
|
@@ -897,7 +903,7 @@ Your browser does not support the audio tag.
|
|
897
903
|
end
|
898
904
|
end
|
899
905
|
else
|
900
|
-
ul_class_attribute = node.style ? %( class="#{node.style}") :
|
906
|
+
ul_class_attribute = node.style ? %( class="#{node.style}") : ''
|
901
907
|
end
|
902
908
|
result << %(<div#{id_attribute} class="#{div_classes * ' '}">)
|
903
909
|
result << %(<div class="title">#{node.title}</div>) if node.title?
|
@@ -920,18 +926,18 @@ Your browser does not support the audio tag.
|
|
920
926
|
end
|
921
927
|
|
922
928
|
def verse node
|
923
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
929
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
924
930
|
classes = ['verseblock', node.role].compact
|
925
931
|
class_attribute = %( class="#{classes * ' '}")
|
926
|
-
title_element = node.title? ? %(\n<div class="title">#{node.title}</div>) :
|
932
|
+
title_element = node.title? ? %(\n<div class="title">#{node.title}</div>) : ''
|
927
933
|
attribution = (node.attr? 'attribution') ? (node.attr 'attribution') : nil
|
928
934
|
citetitle = (node.attr? 'citetitle') ? (node.attr 'citetitle') : nil
|
929
935
|
if attribution || citetitle
|
930
|
-
cite_element = citetitle ? %(<cite>#{citetitle}</cite>) :
|
931
|
-
attribution_text = attribution ? %(— #{attribution}#{citetitle ? "<br#{@void_element_slash}>\n" :
|
936
|
+
cite_element = citetitle ? %(<cite>#{citetitle}</cite>) : ''
|
937
|
+
attribution_text = attribution ? %(— #{attribution}#{citetitle ? "<br#{@void_element_slash}>\n" : ''}) : ''
|
932
938
|
attribution_element = %(\n<div class="attribution">\n#{attribution_text}#{cite_element}\n</div>)
|
933
939
|
else
|
934
|
-
attribution_element =
|
940
|
+
attribution_element = ''
|
935
941
|
end
|
936
942
|
|
937
943
|
%(<div#{id_attribute}#{class_attribute}>#{title_element}
|
@@ -941,25 +947,29 @@ Your browser does not support the audio tag.
|
|
941
947
|
|
942
948
|
def video node
|
943
949
|
xml = @xml_mode
|
944
|
-
id_attribute = node.id ? %( id="#{node.id}") :
|
950
|
+
id_attribute = node.id ? %( id="#{node.id}") : ''
|
945
951
|
classes = ['videoblock', node.role].compact
|
946
952
|
class_attribute = %( class="#{classes * ' '}")
|
947
|
-
title_element = node.title? ? %(\n<div class="title">#{node.title}</div>) :
|
948
|
-
width_attribute = (node.attr? 'width') ? %( width="#{node.attr 'width'}") :
|
949
|
-
height_attribute = (node.attr? 'height') ? %( height="#{node.attr 'height'}") :
|
953
|
+
title_element = node.title? ? %(\n<div class="title">#{node.title}</div>) : ''
|
954
|
+
width_attribute = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : ''
|
955
|
+
height_attribute = (node.attr? 'height') ? %( height="#{node.attr 'height'}") : ''
|
950
956
|
case node.attr 'poster'
|
951
957
|
when 'vimeo'
|
952
958
|
unless (asset_uri_scheme = (node.document.attr 'asset-uri-scheme', 'https')).empty?
|
953
959
|
asset_uri_scheme = %(#{asset_uri_scheme}:)
|
954
960
|
end
|
955
|
-
start_anchor = (node.attr? 'start', nil, false) ? %(#at=#{node.attr 'start'}) :
|
961
|
+
start_anchor = (node.attr? 'start', nil, false) ? %(#at=#{node.attr 'start'}) : ''
|
956
962
|
delimiter = '?'
|
957
|
-
|
958
|
-
|
959
|
-
|
963
|
+
if node.option? 'autoplay'
|
964
|
+
autoplay_param = %(#{delimiter}autoplay=1)
|
965
|
+
delimiter = '&'
|
966
|
+
else
|
967
|
+
autoplay_param = ''
|
968
|
+
end
|
969
|
+
loop_param = (node.option? 'loop') ? %(#{delimiter}loop=1) : ''
|
960
970
|
%(<div#{id_attribute}#{class_attribute}>#{title_element}
|
961
971
|
<div class="content">
|
962
|
-
<iframe#{width_attribute}#{height_attribute} src="#{asset_uri_scheme}//player.vimeo.com/video/#{node.attr 'target'}#{start_anchor}#{autoplay_param}#{loop_param}" frameborder="0"#{(node.option? 'nofullscreen') ?
|
972
|
+
<iframe#{width_attribute}#{height_attribute} src="#{asset_uri_scheme}//player.vimeo.com/video/#{node.attr 'target'}#{start_anchor}#{autoplay_param}#{loop_param}" frameborder="0"#{(node.option? 'nofullscreen') ? '' : (append_boolean_attribute 'allowfullscreen', xml)}></iframe>
|
963
973
|
</div>
|
964
974
|
</div>)
|
965
975
|
when 'youtube'
|
@@ -968,22 +978,22 @@ Your browser does not support the audio tag.
|
|
968
978
|
end
|
969
979
|
rel_param_val = (node.option? 'related') ? 1 : 0
|
970
980
|
# NOTE start and end must be seconds (t parameter allows XmYs where X is minutes and Y is seconds)
|
971
|
-
start_param = (node.attr? 'start', nil, false) ? %(&start=#{node.attr 'start'}) :
|
972
|
-
end_param = (node.attr? 'end', nil, false) ? %(&end=#{node.attr 'end'}) :
|
973
|
-
autoplay_param = (node.option? 'autoplay') ? '&autoplay=1' :
|
974
|
-
loop_param = (node.option? 'loop') ? '&loop=1' :
|
975
|
-
controls_param = (node.option? 'nocontrols') ? '&controls=0' :
|
981
|
+
start_param = (node.attr? 'start', nil, false) ? %(&start=#{node.attr 'start'}) : ''
|
982
|
+
end_param = (node.attr? 'end', nil, false) ? %(&end=#{node.attr 'end'}) : ''
|
983
|
+
autoplay_param = (node.option? 'autoplay') ? '&autoplay=1' : ''
|
984
|
+
loop_param = (has_loop_param = node.option? 'loop') ? '&loop=1' : ''
|
985
|
+
controls_param = (node.option? 'nocontrols') ? '&controls=0' : ''
|
976
986
|
# cover both ways of controlling fullscreen option
|
977
987
|
if node.option? 'nofullscreen'
|
978
988
|
fs_param = '&fs=0'
|
979
|
-
fs_attribute =
|
989
|
+
fs_attribute = ''
|
980
990
|
else
|
981
|
-
fs_param =
|
991
|
+
fs_param = ''
|
982
992
|
fs_attribute = append_boolean_attribute 'allowfullscreen', xml
|
983
993
|
end
|
984
|
-
modest_param = (node.option? 'modest') ? '&modestbranding=1' :
|
985
|
-
theme_param = (node.attr? 'theme', nil, false) ? %(&theme=#{node.attr 'theme'}) :
|
986
|
-
hl_param = (node.attr? 'lang') ? %(&hl=#{node.attr 'lang'}) :
|
994
|
+
modest_param = (node.option? 'modest') ? '&modestbranding=1' : ''
|
995
|
+
theme_param = (node.attr? 'theme', nil, false) ? %(&theme=#{node.attr 'theme'}) : ''
|
996
|
+
hl_param = (node.attr? 'lang') ? %(&hl=#{node.attr 'lang'}) : ''
|
987
997
|
|
988
998
|
# parse video_id/list_id syntax where list_id (i.e., playlist) is optional
|
989
999
|
target, list = (node.attr 'target').split '/', 2
|
@@ -997,7 +1007,7 @@ Your browser does not support the audio tag.
|
|
997
1007
|
list_param = %(&playlist=#{playlist})
|
998
1008
|
else
|
999
1009
|
# NOTE for loop to work, playlist must be specified; use VIDEO_ID if there's no explicit playlist
|
1000
|
-
list_param =
|
1010
|
+
list_param = has_loop_param ? %(&playlist=#{target}) : ''
|
1001
1011
|
end
|
1002
1012
|
end
|
1003
1013
|
|
@@ -1007,14 +1017,14 @@ Your browser does not support the audio tag.
|
|
1007
1017
|
</div>
|
1008
1018
|
</div>)
|
1009
1019
|
else
|
1010
|
-
poster_attribute = (val = node.attr 'poster', nil, false).nil_or_empty? ?
|
1011
|
-
preload_attribute = (val = node.attr 'preload', nil, false).nil_or_empty? ?
|
1020
|
+
poster_attribute = (val = node.attr 'poster', nil, false).nil_or_empty? ? '' : %( poster="#{node.media_uri val}")
|
1021
|
+
preload_attribute = (val = node.attr 'preload', nil, false).nil_or_empty? ? '' : %( preload="#{val}")
|
1012
1022
|
start_t = node.attr 'start', nil, false
|
1013
1023
|
end_t = node.attr 'end', nil, false
|
1014
|
-
time_anchor = (start_t || end_t) ? %(#t=#{start_t}#{end_t ?
|
1024
|
+
time_anchor = (start_t || end_t) ? %(#t=#{start_t || ''}#{end_t ? ",#{end_t}" : ''}) : ''
|
1015
1025
|
%(<div#{id_attribute}#{class_attribute}>#{title_element}
|
1016
1026
|
<div class="content">
|
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) :
|
1027
|
+
<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}>
|
1018
1028
|
Your browser does not support the video tag.
|
1019
1029
|
</video>
|
1020
1030
|
</div>
|
@@ -1025,29 +1035,34 @@ Your browser does not support the video tag.
|
|
1025
1035
|
def inline_anchor node
|
1026
1036
|
case node.type
|
1027
1037
|
when :xref
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1038
|
+
if (path = node.attributes['path'])
|
1039
|
+
attrs = (append_link_constraint_attrs node, node.role ? [%( class="#{node.role}")] : []).join
|
1040
|
+
text = node.text || path
|
1041
|
+
else
|
1042
|
+
attrs = node.role ? %( class="#{node.role}") : ''
|
1043
|
+
unless (text = node.text)
|
1044
|
+
refid = node.attributes['refid']
|
1045
|
+
if AbstractNode === (ref = (@refs ||= node.document.catalog[:refs])[refid])
|
1046
|
+
text = (ref.xreftext node.attr('xrefstyle')) || %([#{refid}])
|
1047
|
+
else
|
1048
|
+
text = %([#{refid}])
|
1049
|
+
end
|
1033
1050
|
end
|
1034
1051
|
end
|
1035
|
-
%(<a href="#{node.target}">#{text}</a>)
|
1052
|
+
%(<a href="#{node.target}"#{attrs}>#{text}</a>)
|
1036
1053
|
when :ref
|
1037
1054
|
%(<a id="#{node.id}"></a>)
|
1038
1055
|
when :link
|
1039
1056
|
attrs = node.id ? [%( id="#{node.id}")] : []
|
1040
|
-
|
1041
|
-
attrs << %( class="#{role}")
|
1042
|
-
end
|
1057
|
+
attrs << %( class="#{node.role}") if node.role
|
1043
1058
|
attrs << %( title="#{node.attr 'title'}") if node.attr? 'title', nil, false
|
1044
|
-
|
1045
|
-
%(<a href="#{node.target}"#{attrs.join}>#{node.text}</a>)
|
1059
|
+
%(<a href="#{node.target}"#{(append_link_constraint_attrs node, attrs).join}>#{node.text}</a>)
|
1046
1060
|
when :bibref
|
1047
1061
|
# NOTE technically node.text should be node.reftext, but subs have already been applied to text
|
1048
1062
|
%(<a id="#{node.id}"></a>#{node.text})
|
1049
1063
|
else
|
1050
|
-
warn %(
|
1064
|
+
logger.warn %(unknown anchor type: #{node.type.inspect})
|
1065
|
+
nil
|
1051
1066
|
end
|
1052
1067
|
end
|
1053
1068
|
|
@@ -1073,10 +1088,10 @@ Your browser does not support the video tag.
|
|
1073
1088
|
def inline_footnote node
|
1074
1089
|
if (index = node.attr 'index', nil, false)
|
1075
1090
|
if node.type == :xref
|
1076
|
-
%(<sup class="footnoteref">[<a class="footnote" href="#
|
1091
|
+
%(<sup class="footnoteref">[<a class="footnote" href="#_footnotedef_#{index}" title="View footnote.">#{index}</a>]</sup>)
|
1077
1092
|
else
|
1078
|
-
id_attr = node.id ? %( id="_footnote_#{node.id}") :
|
1079
|
-
%(<sup class="footnote"#{id_attr}>[<a id="_footnoteref_#{index}" class="footnote" href="#
|
1093
|
+
id_attr = node.id ? %( id="_footnote_#{node.id}") : ''
|
1094
|
+
%(<sup class="footnote"#{id_attr}>[<a id="_footnoteref_#{index}" class="footnote" href="#_footnotedef_#{index}" title="View footnote.">#{index}</a>]</sup>)
|
1080
1095
|
end
|
1081
1096
|
elsif node.type == :xref
|
1082
1097
|
%(<sup class="footnoteref red" title="Unresolved footnote reference.">[#{node.text}]</sup>)
|
@@ -1089,13 +1104,13 @@ Your browser does not support the video tag.
|
|
1089
1104
|
{'size' => 'fa-', 'rotate' => 'fa-rotate-', 'flip' => 'fa-flip-'}.each do |key, prefix|
|
1090
1105
|
class_attr_val = %(#{class_attr_val} #{prefix}#{node.attr key}) if node.attr? key
|
1091
1106
|
end
|
1092
|
-
title_attr = (node.attr? 'title') ? %( title="#{node.attr 'title'}") :
|
1107
|
+
title_attr = (node.attr? 'title') ? %( title="#{node.attr 'title'}") : ''
|
1093
1108
|
img = %(<i class="#{class_attr_val}"#{title_attr}></i>)
|
1094
1109
|
elsif type == 'icon' && !(node.document.attr? 'icons')
|
1095
1110
|
img = %([#{node.alt}])
|
1096
1111
|
else
|
1097
1112
|
target = node.target
|
1098
|
-
attrs = ['width', 'height', 'title'].map {|name| (node.attr? name) ? %( #{name}="#{node.attr name}") :
|
1113
|
+
attrs = ['width', 'height', 'title'].map {|name| (node.attr? name) ? %( #{name}="#{node.attr name}") : '' }.join
|
1099
1114
|
if type != 'icon' && ((node.attr? 'format', 'svg', false) || (target.include? '.svg')) &&
|
1100
1115
|
node.document.safe < SafeMode::SECURE && ((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
|
1101
1116
|
if svg
|
@@ -1107,12 +1122,11 @@ Your browser does not support the video tag.
|
|
1107
1122
|
end
|
1108
1123
|
img ||= %(<img src="#{type == 'icon' ? (node.icon_uri target) : (node.image_uri target)}" alt="#{encode_quotes node.alt}"#{attrs}#{@void_element_slash}>)
|
1109
1124
|
end
|
1110
|
-
if node.attr? 'link'
|
1111
|
-
|
1112
|
-
img = %(<a class="image" href="#{node.attr 'link'}"#{window_attr}>#{img}</a>)
|
1125
|
+
if node.attr? 'link', nil, false
|
1126
|
+
img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>)
|
1113
1127
|
end
|
1114
1128
|
class_attr_val = (role = node.role) ? %(#{type} #{role}) : type
|
1115
|
-
style_attr = (node.attr? 'float') ? %( style="float: #{node.attr 'float'}") :
|
1129
|
+
style_attr = (node.attr? 'float') ? %( style="float: #{node.attr 'float'}") : ''
|
1116
1130
|
%(<span class="#{class_attr_val}"#{style_attr}>#{img}</span>)
|
1117
1131
|
end
|
1118
1132
|
|
@@ -1145,17 +1159,17 @@ Your browser does not support the video tag.
|
|
1145
1159
|
|
1146
1160
|
def inline_quoted node
|
1147
1161
|
open, close, is_tag = QUOTE_TAGS[node.type]
|
1148
|
-
if node.role
|
1162
|
+
class_attr = %( class="#{node.role}") if node.role
|
1163
|
+
id_attr = %( id="#{node.id}") if node.id
|
1164
|
+
if class_attr || id_attr
|
1149
1165
|
if is_tag
|
1150
|
-
|
1166
|
+
%(#{open.chop}#{id_attr || ''}#{class_attr || ''}>#{node.text}#{close})
|
1151
1167
|
else
|
1152
|
-
|
1168
|
+
%(<span#{id_attr || ''}#{class_attr || ''}>#{open}#{node.text}#{close}</span>)
|
1153
1169
|
end
|
1154
1170
|
else
|
1155
|
-
|
1171
|
+
%(#{open}#{node.text}#{close})
|
1156
1172
|
end
|
1157
|
-
|
1158
|
-
node.id ? %(<a id="#{node.id}"></a>#{quoted_text}) : quoted_text
|
1159
1173
|
end
|
1160
1174
|
|
1161
1175
|
def append_boolean_attribute name, xml
|
@@ -1166,6 +1180,29 @@ Your browser does not support the video tag.
|
|
1166
1180
|
(val.include? '"') ? (val.gsub '"', '"') : val
|
1167
1181
|
end
|
1168
1182
|
|
1183
|
+
def generate_manname_section node
|
1184
|
+
manname_title = (node.attr 'manname-title') || 'Name'
|
1185
|
+
if (next_section = node.sections[0]) && (next_section_title = next_section.title) == next_section_title.upcase
|
1186
|
+
manname_title = manname_title.upcase
|
1187
|
+
end
|
1188
|
+
manname_id_attr = (manname_id = node.attr 'manname-id') ? %( id="#{manname_id}") : ''
|
1189
|
+
%(<h2#{manname_id_attr}>#{manname_title}</h2>
|
1190
|
+
<div class="sectionbody">
|
1191
|
+
<p>#{node.attr 'manname'} - #{node.attr 'manpurpose'}</p>
|
1192
|
+
</div>)
|
1193
|
+
end
|
1194
|
+
|
1195
|
+
def append_link_constraint_attrs node, attrs = []
|
1196
|
+
rel = 'nofollow' if node.option? 'nofollow'
|
1197
|
+
if (window = node.attributes['window'])
|
1198
|
+
attrs << %( target="#{window}")
|
1199
|
+
attrs << (rel ? %( rel="#{rel} noopener") : ' rel="noopener"') if window == '_blank' || (node.option? 'noopener')
|
1200
|
+
elsif rel
|
1201
|
+
attrs << %( rel="#{rel}")
|
1202
|
+
end
|
1203
|
+
attrs
|
1204
|
+
end
|
1205
|
+
|
1169
1206
|
def read_svg_contents node, target
|
1170
1207
|
if (svg = node.read_contents target, :start => (node.document.attr 'imagesdir'), :normalize => true, :label => 'SVG')
|
1171
1208
|
svg = svg.sub SvgPreambleRx, '' unless svg.start_with? '<svg'
|