asciidoctor 2.0.13 → 2.0.17
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 +151 -30
- data/LICENSE +1 -1
- data/README-de.adoc +9 -12
- data/README-fr.adoc +9 -12
- data/README-jp.adoc +10 -13
- data/README-zh_CN.adoc +9 -12
- data/README.adoc +40 -19
- data/asciidoctor.gemspec +2 -9
- data/data/locale/attributes-fr.adoc +2 -2
- data/data/locale/attributes-th.adoc +23 -0
- data/data/locale/attributes-vi.adoc +23 -0
- data/data/stylesheets/asciidoctor-default.css +54 -53
- data/data/stylesheets/coderay-asciidoctor.css +9 -9
- data/lib/asciidoctor/abstract_block.rb +11 -9
- data/lib/asciidoctor/abstract_node.rb +9 -8
- data/lib/asciidoctor/attribute_list.rb +1 -1
- data/lib/asciidoctor/block.rb +6 -6
- data/lib/asciidoctor/cli/invoker.rb +1 -2
- data/lib/asciidoctor/cli/options.rb +25 -25
- data/lib/asciidoctor/convert.rb +1 -0
- data/lib/asciidoctor/converter/docbook5.rb +45 -26
- data/lib/asciidoctor/converter/html5.rb +130 -102
- data/lib/asciidoctor/converter/manpage.rb +69 -64
- data/lib/asciidoctor/converter/template.rb +12 -13
- data/lib/asciidoctor/converter.rb +6 -4
- data/lib/asciidoctor/core_ext/hash/merge.rb +1 -1
- data/lib/asciidoctor/document.rb +61 -57
- data/lib/asciidoctor/extensions.rb +20 -12
- data/lib/asciidoctor/list.rb +2 -6
- data/lib/asciidoctor/load.rb +11 -9
- data/lib/asciidoctor/logging.rb +10 -8
- data/lib/asciidoctor/parser.rb +177 -193
- data/lib/asciidoctor/path_resolver.rb +3 -3
- data/lib/asciidoctor/reader.rb +73 -72
- data/lib/asciidoctor/rx.rb +5 -4
- data/lib/asciidoctor/section.rb +7 -0
- data/lib/asciidoctor/substitutors.rb +121 -121
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +2 -1
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +1 -1
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +16 -7
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +2 -1
- data/lib/asciidoctor/syntax_highlighter.rb +8 -11
- data/lib/asciidoctor/table.rb +18 -20
- data/lib/asciidoctor/timings.rb +3 -3
- data/lib/asciidoctor/version.rb +1 -1
- data/lib/asciidoctor.rb +10 -10
- data/man/asciidoctor.1 +26 -28
- data/man/asciidoctor.adoc +33 -27
- metadata +8 -62
@@ -1,15 +1,15 @@
|
|
1
|
-
|
1
|
+
/*! Stylesheet for CodeRay to loosely match GitHub themes | MIT License */
|
2
2
|
pre.CodeRay{background:#f7f7f8}
|
3
|
-
.CodeRay .line-numbers{border-right:1px solid
|
3
|
+
.CodeRay .line-numbers{border-right:1px solid;opacity:.35;padding:0 .5em 0 0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
4
4
|
.CodeRay span.line-numbers{display:inline-block;margin-right:.75em}
|
5
5
|
.CodeRay .line-numbers strong{color:#000}
|
6
6
|
table.CodeRay{border-collapse:separate;border:0;margin-bottom:0;background:none}
|
7
7
|
table.CodeRay td{vertical-align:top;line-height:inherit}
|
8
8
|
table.CodeRay td.line-numbers{text-align:right}
|
9
9
|
table.CodeRay td.code{padding:0 0 0 .75em}
|
10
|
-
.CodeRay .debug{color:#fff
|
10
|
+
.CodeRay .debug{color:#fff!important;background:navy!important}
|
11
11
|
.CodeRay .annotation{color:#007}
|
12
|
-
.CodeRay .attribute-name{color
|
12
|
+
.CodeRay .attribute-name{color:navy}
|
13
13
|
.CodeRay .attribute-value{color:#700}
|
14
14
|
.CodeRay .binary{color:#509}
|
15
15
|
.CodeRay .comment{color:#998;font-style:italic}
|
@@ -18,7 +18,7 @@ table.CodeRay td.code{padding:0 0 0 .75em}
|
|
18
18
|
.CodeRay .char .delimiter{color:#039}
|
19
19
|
.CodeRay .class{color:#458;font-weight:bold}
|
20
20
|
.CodeRay .complex{color:#a08}
|
21
|
-
.CodeRay .constant,.CodeRay .predefined-constant{color
|
21
|
+
.CodeRay .constant,.CodeRay .predefined-constant{color:teal}
|
22
22
|
.CodeRay .color{color:#099}
|
23
23
|
.CodeRay .class-variable{color:#369}
|
24
24
|
.CodeRay .decorator{color:#b0b}
|
@@ -33,7 +33,7 @@ table.CodeRay td.code{padding:0 0 0 .75em}
|
|
33
33
|
.CodeRay .exception{color:inherit}
|
34
34
|
.CodeRay .filename{color:#099}
|
35
35
|
.CodeRay .function{color:#900;font-weight:bold}
|
36
|
-
.CodeRay .global-variable{color
|
36
|
+
.CodeRay .global-variable{color:teal}
|
37
37
|
.CodeRay .hex{color:#058}
|
38
38
|
.CodeRay .integer,.CodeRay .float{color:#099}
|
39
39
|
.CodeRay .include{color:#555}
|
@@ -44,7 +44,7 @@ table.CodeRay td.code{padding:0 0 0 .75em}
|
|
44
44
|
.CodeRay .inline-delimiter{color:#d14}
|
45
45
|
.CodeRay .important{color:#555;font-weight:bold}
|
46
46
|
.CodeRay .interpreted{color:#b2b}
|
47
|
-
.CodeRay .instance-variable{color
|
47
|
+
.CodeRay .instance-variable{color:teal}
|
48
48
|
.CodeRay .label{color:#970}
|
49
49
|
.CodeRay .local-variable{color:#963}
|
50
50
|
.CodeRay .octal{color:#40e}
|
@@ -54,7 +54,7 @@ table.CodeRay td.code{padding:0 0 0 .75em}
|
|
54
54
|
.CodeRay .directive{font-weight:bold}
|
55
55
|
.CodeRay .type{font-weight:bold}
|
56
56
|
.CodeRay .predefined-type{color:inherit}
|
57
|
-
.CodeRay .reserved,.CodeRay .keyword
|
57
|
+
.CodeRay .reserved,.CodeRay .keyword{color:#000;font-weight:bold}
|
58
58
|
.CodeRay .key{color:#808}
|
59
59
|
.CodeRay .key .delimiter{color:#606}
|
60
60
|
.CodeRay .key .char{color:#80f}
|
@@ -74,7 +74,7 @@ table.CodeRay td.code{padding:0 0 0 .75em}
|
|
74
74
|
.CodeRay .symbol{color:#990073}
|
75
75
|
.CodeRay .symbol .content{color:#a60}
|
76
76
|
.CodeRay .symbol .delimiter{color:#630}
|
77
|
-
.CodeRay .tag{color
|
77
|
+
.CodeRay .tag{color:teal}
|
78
78
|
.CodeRay .tag-special{color:#d70}
|
79
79
|
.CodeRay .variable{color:#036}
|
80
80
|
.CodeRay .insert{background:#afa}
|
@@ -11,7 +11,7 @@ class AbstractBlock < AbstractNode
|
|
11
11
|
# * :compound - this block contains other blocks
|
12
12
|
# * :simple - this block holds a paragraph of prose that receives normal substitutions
|
13
13
|
# * :verbatim - this block holds verbatim text (displayed "as is") that receives verbatim substitutions
|
14
|
-
# * :raw - this block holds unprocessed content passed directly to the output with no
|
14
|
+
# * :raw - this block holds unprocessed content passed directly to the output with no substitutions applied
|
15
15
|
# * :empty - this block has no content
|
16
16
|
attr_accessor :content_model
|
17
17
|
|
@@ -90,7 +90,7 @@ class AbstractBlock < AbstractNode
|
|
90
90
|
#
|
91
91
|
# context - the context Symbol context to assign to this block
|
92
92
|
#
|
93
|
-
# Returns the
|
93
|
+
# Returns the specified Symbol context
|
94
94
|
def context= context
|
95
95
|
@node_name = (@context = context).to_s
|
96
96
|
end
|
@@ -129,11 +129,13 @@ class AbstractBlock < AbstractNode
|
|
129
129
|
|
130
130
|
# Public: Check whether this block has any child Section objects.
|
131
131
|
#
|
132
|
-
#
|
132
|
+
# Acts an an abstract method that always returns false unless this block is an
|
133
|
+
# instance of Document or Section.
|
134
|
+
# Both Document and Section provide overrides for this method.
|
133
135
|
#
|
134
|
-
# Returns
|
136
|
+
# Returns false
|
135
137
|
def sections?
|
136
|
-
|
138
|
+
false
|
137
139
|
end
|
138
140
|
|
139
141
|
# Deprecated: Legacy property to get the String or Integer numeral of this section.
|
@@ -269,7 +271,7 @@ class AbstractBlock < AbstractNode
|
|
269
271
|
ORDERED_LIST_KEYWORDS[list_type || @style]
|
270
272
|
end
|
271
273
|
|
272
|
-
# Public: Get the String title of this Block with title
|
274
|
+
# Public: Get the String title of this Block with title substitutions applied
|
273
275
|
#
|
274
276
|
# The following substitutions are applied to block and section titles:
|
275
277
|
#
|
@@ -296,7 +298,7 @@ class AbstractBlock < AbstractNode
|
|
296
298
|
|
297
299
|
# Public: Set the String block title.
|
298
300
|
#
|
299
|
-
# Returns the
|
301
|
+
# Returns the specified String title
|
300
302
|
def title= val
|
301
303
|
@converted_title = nil
|
302
304
|
@title = val
|
@@ -480,7 +482,7 @@ class AbstractBlock < AbstractNode
|
|
480
482
|
@header.find_by_internal selector, result, &block
|
481
483
|
end
|
482
484
|
@blocks.each do |b|
|
483
|
-
next if
|
485
|
+
next if context_selector == :section && b.context != :section # optimization
|
484
486
|
b.find_by_internal selector, result, &block
|
485
487
|
end
|
486
488
|
end
|
@@ -505,7 +507,7 @@ class AbstractBlock < AbstractNode
|
|
505
507
|
end
|
506
508
|
else
|
507
509
|
@blocks.each do |b|
|
508
|
-
next if
|
510
|
+
next if context_selector == :section && b.context != :section # optimization
|
509
511
|
b.find_by_internal selector, result, &block
|
510
512
|
end
|
511
513
|
end
|
@@ -4,7 +4,8 @@ module Asciidoctor
|
|
4
4
|
# node of AsciiDoc content. The state and methods on this class are common to
|
5
5
|
# all content segments in an AsciiDoc document.
|
6
6
|
class AbstractNode
|
7
|
-
include
|
7
|
+
include Logging
|
8
|
+
include Substitutors
|
8
9
|
|
9
10
|
# Public: Get the Hash of attributes for this node
|
10
11
|
attr_reader :attributes
|
@@ -65,7 +66,7 @@ class AbstractNode
|
|
65
66
|
#
|
66
67
|
# parent - The Block to set as the parent of this Block
|
67
68
|
#
|
68
|
-
# Returns the
|
69
|
+
# Returns the the specified Block parent
|
69
70
|
def parent= parent
|
70
71
|
@parent, @document = parent, parent.document
|
71
72
|
end
|
@@ -155,7 +156,7 @@ class AbstractNode
|
|
155
156
|
#
|
156
157
|
# name - the String name of the option
|
157
158
|
#
|
158
|
-
# Returns
|
159
|
+
# Returns nothing
|
159
160
|
def set_option name
|
160
161
|
@attributes[%(#{name}-option)] = ''
|
161
162
|
nil
|
@@ -220,7 +221,7 @@ class AbstractNode
|
|
220
221
|
#
|
221
222
|
# names - A single role name, a space-separated String of role names, or an Array of role names
|
222
223
|
#
|
223
|
-
# Returns the
|
224
|
+
# Returns the specified String role name or Array of role names
|
224
225
|
def role= names
|
225
226
|
@attributes['role'] = (::Array === names) ? (names.join ' ') : names
|
226
227
|
end
|
@@ -462,8 +463,8 @@ class AbstractNode
|
|
462
463
|
start = doc.base_dir
|
463
464
|
end
|
464
465
|
else
|
465
|
-
start
|
466
|
-
jail
|
466
|
+
start ||= doc.base_dir
|
467
|
+
jail ||= doc.base_dir
|
467
468
|
end
|
468
469
|
doc.path_resolver.system_path target, start, jail, opts
|
469
470
|
end
|
@@ -542,8 +543,8 @@ class AbstractNode
|
|
542
543
|
rescue
|
543
544
|
logger.warn %(could not retrieve contents of #{opts[:label] || 'asset'} at URI: #{target}) if opts.fetch :warn_on_failure, true
|
544
545
|
end
|
545
|
-
|
546
|
-
logger.warn %(cannot retrieve contents of #{opts[:label] || 'asset'} at URI: #{target} (allow-uri-read attribute not enabled))
|
546
|
+
elsif opts.fetch :warn_on_failure, true
|
547
|
+
logger.warn %(cannot retrieve contents of #{opts[:label] || 'asset'} at URI: #{target} (allow-uri-read attribute not enabled))
|
547
548
|
end
|
548
549
|
else
|
549
550
|
target = normalize_system_path target, opts[:start], nil, target_name: (opts[:label] || 'asset')
|
@@ -173,7 +173,7 @@ class AttributeList
|
|
173
173
|
end
|
174
174
|
else
|
175
175
|
name = @block.apply_subs name if single_quoted && @block
|
176
|
-
if (positional_attr_name = positional_attrs[index])
|
176
|
+
if (positional_attr_name = positional_attrs[index]) && name
|
177
177
|
@attributes[positional_attr_name] = name
|
178
178
|
end
|
179
179
|
# QUESTION should we assign the positional key even when it's claimed by a positional attribute?
|
data/lib/asciidoctor/block.rb
CHANGED
@@ -54,21 +54,21 @@ class Block < AbstractBlock
|
|
54
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
|
+
case subs
|
58
|
+
# e.g., subs: :default
|
58
59
|
# subs attribute is honored; falls back to opts[:default_subs], then built-in defaults based on context
|
59
|
-
|
60
|
+
when :default
|
60
61
|
@default_subs = opts[:default_subs]
|
61
62
|
# e.g., subs: [:quotes]
|
62
63
|
# subs attribute is not honored
|
63
|
-
|
64
|
+
when ::Array
|
64
65
|
@default_subs = subs.drop 0
|
65
66
|
@attributes.delete 'subs'
|
66
67
|
# e.g., subs: :normal or subs: 'normal'
|
67
68
|
# subs attribute is not honored
|
68
69
|
else
|
69
70
|
@default_subs = nil
|
70
|
-
|
71
|
-
@attributes['subs'] = %(#{subs})
|
71
|
+
@attributes['subs'] = subs.to_s
|
72
72
|
end
|
73
73
|
# resolve the subs eagerly only if subs option is specified
|
74
74
|
# QUESTION should we skip subsequent calls to commit_subs?
|
@@ -123,7 +123,7 @@ class Block < AbstractBlock
|
|
123
123
|
result.join LF
|
124
124
|
end
|
125
125
|
else
|
126
|
-
logger.warn %(Unknown content model '#{@content_model}' for block: #{
|
126
|
+
logger.warn %(Unknown content model '#{@content_model}' for block: #{self}) unless @content_model == :empty
|
127
127
|
nil
|
128
128
|
end
|
129
129
|
end
|
@@ -88,7 +88,6 @@ module Asciidoctor
|
|
88
88
|
end
|
89
89
|
|
90
90
|
if outfile == '-'
|
91
|
-
# NOTE set_encoding returns nil on JRuby 9.1
|
92
91
|
(tofile = @out) || ((tofile = $stdout).set_encoding UTF_8)
|
93
92
|
elsif outfile
|
94
93
|
opts[:mkdirs] = true
|
@@ -143,7 +142,7 @@ module Asciidoctor
|
|
143
142
|
raise e
|
144
143
|
else
|
145
144
|
err.puts ::RuntimeError === e ? %(#{e.message} (#{e.class})) : e.message
|
146
|
-
err.puts ' Use --trace
|
145
|
+
err.puts ' Use --trace to show backtrace'
|
147
146
|
end
|
148
147
|
end
|
149
148
|
nil
|
@@ -47,12 +47,12 @@ module Asciidoctor
|
|
47
47
|
EOS
|
48
48
|
|
49
49
|
opts.on('-b', '--backend BACKEND', 'set backend output format: [html5, xhtml5, docbook5, manpage] (default: html5)',
|
50
|
-
|
50
|
+
'additional backends are supported via extended converters (e.g., pdf, epub3)') do |backend|
|
51
51
|
self[:attributes]['backend'] = backend
|
52
52
|
end
|
53
53
|
opts.on('-d', '--doctype DOCTYPE', ['article', 'book', 'manpage', 'inline'],
|
54
|
-
|
55
|
-
self[:attributes]['doctype'] =
|
54
|
+
'document type to use when converting document: [article, book, manpage, inline] (default: article)') do |doctype|
|
55
|
+
self[:attributes]['doctype'] = doctype
|
56
56
|
end
|
57
57
|
opts.on('-e', '--embedded', 'suppress enclosing document structure and output an embedded document (default: false)') do
|
58
58
|
self[:standalone] = false
|
@@ -61,14 +61,14 @@ module Asciidoctor
|
|
61
61
|
self[:output_file] = output_file
|
62
62
|
end
|
63
63
|
opts.on('--safe',
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
'set safe mode level to safe (default: unsafe)',
|
65
|
+
'enables include directives, but prevents access to ancestor paths of source file',
|
66
|
+
'provided for compatibility with the asciidoc command') do
|
67
67
|
self[:safe] = SafeMode::SAFE
|
68
68
|
end
|
69
69
|
opts.on('-S', '--safe-mode SAFE_MODE', (safe_mode_names = SafeMode.names),
|
70
|
-
|
71
|
-
|
70
|
+
%(set safe mode level explicitly: [#{safe_mode_names.join ', '}] (default: unsafe)),
|
71
|
+
'disables potentially dangerous macros in source files, such as include::[]') do |name|
|
72
72
|
self[:safe] = SafeMode.value_for_name name
|
73
73
|
end
|
74
74
|
opts.on('-s', '--no-header-footer', 'suppress enclosing document structure and output an embedded document (default: false)') do
|
@@ -78,19 +78,19 @@ module Asciidoctor
|
|
78
78
|
self[:attributes]['sectnums'] = ''
|
79
79
|
end
|
80
80
|
opts.on('--eruby ERUBY', ['erb', 'erubi', 'erubis'],
|
81
|
-
|
81
|
+
'specify eRuby implementation to use when rendering custom ERB templates: [erb, erubi, erubis] (default: erb)') do |eruby|
|
82
82
|
self[:eruby] = eruby
|
83
83
|
end
|
84
84
|
opts.on('-a', '--attribute name[=value]', 'a document attribute to set in the form of name, name!, or name=value pair',
|
85
|
-
|
86
|
-
|
85
|
+
'this attribute takes precedence over the same attribute defined in the source document',
|
86
|
+
'unless either the name or value ends in @ (i.e., name@=value or name=value@)') do |attr|
|
87
87
|
next if (attr = attr.rstrip).empty? || attr == '='
|
88
88
|
attr = attr.encode UTF_8 unless attr.encoding == UTF_8
|
89
89
|
name, _, val = attr.partition '='
|
90
90
|
self[:attributes][name] = val
|
91
91
|
end
|
92
92
|
opts.on('-T', '--template-dir DIR', 'a directory containing custom converter templates that override the built-in converter (requires tilt gem)',
|
93
|
-
|
93
|
+
'may be specified multiple times') do |template_dir|
|
94
94
|
if self[:template_dirs].nil?
|
95
95
|
self[:template_dirs] = [template_dir]
|
96
96
|
elsif ::Array === self[:template_dirs]
|
@@ -119,23 +119,23 @@ module Asciidoctor
|
|
119
119
|
'may be specified more than once') do |path|
|
120
120
|
(self[:requires] ||= []).concat(path.split ',')
|
121
121
|
end
|
122
|
-
opts.on('--failure-level LEVEL', %w(warning WARNING error ERROR
|
122
|
+
opts.on('--failure-level LEVEL', %w(info INFO warning WARNING error ERROR fatal FATAL), 'set minimum log level that yields a non-zero exit code: [INFO, WARN, ERROR, FATAL] (default: FATAL)') do |level|
|
123
123
|
level = 'WARN' if (level = level.upcase) == 'WARNING'
|
124
|
-
self[:failure_level] = ::Logger::Severity.const_get level
|
124
|
+
self[:failure_level] = ::Logger::Severity.const_get level
|
125
125
|
end
|
126
|
-
opts.on('-q', '--quiet', 'silence application log messages and script warnings (default: false)') do
|
126
|
+
opts.on('-q', '--quiet', 'silence application log messages and script warnings (default: false)') do
|
127
127
|
self[:verbose] = 0
|
128
128
|
end
|
129
|
-
opts.on('--trace', 'include backtrace information when reporting errors (default: false)') do
|
129
|
+
opts.on('--trace', 'include backtrace information when reporting errors (default: false)') do
|
130
130
|
self[:trace] = true
|
131
131
|
end
|
132
|
-
opts.on('-v', '--verbose', 'directs application messages logged at DEBUG or INFO level to STDERR (default: false)') do
|
132
|
+
opts.on('-v', '--verbose', 'directs application messages logged at DEBUG or INFO level to STDERR (default: false)') do
|
133
133
|
self[:verbose] = 2
|
134
134
|
end
|
135
|
-
opts.on('-w', '--warnings', 'turn on script warnings (default: false)') do
|
135
|
+
opts.on('-w', '--warnings', 'turn on script warnings (default: false)') do
|
136
136
|
self[:warnings] = true
|
137
137
|
end
|
138
|
-
opts.on('-t', '--timings', 'print timings report (default: false)') do
|
138
|
+
opts.on('-t', '--timings', 'print timings report (default: false)') do
|
139
139
|
self[:timings] = true
|
140
140
|
end
|
141
141
|
opts.on_tail('-h', '--help [TOPIC]', 'print a help message',
|
@@ -161,7 +161,7 @@ module Asciidoctor
|
|
161
161
|
elsif ::File.exist? (manpage_path = (::File.join ROOT_DIR, 'man', 'asciidoctor.1'))
|
162
162
|
$stdout.puts ::File.read manpage_path
|
163
163
|
else
|
164
|
-
manpage_path =
|
164
|
+
manpage_path = %x(man -w asciidoctor).chop rescue ''
|
165
165
|
if manpage_path.empty?
|
166
166
|
$stderr.puts 'asciidoctor: FAILED: manual page not found; try `man asciidoctor`'
|
167
167
|
return 1
|
@@ -249,7 +249,7 @@ module Asciidoctor
|
|
249
249
|
|
250
250
|
self[:input_files] = infiles
|
251
251
|
|
252
|
-
|
252
|
+
delete :attributes if self[:attributes].empty?
|
253
253
|
|
254
254
|
if self[:template_dirs]
|
255
255
|
begin
|
@@ -258,7 +258,7 @@ module Asciidoctor
|
|
258
258
|
raise $! if self[:trace]
|
259
259
|
$stderr.puts 'asciidoctor: FAILED: \'tilt\' could not be loaded'
|
260
260
|
$stderr.puts ' You must have the tilt gem installed (gem install tilt) to use custom backend templates'
|
261
|
-
$stderr.puts ' Use --trace
|
261
|
+
$stderr.puts ' Use --trace to show backtrace'
|
262
262
|
return 1
|
263
263
|
rescue ::SystemExit
|
264
264
|
# not permitted here
|
@@ -278,7 +278,7 @@ module Asciidoctor
|
|
278
278
|
rescue ::LoadError
|
279
279
|
raise $! if self[:trace]
|
280
280
|
$stderr.puts %(asciidoctor: FAILED: '#{path}' could not be loaded)
|
281
|
-
$stderr.puts ' Use --trace
|
281
|
+
$stderr.puts ' Use --trace to show backtrace'
|
282
282
|
return 1
|
283
283
|
rescue ::SystemExit
|
284
284
|
# not permitted here
|
@@ -290,11 +290,11 @@ module Asciidoctor
|
|
290
290
|
rescue ::OptionParser::MissingArgument
|
291
291
|
$stderr.puts %(asciidoctor: option #{$!.message})
|
292
292
|
$stdout.puts opts_parser
|
293
|
-
|
293
|
+
1
|
294
294
|
rescue ::OptionParser::InvalidOption, ::OptionParser::InvalidArgument
|
295
295
|
$stderr.puts %(asciidoctor: #{$!.message})
|
296
296
|
$stdout.puts opts_parser
|
297
|
-
|
297
|
+
1
|
298
298
|
ensure
|
299
299
|
$VERBOSE = old_verbose
|
300
300
|
end
|
data/lib/asciidoctor/convert.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
3
|
# A built-in {Converter} implementation that generates DocBook 5 output. The output is inspired by the output produced
|
4
|
-
# by the docbook45 backend from AsciiDoc
|
4
|
+
# by the docbook45 backend from AsciiDoc.py, except it has been migrated to the DocBook 5 specification.
|
5
5
|
class Converter::DocBook5Converter < Converter::Base
|
6
6
|
register_for 'docbook5'
|
7
7
|
|
8
8
|
# default represents variablelist
|
9
9
|
(DLIST_TAGS = {
|
10
|
-
'qanda' => { list:
|
11
|
-
'glossary' => { list:
|
12
|
-
}).default = { list:
|
10
|
+
'qanda' => { list: 'qandaset', entry: 'qandaentry', label: 'question', term: 'simpara', item: 'answer' },
|
11
|
+
'glossary' => { list: nil, entry: 'glossentry', term: 'glossterm', item: 'glossdef' },
|
12
|
+
}).default = { list: 'variablelist', entry: 'varlistentry', term: 'term', item: 'listitem' }
|
13
13
|
|
14
14
|
(QUOTE_TAGS = {
|
15
15
|
monospaced: ['<literal>', '</literal>'],
|
@@ -25,7 +25,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
25
25
|
MANPAGE_SECTION_TAGS = { 'section' => 'refsection', 'synopsis' => 'refsynopsisdiv' }
|
26
26
|
TABLE_PI_NAMES = ['dbhtml', 'dbfo', 'dblatex']
|
27
27
|
|
28
|
-
CopyrightRx = /^(#{CC_ANY}+?)(?: ((?:\d{4}
|
28
|
+
CopyrightRx = /^(#{CC_ANY}+?)(?: ((?:\d{4}-)?\d{4}))?$/
|
29
29
|
ImageMacroRx = /^image::?(\S|\S#{CC_ANY}*?\S)\[(#{CC_ANY}+)?\]$/
|
30
30
|
|
31
31
|
def initialize backend, opts = {}
|
@@ -41,7 +41,8 @@ class Converter::DocBook5Converter < Converter::Base
|
|
41
41
|
if (root_tag_name = node.doctype) == 'manpage'
|
42
42
|
root_tag_name = 'refentry'
|
43
43
|
end
|
44
|
-
|
44
|
+
root_tag_idx = result.size
|
45
|
+
id = node.id
|
45
46
|
result << (document_info_tag node) unless node.noheader
|
46
47
|
unless (docinfo_content = node.docinfo :header).empty?
|
47
48
|
result << docinfo_content
|
@@ -50,6 +51,9 @@ class Converter::DocBook5Converter < Converter::Base
|
|
50
51
|
unless (docinfo_content = node.docinfo :footer).empty?
|
51
52
|
result << docinfo_content
|
52
53
|
end
|
54
|
+
id, node.id = node.id, nil unless id
|
55
|
+
# defer adding root tag in case document ID is auto-generated on demand
|
56
|
+
result.insert root_tag_idx, %(<#{root_tag_name} xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0"#{lang_attribute}#{common_attributes id}>)
|
53
57
|
result << %(</#{root_tag_name}>)
|
54
58
|
result.join LF
|
55
59
|
end
|
@@ -298,13 +302,13 @@ class Converter::DocBook5Converter < Converter::Base
|
|
298
302
|
</abstract>)
|
299
303
|
end
|
300
304
|
when 'partintro'
|
301
|
-
|
302
|
-
logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
303
|
-
''
|
304
|
-
else
|
305
|
+
if node.level == 0 && node.parent.context == :section && node.document.doctype == 'book'
|
305
306
|
%(<partintro#{common_attributes node.id, node.role, node.reftext}>
|
306
307
|
#{title_tag node}#{enclose_content node}
|
307
308
|
</partintro>)
|
309
|
+
else
|
310
|
+
logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
311
|
+
''
|
308
312
|
end
|
309
313
|
else
|
310
314
|
reftext = node.reftext if (id = node.id)
|
@@ -374,19 +378,19 @@ class Converter::DocBook5Converter < Converter::Base
|
|
374
378
|
frame = 'topbot' if (frame = node.attr 'frame', 'all', 'table-frame') == 'ends'
|
375
379
|
grid = node.attr 'grid', nil, 'table-grid'
|
376
380
|
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"' : ''}>)
|
377
|
-
if
|
381
|
+
if node.option? 'unbreakable'
|
378
382
|
result << '<?dbfo keep-together="always"?>'
|
379
|
-
elsif
|
383
|
+
elsif node.option? 'breakable'
|
380
384
|
result << '<?dbfo keep-together="auto"?>'
|
381
385
|
end
|
382
386
|
result << %(<title>#{node.title}</title>) if tag_name == 'table'
|
383
|
-
|
387
|
+
if (width = (node.attr? 'width') ? (node.attr 'width') : nil)
|
384
388
|
TABLE_PI_NAMES.each do |pi_name|
|
385
389
|
result << %(<?#{pi_name} table-width="#{width}"?>)
|
386
390
|
end
|
387
|
-
'colabswidth'
|
391
|
+
col_width_key = 'colabswidth'
|
388
392
|
else
|
389
|
-
'colpcwidth'
|
393
|
+
col_width_key = 'colpcwidth'
|
390
394
|
end
|
391
395
|
result << %(<tgroup cols="#{node.attr 'colcount'}">)
|
392
396
|
node.columns.each do |col|
|
@@ -474,10 +478,16 @@ class Converter::DocBook5Converter < Converter::Base
|
|
474
478
|
%(<anchor#{common_attributes((id = node.id), nil, node.reftext || %([#{id}]))}/>)
|
475
479
|
when :xref
|
476
480
|
if (path = node.attributes['path'])
|
477
|
-
# QUESTION should we use refid as fallback text instead? (like the html5 backend?)
|
478
481
|
%(<link xl:href="#{node.target}">#{node.text || path}</link>)
|
479
482
|
else
|
480
|
-
linkend = node.attributes['
|
483
|
+
if (linkend = node.attributes['refid']).nil_or_empty?
|
484
|
+
root_doc = get_root_document node
|
485
|
+
# Q: should we warn instead of generating a document ID on demand?
|
486
|
+
linkend = (root_doc.id ||= generate_document_id root_doc)
|
487
|
+
end
|
488
|
+
# NOTE the xref tag in DocBook does not support explicit link text, so the link tag must be used instead
|
489
|
+
# The section at http://www.sagehill.net/docbookxsl/CrossRefs.html#IdrefLinks gives an explanation for this choice
|
490
|
+
# "link - a cross reference where you supply the text of the reference as the content of the link element."
|
481
491
|
(text = node.text) ? %(<link linkend="#{linkend}">#{text}</link>) : %(<xref linkend="#{linkend}"/>)
|
482
492
|
end
|
483
493
|
when :link
|
@@ -533,9 +543,8 @@ class Converter::DocBook5Converter < Converter::Base
|
|
533
543
|
%(<indexterm>
|
534
544
|
<primary>#{node.text}</primary>#{rel}
|
535
545
|
</indexterm>#{node.text})
|
536
|
-
|
537
|
-
|
538
|
-
%(<indexterm>
|
546
|
+
elsif (numterms = (terms = node.attr 'terms').size) > 2
|
547
|
+
%(<indexterm>
|
539
548
|
<primary>#{terms[0]}</primary><secondary>#{terms[1]}</secondary><tertiary>#{terms[2]}</tertiary>#{rel}
|
540
549
|
</indexterm>#{(node.document.option? 'indexterm-promotion') ? %[
|
541
550
|
<indexterm>
|
@@ -544,18 +553,17 @@ class Converter::DocBook5Converter < Converter::Base
|
|
544
553
|
<indexterm>
|
545
554
|
<primary>#{terms[2]}</primary>
|
546
555
|
</indexterm>] : ''})
|
547
|
-
|
548
|
-
|
556
|
+
elsif numterms > 1
|
557
|
+
%(<indexterm>
|
549
558
|
<primary>#{terms[0]}</primary><secondary>#{terms[1]}</secondary>#{rel}
|
550
|
-
</indexterm>#{(node.document.option?
|
559
|
+
</indexterm>#{(node.document.option? 'indexterm-promotion') ? %[
|
551
560
|
<indexterm>
|
552
561
|
<primary>#{terms[1]}</primary>
|
553
562
|
</indexterm>] : ''})
|
554
|
-
|
555
|
-
|
563
|
+
else
|
564
|
+
%(<indexterm>
|
556
565
|
<primary>#{terms[0]}</primary>#{rel}
|
557
566
|
</indexterm>)
|
558
|
-
end
|
559
567
|
end
|
560
568
|
end
|
561
569
|
|
@@ -710,6 +718,17 @@ class Converter::DocBook5Converter < Converter::Base
|
|
710
718
|
result.join LF
|
711
719
|
end
|
712
720
|
|
721
|
+
def get_root_document node
|
722
|
+
while (node = node.document).nested?
|
723
|
+
node = node.parent_document
|
724
|
+
end
|
725
|
+
node
|
726
|
+
end
|
727
|
+
|
728
|
+
def generate_document_id doc
|
729
|
+
%(__#{doc.doctype}-root__)
|
730
|
+
end
|
731
|
+
|
713
732
|
# FIXME this should be handled through a template mechanism
|
714
733
|
def enclose_content node
|
715
734
|
node.content_model == :compound ? node.content : %(<simpara>#{node.content}</simpara>)
|