asciidoctor 2.0.13 → 2.0.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +151 -30
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +9 -12
  5. data/README-fr.adoc +9 -12
  6. data/README-jp.adoc +10 -13
  7. data/README-zh_CN.adoc +9 -12
  8. data/README.adoc +40 -19
  9. data/asciidoctor.gemspec +2 -9
  10. data/data/locale/attributes-fr.adoc +2 -2
  11. data/data/locale/attributes-th.adoc +23 -0
  12. data/data/locale/attributes-vi.adoc +23 -0
  13. data/data/stylesheets/asciidoctor-default.css +54 -53
  14. data/data/stylesheets/coderay-asciidoctor.css +9 -9
  15. data/lib/asciidoctor/abstract_block.rb +11 -9
  16. data/lib/asciidoctor/abstract_node.rb +9 -8
  17. data/lib/asciidoctor/attribute_list.rb +1 -1
  18. data/lib/asciidoctor/block.rb +6 -6
  19. data/lib/asciidoctor/cli/invoker.rb +1 -2
  20. data/lib/asciidoctor/cli/options.rb +25 -25
  21. data/lib/asciidoctor/convert.rb +1 -0
  22. data/lib/asciidoctor/converter/docbook5.rb +45 -26
  23. data/lib/asciidoctor/converter/html5.rb +130 -102
  24. data/lib/asciidoctor/converter/manpage.rb +69 -64
  25. data/lib/asciidoctor/converter/template.rb +12 -13
  26. data/lib/asciidoctor/converter.rb +6 -4
  27. data/lib/asciidoctor/core_ext/hash/merge.rb +1 -1
  28. data/lib/asciidoctor/document.rb +61 -57
  29. data/lib/asciidoctor/extensions.rb +20 -12
  30. data/lib/asciidoctor/list.rb +2 -6
  31. data/lib/asciidoctor/load.rb +11 -9
  32. data/lib/asciidoctor/logging.rb +10 -8
  33. data/lib/asciidoctor/parser.rb +177 -193
  34. data/lib/asciidoctor/path_resolver.rb +3 -3
  35. data/lib/asciidoctor/reader.rb +73 -72
  36. data/lib/asciidoctor/rx.rb +5 -4
  37. data/lib/asciidoctor/section.rb +7 -0
  38. data/lib/asciidoctor/substitutors.rb +121 -121
  39. data/lib/asciidoctor/syntax_highlighter/coderay.rb +2 -1
  40. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +1 -1
  41. data/lib/asciidoctor/syntax_highlighter/pygments.rb +16 -7
  42. data/lib/asciidoctor/syntax_highlighter/rouge.rb +2 -1
  43. data/lib/asciidoctor/syntax_highlighter.rb +8 -11
  44. data/lib/asciidoctor/table.rb +18 -20
  45. data/lib/asciidoctor/timings.rb +3 -3
  46. data/lib/asciidoctor/version.rb +1 -1
  47. data/lib/asciidoctor.rb +10 -10
  48. data/man/asciidoctor.1 +26 -28
  49. data/man/asciidoctor.adoc +33 -27
  50. metadata +8 -62
@@ -40,13 +40,13 @@ class Converter::TemplateConverter < Converter::Base
40
40
  @caches = { scans: {}, templates: {} }
41
41
  end
42
42
 
43
- def self.caches
44
- @caches
45
- end
43
+ class << self
44
+ attr_reader :caches
46
45
 
47
- def self.clear_caches
48
- @caches[:scans].clear if @caches[:scans]
49
- @caches[:templates].clear if @caches[:templates]
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
- @templates[name] = if (template_cache = @caches[:templates])
137
+ if (template_cache = @caches[:templates])
138
138
  template_cache[template.file] = template
139
- else
140
- template
141
139
  end
142
- #create_handler name, template
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).select {|match| ::File.file? match }.each do |file|
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, { engine_class: ::Erubis::FastEruby }]
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
- private_class_method def self.included into
369
+ def self.included into
370
370
  into.send :include, BackendTraits
371
371
  into.extend Config
