asciidoctor 2.0.15 → 2.0.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +38 -2
- data/LICENSE +1 -1
- data/README-de.adoc +3 -3
- data/README-fr.adoc +3 -3
- data/README-jp.adoc +3 -3
- data/README-zh_CN.adoc +3 -3
- data/README.adoc +2 -2
- data/asciidoctor.gemspec +1 -8
- data/data/locale/attributes-th.adoc +23 -0
- data/data/locale/attributes-vi.adoc +23 -0
- data/data/stylesheets/asciidoctor-default.css +50 -48
- data/lib/asciidoctor.rb +7 -7
- data/lib/asciidoctor/abstract_block.rb +4 -4
- data/lib/asciidoctor/abstract_node.rb +9 -8
- data/lib/asciidoctor/block.rb +6 -6
- data/lib/asciidoctor/cli/invoker.rb +0 -1
- data/lib/asciidoctor/cli/options.rb +22 -22
- data/lib/asciidoctor/convert.rb +1 -0
- data/lib/asciidoctor/converter.rb +5 -3
- data/lib/asciidoctor/converter/docbook5.rb +20 -22
- data/lib/asciidoctor/converter/html5.rb +70 -60
- data/lib/asciidoctor/converter/manpage.rb +61 -52
- data/lib/asciidoctor/converter/template.rb +11 -12
- data/lib/asciidoctor/document.rb +22 -37
- data/lib/asciidoctor/extensions.rb +10 -10
- data/lib/asciidoctor/list.rb +2 -6
- data/lib/asciidoctor/load.rb +10 -9
- data/lib/asciidoctor/logging.rb +10 -8
- data/lib/asciidoctor/parser.rb +122 -141
- data/lib/asciidoctor/path_resolver.rb +3 -3
- data/lib/asciidoctor/reader.rb +67 -68
- data/lib/asciidoctor/rx.rb +2 -1
- data/lib/asciidoctor/substitutors.rb +97 -99
- data/lib/asciidoctor/syntax_highlighter.rb +8 -11
- 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 +2 -1
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +2 -1
- data/lib/asciidoctor/table.rb +17 -19
- data/lib/asciidoctor/timings.rb +3 -3
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +8 -9
- data/man/asciidoctor.adoc +7 -6
- metadata +7 -61
data/lib/asciidoctor.rb
CHANGED
@@ -53,12 +53,12 @@ module Asciidoctor
|
|
53
53
|
module SafeMode
|
54
54
|
# A safe mode level that disables any of the security features enforced
|
55
55
|
# by Asciidoctor (Ruby is still subject to its own restrictions).
|
56
|
-
UNSAFE = 0
|
56
|
+
UNSAFE = 0
|
57
57
|
|
58
58
|
# A safe mode level that closely parallels safe mode in AsciiDoc. This value
|
59
59
|
# prevents access to files which reside outside of the parent directory of
|
60
60
|
# the source file and disables any macro other than the include::[] directive.
|
61
|
-
SAFE = 1
|
61
|
+
SAFE = 1
|
62
62
|
|
63
63
|
# A safe mode level that disallows the document from setting attributes
|
64
64
|
# that would affect the conversion of the document, in addition to all the
|
@@ -66,19 +66,19 @@ module Asciidoctor
|
|
66
66
|
# changing the backend or source-highlighter using an attribute defined
|
67
67
|
# in the source document header. This is the most fundamental level of
|
68
68
|
# security for server deployments (hence the name).
|
69
|
-
SERVER = 10
|
69
|
+
SERVER = 10
|
70
70
|
|
71
71
|
# A safe mode level that disallows the document from attempting to read
|
72
72
|
# files from the file system and including the contents of them into the
|
73
73
|
# document, in additional to all the security features of SafeMode::SERVER.
|
74
74
|
# For instance, this level disallows use of the include::[] directive and the
|
75
75
|
# embedding of binary content (data uri), stylesheets and JavaScripts
|
76
|
-
# referenced by the document.(Asciidoctor and trusted extensions may still
|
76
|
+
# referenced by the document. (Asciidoctor and trusted extensions may still
|
77
77
|
# be allowed to embed trusted content into the document).
|
78
78
|
#
|
79
79
|
# Since Asciidoctor is aiming for wide adoption, this level is the default
|
80
80
|
# and is recommended for server deployments.
|
81
|
-
SECURE = 20
|
81
|
+
SECURE = 20
|
82
82
|
|
83
83
|
# A planned safe mode level that disallows the use of passthrough macros and
|
84
84
|
# prevents the document from setting any known attributes, in addition to all
|
@@ -86,9 +86,9 @@ module Asciidoctor
|
|
86
86
|
#
|
87
87
|
# Please note that this level is not currently implemented (and therefore not
|
88
88
|
# enforced)!
|
89
|
-
#PARANOID = 100
|
89
|
+
#PARANOID = 100
|
90
90
|
|
91
|
-
@names_by_value =
|
91
|
+
@names_by_value = (constants false).map {|sym| [(const_get sym), sym.to_s.downcase] }.sort {|(a), (b)| a <=> b }.to_h
|
92
92
|
|
93
93
|
def self.value_for_name name
|
94
94
|
const_get name.upcase, false
|
@@ -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
|
@@ -296,7 +296,7 @@ class AbstractBlock < AbstractNode
|
|
296
296
|
|
297
297
|
# Public: Set the String block title.
|
298
298
|
#
|
299
|
-
# Returns the
|
299
|
+
# Returns the specified String title
|
300
300
|
def title= val
|
301
301
|
@converted_title = nil
|
302
302
|
@title = val
|
@@ -480,7 +480,7 @@ class AbstractBlock < AbstractNode
|
|
480
480
|
@header.find_by_internal selector, result, &block
|
481
481
|
end
|
482
482
|
@blocks.each do |b|
|
483
|
-
next if
|
483
|
+
next if context_selector == :section && b.context != :section # optimization
|
484
484
|
b.find_by_internal selector, result, &block
|
485
485
|
end
|
486
486
|
end
|
@@ -505,7 +505,7 @@ class AbstractBlock < AbstractNode
|
|
505
505
|
end
|
506
506
|
else
|
507
507
|
@blocks.each do |b|
|
508
|
-
next if
|
508
|
+
next if context_selector == :section && b.context != :section # optimization
|
509
509
|
b.find_by_internal selector, result, &block
|
510
510
|
end
|
511
511
|
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')
|
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
|
@@ -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]
|
@@ -121,21 +121,21 @@ module Asciidoctor
|
|
121
121
|
end
|
122
122
|
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|
|
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
|
@@ -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
@@ -366,15 +366,17 @@ module Converter
|
|
366
366
|
# into - The Class into which the {Converter} module is being included.
|
367
367
|
#
|
368
368
|
# Returns nothing.
|
369
|
-
|
369
|
+
def self.included into
|
370
370
|
into.send :include, BackendTraits
|
371
371
|
into.extend Config
|
372
|
-
end
|
372
|
+
end
|
373
|
+
private_class_method :included # use separate declaration for Ruby 2.0.x
|
373
374
|
|
374
375
|
# An abstract base class for defining converters that can be used to convert {AbstractNode} objects in a parsed
|
375
376
|
# AsciiDoc document to a backend format such as HTML or DocBook.
|
376
377
|
class Base
|
377
|
-
include
|
378
|
+
include Logging
|
379
|
+
include Converter
|
378
380
|
|
379
381
|
# Public: Converts an {AbstractNode} by delegating to a method that matches the transform value.
|
380
382
|
#
|
@@ -7,9 +7,9 @@ class Converter::DocBook5Converter < Converter::Base
|
|
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 = {}
|
@@ -302,13 +302,13 @@ class Converter::DocBook5Converter < Converter::Base
|
|
302
302
|
</abstract>)
|
303
303
|
end
|
304
304
|
when 'partintro'
|
305
|
-
|
306
|
-
logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
307
|
-
''
|
308
|
-
else
|
305
|
+
if node.level == 0 && node.parent.context == :section && node.document.doctype == 'book'
|
309
306
|
%(<partintro#{common_attributes node.id, node.role, node.reftext}>
|
310
307
|
#{title_tag node}#{enclose_content node}
|
311
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
|
+
''
|
312
312
|
end
|
313
313
|
else
|
314
314
|
reftext = node.reftext if (id = node.id)
|
@@ -378,19 +378,19 @@ class Converter::DocBook5Converter < Converter::Base
|
|
378
378
|
frame = 'topbot' if (frame = node.attr 'frame', 'all', 'table-frame') == 'ends'
|
379
379
|
grid = node.attr 'grid', nil, 'table-grid'
|
380
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"' : ''}>)
|
381
|
-
if
|
381
|
+
if node.option? 'unbreakable'
|
382
382
|
result << '<?dbfo keep-together="always"?>'
|
383
|
-
elsif
|
383
|
+
elsif node.option? 'breakable'
|
384
384
|
result << '<?dbfo keep-together="auto"?>'
|
385
385
|
end
|
386
386
|
result << %(<title>#{node.title}</title>) if tag_name == 'table'
|
387
|
-
|
387
|
+
if (width = (node.attr? 'width') ? (node.attr 'width') : nil)
|
388
388
|
TABLE_PI_NAMES.each do |pi_name|
|
389
389
|
result << %(<?#{pi_name} table-width="#{width}"?>)
|
390
390
|
end
|
391
|
-
'colabswidth'
|
391
|
+
col_width_key = 'colabswidth'
|
392
392
|
else
|
393
|
-
'colpcwidth'
|
393
|
+
col_width_key = 'colpcwidth'
|
394
394
|
end
|
395
395
|
result << %(<tgroup cols="#{node.attr 'colcount'}">)
|
396
396
|
node.columns.each do |col|
|
@@ -543,9 +543,8 @@ class Converter::DocBook5Converter < Converter::Base
|
|
543
543
|
%(<indexterm>
|
544
544
|
<primary>#{node.text}</primary>#{rel}
|
545
545
|
</indexterm>#{node.text})
|
546
|
-
|
547
|
-
|
548
|
-
%(<indexterm>
|
546
|
+
elsif (numterms = (terms = node.attr 'terms').size) > 2
|
547
|
+
%(<indexterm>
|
549
548
|
<primary>#{terms[0]}</primary><secondary>#{terms[1]}</secondary><tertiary>#{terms[2]}</tertiary>#{rel}
|
550
549
|
</indexterm>#{(node.document.option? 'indexterm-promotion') ? %[
|
551
550
|
<indexterm>
|
@@ -554,18 +553,17 @@ class Converter::DocBook5Converter < Converter::Base
|
|
554
553
|
<indexterm>
|
555
554
|
<primary>#{terms[2]}</primary>
|
556
555
|
</indexterm>] : ''})
|
557
|
-
|
558
|
-
|
556
|
+
elsif numterms > 1
|
557
|
+
%(<indexterm>
|
559
558
|
<primary>#{terms[0]}</primary><secondary>#{terms[1]}</secondary>#{rel}
|
560
|
-
</indexterm>#{(node.document.option?
|
559
|
+
</indexterm>#{(node.document.option? 'indexterm-promotion') ? %[
|
561
560
|
<indexterm>
|
562
561
|
<primary>#{terms[1]}</primary>
|
563
562
|
</indexterm>] : ''})
|
564
|
-
|
565
|
-
|
563
|
+
else
|
564
|
+
%(<indexterm>
|
566
565
|
<primary>#{terms[0]}</primary>#{rel}
|
567
566
|
</indexterm>)
|
568
|
-
end
|
569
567
|
end
|
570
568
|
end
|
571
569
|
|
@@ -21,7 +21,7 @@ class Converter::Html5Converter < Converter::Base
|
|
21
21
|
#latexmath: INLINE_MATH_DELIMITERS[:latexmath] + [false],
|
22
22
|
}).default = ['', '']
|
23
23
|
|
24
|
-
DropAnchorRx =
|
24
|
+
DropAnchorRx = %r(<(?:a\b[^>]*|/a)>)
|
25
25
|
StemBreakRx = / *\\\n(?:\\?\n)*|\n\n+/
|
26
26
|
if RUBY_ENGINE == 'opal'
|
27
27
|
# NOTE In JavaScript, ^ matches the start of the string when the m flag is not set
|
@@ -48,44 +48,45 @@ class Converter::Html5Converter < Converter::Base
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def convert node, transform = node.node_name, opts = nil
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
51
|
+
case transform
|
52
|
+
when 'inline_quoted' then convert_inline_quoted node
|
53
|
+
when 'paragraph' then convert_paragraph node
|
54
|
+
when 'inline_anchor' then convert_inline_anchor node
|
55
|
+
when 'section' then convert_section node
|
56
|
+
when 'listing' then convert_listing node
|
57
|
+
when 'literal' then convert_literal node
|
58
|
+
when 'ulist' then convert_ulist node
|
59
|
+
when 'olist' then convert_olist node
|
60
|
+
when 'dlist' then convert_dlist node
|
61
|
+
when 'admonition' then convert_admonition node
|
62
|
+
when 'colist' then convert_colist node
|
63
|
+
when 'embedded' then convert_embedded node
|
64
|
+
when 'example' then convert_example node
|
65
|
+
when 'floating_title' then convert_floating_title node
|
66
|
+
when 'image' then convert_image node
|
67
|
+
when 'inline_break' then convert_inline_break node
|
68
|
+
when 'inline_button' then convert_inline_button node
|
69
|
+
when 'inline_callout' then convert_inline_callout node
|
70
|
+
when 'inline_footnote' then convert_inline_footnote node
|
71
|
+
when 'inline_image' then convert_inline_image node
|
72
|
+
when 'inline_indexterm' then convert_inline_indexterm node
|
73
|
+
when 'inline_kbd' then convert_inline_kbd node
|
74
|
+
when 'inline_menu' then convert_inline_menu node
|
75
|
+
when 'open' then convert_open node
|
76
|
+
when 'page_break' then convert_page_break node
|
77
|
+
when 'preamble' then convert_preamble node
|
78
|
+
when 'quote' then convert_quote node
|
79
|
+
when 'sidebar' then convert_sidebar node
|
80
|
+
when 'stem' then convert_stem node
|
81
|
+
when 'table' then convert_table node
|
82
|
+
when 'thematic_break' then convert_thematic_break node
|
83
|
+
when 'verse' then convert_verse node
|
84
|
+
when 'video' then convert_video node
|
85
|
+
when 'document' then convert_document node
|
86
|
+
when 'toc' then convert_toc node
|
87
|
+
when 'pass' then convert_pass node
|
88
|
+
when 'audio' then convert_audio node
|
89
|
+
else; super
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
@@ -350,9 +351,10 @@ MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
|
|
350
351
|
stitle = section.captioned_title
|
351
352
|
elsif section.numbered && slevel <= sectnumlevels
|
352
353
|
if slevel < 2 && node.document.doctype == 'book'
|
353
|
-
|
354
|
+
case section.sectname
|
355
|
+
when 'chapter'
|
354
356
|
stitle = %(#{(signifier = node.document.attributes['chapter-signifier']) ? "#{signifier} " : ''}#{section.sectnum} #{section.title})
|
355
|
-
|
357
|
+
when 'part'
|
356
358
|
stitle = %(#{(signifier = node.document.attributes['part-signifier']) ? "#{signifier} " : ''}#{section.sectnum nil, ':'} #{section.title})
|
357
359
|
else
|
358
360
|
stitle = %(#{section.sectnum} #{section.title})
|
@@ -383,9 +385,10 @@ MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
|
|
383
385
|
title = node.captioned_title
|
384
386
|
elsif node.numbered && level <= (doc_attrs['sectnumlevels'] || 3).to_i
|
385
387
|
if level < 2 && node.document.doctype == 'book'
|
386
|
-
|
388
|
+
case node.sectname
|
389
|
+
when 'chapter'
|
387
390
|
title = %(#{(signifier = doc_attrs['chapter-signifier']) ? "#{signifier} " : ''}#{node.sectnum} #{node.title})
|
388
|
-
|
391
|
+
when 'part'
|
389
392
|
title = %(#{(signifier = doc_attrs['part-signifier']) ? "#{signifier} " : ''}#{node.sectnum nil, ':'} #{node.title})
|
390
393
|
else
|
391
394
|
title = %(#{node.sectnum} #{node.title})
|
@@ -513,16 +516,16 @@ Your browser does not support the audio tag.
|
|
513
516
|
result = []
|
514
517
|
id_attribute = node.id ? %( id="#{node.id}") : ''
|
515
518
|
|
516
|
-
|
519
|
+
case node.style
|
517
520
|
when 'qanda'
|
518
|
-
['qlist', 'qanda', node.role]
|
521
|
+
classes = ['qlist', 'qanda', node.role]
|
519
522
|
when 'horizontal'
|
520
|
-
['hdlist', node.role]
|
523
|
+
classes = ['hdlist', node.role]
|
521
524
|
else
|
522
|
-
['dlist', node.style, node.role]
|
523
|
-
end
|
525
|
+
classes = ['dlist', node.style, node.role]
|
526
|
+
end
|
524
527
|
|
525
|
-
class_attribute = %( class="#{classes.join ' '}")
|
528
|
+
class_attribute = %( class="#{classes.compact.join ' '}")
|
526
529
|
|
527
530
|
result << %(<div#{id_attribute}#{class_attribute}>)
|
528
531
|
result << %(<div class="title">#{node.title}</div>) if node.title?
|
@@ -578,12 +581,11 @@ Your browser does not support the audio tag.
|
|
578
581
|
terms.each do |dt|
|
579
582
|
result << %(<dt#{dt_style_attribute}>#{dt.text}</dt>)
|
580
583
|
end
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
end
|
584
|
+
next unless dd
|
585
|
+
result << '<dd>'
|
586
|
+
result << %(<p>#{dd.text}</p>) if dd.text?
|
587
|
+
result << dd.content if dd.blocks?
|
588
|
+
result << '</dd>'
|
587
589
|
end
|
588
590
|
result << '</dl>'
|
589
591
|
end
|
@@ -759,8 +761,8 @@ Your browser does not support the audio tag.
|
|
759
761
|
logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
760
762
|
''
|
761
763
|
else
|
762
|
-
|
763
|
-
|
764
|
+
id_attr = node.id ? %( id="#{node.id}") : ''
|
765
|
+
title_el = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
|
764
766
|
%(<div#{id_attr} class="openblock#{style && style != 'open' ? " #{style}" : ''}#{(role = node.role) ? " #{role}" : ''}">
|
765
767
|
#{title_el}<div class="content">
|
766
768
|
#{node.content}
|
@@ -1189,7 +1191,11 @@ Your browser does not support the video tag.
|
|
1189
1191
|
img = %([#{node.alt}])
|
1190
1192
|
else
|
1191
1193
|
target = node.target
|
1192
|
-
attrs = [
|
1194
|
+
attrs = []
|
1195
|
+
attrs << %( width="#{node.attr 'width'}") if node.attr? 'width'
|
1196
|
+
attrs << %( height="#{node.attr 'height'}") if node.attr? 'height'
|
1197
|
+
attrs << %( title="#{node.attr 'title'}") if node.attr? 'title'
|
1198
|
+
attrs = attrs.empty? ? '' : attrs.join
|
1193
1199
|
if type != 'icon' && ((node.attr? 'format', 'svg') || (target.include? '.svg')) &&
|
1194
1200
|
node.document.safe < SafeMode::SECURE && ((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
|
1195
1201
|
if svg
|
@@ -1325,8 +1331,12 @@ Your browser does not support the video tag.
|
|
1325
1331
|
end
|
1326
1332
|
|
1327
1333
|
# NOTE adapt to older converters that relied on unprefixed method names
|
1328
|
-
def method_missing id, *
|
1329
|
-
!((name = id.to_s).start_with? 'convert_') && (handles? name) ? (send %(convert_#{name}), *
|
1334
|
+
def method_missing id, *args
|
1335
|
+
!((name = id.to_s).start_with? 'convert_') && (handles? name) ? (send %(convert_#{name}), *args) : super
|
1336
|
+
end
|
1337
|
+
|
1338
|
+
def respond_to_missing? id, *options
|
1339
|
+
!((name = id.to_s).start_with? 'convert_') && (handles? name)
|
1330
1340
|
end
|
1331
1341
|
end
|
1332
1342
|
end
|