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
@@ -40,13 +40,13 @@ class Converter::TemplateConverter < Converter::Base
|
|
40
40
|
@caches = { scans: {}, templates: {} }
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
43
|
+
class << self
|
44
|
+
attr_reader :caches
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
def clear_caches
|
47
|
+
@caches[:scans].clear
|
48
|
+
@caches[:templates].clear
|
49
|
+
end
|
50
50
|
end
|
51
51
|
|
52
52
|
def initialize backend, template_dirs, opts = {}
|
@@ -134,12 +134,10 @@ class Converter::TemplateConverter < Converter::Base
|
|
134
134
|
#
|
135
135
|
# Returns the Tilt template object
|
136
136
|
def register name, template
|
137
|
-
|
137
|
+
if (template_cache = @caches[:templates])
|
138
138
|
template_cache[template.file] = template
|
139
|
-
else
|
140
|
-
template
|
141
139
|
end
|
142
|
-
|
140
|
+
@templates[name] = template
|
143
141
|
end
|
144
142
|
|
145
143
|
private
|
@@ -155,6 +153,7 @@ class Converter::TemplateConverter < Converter::Base
|
|
155
153
|
engine = @engine
|
156
154
|
@template_dirs.each do |template_dir|
|
157
155
|
# FIXME need to think about safe mode restrictions here
|
156
|
+
# Ruby 2.3 requires the extra brackets around the path_resolver.system_path method call
|
158
157
|
next unless ::File.directory?(template_dir = (path_resolver.system_path template_dir))
|
159
158
|
|
160
159
|
if engine
|
@@ -186,8 +185,8 @@ class Converter::TemplateConverter < Converter::Base
|
|
186
185
|
else
|
187
186
|
@templates.update scan_dir(template_dir, pattern, @caches[:templates])
|
188
187
|
end
|
189
|
-
nil
|
190
188
|
end
|
189
|
+
nil
|
191
190
|
end
|
192
191
|
|
193
192
|
# Internal: Scan the specified directory for template files matching pattern and instantiate
|
@@ -197,7 +196,7 @@ class Converter::TemplateConverter < Converter::Base
|
|
197
196
|
def scan_dir template_dir, pattern, template_cache = nil
|
198
197
|
result, helpers = {}, nil
|
199
198
|
# Grab the files in the top level of the directory (do not recurse)
|
200
|
-
::Dir.glob(pattern).
|
199
|
+
::Dir.glob(pattern).keep_if {|match| ::File.file? match }.each do |file|
|
201
200
|
if (basename = ::File.basename file) == 'helpers.rb'
|
202
201
|
helpers = file
|
203
202
|
next
|
@@ -262,7 +261,7 @@ class Converter::TemplateConverter < Converter::Base
|
|
262
261
|
[::Tilt::ErubiTemplate, {}]
|
263
262
|
elsif name == 'erubis'
|
264
263
|
Helpers.require_library 'erubis' unless defined? ::Erubis::FastEruby
|
265
|
-
[::Tilt::ErubisTemplate,
|
264
|
+
[::Tilt::ErubisTemplate, engine_class: ::Erubis::FastEruby]
|
266
265
|
else
|
267
266
|
raise ::ArgumentError, %(Unknown ERB implementation: #{name})
|
268
267
|
end
|
@@ -42,7 +42,7 @@ module Asciidoctor
|
|
42
42
|
# puts Asciidoctor.convert_file 'sample.adoc', safe: :safe
|
43
43
|
module Converter
|
44
44
|
autoload :CompositeConverter, %(#{__dir__}/converter/composite)
|
45
|
-
autoload :TemplateConverter, %(#{__dir__}/converter/template)
|
45
|
+
autoload :TemplateConverter, %(#{__dir__}/converter/template) unless RUBY_ENGINE == 'opal'
|
46
46
|
|
47
47
|
# Public: The String backend name that this converter is handling.
|
48
48
|
attr_reader :backend
|
@@ -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
|
#
|
@@ -3,6 +3,6 @@
|
|
3
3
|
# NOTE use `send :prepend` to be nice to Ruby 2.0
|
4
4
|
Hash.send :prepend, (Module.new do
|
5
5
|
def merge *args
|
6
|
-
(len = args.length) < 1 ?
|
6
|
+
(len = args.length) < 1 ? dup : (len > 1 ? args.inject(self) {|acc, arg| acc.merge arg } : (super args[0]))
|
7
7
|
end
|
8
8
|
end) if (Hash.instance_method :merge).arity == 1
|
data/lib/asciidoctor/document.rb
CHANGED
@@ -198,7 +198,7 @@ class Document < AbstractBlock
|
|
198
198
|
# Public: Get the document catalog Hash
|
199
199
|
attr_reader :catalog
|
200
200
|
|
201
|
-
# Public: Alias catalog property as references for backwards
|
201
|
+
# Public: Alias catalog property as references for backwards compatibility
|
202
202
|
alias references catalog
|
203
203
|
|
204
204
|
# Public: Get the Hash of document counters
|
@@ -259,12 +259,14 @@ class Document < AbstractBlock
|
|
259
259
|
options[:catalog_assets] = true if parent_doc.options[:catalog_assets]
|
260
260
|
@catalog = parent_doc.catalog.merge footnotes: []
|
261
261
|
# QUESTION should we support setting attribute in parent document from nested document?
|
262
|
-
|
263
|
-
@attribute_overrides = attr_overrides = parent_doc.attributes.merge
|
264
|
-
parent_doctype = attr_overrides.delete 'doctype'
|
262
|
+
@attribute_overrides = attr_overrides = (parent_doc.instance_variable_get :@attribute_overrides).merge parent_doc.attributes
|
265
263
|
attr_overrides.delete 'compat-mode'
|
264
|
+
parent_doctype = attr_overrides.delete 'doctype'
|
265
|
+
attr_overrides.delete 'notitle'
|
266
|
+
attr_overrides.delete 'showtitle'
|
267
|
+
# QUESTION if toc is hard unset in parent document, should it be hard unset in nested document?
|
266
268
|
attr_overrides.delete 'toc'
|
267
|
-
attr_overrides.delete 'toc-placement'
|
269
|
+
@attributes['toc-placement'] = (attr_overrides.delete 'toc-placement') || 'auto'
|
268
270
|
attr_overrides.delete 'toc-position'
|
269
271
|
@safe = parent_doc.safe
|
270
272
|
@attributes['compat-mode'] = '' if (@compat_mode = parent_doc.compat_mode)
|
@@ -284,7 +286,6 @@ class Document < AbstractBlock
|
|
284
286
|
footnotes: [],
|
285
287
|
links: [],
|
286
288
|
images: [],
|
287
|
-
#indexterms: [],
|
288
289
|
callouts: Callouts.new,
|
289
290
|
includes: {},
|
290
291
|
}
|
@@ -309,7 +310,7 @@ class Document < AbstractBlock
|
|
309
310
|
end
|
310
311
|
attr_overrides[key.downcase] = val
|
311
312
|
end
|
312
|
-
if (to_file = options[:to_file])
|
313
|
+
if ::String === (to_file = options[:to_file])
|
313
314
|
attr_overrides['outfilesuffix'] = Helpers.extname to_file
|
314
315
|
end
|
315
316
|
# safely resolve the safe mode from const, int or string
|
@@ -327,7 +328,7 @@ class Document < AbstractBlock
|
|
327
328
|
@timings = options.delete :timings
|
328
329
|
@path_resolver = PathResolver.new
|
329
330
|
initialize_extensions = (defined? ::Asciidoctor::Extensions) || (options.key? :extensions) ? ::Asciidoctor::Extensions : nil
|
330
|
-
@extensions = nil # initialize
|
331
|
+
@extensions = nil # initialize further down if initialize_extensions is true
|
331
332
|
options[:standalone] = options[:header_footer] if (options.key? :header_footer) && !(options.key? :standalone)
|
332
333
|
end
|
333
334
|
|
@@ -339,11 +340,13 @@ class Document < AbstractBlock
|
|
339
340
|
(@options = options).freeze
|
340
341
|
|
341
342
|
attrs = @attributes
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
343
|
+
unless parent_doc
|
344
|
+
attrs['attribute-undefined'] = Compliance.attribute_undefined
|
345
|
+
attrs['attribute-missing'] = Compliance.attribute_missing
|
346
|
+
attrs.update DEFAULT_ATTRIBUTES
|
347
|
+
# TODO if lang attribute is set, @safe mode < SafeMode::SERVER, and !parent_doc,
|
348
|
+
# load attributes from data/locale/attributes-<lang>.adoc
|
349
|
+
end
|
347
350
|
|
348
351
|
if standalone
|
349
352
|
# sync embedded attribute with :standalone option value
|
@@ -356,9 +359,9 @@ class Document < AbstractBlock
|
|
356
359
|
# sync embedded attribute with :standalone option value
|
357
360
|
attr_overrides['embedded'] = ''
|
358
361
|
if (attr_overrides.key? 'showtitle') && (attr_overrides.keys & %w(notitle showtitle))[-1] == 'showtitle'
|
359
|
-
attr_overrides['notitle'] = { nil => '', false => '@', '@' => false}[attr_overrides['showtitle']]
|
362
|
+
attr_overrides['notitle'] = { nil => '', false => '@', '@' => false }[attr_overrides['showtitle']]
|
360
363
|
elsif attr_overrides.key? 'notitle'
|
361
|
-
attr_overrides['showtitle'] = { nil => '', false => '@', '@' => false}[attr_overrides['notitle']]
|
364
|
+
attr_overrides['showtitle'] = { nil => '', false => '@', '@' => false }[attr_overrides['notitle']]
|
362
365
|
else
|
363
366
|
attrs['notitle'] = ''
|
364
367
|
end
|
@@ -371,14 +374,12 @@ class Document < AbstractBlock
|
|
371
374
|
attr_overrides[%(safe-mode-#{safe_mode_name})] = ''
|
372
375
|
attr_overrides['safe-mode-level'] = @safe
|
373
376
|
|
374
|
-
# the only way to set the max-include-depth attribute is via the API; default to 64 like AsciiDoc
|
377
|
+
# the only way to set the max-include-depth attribute is via the API; default to 64 like AsciiDoc.py
|
375
378
|
attr_overrides['max-include-depth'] ||= 64
|
376
379
|
|
377
380
|
# the only way to set the allow-uri-read attribute is via the API; disabled by default
|
378
381
|
attr_overrides['allow-uri-read'] ||= nil
|
379
382
|
|
380
|
-
attr_overrides['user-home'] = USER_HOME
|
381
|
-
|
382
383
|
# remap legacy attribute names
|
383
384
|
attr_overrides['sectnums'] = attr_overrides.delete 'numbered' if attr_overrides.key? 'numbered'
|
384
385
|
attr_overrides['hardbreaks-option'] = attr_overrides.delete 'hardbreaks' if attr_overrides.key? 'hardbreaks'
|
@@ -397,11 +398,11 @@ class Document < AbstractBlock
|
|
397
398
|
|
398
399
|
# allow common attributes backend and doctype to be set using options hash, coerce values to string
|
399
400
|
if (backend_val = options[:backend])
|
400
|
-
attr_overrides['backend'] =
|
401
|
+
attr_overrides['backend'] = backend_val.to_s
|
401
402
|
end
|
402
403
|
|
403
404
|
if (doctype_val = options[:doctype])
|
404
|
-
attr_overrides['doctype'] =
|
405
|
+
attr_overrides['doctype'] = doctype_val.to_s
|
405
406
|
end
|
406
407
|
|
407
408
|
if @safe >= SafeMode::SERVER
|
@@ -414,7 +415,7 @@ class Document < AbstractBlock
|
|
414
415
|
attr_overrides['docfile'] = attr_overrides['docfile'][(attr_overrides['docdir'].length + 1)..-1]
|
415
416
|
end
|
416
417
|
attr_overrides['docdir'] = ''
|
417
|
-
attr_overrides['user-home']
|
418
|
+
attr_overrides['user-home'] ||= '.'
|
418
419
|
if @safe >= SafeMode::SECURE
|
419
420
|
attr_overrides['max-attribute-value-size'] = 4096 unless attr_overrides.key? 'max-attribute-value-size'
|
420
421
|
# assign linkcss (preventing css embedding) unless explicitly disabled from the commandline or API
|
@@ -423,6 +424,8 @@ class Document < AbstractBlock
|
|
423
424
|
# restrict document from enabling icons
|
424
425
|
attr_overrides['icons'] ||= nil
|
425
426
|
end
|
427
|
+
else
|
428
|
+
attr_overrides['user-home'] ||= USER_HOME
|
426
429
|
end
|
427
430
|
|
428
431
|
# the only way to set the max-attribute-value-size attribute is via the API; disabled by default
|
@@ -562,15 +565,15 @@ class Document < AbstractBlock
|
|
562
565
|
# returns the next number in the sequence for the specified counter
|
563
566
|
def counter name, seed = nil
|
564
567
|
return @parent_document.counter name, seed if @parent_document
|
565
|
-
if attribute_locked? name
|
566
|
-
@
|
567
|
-
elsif (attr_seed = !(attr_val = @attributes[name]).nil_or_empty?) && (@counters.key? name)
|
568
|
-
@attributes[name] = @counters[name] = Helpers.nextval attr_val
|
568
|
+
if ((locked = attribute_locked? name) && (curr_val = @counters[name])) || !(curr_val = @attributes[name]).nil_or_empty?
|
569
|
+
next_val = @counters[name] = Helpers.nextval curr_val
|
569
570
|
elsif seed
|
570
|
-
|
571
|
+
next_val = @counters[name] = seed == seed.to_i.to_s ? seed.to_i : seed
|
571
572
|
else
|
572
|
-
|
573
|
+
next_val = @counters[name] = 1
|
573
574
|
end
|
575
|
+
@attributes[name] = next_val unless locked
|
576
|
+
next_val
|
574
577
|
end
|
575
578
|
|
576
579
|
# Public: Increment the specified counter and store it in the block's attributes
|
@@ -612,15 +615,29 @@ class Document < AbstractBlock
|
|
612
615
|
# @reftexts is set eagerly to prevent nested lazy init
|
613
616
|
(@reftexts = {}).tap {|accum| @catalog[:refs].each {|id, ref| accum[ref.xreftext] ||= id } }[text]
|
614
617
|
else
|
615
|
-
# @reftexts is set eagerly to prevent nested lazy init
|
616
618
|
resolved_id = nil
|
617
|
-
#
|
618
|
-
|
619
|
+
# @reftexts is set eagerly to prevent nested lazy init
|
620
|
+
@reftexts = accum = {}
|
621
|
+
@catalog[:refs].each do |id, ref|
|
622
|
+
# NOTE short-circuit early since we're throwing away this table anyway
|
623
|
+
if (xreftext = ref.xreftext) == text
|
624
|
+
resolved_id = id
|
625
|
+
break
|
626
|
+
end
|
627
|
+
accum[xreftext] ||= id
|
628
|
+
end
|
619
629
|
@reftexts = nil
|
620
630
|
resolved_id
|
621
631
|
end
|
622
632
|
end
|
623
633
|
|
634
|
+
# Public: Check whether this Document has any child Section objects.
|
635
|
+
#
|
636
|
+
# Returns A [Boolean] to indicate whether this Document has child Section objects
|
637
|
+
def sections?
|
638
|
+
@next_section_index > 0
|
639
|
+
end
|
640
|
+
|
624
641
|
def footnotes?
|
625
642
|
@catalog[:footnotes].empty? ? false : true
|
626
643
|
end
|
@@ -673,7 +690,7 @@ class Document < AbstractBlock
|
|
673
690
|
#
|
674
691
|
# title - the String title to assign as the title of the document header
|
675
692
|
#
|
676
|
-
# Returns the
|
693
|
+
# Returns the specified [String] title
|
677
694
|
def title= title
|
678
695
|
unless (sect = @header)
|
679
696
|
(sect = (@header = Section.new self, 0)).sectname = 'header'
|
@@ -955,8 +972,14 @@ class Document < AbstractBlock
|
|
955
972
|
|
956
973
|
# Public: Write the output to the specified file
|
957
974
|
#
|
958
|
-
# If the converter responds to :write, delegate the work of writing the
|
959
|
-
# to that method. Otherwise, write the output the specified file.
|
975
|
+
# If the converter responds to :write, delegate the work of writing the output
|
976
|
+
# to that method. Otherwise, write the output to the specified file. In the
|
977
|
+
# latter case, this method ensures the output has a trailing newline if the
|
978
|
+
# target responds to write and the output is not empty.
|
979
|
+
#
|
980
|
+
# output - The output to write. Unless the converter responds to write, this
|
981
|
+
# object is expected to be a String.
|
982
|
+
# target - The file to write, either a File object or a String path.
|
960
983
|
#
|
961
984
|
# Returns nothing
|
962
985
|
def write output, target
|
@@ -982,25 +1005,6 @@ class Document < AbstractBlock
|
|
982
1005
|
nil
|
983
1006
|
end
|
984
1007
|
|
985
|
-
=begin
|
986
|
-
def convert_to target, opts = {}
|
987
|
-
start = ::Time.now.to_f if (monitor = opts[:monitor])
|
988
|
-
output = (r = converter opts).convert
|
989
|
-
monitor[:convert] = ::Time.now.to_f - start if monitor
|
990
|
-
|
991
|
-
unless target.respond_to? :write
|
992
|
-
@attributes['outfile'] = target = ::File.expand_path target
|
993
|
-
@attributes['outdir'] = ::File.dirname target
|
994
|
-
end
|
995
|
-
|
996
|
-
start = ::Time.now.to_f if monitor
|
997
|
-
r.write output, target
|
998
|
-
monitor[:write] = ::Time.now.to_f - start if monitor
|
999
|
-
|
1000
|
-
output
|
1001
|
-
end
|
1002
|
-
=end
|
1003
|
-
|
1004
1008
|
def content
|
1005
1009
|
# NOTE per AsciiDoc-spec, remove the title before converting the body
|
1006
1010
|
@attributes.delete('title')
|
@@ -1022,7 +1026,7 @@ class Document < AbstractBlock
|
|
1022
1026
|
def docinfo location = :head, suffix = nil
|
1023
1027
|
if safe < SafeMode::SECURE
|
1024
1028
|
qualifier = %(-#{location}) unless location == :head
|
1025
|
-
suffix
|
1029
|
+
suffix ||= @outfilesuffix
|
1026
1030
|
|
1027
1031
|
if (docinfo = @attributes['docinfo']).nil_or_empty?
|
1028
1032
|
if @attributes.key? 'docinfo2'
|
@@ -1079,7 +1083,7 @@ class Document < AbstractBlock
|
|
1079
1083
|
end
|
1080
1084
|
|
1081
1085
|
def to_s
|
1082
|
-
%(#<#{self.class}@#{object_id} {doctype: #{doctype.inspect}, doctitle: #{(@header
|
1086
|
+
%(#<#{self.class}@#{object_id} {doctype: #{doctype.inspect}, doctitle: #{(@header && @header.title).inspect}, blocks: #{@blocks.size}}>)
|
1083
1087
|
end
|
1084
1088
|
|
1085
1089
|
private
|
@@ -1208,8 +1212,8 @@ class Document < AbstractBlock
|
|
1208
1212
|
end
|
1209
1213
|
end
|
1210
1214
|
|
1211
|
-
if (@compat_mode = attrs.key? 'compat-mode')
|
1212
|
-
attrs['source-language'] = attrs['language']
|
1215
|
+
if (@compat_mode = attrs.key? 'compat-mode') && (attrs.key? 'language')
|
1216
|
+
attrs['source-language'] = attrs['language']
|
1213
1217
|
end
|
1214
1218
|
|
1215
1219
|
unless @parent_document
|
@@ -1382,7 +1386,7 @@ class Document < AbstractBlock
|
|
1382
1386
|
attrs[%(basebackend-#{current_basebackend}-doctype-#{new_doctype})] = '' if current_basebackend
|
1383
1387
|
end
|
1384
1388
|
attrs[%(doctype-#{new_doctype})] = ''
|
1385
|
-
|
1389
|
+
@doctype = attrs['doctype'] = new_doctype
|
1386
1390
|
end
|
1387
1391
|
end
|
1388
1392
|
end
|
@@ -134,14 +134,14 @@ module Extensions
|
|
134
134
|
if opts.fetch :numbered, (style == 'appendix')
|
135
135
|
sect.numbered = true
|
136
136
|
elsif !(opts.key? :numbered) && (doc.attr? 'sectnums', 'all')
|
137
|
-
sect.numbered = book && level == 1 ? :chapter : true
|
137
|
+
sect.numbered = (book && level == 1 ? :chapter : true)
|
138
138
|
end
|
139
139
|
elsif level > 0
|
140
140
|
if opts.fetch :numbered, (doc.attr? 'sectnums')
|
141
141
|
sect.numbered = sect.special ? parent.numbered && true : true
|
142
142
|
end
|
143
|
-
|
144
|
-
sect.numbered = true
|
143
|
+
elsif opts.fetch :numbered, (book && (doc.attr? 'partnums'))
|
144
|
+
sect.numbered = true
|
145
145
|
end
|
146
146
|
if (id = attrs['id']) == false
|
147
147
|
attrs.delete 'id'
|
@@ -229,7 +229,7 @@ module Extensions
|
|
229
229
|
def parse_attributes block, attrlist, opts = {}
|
230
230
|
return {} if attrlist ? attrlist.empty? : true
|
231
231
|
attrlist = block.sub_attributes attrlist if opts[:sub_attributes] && (attrlist.include? ATTR_REF_HEAD)
|
232
|
-
(AttributeList.new attrlist).parse
|
232
|
+
(AttributeList.new attrlist).parse opts[:positional_attributes] || []
|
233
233
|
end
|
234
234
|
|
235
235
|
# TODO fill out remaining methods
|
@@ -511,6 +511,10 @@ module Extensions
|
|
511
511
|
# registered to handle this name and, if found, invokes its {Processor#process}
|
512
512
|
# method to build a corresponding node in the document tree.
|
513
513
|
#
|
514
|
+
# If the process method returns an instance of Block, the content model of that
|
515
|
+
# Block is :compound, and the Block contains at least one line, the parser will
|
516
|
+
# parse those lines into blocks an assigned them to the returned block.
|
517
|
+
#
|
514
518
|
# AsciiDoc example:
|
515
519
|
#
|
516
520
|
# [shout]
|
@@ -594,6 +598,10 @@ module Extensions
|
|
594
598
|
# Public: BlockMacroProcessors are used to handle block macros that have a
|
595
599
|
# custom name.
|
596
600
|
#
|
601
|
+
# If the process method returns an instance of Block, the content model of that
|
602
|
+
# Block is :compound, and the Block contains at least one line, the parser will
|
603
|
+
# parse those lines into blocks an assigned them to the returned block.
|
604
|
+
#
|
597
605
|
# BlockMacroProcessor implementations must extend BlockMacroProcessor.
|
598
606
|
class BlockMacroProcessor < MacroProcessor
|
599
607
|
def name
|
@@ -666,7 +674,7 @@ module Extensions
|
|
666
674
|
|
667
675
|
# Public: A specialization of the Extension proxy that additionally stores a
|
668
676
|
# reference to the {Processor#process} method. By storing this reference, its
|
669
|
-
# possible to
|
677
|
+
# possible to accommodate both concrete extension implementations and Procs.
|
670
678
|
class ProcessorExtension < Extension
|
671
679
|
attr_reader :process_method
|
672
680
|
|
@@ -954,7 +962,7 @@ module Extensions
|
|
954
962
|
end
|
955
963
|
|
956
964
|
# Public: Registers an {DocinfoProcessor} with the extension registry to
|
957
|
-
# add
|
965
|
+
# add additional docinfo to the document.
|
958
966
|
#
|
959
967
|
# The DocinfoProcessor may be one of four types:
|
960
968
|
#
|
@@ -1199,7 +1207,7 @@ module Extensions
|
|
1199
1207
|
# name - the String or Symbol (coersed to a Symbol) macro name
|
1200
1208
|
#
|
1201
1209
|
# Returns the [Extension] object stored in the registry that proxies the
|
1202
|
-
#
|
1210
|
+
# corresponding BlockMacroProcessor or nil if a match is not found.
|
1203
1211
|
def find_block_macro_extension name
|
1204
1212
|
@block_macro_extensions[name.to_sym]
|
1205
1213
|
end
|
@@ -1286,7 +1294,7 @@ module Extensions
|
|
1286
1294
|
# name - the String or Symbol (coersed to a Symbol) macro name
|
1287
1295
|
#
|
1288
1296
|
# Returns the [Extension] object stored in the registry that proxies the
|
1289
|
-
#
|
1297
|
+
# corresponding InlineMacroProcessor or nil if a match is not found.
|
1290
1298
|
def find_inline_macro_extension name
|
1291
1299
|
@inline_macro_extensions[name.to_sym]
|
1292
1300
|
end
|
@@ -1328,7 +1336,7 @@ module Extensions
|
|
1328
1336
|
kind_java_class = (defined? ::AsciidoctorJ) ? (::AsciidoctorJ::Extensions.const_get kind_class_symbol, false) : nil
|
1329
1337
|
kind_store = instance_variable_get(%(@#{kind}_extensions).to_sym) || instance_variable_set(%(@#{kind}_extensions).to_sym, [])
|
1330
1338
|
# style 1: specified as block
|
1331
|
-
|
1339
|
+
if block_given?
|
1332
1340
|
config = resolve_args args, 1
|
1333
1341
|
(processor = kind_class.new config).singleton_class.enable_dsl
|
1334
1342
|
if block.arity == 0
|
@@ -1340,7 +1348,7 @@ module Extensions
|
|
1340
1348
|
raise ::ArgumentError, %(No block specified to process #{kind_name} extension at #{block.source_location})
|
1341
1349
|
end
|
1342
1350
|
processor.freeze
|
1343
|
-
ProcessorExtension.new kind, processor
|
1351
|
+
extension = ProcessorExtension.new kind, processor
|
1344
1352
|
else
|
1345
1353
|
processor, config = resolve_args args, 2
|
1346
1354
|
# style 2: specified as Class or String class name
|
@@ -1350,12 +1358,12 @@ module Extensions
|
|
1350
1358
|
end
|
1351
1359
|
processor_instance = processor_class.new config
|
1352
1360
|
processor_instance.freeze
|
1353
|
-
ProcessorExtension.new kind, processor_instance
|
1361
|
+
extension = ProcessorExtension.new kind, processor_instance
|
1354
1362
|
# style 3: specified as instance
|
1355
1363
|
elsif kind_class === processor || (kind_java_class && kind_java_class === processor)
|
1356
1364
|
processor.update_config config
|
1357
1365
|
processor.freeze
|
1358
|
-
ProcessorExtension.new kind, processor
|
1366
|
+
extension = ProcessorExtension.new kind, processor
|
1359
1367
|
else
|
1360
1368
|
raise ::ArgumentError, %(Invalid arguments specified for registering #{kind_name} extension: #{args})
|
1361
1369
|
end
|
data/lib/asciidoctor/list.rb
CHANGED
@@ -80,12 +80,8 @@ class ListItem < AbstractBlock
|
|
80
80
|
@text && (apply_subs @text, @subs)
|
81
81
|
end
|
82
82
|
|
83
|
-
# Public: Set the String text
|
84
|
-
|
85
|
-
# Returns the new String text assigned to this ListItem
|
86
|
-
def text= val
|
87
|
-
@text = val
|
88
|
-
end
|
83
|
+
# Public: Set the String text assigned to this ListItem
|
84
|
+
attr_writer :text
|
89
85
|
|
90
86
|
# Check whether this list item has simple content (no nested blocks aside from a single outline list).
|
91
87
|
# Primarily relevant for outline lists.
|
data/lib/asciidoctor/load.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Asciidoctor
|
2
3
|
class << self
|
3
4
|
# Public: Parse the AsciiDoc source input into a {Document}
|
@@ -53,7 +54,8 @@ module Asciidoctor
|
|
53
54
|
end
|
54
55
|
|
55
56
|
if ::File === input
|
56
|
-
|
57
|
+
# File#mtime on JRuby 9.1 for Windows doesn't honor TZ environment variable; see https://github.com/jruby/jruby/issues/6659
|
58
|
+
options[:input_mtime] = RUBY_ENGINE == 'jruby' ? (::Time.at input.mtime.to_i) : input.mtime
|
57
59
|
# NOTE defer setting infile and indir until we get a better sense of their purpose
|
58
60
|
# TODO cli checks if input path can be read and is file, but might want to add check to API too
|
59
61
|
attrs['docfile'] = input_path = ::File.absolute_path input.path
|
@@ -83,23 +85,23 @@ module Asciidoctor
|
|
83
85
|
|
84
86
|
timings.record :parse if timings
|
85
87
|
doc
|
86
|
-
rescue =>
|
88
|
+
rescue => e
|
87
89
|
begin
|
88
90
|
context = %(asciidoctor: FAILED: #{attrs['docfile'] || '<stdin>'}: Failed to load AsciiDoc document)
|
89
|
-
if
|
91
|
+
if e.respond_to? :exception
|
90
92
|
# The original message must be explicitly preserved when wrapping a Ruby exception
|
91
|
-
|
93
|
+
wrapped_e = e.exception %(#{context} - #{e.message})
|
92
94
|
# JRuby automatically sets backtrace; MRI did not until 2.6
|
93
|
-
|
95
|
+
wrapped_e.set_backtrace e.backtrace
|
94
96
|
else
|
95
97
|
# Likely a Java exception class
|
96
|
-
|
97
|
-
|
98
|
+
wrapped_e = e.class.new context, e
|
99
|
+
wrapped_e.stack_trace = e.stack_trace
|
98
100
|
end
|
99
101
|
rescue
|
100
|
-
|
102
|
+
wrapped_e = e
|
101
103
|
end
|
102
|
-
raise
|
104
|
+
raise wrapped_e
|
103
105
|
end
|
104
106
|
|
105
107
|
# Public: Parse the contents of the AsciiDoc source file into an Asciidoctor::Document
|
data/lib/asciidoctor/logging.rb
CHANGED
@@ -20,10 +20,10 @@ class Logger < ::Logger
|
|
20
20
|
end
|
21
21
|
|
22
22
|
class BasicFormatter < Formatter
|
23
|
-
|
23
|
+
SEVERITY_LABEL_SUBSTITUTES = { 'WARN' => 'WARNING', 'FATAL' => 'FAILED' }
|
24
24
|
|
25
25
|
def call severity, _, progname, msg
|
26
|
-
%(#{progname}: #{
|
26
|
+
%(#{progname}: #{SEVERITY_LABEL_SUBSTITUTES[severity] || severity}: #{::String === msg ? msg : msg.inspect}#{LF})
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -35,7 +35,7 @@ class Logger < ::Logger
|
|
35
35
|
end
|
36
36
|
|
37
37
|
class MemoryLogger < ::Logger
|
38
|
-
|
38
|
+
SEVERITY_SYMBOL_BY_VALUE = (Severity.constants false).map {|c| [(Severity.const_get c), c] }.to_h
|
39
39
|
|
40
40
|
attr_reader :messages
|
41
41
|
|
@@ -45,8 +45,8 @@ class MemoryLogger < ::Logger
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def add severity, message = nil, progname = nil
|
48
|
-
message
|
49
|
-
@messages << { severity:
|
48
|
+
message ||= block_given? ? yield : progname
|
49
|
+
@messages << { severity: SEVERITY_SYMBOL_BY_VALUE[severity || UNKNOWN], message: message }
|
50
50
|
true
|
51
51
|
end
|
52
52
|
|
@@ -59,7 +59,7 @@ class MemoryLogger < ::Logger
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def max_severity
|
62
|
-
empty? ? nil : @messages.map {|m| Severity.const_get m[:severity]
|
62
|
+
empty? ? nil : @messages.map {|m| Severity.const_get m[:severity] }.max
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
@@ -89,6 +89,7 @@ module LoggerManager
|
|
89
89
|
@logger ||= (@logger_class.new pipe)
|
90
90
|
end
|
91
91
|
|
92
|
+
# Returns the specified Logger
|
92
93
|
def logger= new_logger
|
93
94
|
@logger = new_logger || (@logger_class.new $stderr)
|
94
95
|
end
|
@@ -110,9 +111,10 @@ module Logging
|
|
110
111
|
# into - The Class that includes the {Logging} module
|
111
112
|
#
|
112
113
|
# Returns nothing
|
113
|
-
|
114
|
+
def self.included into
|
114
115
|
into.extend Logging
|
115
|
-
end
|
116
|
+
end
|
117
|
+
private_class_method :included # use separate declaration for Ruby 2.0.x
|
116
118
|
|
117
119
|
def logger
|
118
120
|
LoggerManager.logger
|