asciidoctor 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09c8776c68c1c086a0d17e7597f8e5cd2a4ef27a2b57545a0d82bb7520747c8d'
4
- data.tar.gz: 6fa042782d5c3a6e446ce1b3b5a25557055d74248ca618f3bed651d5d6f7535e
3
+ metadata.gz: 07c1b7f136f76a2c716b27f41bc38e42e36c157d97ca50685c98e47be80d77df
4
+ data.tar.gz: f57b9e60b3d8547fdca2d2866758f046ddc5e7a439f0626fda3b7cd96c4a1148
5
5
  SHA512:
6
- metadata.gz: 82e97c50b8ecc3cb09e2aa966e41acc3d714dd8fad4654ab68eadd5e339febdcd680fdb3fba77bb11583eb419120fb6429bcd9d21299ecb4e6f7ff102bda48d3
7
- data.tar.gz: 2c96408f4c51935b2b9d413184358d58a55e528675442167a13e879d5a4506ab29fb628c65c63b616333d555f41a54d1da761889afbba64f563a623d3b2b4446
6
+ metadata.gz: be63260d2dfe6576b65e8e8b47e173107e046f83d4bbce38d27873a86e14fe6526bb3cda436034f80614946c9bddd3629156906bcc479252028860612fab18a0
7
+ data.tar.gz: f699eae9ef69ee56763c81b468245b33aa6edf9ba529ccb6e993ce0a888fcb47649f3779d1e1ebde7dea915ff9e9d55c5b0287c7d65e2bde24e2c5ceab0d3c09
@@ -0,0 +1,11 @@
1
+ --charset UTF-8
2
+ --readme README.adoc
3
+ --hide-api private
4
+ --plugin tomdoc
5
+ --title "Asciidoctor API Documentation"
6
+ --output-dir rdoc
7
+ lib/**/*.rb
8
+ -
9
+ CHANGELOG.adoc
10
+ CONTRIBUTING.adoc
11
+ LICENSE
@@ -13,6 +13,21 @@ endif::[]
13
13
  This document provides a high-level view of the changes introduced in Asciidoctor by release.
14
14
  For a detailed view of what has changed, refer to the {uri-repo}/commits/master[commit history] on GitHub.
15
15
 
