asciidoctor 2.0.0.rc.2 → 2.0.0.rc.3
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 +31 -3
- data/README-de.adoc +2 -8
- data/README-fr.adoc +2 -8
- data/README-jp.adoc +2 -2
- data/README-zh_CN.adoc +2 -2
- data/README.adoc +3 -7
- data/data/locale/attributes-fr.adoc +1 -1
- data/data/stylesheets/asciidoctor-default.css +3 -2
- data/lib/asciidoctor.rb +13 -7
- data/lib/asciidoctor/abstract_block.rb +33 -27
- data/lib/asciidoctor/abstract_node.rb +6 -10
- data/lib/asciidoctor/block.rb +4 -4
- data/lib/asciidoctor/cli/options.rb +23 -24
- data/lib/asciidoctor/converter.rb +17 -16
- data/lib/asciidoctor/converter/docbook5.rb +102 -102
- data/lib/asciidoctor/converter/html5.rb +142 -84
- data/lib/asciidoctor/converter/manpage.rb +81 -81
- data/lib/asciidoctor/converter/template.rb +2 -2
- data/lib/asciidoctor/core_ext.rb +1 -0
- data/lib/asciidoctor/core_ext/hash/merge.rb +7 -0
- data/lib/asciidoctor/document.rb +28 -14
- data/lib/asciidoctor/extensions.rb +4 -3
- data/lib/asciidoctor/inline.rb +2 -9
- data/lib/asciidoctor/parser.rb +27 -17
- data/lib/asciidoctor/reader.rb +41 -26
- data/lib/asciidoctor/section.rb +1 -8
- data/lib/asciidoctor/substitutors.rb +125 -124
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +1 -1
- data/lib/asciidoctor/table.rb +1 -1
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +4 -4
- data/man/asciidoctor.adoc +1 -1
- metadata +3 -2
data/lib/asciidoctor/block.rb
CHANGED
@@ -40,7 +40,7 @@ class Block < AbstractBlock
|
|
40
40
|
# * :source a String or Array of raw source for this Block. (default: nil)
|
41
41
|
#
|
42
42
|
# IMPORTANT: If you don't specify the `:subs` option, you must explicitly call
|
43
|
-
# the `
|
43
|
+
# the `commit_subs` method to resolve and assign the substitutions to this
|
44
44
|
# block (which are resolved from the `subs` attribute, if specified, or the
|
45
45
|
# default substitutions based on this block's context). If you want to use the
|
46
46
|
# default subs for a block, pass the option `subs: :default`. You can
|
@@ -51,7 +51,7 @@ class Block < AbstractBlock
|
|
51
51
|
super
|
52
52
|
@content_model = opts[:content_model] || DEFAULT_CONTENT_MODEL[context]
|
53
53
|
if opts.key? :subs
|
54
|
-
# FIXME feels funky; we have to be defensive to get
|
54
|
+
# FIXME feels funky; we have to be defensive to get commit_subs to honor override
|
55
55
|
# FIXME does not resolve substitution groups inside Array (e.g., [:normal])
|
56
56
|
if (subs = opts[:subs])
|
57
57
|
# e.g., subs: :defult
|
@@ -71,8 +71,8 @@ class Block < AbstractBlock
|
|
71
71
|
@attributes['subs'] = %(#{subs})
|
72
72
|
end
|
73
73
|
# resolve the subs eagerly only if subs option is specified
|
74
|
-
# QUESTION should we skip subsequent calls to
|
75
|
-
|
74
|
+
# QUESTION should we skip subsequent calls to commit_subs?
|
75
|
+
commit_subs
|
76
76
|
# e.g., subs: nil
|
77
77
|
else
|
78
78
|
# NOTE @subs is initialized as empty array by super constructor
|
@@ -1,34 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
3
|
module Cli
|
4
|
-
FS =
|
5
|
-
RS =
|
4
|
+
FS = ?/
|
5
|
+
RS = ?\\
|
6
6
|
|
7
7
|
# Public: List of options that can be specified on the command line
|
8
8
|
class Options < ::Hash
|
9
9
|
|
10
10
|
def initialize(options = {})
|
11
11
|
self[:attributes] = options[:attributes] || {}
|
12
|
-
self[:input_files] = options[:input_files]
|
13
|
-
self[:output_file] = options[:output_file]
|
12
|
+
self[:input_files] = options[:input_files]
|
13
|
+
self[:output_file] = options[:output_file]
|
14
14
|
self[:safe] = options[:safe] || SafeMode::UNSAFE
|
15
|
-
self[:
|
16
|
-
self[:template_dirs] = options[:template_dirs]
|
17
|
-
self[:template_engine] = options[:template_engine]
|
18
|
-
if options[:doctype]
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
self[:
|
25
|
-
self[:verbose] = options[:verbose] || 1
|
26
|
-
self[:warnings] = options[:warnings] || false
|
27
|
-
self[:load_paths] = options[:load_paths] || nil
|
28
|
-
self[:requires] = options[:requires] || nil
|
15
|
+
self[:standalone] = options.fetch :standalone, true
|
16
|
+
self[:template_dirs] = options[:template_dirs]
|
17
|
+
self[:template_engine] = options[:template_engine]
|
18
|
+
self[:attributes]['doctype'] = options[:doctype] if options[:doctype]
|
19
|
+
self[:attributes]['backend'] = options[:backend] if options[:backend]
|
20
|
+
self[:eruby] = options[:eruby]
|
21
|
+
self[:verbose] = options.fetch :verbose, 1
|
22
|
+
self[:warnings] = options.fetch :warnings, false
|
23
|
+
self[:load_paths] = options[:load_paths]
|
24
|
+
self[:requires] = options[:requires]
|
29
25
|
self[:base_dir] = options[:base_dir]
|
30
|
-
self[:source_dir] = options[:source_dir]
|
31
|
-
self[:destination_dir] = options[:destination_dir]
|
26
|
+
self[:source_dir] = options[:source_dir]
|
27
|
+
self[:destination_dir] = options[:destination_dir]
|
32
28
|
self[:failure_level] = ::Logger::Severity::FATAL
|
33
29
|
self[:trace] = false
|
34
30
|
self[:timings] = false
|
@@ -56,6 +52,9 @@ module Asciidoctor
|
|
56
52
|
'document type to use when converting document: [article, book, manpage, inline] (default: article)') do |doc_type|
|
57
53
|
self[:attributes]['doctype'] = doc_type
|
58
54
|
end
|
55
|
+
opts.on('-e', '--embedded', 'suppress enclosing document structure and output an embedded document (default: false)') do
|
56
|
+
self[:standalone] = false
|
57
|
+
end
|
59
58
|
opts.on('-o', '--out-file FILE', 'output file (default: based on path of input file); use - to output to STDOUT') do |output_file|
|
60
59
|
self[:output_file] = output_file
|
61
60
|
end
|
@@ -70,13 +69,13 @@ module Asciidoctor
|
|
70
69
|
'disables potentially dangerous macros in source files, such as include::[]') do |name|
|
71
70
|
self[:safe] = SafeMode.value_for_name name
|
72
71
|
end
|
73
|
-
opts.on('-s', '--no-header-footer', 'suppress
|
74
|
-
self[:
|
72
|
+
opts.on('-s', '--no-header-footer', 'suppress enclosing document structure and output an embedded document (default: false)') do
|
73
|
+
self[:standalone] = false
|
75
74
|
end
|
76
75
|
opts.on('-n', '--section-numbers', 'auto-number section titles in the HTML backend; disabled by default') do
|
77
76
|
self[:attributes]['sectnums'] = ''
|
78
77
|
end
|
79
|
-
opts.on('
|
78
|
+
opts.on('--eruby ERUBY', ['erb', 'erubis'],
|
80
79
|
'specify eRuby implementation to use when rendering custom ERB templates: [erb, erubis] (default: erb)') do |eruby|
|
81
80
|
self[:eruby] = eruby
|
82
81
|
end
|
@@ -118,7 +117,7 @@ module Asciidoctor
|
|
118
117
|
'may be specified more than once') do |path|
|
119
118
|
(self[:requires] ||= []).concat(path.split ',')
|
120
119
|
end
|
121
|
-
opts.on('--failure-level LEVEL', %w(warning WARNING error ERROR
|
120
|
+
opts.on('--failure-level LEVEL', %w(warning WARNING error ERROR info INFO), 'set minimum logging level that triggers non-zero exit code: [WARN, ERROR, INFO] (default: FATAL)') do |level|
|
122
121
|
level = 'WARN' if (level = level.upcase) == 'WARNING'
|
123
122
|
self[:failure_level] = ::Logger::Severity.const_get level, false
|
124
123
|
end
|
@@ -36,7 +36,7 @@ module Asciidoctor
|
|
36
36
|
#
|
37
37
|
# class Html5Converter < (Asciidoctor::Converter.for 'html5')
|
38
38
|
# register_for 'html5'
|
39
|
-
# def
|
39
|
+
# def convert_paragraph node
|
40
40
|
# %(<p>#{node.content}</p>)
|
41
41
|
# end
|
42
42
|
# end
|
@@ -73,13 +73,13 @@ module Converter
|
|
73
73
|
raise ::NotImplementedError, %(#{self.class} (backend: #{@backend}) must implement the ##{__method__} method)
|
74
74
|
end
|
75
75
|
|
76
|
-
# Public: Reports whether the current converter is able to convert this node (by its name). Used by the
|
76
|
+
# Public: Reports whether the current converter is able to convert this node (by its transform name). Used by the
|
77
77
|
# {CompositeConverter} to select which converter to use to handle a given node. Returns true by default.
|
78
78
|
#
|
79
|
-
#
|
79
|
+
# transform - the String name of the node transformation (typically the node name).
|
80
80
|
#
|
81
|
-
# Returns a [Boolean] indicating whether this converter can handle the specified
|
82
|
-
def handles?
|
81
|
+
# Returns a [Boolean] indicating whether this converter can handle the specified transform.
|
82
|
+
def handles? transform
|
83
83
|
true
|
84
84
|
end
|
85
85
|
|
@@ -238,7 +238,7 @@ module Converter
|
|
238
238
|
|
239
239
|
# Public: Get the Hash of Converter classes keyed by backend name. Intended for testing only.
|
240
240
|
def converters
|
241
|
-
registry.
|
241
|
+
registry.merge
|
242
242
|
end
|
243
243
|
|
244
244
|
private def registry
|
@@ -368,35 +368,36 @@ module Converter
|
|
368
368
|
|
369
369
|
# Public: Converts an {AbstractNode} by delegating to a method that matches the transform value.
|
370
370
|
#
|
371
|
-
# This method looks for a method
|
372
|
-
# non-nil, this method assumes the dispatch method accepts two arguments, the node and an options
|
373
|
-
# Hash may be used by converters to delegate back to the top-level converter. Currently,
|
374
|
-
# transform. If the +opts+ argument is nil, this method assumes the dispatch method
|
375
|
-
#
|
376
|
-
# underscore and mark them as private. Implementations may override this method to provide different behavior.
|
371
|
+
# This method looks for a method whose name matches the transform prefixed with "convert_" to dispatch to. If the
|
372
|
+
# +opts+ argument is non-nil, this method assumes the dispatch method accepts two arguments, the node and an options
|
373
|
+
# Hash. The options Hash may be used by converters to delegate back to the top-level converter. Currently, this
|
374
|
+
# feature is used for the outline transform. If the +opts+ argument is nil, this method assumes the dispatch method
|
375
|
+
# accepts the node as its only argument.
|
377
376
|
#
|
378
377
|
# See {Converter#convert} for details about the arguments and return value.
|
379
378
|
def convert node, transform = node.node_name, opts = nil
|
380
|
-
opts ? (send transform, node, opts) : (send transform, node)
|
379
|
+
opts ? (send 'convert_' + transform, node, opts) : (send 'convert_' + transform, node)
|
381
380
|
rescue
|
382
381
|
raise unless ::NoMethodError === (ex = $!) && ex.receiver == self && ex.name.to_s == transform
|
383
382
|
logger.warn %(missing convert handler for #{ex.name} node in #{@backend} backend (#{self.class}))
|
384
383
|
nil
|
385
384
|
end
|
386
385
|
|
387
|
-
|
386
|
+
def handles? transform
|
387
|
+
respond_to? %(convert_#{transform})
|
388
|
+
end
|
388
389
|
|
389
390
|
# Public: Converts the {AbstractNode} using only its converted content.
|
390
391
|
#
|
391
392
|
# Returns the converted [String] content.
|
392
|
-
def
|
393
|
+
def content_only node
|
393
394
|
node.content
|
394
395
|
end
|
395
396
|
|
396
397
|
# Public: Skips conversion of the {AbstractNode}.
|
397
398
|
#
|
398
399
|
# Returns nothing.
|
399
|
-
def
|
400
|
+
def skip node; end
|
400
401
|
end
|
401
402
|
|
402
403
|
extend DefaultFactory # exports static methods
|
@@ -33,7 +33,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
33
33
|
init_backend_traits basebackend: 'docbook', filetype: 'xml', outfilesuffix: '.xml', supports_templates: true
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
36
|
+
def convert_document node
|
37
37
|
result = ['<?xml version="1.0" encoding="UTF-8"?>']
|
38
38
|
if node.attr? 'toc'
|
39
39
|
if node.attr? 'toclevels'
|
@@ -53,8 +53,8 @@ class Converter::DocBook5Converter < Converter::Base
|
|
53
53
|
if (root_tag_name = node.doctype) == 'manpage'
|
54
54
|
root_tag_name = 'refentry'
|
55
55
|
end
|
56
|
-
result << %(<#{root_tag_name} xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0"#{lang_attribute}#{
|
57
|
-
result << (
|
56
|
+
result << %(<#{root_tag_name} xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0"#{lang_attribute}#{common_attributes node.id}>)
|
57
|
+
result << (document_info_tag node) unless node.noheader
|
58
58
|
unless (docinfo_content = node.docinfo :header).empty?
|
59
59
|
result << docinfo_content
|
60
60
|
end
|
@@ -66,31 +66,31 @@ class Converter::DocBook5Converter < Converter::Base
|
|
66
66
|
result.join LF
|
67
67
|
end
|
68
68
|
|
69
|
-
alias
|
69
|
+
alias convert_embedded content_only
|
70
70
|
|
71
|
-
def
|
71
|
+
def convert_section node
|
72
72
|
if node.document.doctype == 'manpage'
|
73
73
|
tag_name = MANPAGE_SECTION_TAGS[tag_name = node.sectname] || tag_name
|
74
74
|
else
|
75
75
|
tag_name = node.sectname
|
76
76
|
end
|
77
77
|
title_el = node.special && (node.option? 'untitled') ? '' : %(<title>#{node.title}</title>\n)
|
78
|
-
%(<#{tag_name}#{
|
78
|
+
%(<#{tag_name}#{common_attributes node.id, node.role, node.reftext}>
|
79
79
|
#{title_el}#{node.content}
|
80
80
|
</#{tag_name}>)
|
81
81
|
end
|
82
82
|
|
83
|
-
def
|
84
|
-
%(<#{tag_name = node.attr 'name'}#{
|
85
|
-
#{
|
83
|
+
def convert_admonition node
|
84
|
+
%(<#{tag_name = node.attr 'name'}#{common_attributes node.id, node.role, node.reftext}>
|
85
|
+
#{title_tag node}#{enclose_content node}
|
86
86
|
</#{tag_name}>)
|
87
87
|
end
|
88
88
|
|
89
|
-
alias
|
89
|
+
alias convert_audio skip
|
90
90
|
|
91
|
-
def
|
91
|
+
def convert_colist node
|
92
92
|
result = []
|
93
|
-
result << %(<calloutlist#{
|
93
|
+
result << %(<calloutlist#{common_attributes node.id, node.role, node.reftext}>)
|
94
94
|
result << %(<title>#{node.title}</title>) if node.title?
|
95
95
|
node.items.each do |item|
|
96
96
|
result << %(<callout arearefs="#{item.attr 'coids'}">)
|
@@ -102,11 +102,11 @@ class Converter::DocBook5Converter < Converter::Base
|
|
102
102
|
result.join LF
|
103
103
|
end
|
104
104
|
|
105
|
-
def
|
105
|
+
def convert_dlist node
|
106
106
|
result = []
|
107
107
|
if node.style == 'horizontal'
|
108
|
-
result << %(<#{tag_name = node.title? ? 'table' : 'informaltable'}#{
|
109
|
-
#{
|
108
|
+
result << %(<#{tag_name = node.title? ? 'table' : 'informaltable'}#{common_attributes node.id, node.role, node.reftext} tabstyle="horizontal" frame="none" colsep="0" rowsep="0">
|
109
|
+
#{title_tag node}<tgroup cols="2">
|
110
110
|
<colspec colwidth="#{node.attr 'labelwidth', 15}*"/>
|
111
111
|
<colspec colwidth="#{node.attr 'itemwidth', 85}*"/>
|
112
112
|
<tbody valign="top">)
|
@@ -134,7 +134,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
134
134
|
term_tag = tags[:term]
|
135
135
|
item_tag = tags[:item]
|
136
136
|
if list_tag
|
137
|
-
result << %(<#{list_tag}#{
|
137
|
+
result << %(<#{list_tag}#{common_attributes node.id, node.role, node.reftext}>)
|
138
138
|
result << %(<title>#{node.title}</title>) if node.title?
|
139
139
|
end
|
140
140
|
|
@@ -158,24 +158,24 @@ class Converter::DocBook5Converter < Converter::Base
|
|
158
158
|
result.join LF
|
159
159
|
end
|
160
160
|
|
161
|
-
def
|
161
|
+
def convert_example node
|
162
162
|
if node.title?
|
163
|
-
%(<example#{
|
163
|
+
%(<example#{common_attributes node.id, node.role, node.reftext}>
|
164
164
|
<title>#{node.title}</title>
|
165
|
-
#{
|
165
|
+
#{enclose_content node}
|
166
166
|
</example>)
|
167
167
|
else
|
168
|
-
%(<informalexample#{
|
169
|
-
#{
|
168
|
+
%(<informalexample#{common_attributes node.id, node.role, node.reftext}>
|
169
|
+
#{enclose_content node}
|
170
170
|
</informalexample>)
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
-
def
|
175
|
-
%(<bridgehead#{
|
174
|
+
def convert_floating_title node
|
175
|
+
%(<bridgehead#{common_attributes node.id, node.role, node.reftext} renderas="sect#{node.level}">#{node.title}</bridgehead>)
|
176
176
|
end
|
177
177
|
|
178
|
-
def
|
178
|
+
def convert_image node
|
179
179
|
# NOTE according to the DocBook spec, content area, scaling, and scaling to fit are mutually exclusive
|
180
180
|
# See http://tdg.docbook.org/tdg/4.5/imagedata-x.html#d0e79635
|
181
181
|
if node.attr? 'scaledwidth'
|
@@ -202,20 +202,20 @@ class Converter::DocBook5Converter < Converter::Base
|
|
202
202
|
</mediaobject>)
|
203
203
|
|
204
204
|
if node.title?
|
205
|
-
%(<figure#{
|
205
|
+
%(<figure#{common_attributes node.id, node.role, node.reftext}>
|
206
206
|
<title>#{node.title}</title>
|
207
207
|
#{mediaobject}
|
208
208
|
</figure>)
|
209
209
|
else
|
210
|
-
%(<informalfigure#{
|
210
|
+
%(<informalfigure#{common_attributes node.id, node.role, node.reftext}>
|
211
211
|
#{mediaobject}
|
212
212
|
</informalfigure>)
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
216
|
-
def
|
216
|
+
def convert_listing node
|
217
217
|
informal = !node.title?
|
218
|
-
common_attrs =
|
218
|
+
common_attrs = common_attributes node.id, node.role, node.reftext
|
219
219
|
if node.style == 'source'
|
220
220
|
if (attrs = node.attributes).key? 'linenums'
|
221
221
|
numbering_attrs = (attrs.key? 'start') ? %( linenumbering="numbered" startinglinenumber="#{attrs['start'].to_i}") : ' linenumbering="numbered"'
|
@@ -238,22 +238,22 @@ class Converter::DocBook5Converter < Converter::Base
|
|
238
238
|
</formalpara>)
|
239
239
|
end
|
240
240
|
|
241
|
-
def
|
241
|
+
def convert_literal node
|
242
242
|
if node.title?
|
243
|
-
%(<formalpara#{
|
243
|
+
%(<formalpara#{common_attributes node.id, node.role, node.reftext}>
|
244
244
|
<title>#{node.title}</title>
|
245
245
|
<para>
|
246
246
|
<literallayout class="monospaced">#{node.content}</literallayout>
|
247
247
|
</para>
|
248
248
|
</formalpara>)
|
249
249
|
else
|
250
|
-
%(<literallayout#{
|
250
|
+
%(<literallayout#{common_attributes node.id, node.role, node.reftext} class="monospaced">#{node.content}</literallayout>)
|
251
251
|
end
|
252
252
|
end
|
253
253
|
|
254
|
-
alias
|
254
|
+
alias convert_pass content_only
|
255
255
|
|
256
|
-
def
|
256
|
+
def convert_stem node
|
257
257
|
if (idx = node.subs.index :specialcharacters)
|
258
258
|
node.subs.delete_at idx
|
259
259
|
equation = node.content || ''
|
@@ -263,33 +263,33 @@ class Converter::DocBook5Converter < Converter::Base
|
|
263
263
|
end
|
264
264
|
if node.style == 'asciimath'
|
265
265
|
# NOTE fop requires jeuclid to process mathml markup
|
266
|
-
equation_data =
|
266
|
+
equation_data = asciimath_available? ? ((::AsciiMath.parse equation).to_mathml 'mml:', 'xmlns:mml' => 'http://www.w3.org/1998/Math/MathML') : %(<mathphrase><![CDATA[#{equation}]]></mathphrase>)
|
267
267
|
else
|
268
268
|
# unhandled math; pass source to alt and required mathphrase element; dblatex will process alt as LaTeX math
|
269
269
|
equation_data = %(<alt><![CDATA[#{equation}]]></alt>
|
270
270
|
<mathphrase><![CDATA[#{equation}]]></mathphrase>)
|
271
271
|
end
|
272
272
|
if node.title?
|
273
|
-
%(<equation#{
|
273
|
+
%(<equation#{common_attributes node.id, node.role, node.reftext}>
|
274
274
|
<title>#{node.title}</title>
|
275
275
|
#{equation_data}
|
276
276
|
</equation>)
|
277
277
|
else
|
278
278
|
# WARNING dblatex displays the <informalequation> element inline instead of block as documented (except w/ mathml)
|
279
|
-
%(<informalequation#{
|
279
|
+
%(<informalequation#{common_attributes node.id, node.role, node.reftext}>
|
280
280
|
#{equation_data}
|
281
281
|
</informalequation>)
|
282
282
|
end
|
283
283
|
end
|
284
284
|
|
285
|
-
def
|
285
|
+
def convert_olist node
|
286
286
|
result = []
|
287
287
|
num_attribute = node.style ? %( numeration="#{node.style}") : ''
|
288
288
|
start_attribute = (node.attr? 'start') ? %( startingnumber="#{node.attr 'start'}") : ''
|
289
|
-
result << %(<orderedlist#{
|
289
|
+
result << %(<orderedlist#{common_attributes node.id, node.role, node.reftext}#{num_attribute}#{start_attribute}>)
|
290
290
|
result << %(<title>#{node.title}</title>) if node.title?
|
291
291
|
node.items.each do |item|
|
292
|
-
result << %(<listitem#{
|
292
|
+
result << %(<listitem#{common_attributes item.id, item.role}>)
|
293
293
|
result << %(<simpara>#{item.text}</simpara>)
|
294
294
|
result << item.content if item.blocks?
|
295
295
|
result << '</listitem>'
|
@@ -298,7 +298,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
298
298
|
result.join LF
|
299
299
|
end
|
300
300
|
|
301
|
-
def
|
301
|
+
def convert_open node
|
302
302
|
case node.style
|
303
303
|
when 'abstract'
|
304
304
|
if node.parent == node.document && node.document.doctype == 'book'
|
@@ -306,7 +306,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
306
306
|
''
|
307
307
|
else
|
308
308
|
%(<abstract>
|
309
|
-
#{
|
309
|
+
#{title_tag node}#{enclose_content node}
|
310
310
|
</abstract>)
|
311
311
|
end
|
312
312
|
when 'partintro'
|
@@ -314,72 +314,72 @@ class Converter::DocBook5Converter < Converter::Base
|
|
314
314
|
logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
315
315
|
''
|
316
316
|
else
|
317
|
-
%(<partintro#{
|
318
|
-
#{
|
317
|
+
%(<partintro#{common_attributes node.id, node.role, node.reftext}>
|
318
|
+
#{title_tag node}#{enclose_content node}
|
319
319
|
</partintro>)
|
320
320
|
end
|
321
321
|
else
|
322
322
|
reftext = node.reftext if (id = node.id)
|
323
323
|
role = node.role
|
324
324
|
if node.title?
|
325
|
-
%(<formalpara#{
|
325
|
+
%(<formalpara#{common_attributes id, role, reftext}>
|
326
326
|
<title>#{node.title}</title>
|
327
327
|
<para>#{content_spacer = node.content_model == :compound ? LF : ''}#{node.content}#{content_spacer}</para>
|
328
328
|
</formalpara>)
|
329
329
|
elsif id || role
|
330
330
|
if node.content_model == :compound
|
331
|
-
%(<para#{
|
331
|
+
%(<para#{common_attributes id, role, reftext}>
|
332
332
|
#{node.content}
|
333
333
|
</para>)
|
334
334
|
else
|
335
|
-
%(<simpara#{
|
335
|
+
%(<simpara#{common_attributes id, role, reftext}>#{node.content}</simpara>)
|
336
336
|
end
|
337
337
|
else
|
338
|
-
|
338
|
+
enclose_content node
|
339
339
|
end
|
340
340
|
end
|
341
341
|
end
|
342
342
|
|
343
|
-
def
|
343
|
+
def convert_page_break node
|
344
344
|
'<simpara><?asciidoc-pagebreak?></simpara>'
|
345
345
|
end
|
346
346
|
|
347
|
-
def
|
347
|
+
def convert_paragraph node
|
348
348
|
if node.title?
|
349
|
-
%(<formalpara#{
|
349
|
+
%(<formalpara#{common_attributes node.id, node.role, node.reftext}>
|
350
350
|
<title>#{node.title}</title>
|
351
351
|
<para>#{node.content}</para>
|
352
352
|
</formalpara>)
|
353
353
|
else
|
354
|
-
%(<simpara#{
|
354
|
+
%(<simpara#{common_attributes node.id, node.role, node.reftext}>#{node.content}</simpara>)
|
355
355
|
end
|
356
356
|
end
|
357
357
|
|
358
|
-
def
|
358
|
+
def convert_preamble node
|
359
359
|
if node.document.doctype == 'book'
|
360
|
-
%(<preface#{
|
361
|
-
#{
|
360
|
+
%(<preface#{common_attributes node.id, node.role, node.reftext}>
|
361
|
+
#{title_tag node, false}#{node.content}
|
362
362
|
</preface>)
|
363
363
|
else
|
364
364
|
node.content
|
365
365
|
end
|
366
366
|
end
|
367
367
|
|
368
|
-
def
|
369
|
-
|
368
|
+
def convert_quote node
|
369
|
+
blockquote_tag(node, (node.has_role? 'epigraph') && 'epigraph') { enclose_content node }
|
370
370
|
end
|
371
371
|
|
372
|
-
def
|
372
|
+
def convert_thematic_break node
|
373
373
|
'<simpara><?asciidoc-hr?></simpara>'
|
374
374
|
end
|
375
375
|
|
376
|
-
def
|
377
|
-
%(<sidebar#{
|
378
|
-
#{
|
376
|
+
def convert_sidebar node
|
377
|
+
%(<sidebar#{common_attributes node.id, node.role, node.reftext}>
|
378
|
+
#{title_tag node}#{enclose_content node}
|
379
379
|
</sidebar>)
|
380
380
|
end
|
381
381
|
|
382
|
-
def
|
382
|
+
def convert_table node
|
383
383
|
has_body = false
|
384
384
|
result = []
|
385
385
|
pgwide_attribute = (node.option? 'pgwide') ? ' pgwide="1"' : ''
|
@@ -387,7 +387,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
387
387
|
frame = 'topbot'
|
388
388
|
end
|
389
389
|
grid = node.attr 'grid', nil, 'table-grid'
|
390
|
-
result << %(<#{tag_name = node.title? ? 'table' : 'informaltable'}#{
|
390
|
+
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"' : ''}>)
|
391
391
|
if (node.option? 'unbreakable')
|
392
392
|
result << '<?dbfo keep-together="always"?>'
|
393
393
|
elsif (node.option? 'breakable')
|
@@ -447,12 +447,12 @@ class Converter::DocBook5Converter < Converter::Base
|
|
447
447
|
result.join LF
|
448
448
|
end
|
449
449
|
|
450
|
-
alias
|
450
|
+
alias convert_toc skip
|
451
451
|
|
452
|
-
def
|
452
|
+
def convert_ulist node
|
453
453
|
result = []
|
454
454
|
if node.style == 'bibliography'
|
455
|
-
result << %(<bibliodiv#{
|
455
|
+
result << %(<bibliodiv#{common_attributes node.id, node.role, node.reftext}>)
|
456
456
|
result << %(<title>#{node.title}</title>) if node.title?
|
457
457
|
node.items.each do |item|
|
458
458
|
result << '<bibliomixed>'
|
@@ -464,11 +464,11 @@ class Converter::DocBook5Converter < Converter::Base
|
|
464
464
|
else
|
465
465
|
mark_type = (checklist = node.option? 'checklist') ? 'none' : node.style
|
466
466
|
mark_attribute = mark_type ? %( mark="#{mark_type}") : ''
|
467
|
-
result << %(<itemizedlist#{
|
467
|
+
result << %(<itemizedlist#{common_attributes node.id, node.role, node.reftext}#{mark_attribute}>)
|
468
468
|
result << %(<title>#{node.title}</title>) if node.title?
|
469
469
|
node.items.each do |item|
|
470
470
|
text_marker = (item.attr? 'checked') ? '✓ ' : '❏ ' if checklist && (item.attr? 'checkbox')
|
471
|
-
result << %(<listitem#{
|
471
|
+
result << %(<listitem#{common_attributes item.id, item.role}>)
|
472
472
|
result << %(<simpara>#{text_marker || ''}#{item.text}</simpara>)
|
473
473
|
result << item.content if item.blocks?
|
474
474
|
result << '</listitem>'
|
@@ -478,16 +478,16 @@ class Converter::DocBook5Converter < Converter::Base
|
|
478
478
|
result.join LF
|
479
479
|
end
|
480
480
|
|
481
|
-
def
|
482
|
-
|
481
|
+
def convert_verse node
|
482
|
+
blockquote_tag(node, (node.has_role? 'epigraph') && 'epigraph') { %(<literallayout>#{node.content}</literallayout>) }
|
483
483
|
end
|
484
484
|
|
485
|
-
alias
|
485
|
+
alias convert_video skip
|
486
486
|
|
487
|
-
def
|
487
|
+
def convert_inline_anchor node
|
488
488
|
case node.type
|
489
489
|
when :ref
|
490
|
-
%(<anchor#{
|
490
|
+
%(<anchor#{common_attributes((id = node.id), nil, node.reftext || %([#{id}]))}/>)
|
491
491
|
when :xref
|
492
492
|
if (path = node.attributes['path'])
|
493
493
|
# QUESTION should we use refid as fallback text instead? (like the html5 backend?)
|
@@ -499,34 +499,34 @@ class Converter::DocBook5Converter < Converter::Base
|
|
499
499
|
when :link
|
500
500
|
%(<link xl:href="#{node.target}">#{node.text}</link>)
|
501
501
|
when :bibref
|
502
|
-
%(<anchor#{
|
502
|
+
%(<anchor#{common_attributes node.id, nil, "[#{node.reftext || node.id}]"}/>#{text})
|
503
503
|
else
|
504
504
|
logger.warn %(unknown anchor type: #{node.type.inspect})
|
505
505
|
nil
|
506
506
|
end
|
507
507
|
end
|
508
508
|
|
509
|
-
def
|
509
|
+
def convert_inline_break node
|
510
510
|
%(#{node.text}<?asciidoc-br?>)
|
511
511
|
end
|
512
512
|
|
513
|
-
def
|
513
|
+
def convert_inline_button node
|
514
514
|
%(<guibutton>#{node.text}</guibutton>)
|
515
515
|
end
|
516
516
|
|
517
|
-
def
|
518
|
-
%(<co#{
|
517
|
+
def convert_inline_callout node
|
518
|
+
%(<co#{common_attributes node.id}/>)
|
519
519
|
end
|
520
520
|
|
521
|
-
def
|
521
|
+
def convert_inline_footnote node
|
522
522
|
if node.type == :xref
|
523
523
|
%(<footnoteref linkend="#{node.target}"/>)
|
524
524
|
else
|
525
|
-
%(<footnote#{
|
525
|
+
%(<footnote#{common_attributes node.id}><simpara>#{node.text}</simpara></footnote>)
|
526
526
|
end
|
527
527
|
end
|
528
528
|
|
529
|
-
def
|
529
|
+
def convert_inline_image node
|
530
530
|
width_attribute = (node.attr? 'width') ? %( contentwidth="#{node.attr 'width'}") : ''
|
531
531
|
depth_attribute = (node.attr? 'height') ? %( contentdepth="#{node.attr 'height'}") : ''
|
532
532
|
%(<inlinemediaobject>
|
@@ -537,7 +537,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
537
537
|
</inlinemediaobject>)
|
538
538
|
end
|
539
539
|
|
540
|
-
def
|
540
|
+
def convert_inline_indexterm node
|
541
541
|
if node.type == :visible
|
542
542
|
%(<indexterm><primary>#{node.text}</primary></indexterm>#{node.text})
|
543
543
|
else
|
@@ -560,7 +560,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
560
560
|
end
|
561
561
|
end
|
562
562
|
|
563
|
-
def
|
563
|
+
def convert_inline_kbd node
|
564
564
|
if (keys = node.attr 'keys').size == 1
|
565
565
|
%(<keycap>#{keys[0]}</keycap>)
|
566
566
|
else
|
@@ -568,7 +568,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
568
568
|
end
|
569
569
|
end
|
570
570
|
|
571
|
-
def
|
571
|
+
def convert_inline_menu node
|
572
572
|
menu = node.attr 'menu'
|
573
573
|
if (submenus = node.attr 'submenus').empty?
|
574
574
|
if (menuitem = node.attr 'menuitem')
|
@@ -581,10 +581,10 @@ class Converter::DocBook5Converter < Converter::Base
|
|
581
581
|
end
|
582
582
|
end
|
583
583
|
|
584
|
-
def
|
584
|
+
def convert_inline_quoted node
|
585
585
|
if (type = node.type) == :asciimath
|
586
586
|
# NOTE fop requires jeuclid to process mathml markup
|
587
|
-
|
587
|
+
asciimath_available? ? %(<inlineequation>#{(::AsciiMath.parse node.text).to_mathml 'mml:', 'xmlns:mml' => 'http://www.w3.org/1998/Math/MathML'}</inlineequation>) : %(<inlineequation><mathphrase><![CDATA[#{node.text}]]></mathphrase></inlineequation>)
|
588
588
|
elsif type == :latexmath
|
589
589
|
# unhandled math; pass source to alt and required mathphrase element; dblatex will process alt as LaTeX math
|
590
590
|
%(<inlineequation><alt><![CDATA[#{equation = node.text}]]></alt><mathphrase><![CDATA[#{equation}]]></mathphrase></inlineequation>)
|
@@ -601,13 +601,13 @@ class Converter::DocBook5Converter < Converter::Base
|
|
601
601
|
quoted_text = %(#{open}#{text}#{close})
|
602
602
|
end
|
603
603
|
|
604
|
-
node.id ? %(<anchor#{
|
604
|
+
node.id ? %(<anchor#{common_attributes node.id, nil, text}/>#{quoted_text}) : quoted_text
|
605
605
|
end
|
606
606
|
end
|
607
607
|
|
608
608
|
private
|
609
609
|
|
610
|
-
def
|
610
|
+
def common_attributes id, role = nil, reftext = nil
|
611
611
|
if id
|
612
612
|
attrs = %( xml:id="#{id}"#{role ? %[ role="#{role}"] : ''})
|
613
613
|
elsif role
|
@@ -626,7 +626,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
626
626
|
end
|
627
627
|
end
|
628
628
|
|
629
|
-
def
|
629
|
+
def author_tag author
|
630
630
|
result = []
|
631
631
|
result << '<author>'
|
632
632
|
result << '<personname>'
|
@@ -639,7 +639,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
639
639
|
result.join LF
|
640
640
|
end
|
641
641
|
|
642
|
-
def
|
642
|
+
def document_info_tag doc
|
643
643
|
result = ['<info>']
|
644
644
|
unless doc.notitle
|
645
645
|
if (title = doc.doctitle partition: true, use_fallback: true).subtitle?
|
@@ -663,10 +663,10 @@ class Converter::DocBook5Converter < Converter::Base
|
|
663
663
|
unless (authors = doc.authors).empty?
|
664
664
|
if authors.size > 1
|
665
665
|
result << '<authorgroup>'
|
666
|
-
authors.each {|author| result << (
|
666
|
+
authors.each {|author| result << (author_tag author) }
|
667
667
|
result << '</authorgroup>'
|
668
668
|
else
|
669
|
-
result <<
|
669
|
+
result << author_tag(author = authors[0])
|
670
670
|
result << %(<authorinitials>#{author.initials}</authorinitials>) if author.initials
|
671
671
|
end
|
672
672
|
end
|
@@ -681,10 +681,10 @@ class Converter::DocBook5Converter < Converter::Base
|
|
681
681
|
</revhistory>)
|
682
682
|
end
|
683
683
|
if (doc.attr? 'front-cover-image') || (doc.attr? 'back-cover-image')
|
684
|
-
if (back_cover_tag =
|
685
|
-
result << (
|
684
|
+
if (back_cover_tag = cover_tag doc, 'back')
|
685
|
+
result << (cover_tag doc, 'front', true)
|
686
686
|
result << back_cover_tag
|
687
|
-
elsif (front_cover_tag =
|
687
|
+
elsif (front_cover_tag = cover_tag doc, 'front')
|
688
688
|
result << front_cover_tag
|
689
689
|
end
|
690
690
|
end
|
@@ -712,15 +712,15 @@ class Converter::DocBook5Converter < Converter::Base
|
|
712
712
|
end
|
713
713
|
|
714
714
|
# FIXME this should be handled through a template mechanism
|
715
|
-
def
|
715
|
+
def enclose_content node
|
716
716
|
node.content_model == :compound ? node.content : %(<simpara>#{node.content}</simpara>)
|
717
717
|
end
|
718
718
|
|
719
|
-
def
|
719
|
+
def title_tag node, optional = true
|
720
720
|
!optional || node.title? ? %(<title>#{node.title}</title>\n) : ''
|
721
721
|
end
|
722
722
|
|
723
|
-
def
|
723
|
+
def cover_tag doc, face, use_placeholder = false
|
724
724
|
if (cover_image = doc.attr %(#{face}-cover-image))
|
725
725
|
width_attr = ''
|
726
726
|
depth_attr = ''
|
@@ -749,13 +749,13 @@ class Converter::DocBook5Converter < Converter::Base
|
|
749
749
|
end
|
750
750
|
end
|
751
751
|
|
752
|
-
def
|
752
|
+
def blockquote_tag node, tag_name = nil
|
753
753
|
if tag_name
|
754
754
|
start_tag, end_tag = %(<#{tag_name}), %(</#{tag_name}>)
|
755
755
|
else
|
756
756
|
start_tag, end_tag = '<blockquote', '</blockquote>'
|
757
757
|
end
|
758
|
-
result = [%(#{start_tag}#{
|
758
|
+
result = [%(#{start_tag}#{common_attributes node.id, node.role, node.reftext}>)]
|
759
759
|
result << %(<title>#{node.title}</title>) if node.title?
|
760
760
|
if (node.attr? 'attribution') || (node.attr? 'citetitle')
|
761
761
|
result << '<attribution>'
|
@@ -768,11 +768,11 @@ class Converter::DocBook5Converter < Converter::Base
|
|
768
768
|
result.join LF
|
769
769
|
end
|
770
770
|
|
771
|
-
def
|
772
|
-
(@asciimath_status ||=
|
771
|
+
def asciimath_available?
|
772
|
+
(@asciimath_status ||= load_asciimath) == :loaded
|
773
773
|
end
|
774
774
|
|
775
|
-
def
|
775
|
+
def load_asciimath
|
776
776
|
(defined? ::AsciiMath.parse) ? :loaded : (Helpers.require_library 'asciimath', true, :warn).nil? ? :unavailable : :loaded
|
777
777
|
end
|
778
778
|
end
|