372
- end || :included
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 Converter, Logging
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 ? super({}) : (len > 1 ? args.inject(self) {|acc, arg| acc.merge arg } : (super args[0]))
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
@@ -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 compatiblity
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
- # NOTE we must dup or else all the assignments to the overrides clobbers the real attributes
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 furthur down if initialize_extensions is true
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
- attrs['attribute-undefined'] = Compliance.attribute_undefined
343
- attrs['attribute-missing'] = Compliance.attribute_missing
344
- attrs.update DEFAULT_ATTRIBUTES
345
- # TODO if lang attribute is set, @safe mode < SafeMode::SERVER, and !parent_doc,
346
- # load attributes from data/locale/attributes-<lang>.adoc
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 Python
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'] = %(#{backend_val})
401
+ attr_overrides['backend'] = backend_val.to_s
401
402
  end
402
403
 
403
404
  if (doctype_val = options[:doctype])
404
- attr_overrides['doctype'] = %(#{doctype_val})
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
- @attributes[name]
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
- @attributes[name] = @counters[name] = seed == seed.to_i.to_s ? seed.to_i : seed
571
+ next_val = @counters[name] = seed == seed.to_i.to_s ? seed.to_i : seed
571
572
  else
572
- @attributes[name] = @counters[name] = Helpers.nextval attr_seed ? attr_val : 0
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
- # NOTE short-circuit early since we're throwing away this table
618
- (@reftexts = {}).tap {|accum| @catalog[:refs].each {|id, ref| (xreftext = ref.xreftext) == text ? (break (resolved_id = id)) : (accum[xreftext] ||= id) } }
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 new [String] title assigned to the document header
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 file
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 = @outfilesuffix unless 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 != nil ? @header.title : nil).inspect}, blocks: #{@blocks.size}}>)
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'] if attrs.key? '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
- return @doctype = attrs['doctype'] = new_doctype
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
- else
144
- sect.numbered = true if opts.fetch :numbered, (book && (doc.attr? 'partnums'))
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 (opts[:positional_attributes] || [])
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 accomodate both concrete extension implementations and Procs.
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 additionnal docinfo to the document.
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
- # cooresponding BlockMacroProcessor or nil if a match is not found.
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
- # cooresponding InlineMacroProcessor or nil if a match is not found.
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
- extension = if block_given?
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
@@ -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.
@@ -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
- options[:input_mtime] = input.mtime
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 => ex
88
+ rescue => e
87
89
  begin
88
90
  context = %(asciidoctor: FAILED: #{attrs['docfile'] || '<stdin>'}: Failed to load AsciiDoc document)
89
- if ex.respond_to? :exception
91
+ if e.respond_to? :exception
90
92
  # The original message must be explicitly preserved when wrapping a Ruby exception
91
- wrapped_ex = ex.exception %(#{context} - #{ex.message})
93
+ wrapped_e = e.exception %(#{context} - #{e.message})
92
94
  # JRuby automatically sets backtrace; MRI did not until 2.6
93
- wrapped_ex.set_backtrace ex.backtrace
95
+ wrapped_e.set_backtrace e.backtrace
94
96
  else
95
97
  # Likely a Java exception class
96
- wrapped_ex = ex.class.new context, ex
97
- wrapped_ex.stack_trace = ex.stack_trace
98
+ wrapped_e = e.class.new context, e
99
+ wrapped_e.stack_trace = e.stack_trace
98
100
  end
99
101
  rescue
100
- wrapped_ex = ex
102
+ wrapped_e = e
101
103
  end
102
- raise wrapped_ex
104
+ raise wrapped_e
103
105
  end
104
106
 
105
107
  # Public: Parse the contents of the AsciiDoc source file into an Asciidoctor::Document
@@ -20,10 +20,10 @@ class Logger < ::Logger
20
20
  end
21
21
 
22
22
  class BasicFormatter < Formatter
23
- SEVERITY_LABELS = { 'WARN' => 'WARNING', 'FATAL' => 'FAILED' }
23
+ SEVERITY_LABEL_SUBSTITUTES = { 'WARN' => 'WARNING', 'FATAL' => 'FAILED' }
24
24
 
25
25
  def call severity, _, progname, msg
26
- %(#{progname}: #{SEVERITY_LABELS[severity] || severity}: #{::String === msg ? msg : msg.inspect}#{LF})
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
- SEVERITY_LABELS = {}.tap {|accum| (Severity.constants false).each {|c| accum[Severity.const_get c, false] = c } }
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 = block_given? ? yield : progname unless message
49
- @messages << { severity: SEVERITY_LABELS[severity || UNKNOWN], message: message }
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], false }.max
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
- private_class_method def self.included into
114
+ def self.included into
114
115
  into.extend Logging
115
- end || :included
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