16
+ == 2.0.1 (2019-03-25) - @mojavelinux
17
+
18
+ Bug Fixes::
19
+
20
+ * convert titles of cataloged block and section nodes containing attribute references eagerly to resolve attributes while in scope (#3202)
21
+ * customize MathJax (using a postfilter hook) to apply displaymath formatting to AsciiMath block (#2498)
22
+ * fix misspelling of deprecated default_attrs DSL function (missing trailing "s")
23
+ * remove unused location property (attr_accessor :location) on DocinfoProcessor class
24
+ * look for deprecated extension option :pos_attrs if :positional_attrs option is missing (#3199)
25
+ * add detail to load error message if path differs from gem name (#1884)
26
+
27
+ Build / Infrastructure::
28
+
29
+ * bundle .yardopts in RubyGem (#3193)
30
+
16
31
  == 2.0.0 (2019-03-22) - @mojavelinux
17
32
 
18
33
  Enhancements / Compliance::
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>; Ryan Waldron <https://github.com/erebor[@erebor]>
3
- v2.0.0, 2019-03-22
3
+ v2.0.1, 2019-03-25
4
4
  // settings:
5
5
  :idprefix:
6
6
  :idseparator: -
@@ -17,7 +17,7 @@ ifdef::env-github[]
17
17
  :warning-caption: :warning:
18
18
  endif::[]
19
19
  // Variables:
20
- :release-version: 2.0.0
20
+ :release-version: 2.0.1
21
21
  // URIs:
22
22
  :uri-org: https://github.com/asciidoctor
23
23
  :uri-repo: {uri-org}/asciidoctor
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>; Ryan Waldron <https://github.com/erebor[@erebor]>
3
- v2.0.0, 2019-03-22
3
+ v2.0.1, 2019-03-25
4
4
  // settings:
5
5
  :idprefix:
6
6
  :idseparator: -
@@ -17,7 +17,7 @@ ifdef::env-github[]
17
17
  :warning-caption: :warning:
18
18
  endif::[]
19
19
  // Variables:
20
- :release-version: 2.0.0
20
+ :release-version: 2.0.1
21
21
  // URIs:
22
22
  :uri-org: https://github.com/asciidoctor
23
23
  :uri-repo: {uri-org}/asciidoctor
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>; Ryan Waldron <https://github.com/erebor[@erebor]>
3
- v2.0.0, 2019-03-22
3
+ v2.0.1, 2019-03-25
4
4
  // settings:
5
5
  :page-layout: base
6
6
  :idprefix:
@@ -18,7 +18,7 @@ ifdef::env-github[]
18
18
  :warning-caption: :warning:
19
19
  endif::[]
20
20
  // Variables:
21
- :release-version: 2.0.0
21
+ :release-version: 2.0.1
22
22
  // URIs:
23
23
  :uri-org: https://github.com/asciidoctor
24
24
  :uri-repo: {uri-org}/asciidoctor
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>; Ryan Waldron <https://github.com/erebor[@erebor]>
3
- v2.0.0, 2019-03-22
3
+ v2.0.1, 2019-03-25
4
4
  // settings:
5
5
  :page-layout: base
6
6
  :idprefix:
@@ -18,7 +18,7 @@ ifdef::env-github[]
18
18
  :warning-caption: :warning:
19
19
  endif::[]
20
20
  // Variables:
21
- :release-version: 2.0.0
21
+ :release-version: 2.0.1
22
22
  // URIs:
23
23
  :uri-org: https://github.com/asciidoctor
24
24
  :uri-repo: {uri-org}/asciidoctor
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>; Ryan Waldron <https://github.com/erebor[@erebor]>
3
- v2.0.0, 2019-03-22
3
+ v2.0.1, 2019-03-25
4
4
  // settings:
5
5
  :idprefix:
6
6
  :idseparator: -
@@ -17,7 +17,7 @@ ifdef::env-github[]
17
17
  :warning-caption: :warning:
18
18
  endif::[]
19
19
  // Variables:
20
- :release-version: 2.0.0
20
+ :release-version: 2.0.1
21
21
  // URIs:
22
22
  :uri-org: https://github.com/asciidoctor
23
23
  :uri-repo: {uri-org}/asciidoctor
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
28
28
  rescue
29
29
  Dir['**/*']
30
30
  end
31
- s.files = files.grep %r/^(?:(?:data|lib|man)\/.+|LICENSE|(?:CHANGELOG|README(?:-\w+)?)\.adoc|#{s.name}\.gemspec)$/
31
+ s.files = files.grep %r/^(?:(?:data|lib|man)\/.+|LICENSE|(?:CHANGELOG|README(?:-\w+)?)\.adoc|\.yardopts|#{s.name}\.gemspec)$/
32
32
  s.executables = (files.grep %r/^bin\//).map {|f| File.basename f }
33
33
  s.require_paths = ['lib']
34
34
  #s.test_files = files.grep %r/^(?:(?:features|test)\/.+)$/
@@ -293,6 +293,8 @@ module Asciidoctor
293
293
  DELIMITED_BLOCK_HEADS = {}.tap {|accum| DELIMITED_BLOCKS.each_key {|k| accum[k.slice 0, 2] = true } }
294
294
  DELIMITED_BLOCK_TAILS = {}.tap {|accum| DELIMITED_BLOCKS.each_key {|k| accum[k] = k[k.length - 1] if k.length == 4 } }
295
295
 
296
+ CAPTIONABLE_BLOCKS = { example: true, listing: true, table: true }
297
+
296
298
  LAYOUT_BREAK_CHARS = {
297
299
  '\'' => :thematic_break,
298
300
  '<' => :page_break
@@ -1271,9 +1273,8 @@ module Asciidoctor
1271
1273
 
1272
1274
  if ::File === input
1273
1275
  options[:input_mtime] = input.mtime
1274
- # TODO cli checks if input path can be read and is file, but might want to add check to API too
1275
- input_path = ::File.absolute_path input.path
1276
1276
  # NOTE defer setting infile and indir until we get a better sense of their purpose
1277
+ # TODO cli checks if input path can be read and is file, but might want to add check to API too
1277
1278
  attrs['docfile'] = input_path = ::File.absolute_path input.path
1278
1279
  attrs['docdir'] = ::File.dirname input_path
1279
1280
  attrs['docname'] = Helpers.basename input_path, (attrs['docfilesuffix'] = ::File.extname input_path)
@@ -1363,32 +1364,26 @@ module Asciidoctor
1363
1364
  # Returns the Document object if the converted String is written to a
1364
1365
  # file, otherwise the converted String
1365
1366
  def convert input, options = {}
1366
- options = options.merge
1367
- options.delete(:parse)
1368
- to_file = options.delete(:to_file)
1369
- to_dir = options.delete(:to_dir)
1370
- mkdirs = options.delete(:mkdirs) || false
1367
+ (options = options.merge).delete :parse
1368
+ to_dir = options.delete :to_dir
1369
+ mkdirs = options.delete :mkdirs
1371
1370
 
1372
- case to_file
1371
+ case (to_file = options.delete :to_file)
1373
1372
  when true, nil
1374
- write_to_same_dir = !to_dir && ::File === input
1375
- stream_output = false
1376
- write_to_target = to_dir
1373
+ unless (write_to_target = to_dir)
1374
+ sibling_path = ::File.absolute_path input.path if ::File === input
1375
+ end
1377
1376
  to_file = nil
1378
1377
  when false
1379
- write_to_same_dir = false
1380
- stream_output = false
1381
- write_to_target = false
1382
1378
  to_file = nil
1383
1379
  when '/dev/null'
1384
1380
  return self.load input, options
1385
1381
  else
1386
- write_to_same_dir = false
1387
- write_to_target = (stream_output = to_file.respond_to? :write) ? false : (options[:to_file] = to_file)
1382
+ options[:to_file] = write_to_target = to_file unless (stream_output = to_file.respond_to? :write)
1388
1383
  end
1389
1384
 
1390
1385
  unless options.key? :standalone
1391
- if write_to_same_dir || write_to_target
1386
+ if sibling_path || write_to_target
1392
1387
  options[:standalone] = true
1393
1388
  elsif options.key? :header_footer
1394
1389
  options[:standalone] = options[:header_footer]
@@ -1396,9 +1391,8 @@ module Asciidoctor
1396
1391
  end
1397
1392
 
1398
1393
  # NOTE outfile may be controlled by document attributes, so resolve outfile after loading
1399
- if write_to_same_dir
1400
- input_path = ::File.absolute_path input.path
1401
- options[:to_dir] = (outdir = ::File.dirname input_path)
1394
+ if sibling_path
1395
+ options[:to_dir] = outdir = ::File.dirname sibling_path
1402
1396
  elsif write_to_target
1403
1397
  if to_dir
1404
1398
  if to_file
@@ -1415,11 +1409,9 @@ module Asciidoctor
1415
1409
  # NOTE :to_file option only passed if assigned an explicit path
1416
1410
  doc = self.load input, options
1417
1411
 
1418
- if write_to_same_dir # write to file in same directory
1412
+ if sibling_path # write to file in same directory
1419
1413
  outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
1420
- if outfile == input_path
1421
- raise ::IOError, %(input file and output file cannot be the same: #{outfile})
1422
- end
1414
+ raise ::IOError, %(input file and output file cannot be the same: #{outfile}) if outfile == sibling_path
1423
1415
  elsif write_to_target # write to explicit file or directory
1424
1416
  working_dir = (options.key? :base_dir) ? (::File.expand_path options[:base_dir]) : ::Dir.pwd
1425
1417
  # QUESTION should the jail be the working_dir or doc.base_dir???
@@ -1447,15 +1439,18 @@ module Asciidoctor
1447
1439
  Helpers.mkdir_p outdir
1448
1440
  else
1449
1441
  # NOTE we intentionally refer to the directory as it was passed to the API
1450
- raise ::IOError, %(target directory does not exist: #{to_dir} (hint: set mkdirs option)) unless ::File.directory? outdir
1442
+ raise ::IOError, %(target directory does not exist: #{to_dir} (hint: set :mkdirs option)) unless ::File.directory? outdir
1451
1443
  end
1452
1444
  else # write to stream
1453
1445
  outfile = to_file
1454
1446
  outdir = nil
1455
1447
  end
1456
1448
 
1457
- opts = outfile && !stream_output ? { 'outfile' => outfile, 'outdir' => outdir } : {}
1458
- output = doc.convert opts
1449
+ if outfile && !stream_output
1450
+ output = doc.convert 'outfile' => outfile, 'outdir' => outdir
1451
+ else
1452
+ output = doc.convert
1453
+ end
1459
1454
 
1460
1455
  if outfile
1461
1456
  doc.write output, outfile
@@ -1477,7 +1472,7 @@ module Asciidoctor
1477
1472
  if mkdirs
1478
1473
  Helpers.mkdir_p stylesoutdir
1479
1474
  else
1480
- raise ::IOError, %(target stylesheet directory does not exist: #{stylesoutdir} (hint: set mkdirs option)) unless ::File.directory? stylesoutdir
1475
+ raise ::IOError, %(target stylesheet directory does not exist: #{stylesoutdir} (hint: set :mkdirs option)) unless ::File.directory? stylesoutdir
1481
1476
  end
1482
1477
 
1483
1478
  if copy_asciidoctor_stylesheet
@@ -375,13 +375,13 @@ class AbstractBlock < AbstractNode
375
375
  # value - The explicit String caption to assign to this block (default: nil).
376
376
  # key - The String prefix for the caption and counter attribute names.
377
377
  # If not provided, the name of the context for this block is used.
378
- # (default: nil)
378
+ # (default: @context)
379
379
  #
380
380
  # Returns nothing.
381
- def assign_caption value = nil, key = nil
381
+ def assign_caption value = nil, key = @context
382
382
  unless @caption || !@title || (@caption = value || @document.attributes['caption'])
383
- if (prefix = @document.attributes[%(#{key ||= @context}-caption)])
384
- @caption = %(#{prefix} #{@numeral = @document.increment_and_store_counter "#{key}-number", self}. )
383
+ if (prefix = @document.attributes[%(#{key}-caption)])
384
+ @caption = %(#{prefix} #{@numeral = @document.increment_and_store_counter %[#{key}-number], self}. )
385
385
  nil
386
386
  end
387
387
  end
@@ -252,18 +252,26 @@ class Converter::Html5Converter < Converter::Base
252
252
  # IMPORTANT inspect calls on delimiter arrays are intentional for JavaScript compat (emulates JSON.stringify)
253
253
  result << %(<script type="text/x-mathjax-config">
254
254
  MathJax.Hub.Config({
255
- messageStyle: "none",
256
- tex2jax: {
257
- inlineMath: [#{INLINE_MATH_DELIMITERS[:latexmath].inspect}],
258
- displayMath: [#{BLOCK_MATH_DELIMITERS[:latexmath].inspect}],
259
- ignoreClass: "nostem|nolatexmath"
260
- },
261
- asciimath2jax: {
262
- delimiters: [#{BLOCK_MATH_DELIMITERS[:asciimath].inspect}],
263
- ignoreClass: "nostem|noasciimath"
264
- },
265
- TeX: {#{eqnums_opt}}
266
- });
255
+ messageStyle: "none",
256
+ tex2jax: {
257
+ inlineMath: [#{INLINE_MATH_DELIMITERS[:latexmath].inspect}],
258
+ displayMath: [#{BLOCK_MATH_DELIMITERS[:latexmath].inspect}],
259
+ ignoreClass: "nostem|nolatexmath"
260
+ },
261
+ asciimath2jax: {
262
+ delimiters: [#{BLOCK_MATH_DELIMITERS[:asciimath].inspect}],
263
+ ignoreClass: "nostem|noasciimath"
264
+ },
265
+ TeX: {#{eqnums_opt}}
266
+ })
267
+ MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
268
+ MathJax.InputJax.AsciiMath.postfilterHooks.Add(function (data, node) {
269
+ if ((node = data.script.parentNode) && (node = node.parentNode) && node.classList.contains('stemblock')) {
270
+ data.math.root.display = "block"
271
+ }
272
+ return data
273
+ })
274
+ })
267
275
  </script>
268
276
  <script src="#{cdn_base_url}/mathjax/#{MATHJAX_VERSION}/MathJax.js?config=TeX-MML-AM_HTMLorMML"></script>)
269
277
  end
@@ -197,7 +197,7 @@ module Extensions
197
197
  block = create_block parent, :image, nil, attrs, opts
198
198
  if title
199
199
  block.title = title
200
- block.assign_caption((attrs.delete 'caption'), (opts[:caption_context] || 'figure'))
200
+ block.assign_caption (attrs.delete 'caption'), (opts[:caption_context] || 'figure')
201
201
  end
202
202
  block
203
203
  end
@@ -319,7 +319,7 @@ module Extensions
319
319
  option :default_attrs, value
320
320
  end
321
321
  # NOTE default_attrs alias is deprecated
322
- alias default_attr default_attributes
322
+ alias default_attrs default_attributes
323
323
 
324
324
  def resolve_attributes *args
325
325
  # NOTE assume true as default value; rewrap single-argument string or symbol
@@ -484,8 +484,6 @@ module Extensions
484
484
  # If a location is not specified, the DocinfoProcessor is assumed
485
485
  # to add content to the header.
486
486
  class DocinfoProcessor < Processor
487
- attr_accessor :location
488
-
489
487
  def initialize config = {}
490
488
  super config
491
489
  @config[:location] ||= :head
@@ -584,10 +582,10 @@ module Extensions
584
582
  def resolve_attributes *args
585
583
  if args.size == 1 && !args[0]
586
584
  option :content_model, :text
587
- return
585
+ else
586
+ super
587
+ option :content_model, :attributes
588
588
  end
589
- super
590
- option :content_model, :attributes
591
589
  end
592
590
  # NOTE resolves_attributes alias is deprecated
593
591
  alias resolves_attributes resolve_attributes
@@ -23,22 +23,24 @@ module Helpers
23
23
  # Otherwise, nil is returned.
24
24
  def self.require_library name, gem_name = true, on_failure = :abort
25
25
  require name
26
- rescue ::LoadError => e
26
+ rescue ::LoadError
27
27
  include Logging unless include? Logging
28
28
  if gem_name
29
29
  gem_name = name if gem_name == true
30
30
  case on_failure
31
31
  when :abort
32
- raise ::LoadError, %(asciidoctor: FAILED: required gem '#{gem_name}' is not installed. Processing aborted.)
32
+ details = $!.path == gem_name ? '' : %[ (reason: #{$!.path ? %(cannot load '#{$!.path}') : $!.message})]
33
+ raise ::LoadError, %(asciidoctor: FAILED: required gem '#{gem_name}' is not available#{details}. Processing aborted.)
33
34
  when :warn
34
- logger.warn %(optional gem '#{gem_name}' is not installed. Functionality disabled.)
35
+ details = $!.path == gem_name ? '' : %[ (reason: #{$!.path ? %(cannot load '#{$!.path}') : $!.message})]
36
+ logger.warn %(optional gem '#{gem_name}' is not available#{details}. Functionality disabled.)
35
37
  end
36
38
  else
37
39
  case on_failure
38
40
  when :abort
39
- raise ::LoadError, %(asciidoctor: FAILED: #{e.message.chomp '.'}. Processing aborted.)
41
+ raise ::LoadError, %(asciidoctor: FAILED: #{$!.message.chomp '.'}. Processing aborted.)
40
42
  when :warn
41
- logger.warn %(#{e.message.chomp '.'}. Functionality disabled.)
43
+ logger.warn %(#{$!.message.chomp '.'}. Functionality disabled.)
42
44
  end
43
45
  end
44
46
  nil
@@ -602,9 +602,9 @@ class Parser
602
602
  # NOTE assume % units if not specified
603
603
  attributes['scaledwidth'] = (TrailingDigitsRx.match? scaledwidth) ? %(#{scaledwidth}%) : scaledwidth
604
604
  end
605
- if attributes.key? 'title'
606
- block.title = attributes.delete 'title'
607
- block.assign_caption((attributes.delete 'caption'), 'figure')
605
+ if attributes['title']
606
+ block.title = block_title = attributes.delete 'title'
607
+ block.assign_caption (attributes.delete 'caption'), 'figure'
608
608
  end
609
609
  end
610
610
  attributes['target'] = target
@@ -632,12 +632,12 @@ class Parser
632
632
  target = expanded_target
633
633
  end
634
634
  end
635
- if extension.config[:content_model] == :attributes
636
- document.parse_attributes content, extension.config[:positional_attrs] || [], sub_input: true, into: attributes if content
635
+ if (ext_config = extension.config)[:content_model] == :attributes
636
+ document.parse_attributes content, ext_config[:positional_attrs] || ext_config[:pos_attrs] || [], sub_input: true, into: attributes if content
637
637
  else
638
638
  attributes['text'] = content || ''
639
639
  end
640
- if (default_attrs = extension.config[:default_attrs])
640
+ if (default_attrs = ext_config[:default_attrs])
641
641
  attributes.update(default_attrs) {|_, old_v| old_v }
642
642
  end
643
643
  if (block = extension.process_method[parent, target, attributes])
@@ -680,10 +680,10 @@ class Parser
680
680
  elsif (style == 'float' || style == 'discrete') && (Compliance.underline_style_section_titles ?
681
681
  (is_section_title? this_line, reader.peek_line) : !indented && (atx_section_title? this_line))
682
682
  reader.unshift_line this_line
683
- float_id, float_reftext, float_title, float_level = parse_section_title reader, document, attributes['id']
683
+ float_id, float_reftext, block_title, float_level = parse_section_title reader, document, attributes['id']
684
684
  attributes['reftext'] = float_reftext if float_reftext
685
685
  block = Block.new(parent, :floating_title, content_model: :empty)
686
- block.title = float_title
686
+ block.title = block_title
687
687
  attributes.delete 'title'
688
688
  block.id = float_id || ((doc_attrs.key? 'sectids') ? (Section.generate_id block.title, document) : nil)
689
689
  block.level = float_level
@@ -871,11 +871,11 @@ class Parser
871
871
  return
872
872
  else
873
873
  if block_extensions && (extension = extensions.registered_for_block? block_context, cloaked_context)
874
- unless (content_model = extension.config[:content_model]) == :skip
875
- unless (positional_attrs = extension.config[:positional_attrs] || []).empty?
874
+ unless (content_model = (ext_config = extension.config)[:content_model]) == :skip
875
+ unless (positional_attrs = ext_config[:positional_attrs] || ext_config[:pos_attrs]).nil_or_empty?
876
876
  AttributeList.rekey(attributes, [nil] + positional_attrs)
877
877
  end
878
- if (default_attrs = extension.config[:default_attrs])
878
+ if (default_attrs = ext_config[:default_attrs])
879
879
  default_attrs.each {|k, v| attributes[k] ||= v }
880
880
  end
881
881
  # QUESTION should we clone the extension for each cloaked context and set in config?
@@ -894,12 +894,19 @@ class Parser
894
894
 
895
895
  # FIXME we've got to clean this up, it's horrible!
896
896
  block.source_location = reader.cursor_at_mark if document.sourcemap
897
- # FIXME title should be assigned when block is constructed
898
- block.title = attributes.delete 'title' if attributes.key? 'title'
897
+ # FIXME title and caption should be assigned when block is constructed (though we need to handle all cases)
898
+ if attributes['title']
899
+ block.title = block_title = attributes.delete 'title'
900
+ if CAPTIONABLE_BLOCKS[block_context = block.context] && document.attributes[%(#{block.context}-caption)]
901
+ block.assign_caption (attributes.delete 'caption'), block_context
902
+ end
903
+ end
899
904
  # TODO eventually remove the style attribute from the attributes hash
900
905
  #block.style = attributes.delete 'style'
901
906
  block.style = attributes['style']
902
907
  if (block_id = block.id || (block.id = attributes['id']))
908
+ # convert title to resolve attributes while in scope
909
+ block.title if block_title ? (block_title.include? ATTR_REF_HEAD) : block.title?
903
910
  unless document.register :refs, [block_id, block]
904
911
  logger.warn message_with_context %(id assigned to block already in use: #{block_id}), source_location: reader.cursor_at_mark
905
912
  end
@@ -1044,13 +1051,6 @@ class Parser
1044
1051
  block = Block.new(parent, block_context, content_model: content_model, source: lines, attributes: attributes)
1045
1052
  end
1046
1053
 
1047
- # QUESTION should we have an explicit map or can we rely on check for *-caption attribute?
1048
- if (attributes.key? 'title') && block.context != :admonition &&
1049
- (parent.document.attributes.key? %(#{block.context}-caption))
1050
- block.title = attributes.delete 'title'
1051
- block.assign_caption(attributes.delete 'caption')
1052
- end
1053
-
1054
1054
  # reader is confined within boundaries of a delimited block, so look for
1055
1055
  # blocks until there are no more lines
1056
1056
  parse_blocks block_reader, block if content_model == :compound
@@ -1521,7 +1521,7 @@ class Parser
1521
1521
  end
1522
1522
  end
1523
1523
  else
1524
- has_text = true if !this_line.empty?
1524
+ has_text = true unless this_line.empty?
1525
1525
  if nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line }
1526
1526
  within_nested_list = true
1527
1527
  if nested_list_type == :dlist && $3.nil_or_empty?
@@ -1612,7 +1612,9 @@ class Parser
1612
1612
  end
1613
1613
 
1614
1614
  # generate an ID if one was not embedded or specified as anchor above section title
1615
- if (id = section.id || (section.id = (document.attributes.key? 'sectids') ? (Section.generate_id section.title, document) : nil))
1615
+ if (id = section.id || (section.id = (document.attributes.key? 'sectids') ? (generated_id = Section.generate_id section.title, document) : nil))
1616
+ # convert title to resolve attributes while in scope
1617
+ section.title if sect_title.include? ATTR_REF_HEAD unless generated_id
1616
1618
  unless document.register :refs, [id, section]
1617
1619
  logger.warn message_with_context %(id assigned to section already in use: #{id}), source_location: (reader.cursor_at_line reader.lineno - (sect_atx ? 1 : 2))
1618
1620
  end
@@ -2268,10 +2270,6 @@ class Parser
2268
2270
  # returns an instance of Asciidoctor::Table parsed from the provided reader
2269
2271
  def self.parse_table(table_reader, parent, attributes)
2270
2272
  table = Table.new(parent, attributes)
2271
- if attributes.key? 'title'
2272
- table.title = attributes.delete 'title'
2273
- table.assign_caption(attributes.delete 'caption')
2274
- end
2275
2273
 
2276
2274
  if (attributes.key? 'cols') && !(colspecs = parse_colspecs attributes['cols']).empty?
2277
2275
  table.create_columns colspecs
@@ -309,26 +309,27 @@ module Substitutors
309
309
  text = text.gsub extension.instance.regexp do
310
310
  # honor the escape
311
311
  next $&.slice 1, $&.length if $&.start_with? RS
312
- extconf = extension.config
313
312
  if $~.names.empty?
314
313
  target, content = $1, $2
315
314
  else
316
315
  target, content = ($~[:target] rescue nil), ($~[:content] rescue nil)
317
316
  end
318
- attributes = (attributes = extconf[:default_attrs]) ? attributes.merge : {}
319
- if content.nil_or_empty?
320
- attributes['text'] = content if content && extconf[:content_model] != :attributes
321
- else
322
- content = normalize_text content, true, true
323
- # QUESTION should we store the unparsed attrlist in the attrlist key?
324
- if extconf[:content_model] == :attributes
325
- parse_attributes content, extconf[:positional_attrs] || [], into: attributes
317
+ attributes = (default_attrs = (ext_config = extension.config)[:default_attrs]) ? default_attrs.merge : {}
318
+ if content
319
+ if content.empty?
320
+ attributes['text'] = content unless ext_config[:content_model] == :attributes
326
321
  else
327
- attributes['text'] = content
322
+ content = normalize_text content, true, true
323
+ # QUESTION should we store the unparsed attrlist in the attrlist key?
324
+ if ext_config[:content_model] == :attributes
325
+ parse_attributes content, ext_config[:positional_attrs] || ext_config[:pos_attrs] || [], into: attributes
326
+ else
327
+ attributes['text'] = content
328
+ end
328
329
  end
330
+ # NOTE for convenience, map content (unparsed attrlist) to target when format is short
331
+ target ||= ext_config[:format] == :short ? content : target
329
332
  end
330
- # NOTE for convenience, map content (unparsed attrlist) to target when format is short
331
- target ||= extconf[:format] == :short ? content : target
332
333
  if (Inline === (replacement = extension.process_method[self, target, attributes]))
333
334
  if (inline_subs = replacement.attributes.delete 'subs')
334
335
  replacement.text = apply_subs replacement.text, (expand_subs inline_subs)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Asciidoctor
3
- VERSION = '2.0.0'
3
+ VERSION = '2.0.1'
4
4
  end
@@ -1,13 +1,13 @@
1
1
  '\" t
2
2
  .\" Title: asciidoctor
3
3
  .\" Author: Dan Allen, Sarah White, Ryan Waldron
4
- .\" Generator: Asciidoctor 2.0.0
5
- .\" Date: 2019-03-22
4
+ .\" Generator: Asciidoctor 2.0.1
5
+ .\" Date: 2019-03-25
6
6
  .\" Manual: Asciidoctor Manual
7
- .\" Source: Asciidoctor 2.0.0
7
+ .\" Source: Asciidoctor 2.0.1
8
8
  .\" Language: English
9
9
  .\"
10
- .TH "ASCIIDOCTOR" "1" "2019-03-22" "Asciidoctor 2.0.0" "Asciidoctor Manual"
10
+ .TH "ASCIIDOCTOR" "1" "2019-03-25" "Asciidoctor 2.0.1" "Asciidoctor Manual"
11
11
  .ie \n(.g .ds Aq \(aq
12
12
  .el .ds Aq '
13
13
  .ss \n[.ss] 0
@@ -2,7 +2,7 @@
2
2
  Dan Allen; Sarah White; Ryan Waldron
3
3
  :doctype: manpage
4
4
  :man manual: Asciidoctor Manual
5
- :man source: Asciidoctor 2.0.0
5
+ :man source: Asciidoctor 2.0.1
6
6
  :page-layout: base
7
7
 
8
8
  == NAME
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Allen
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2019-03-22 00:00:00.000000000 Z
16
+ date: 2019-03-25 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: asciimath
@@ -206,6 +206,7 @@ executables:
206
206
  extensions: []
207
207
  extra_rdoc_files: []
208
208
  files:
209
+ - ".yardopts"
209
210
  - CHANGELOG.adoc
210
211
  - LICENSE
211
212
  - README-de.adoc