asciidoctor 2.0.0.rc.2 → 2.0.0.rc.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|