asciidoctor 1.5.7.1 → 1.5.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +95 -5
  3. data/Gemfile +23 -13
  4. data/README-de.adoc +482 -0
  5. data/README-fr.adoc +128 -119
  6. data/README-jp.adoc +2 -3
  7. data/README-zh_CN.adoc +2 -3
  8. data/README.adoc +131 -106
  9. data/asciidoctor.gemspec +9 -7
  10. data/data/locale/attributes-ar.adoc +1 -1
  11. data/data/locale/attributes-bg.adoc +1 -1
  12. data/data/locale/attributes-ca.adoc +1 -1
  13. data/data/locale/attributes-cs.adoc +1 -1
  14. data/data/locale/attributes-da.adoc +1 -1
  15. data/data/locale/attributes-de.adoc +1 -1
  16. data/data/locale/attributes-en.adoc +1 -1
  17. data/data/locale/attributes-es.adoc +1 -1
  18. data/data/locale/attributes-fa.adoc +1 -1
  19. data/data/locale/attributes-fi.adoc +1 -1
  20. data/data/locale/attributes-fr.adoc +1 -1
  21. data/data/locale/attributes-hu.adoc +1 -1
  22. data/data/locale/attributes-id.adoc +1 -1
  23. data/data/locale/attributes-it.adoc +1 -1
  24. data/data/locale/attributes-ja.adoc +1 -1
  25. data/data/locale/attributes-kr.adoc +1 -1
  26. data/data/locale/attributes-nb.adoc +1 -1
  27. data/data/locale/attributes-nl.adoc +1 -1
  28. data/data/locale/attributes-nn.adoc +1 -1
  29. data/data/locale/attributes-pl.adoc +1 -1
  30. data/data/locale/attributes-pt.adoc +1 -1
  31. data/data/locale/attributes-pt_BR.adoc +1 -1
  32. data/data/locale/attributes-ro.adoc +1 -1
  33. data/data/locale/attributes-ru.adoc +1 -1
  34. data/data/locale/attributes-sr.adoc +5 -4
  35. data/data/locale/attributes-sr_Latn.adoc +5 -4
  36. data/data/locale/attributes-sv.adoc +23 -0
  37. data/data/locale/attributes-tr.adoc +1 -1
  38. data/data/locale/attributes-uk.adoc +1 -1
  39. data/data/locale/attributes-zh_CN.adoc +1 -1
  40. data/data/locale/attributes-zh_TW.adoc +1 -1
  41. data/data/stylesheets/asciidoctor-default.css +23 -23
  42. data/lib/asciidoctor.rb +110 -104
  43. data/lib/asciidoctor/abstract_block.rb +55 -32
  44. data/lib/asciidoctor/abstract_node.rb +32 -17
  45. data/lib/asciidoctor/attribute_list.rb +8 -7
  46. data/lib/asciidoctor/block.rb +5 -7
  47. data/lib/asciidoctor/cli/options.rb +5 -9
  48. data/lib/asciidoctor/converter.rb +2 -2
  49. data/lib/asciidoctor/converter/docbook45.rb +7 -20
  50. data/lib/asciidoctor/converter/docbook5.rb +36 -37
  51. data/lib/asciidoctor/converter/factory.rb +10 -8
  52. data/lib/asciidoctor/converter/html5.rb +90 -65
  53. data/lib/asciidoctor/converter/manpage.rb +72 -62
  54. data/lib/asciidoctor/converter/template.rb +8 -6
  55. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +5 -0
  56. data/lib/asciidoctor/document.rb +62 -10
  57. data/lib/asciidoctor/extensions.rb +74 -16
  58. data/lib/asciidoctor/helpers.rb +11 -14
  59. data/lib/asciidoctor/list.rb +2 -2
  60. data/lib/asciidoctor/parser.rb +223 -195
  61. data/lib/asciidoctor/path_resolver.rb +15 -7
  62. data/lib/asciidoctor/reader.rb +65 -36
  63. data/lib/asciidoctor/section.rb +6 -4
  64. data/lib/asciidoctor/substitutors.rb +170 -149
  65. data/lib/asciidoctor/table.rb +16 -8
  66. data/lib/asciidoctor/version.rb +1 -1
  67. data/man/asciidoctor.1 +6 -5
  68. data/man/asciidoctor.adoc +3 -2
  69. data/test/api_test.rb +236 -0
  70. data/test/attribute_list_test.rb +242 -0
  71. data/test/attributes_test.rb +65 -52
  72. data/test/blocks_test.rb +408 -260
  73. data/test/converter_test.rb +7 -7
  74. data/test/document_test.rb +60 -54
  75. data/test/extensions_test.rb +218 -32
  76. data/test/fixtures/doctime-localtime.adoc +2 -0
  77. data/test/fixtures/section-a.adoc +4 -0
  78. data/test/fixtures/subs.adoc +0 -1
  79. data/test/invoker_test.rb +56 -18
  80. data/test/links_test.rb +105 -81
  81. data/test/lists_test.rb +636 -265
  82. data/test/logger_test.rb +1 -1
  83. data/test/manpage_test.rb +140 -3
  84. data/test/paragraphs_test.rb +42 -42
  85. data/test/parser_test.rb +63 -183
  86. data/test/paths_test.rb +21 -4
  87. data/test/preamble_test.rb +9 -9
  88. data/test/reader_test.rb +78 -28
  89. data/test/sections_test.rb +273 -151
  90. data/test/substitutions_test.rb +53 -19
  91. data/test/tables_test.rb +286 -163
  92. data/test/test_helper.rb +4 -3
  93. data/test/text_test.rb +65 -65
  94. metadata +16 -21
@@ -13,10 +13,14 @@ class AbstractBlock < AbstractNode
13
13
  # Public: Set the Integer level of this Section or the Section level in which this Block resides
14
14
  attr_accessor :level
15
15
 
16
- # Public: Get/Set the number of this block (if section, relative to parent, otherwise absolute)
16
+ # Public: Get/Set the numeral of this block (if section, relative to parent, otherwise absolute)
17
17
  # Only assigned to section if automatic section numbering is enabled
18
18
  # Only assigned to formal block (block with title) if corresponding caption attribute is present
19
- attr_accessor :number
19
+ attr_accessor :numeral
20
+
21
+ # Deprecated: Legacy property to get/set the numeral of this block
22
+ alias number numeral
23
+ alias number= numeral=
20
24
 
21
25
  # Public: Gets/Sets the location in the AsciiDoc source where this block begins
22
26
  attr_accessor :source_location
@@ -32,7 +36,7 @@ class AbstractBlock < AbstractNode
32
36
  @content_model = :compound
33
37
  @blocks = []
34
38
  @subs = []
35
- @id = @title = @title_converted = @caption = @number = @style = @default_subs = @source_location = nil
39
+ @id = @title = @title_converted = @caption = @numeral = @style = @default_subs = @source_location = nil
36
40
  if context == :document
37
41
  @level = 0
38
42
  elsif parent && context != :section
@@ -41,7 +45,7 @@ class AbstractBlock < AbstractNode
41
45
  @level = nil
42
46
  end
43
47
  @next_section_index = 0
44
- @next_section_number = 1
48
+ @next_section_ordinal = 1
45
49
  end
46
50
 
47
51
  def block?
@@ -77,7 +81,7 @@ class AbstractBlock < AbstractNode
77
81
  # Public: Get the converted result of the child blocks by converting the
78
82
  # children appropriate to content model that this block supports.
79
83
  def content
80
- @blocks.map {|b| b.convert } * LF
84
+ @blocks.map {|b| b.convert }.join LF
81
85
  end
82
86
 
83
87
  # Public: Update the context of this block.
@@ -132,10 +136,16 @@ class AbstractBlock < AbstractNode
132
136
  @next_section_index > 0
133
137
  end
134
138
 
135
- # Public: Query for all descendant block-level nodes in the document tree
136
- # that match the specified selector (context, style, id, and/or role). If a
137
- # Ruby block is given, it's used as an additional filter. If no selector or
138
- # Ruby block is supplied, all block-level nodes in the tree are returned.
139
+ # Public: Walk the document tree and find all block-level nodes that match
140
+ # the specified selector (context, style, id, role, and/or custom filter).
141
+ #
142
+ # If a Ruby block is given, it's treated as an supplemental filter. If the
143
+ # filter returns true, the node is accepted and traversal continues. If the
144
+ # filter returns false, the node is rejected, but traversal continues. If the
145
+ # filter returns :skip, the node and all its descendants are rejected. If the
146
+ # filter returns :skip_children, the node is accepted, but its descendants
147
+ # are rejected. If no selector or filter block is supplied, all block-level
148
+ # nodes in the tree are returned.
139
149
  #
140
150
  # Examples
141
151
  #
@@ -153,20 +163,34 @@ class AbstractBlock < AbstractNode
153
163
  #--
154
164
  # TODO support jQuery-style selector (e.g., image.thumb)
155
165
  def find_by selector = {}, &block
156
- result = []
166
+ find_by_internal selector, (result = []), &block
167
+ rescue ::StopIteration
168
+ result
169
+ end
170
+
171
+ alias query find_by
157
172
 
173
+ # Internal: Performs the work for find_by, but does not handle the StopIteration exception.
174
+ def find_by_internal selector = {}, result = [], &block
158
175
  if ((any_context = !(context_selector = selector[:context])) || context_selector == @context) &&
159
176
  (!(style_selector = selector[:style]) || style_selector == @style) &&
160
177
  (!(role_selector = selector[:role]) || (has_role? role_selector)) &&
161
178
  (!(id_selector = selector[:id]) || id_selector == @id)
162
179
  if id_selector
163
- if block_given?
164
- return (yield self) ? [self] : result
165
- else
166
- return [self]
167
- end
180
+ result.replace block_given? ? ((yield self) ? [self] : []) : [self]
181
+ raise ::StopIteration
168
182
  elsif block_given?
169
- result << self if (yield self)
183
+ if (verdict = yield self)
184
+ case verdict
185
+ when :skip_children
186
+ result << self
187
+ return result
188
+ when :skip
189
+ return result
190
+ else
191
+ result << self
192
+ end
193
+ end
170
194
  else
171
195
  result << self
172
196
  end
@@ -174,7 +198,7 @@ class AbstractBlock < AbstractNode
174
198
 
175
199
  # process document header as a section if present
176
200
  if @context == :document && (any_context || context_selector == :section) && header?
177
- result.concat(@header.find_by selector, &block)
201
+ @header.find_by_internal selector, result, &block
178
202
  end
179
203
 
180
204
  unless context_selector == :document # optimization
@@ -183,21 +207,19 @@ class AbstractBlock < AbstractNode
183
207
  if any_context || context_selector != :section # optimization
184
208
  @blocks.flatten.each do |li|
185
209
  # NOTE the list item of a dlist can be nil, so we have to check
186
- result.concat(li.find_by selector, &block) if li
210
+ li.find_by_internal selector, result, &block if li
187
211
  end
188
212
  end
189
213
  elsif
190
214
  @blocks.each do |b|
191
215
  next if (context_selector == :section && b.context != :section) # optimization
192
- result.concat(b.find_by selector, &block)
216
+ b.find_by_internal selector, result, &block
193
217
  end
194
218
  end
195
219
  end
196
220
  result
197
221
  end
198
222
 
199
- alias query find_by
200
-
201
223
  # Move to the next adjacent block in document order. If the current block is the last
202
224
  # item in a list, this method will return the following sibling of the list block.
203
225
  def next_adjacent_block
@@ -358,14 +380,14 @@ class AbstractBlock < AbstractNode
358
380
  case xrefstyle
359
381
  when 'full'
360
382
  quoted_title = sprintf sub_quotes(@document.compat_mode ? %q(``%s'') : '"`%s`"'), title
361
- if @number && (prefix = @document.attributes[@context == :image ? 'figure-caption' : %(#{@context}-caption)])
362
- %(#{prefix} #{@number}, #{quoted_title})
383
+ if @numeral && (prefix = @document.attributes[@context == :image ? 'figure-caption' : %(#{@context}-caption)])
384
+ %(#{prefix} #{@numeral}, #{quoted_title})
363
385
  else
364
386
  %(#{@caption.chomp '. '}, #{quoted_title})
365
387
  end
366
388
  when 'short'
367
- if @number && (prefix = @document.attributes[@context == :image ? 'figure-caption' : %(#{@context}-caption)])
368
- %(#{prefix} #{@number})
389
+ if @numeral && (prefix = @document.attributes[@context == :image ? 'figure-caption' : %(#{@context}-caption)])
390
+ %(#{prefix} #{@numeral})
369
391
  else
370
392
  @caption.chomp '. '
371
393
  end
@@ -397,7 +419,7 @@ class AbstractBlock < AbstractNode
397
419
  def assign_caption value = nil, key = nil
398
420
  unless @caption || !@title || (@caption = value || @document.attributes['caption'])
399
421
  if (prefix = @document.attributes[%(#{key ||= @context}-caption)])
400
- @caption = %(#{prefix} #{@number = @document.increment_and_store_counter "#{key}-number", self}. )
422
+ @caption = %(#{prefix} #{@numeral = @document.increment_and_store_counter "#{key}-number", self}. )
401
423
  nil
402
424
  end
403
425
  end
@@ -417,17 +439,18 @@ class AbstractBlock < AbstractNode
417
439
  @next_section_index = (section.index = @next_section_index) + 1
418
440
  if (like = section.numbered)
419
441
  if (sectname = section.sectname) == 'appendix'
420
- section.number = @document.counter 'appendix-number', 'A'
442
+ section.numeral = @document.counter 'appendix-number', 'A'
421
443
  if (caption = @document.attributes['appendix-caption'])
422
- section.caption = %(#{caption} #{section.number}: )
444
+ section.caption = %(#{caption} #{section.numeral}: )
423
445
  else
424
- section.caption = %(#{section.number}. )
446
+ section.caption = %(#{section.numeral}. )
425
447
  end
426
448
  # NOTE currently chapters in a book doctype are sequential even for multi-part books (see #979)
427
449
  elsif sectname == 'chapter' || like == :chapter
428
- section.number = @document.counter 'chapter-number', 1
450
+ section.numeral = @document.counter 'chapter-number', 1
429
451
  else
430
- @next_section_number = (section.number = @next_section_number) + 1
452
+ section.numeral = @next_section_ordinal
453
+ @next_section_ordinal += 1
431
454
  end
432
455
  end
433
456
  nil
@@ -445,7 +468,7 @@ class AbstractBlock < AbstractNode
445
468
  # Returns nothing
446
469
  def reindex_sections
447
470
  @next_section_index = 0
448
- @next_section_number = 1
471
+ @next_section_ordinal = 1
449
472
  @blocks.each do |block|
450
473
  if block.context == :section
451
474
  assign_numeral block
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  module Asciidoctor
3
3
  # Public: An abstract base class that provides state and methods for managing a
4
- # node of AsciiDoc content. The state and methods on this class are comment to
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
7
  include Logging
@@ -162,21 +162,32 @@ class AbstractNode
162
162
  @attributes.key? %(#{name}-option)
163
163
  end
164
164
 
165
- # TODO document me
165
+ # Public: Set the specified option on this node.
166
+ #
167
+ # This method sets the specified option on this node if not already set.
168
+ # It will add the name to the options attribute and set the <name>-option
169
+ # attribute.
170
+ #
171
+ # name - the String name of the option
172
+ #
173
+ # returns truthy if the option was set or falsey if the option was already set
166
174
  def set_option(name)
167
- if @attributes.key? 'options'
168
- @attributes['options'] = %(#{@attributes['options']},#{name})
175
+ if (attrs = @attributes)['options']
176
+ unless attrs[key = %(#{name}-option)]
177
+ attrs['options'] += %(,#{name})
178
+ attrs[key] = ''
179
+ end
169
180
  else
170
- @attributes['options'] = name
181
+ attrs['options'] = name
182
+ attrs[%(#{name}-option)] = ''
171
183
  end
172
- @attributes[%(#{name}-option)] = ''
173
184
  end
174
185
 
175
186
  # Public: Update the attributes of this node with the new values in
176
187
  # the attributes argument.
177
188
  #
178
189
  # If an attribute already exists with the same key, it's value will
179
- # be overridden.
190
+ # be overwritten.
180
191
  #
181
192
  # attributes - A Hash of attributes to assign to this node.
182
193
  #
@@ -240,7 +251,7 @@ class AbstractNode
240
251
  if val.empty?
241
252
  @attributes.delete('role')
242
253
  else
243
- @attributes['role'] = val * ' '
254
+ @attributes['role'] = val.join ' '
244
255
  end
245
256
  true
246
257
  else
@@ -358,7 +369,7 @@ class AbstractNode
358
369
  def generate_data_uri(target_image, asset_dir_key = nil)
359
370
  ext = ::File.extname target_image
360
371
  # QUESTION what if ext is empty?
361
- mimetype = (ext == '.svg' ? 'image/svg+xml' : %(image/#{ext[1..-1]}))
372
+ mimetype = (ext == '.svg' ? 'image/svg+xml' : %(image/#{ext.slice 1, ext.length}))
362
373
  if asset_dir_key
363
374
  image_path = normalize_system_path(target_image, @document.attr(asset_dir_key), nil, :target_name => 'image')
364
375
  else
@@ -400,9 +411,9 @@ class AbstractNode
400
411
 
401
412
  begin
402
413
  mimetype = nil
403
- bindata = open image_uri, 'rb' do |fd|
404
- mimetype = fd.content_type
405
- fd.read
414
+ bindata = open image_uri, 'rb' do |f|
415
+ mimetype = f.content_type
416
+ f.read
406
417
  end
407
418
  # NOTE base64 is autoloaded by reference to ::Base64
408
419
  %(data:#{mimetype};base64,#{::Base64.strict_encode64 bindata})
@@ -499,7 +510,8 @@ class AbstractNode
499
510
  opts = { :warn_on_failure => (opts != false) } unless ::Hash === opts
500
511
  if ::File.readable? path
501
512
  if opts[:normalize]
502
- Helpers.normalize_lines_from_string(::IO.read path) * LF
513
+ # NOTE Opal does not yet support File#readlines
514
+ (Helpers.normalize_lines_array ::File.open(path, 'rb') {|f| f.each_line.to_a }).join LF
503
515
  else
504
516
  # QUESTION should we chomp or rstrip content?
505
517
  ::IO.read path
@@ -533,9 +545,12 @@ class AbstractNode
533
545
  if doc.attr? 'allow-uri-read'
534
546
  Helpers.require_library 'open-uri/cached', 'open-uri-cached' if doc.attr? 'cache-uri'
535
547
  begin
536
- data = ::OpenURI.open_uri(target) {|fd| fd.read }
537
- data = (Helpers.normalize_lines_from_string data) * LF if opts[:normalize]
538
- return data
548
+ if opts[:normalize]
549
+ # NOTE Opal does not yet support File#readlines
550
+ (Helpers.normalize_lines_array ::OpenURI.open_uri(target) {|f| f.each_line.to_a }).join LF
551
+ else
552
+ ::OpenURI.open_uri(target) {|f| f.read }
553
+ end
539
554
  rescue
540
555
  logger.warn %(could not retrieve contents of #{opts[:label] || 'asset'} at URI: #{target}) if opts.fetch :warn_on_failure, true
541
556
  return
@@ -546,7 +561,7 @@ class AbstractNode
546
561
  end
547
562
  else
548
563
  target = normalize_system_path target, opts[:start], nil, :target_name => (opts[:label] || 'asset')
549
- return read_asset target, :normalize => opts[:normalize], :warn_on_failure => (opts.fetch :warn_on_failure, true), :label => opts[:label]
564
+ read_asset target, :normalize => opts[:normalize], :warn_on_failure => (opts.fetch :warn_on_failure, true), :label => opts[:label]
550
565
  end
551
566
  end
552
567
 
@@ -23,18 +23,19 @@ module Asciidoctor
23
23
  #
24
24
  class AttributeList
25
25
  BACKSLASH = '\\'
26
+ APOS = '\''
26
27
 
27
28
  # Public: Regular expressions for detecting the boundary of a value
28
29
  BoundaryRxs = {
29
30
  '"' => /.*?[^\\](?=")/,
30
- '\'' => /.*?[^\\](?=')/,
31
+ APOS => /.*?[^\\](?=')/,
31
32
  ',' => /.*?(?=[ \t]*(,|$))/
32
33
  }
33
34
 
34
35
  # Public: Regular expressions for unescaping quoted characters
35
36
  EscapedQuotes = {
36
37
  '"' => '\\"',
37
- '\'' => '\\\''
38
+ APOS => '\\\''
38
39
  }
39
40
 
40
41
  # Public: A regular expression for an attribute name (approx. name token from XML)
@@ -105,10 +106,10 @@ class AttributeList
105
106
  name = parse_attribute_value @scanner.get_byte
106
107
  value = nil
107
108
  # example: 'quote'
108
- elsif first == '\''
109
+ elsif first == APOS
109
110
  name = parse_attribute_value @scanner.get_byte
110
111
  value = nil
111
- single_quoted_value = true
112
+ single_quoted_value = true unless name.start_with? APOS
112
113
  else
113
114
  name = scan_name
114
115
 
@@ -135,12 +136,12 @@ class AttributeList
135
136
  if (c = @scanner.get_byte) == '"'
136
137
  value = parse_attribute_value c
137
138
  # example: foo='bar' || foo='ba\'zaar' || foo='ba"zaar'
138
- elsif c == '\''
139
+ elsif c == APOS
139
140
  value = parse_attribute_value c
140
- single_quoted_value = true
141
+ single_quoted_value = true unless value.start_with? APOS
141
142
  # example: foo=,
142
143
  elsif c == @delimiter
143
- value = nil
144
+ value = ''
144
145
  # example: foo=bar (all spaces ignored)
145
146
  else
146
147
  value = %(#{c}#{scan_to_delimiter})
@@ -61,7 +61,7 @@ class Block < AbstractBlock
61
61
  # e.g., :subs => [:quotes]
62
62
  # subs attribute is not honored
63
63
  elsif ::Array === subs
64
- @default_subs = subs.dup
64
+ @default_subs = subs.drop 0
65
65
  @attributes.delete 'subs'
66
66
  # e.g., :subs => :normal or :subs => 'normal'
67
67
  # subs attribute is not honored
@@ -90,7 +90,7 @@ class Block < AbstractBlock
90
90
  elsif ::String === raw_source
91
91
  @lines = Helpers.normalize_lines_from_string raw_source
92
92
  else
93
- @lines = raw_source.dup
93
+ @lines = raw_source.drop 0
94
94
  end
95
95
  end
96
96
 
@@ -109,10 +109,8 @@ class Block < AbstractBlock
109
109
  when :compound
110
110
  super
111
111
  when :simple
112
- apply_subs @lines * LF, @subs
112
+ apply_subs((@lines.join LF), @subs)
113
113
  when :verbatim, :raw
114
- #((apply_subs @lines * LF, @subs).sub StripLineWiseRx, '\1')
115
-
116
114
  # QUESTION could we use strip here instead of popping empty lines?
117
115
  # maybe apply_subs can know how to strip whitespace?
118
116
  result = apply_subs @lines, @subs
@@ -121,7 +119,7 @@ class Block < AbstractBlock
121
119
  else
122
120
  result.shift while (first = result[0]) && first.rstrip.empty?
123
121
  result.pop while (last = result[-1]) && last.rstrip.empty?
124
- result * LF
122
+ result.join LF
125
123
  end
126
124
  else
127
125
  logger.warn %(Unknown content model '#{@content_model}' for block: #{to_s}) unless @content_model == :empty
@@ -134,7 +132,7 @@ class Block < AbstractBlock
134
132
  # Returns the a String containing the lines joined together or empty string
135
133
  # if there are no lines
136
134
  def source
137
- @lines * LF
135
+ @lines.join LF
138
136
  end
139
137
 
140
138
  def to_s
@@ -65,7 +65,7 @@ Example: asciidoctor -b html5 source.asciidoc
65
65
  self[:safe] = SafeMode::SAFE
66
66
  end
67
67
  opts.on('-S', '--safe-mode SAFE_MODE', (safe_mode_names = SafeMode.names),
68
- %(set safe mode level explicitly: [#{safe_mode_names * ', '}] (default: unsafe)),
68
+ %(set safe mode level explicitly: [#{safe_mode_names.join ', '}] (default: unsafe)),
69
69
  'disables potentially dangerous macros in source files, such as include::[]') do |name|
70
70
  self[:safe] = SafeMode.value_for_name name
71
71
  end
@@ -84,10 +84,6 @@ Example: asciidoctor -b html5 source.asciidoc
84
84
  'defined in the source document') do |attr|
85
85
  key, val = attr.split '=', 2
86
86
  val = val ? (FORCE_ENCODING ? (val.force_encoding ::Encoding::UTF_8) : val) : ''
87
- # move leading ! to end for internal processing
88
- #if !val && key.start_with?('!')
89
- # key = %(#{key[1..-1]}!)
90
- #end
91
87
  self[:attributes][key] = val
92
88
  end
93
89
  opts.on('-T', '--template-dir DIR', 'a directory containing custom converter templates that override the built-in converter (requires tilt gem)',
@@ -199,7 +195,7 @@ Example: asciidoctor -b html5 source.asciidoc
199
195
  args.each do |file|
200
196
  if file == '-' || (file.start_with? '-')
201
197
  # warn, but don't panic; we may have enough to proceed, so we won't force a failure
202
- $stderr.puts %(asciidoctor: WARNING: extra arguments detected (unparsed arguments: '#{args * "', '"}') or incorrect usage of stdin)
198
+ $stderr.puts %(asciidoctor: WARNING: extra arguments detected (unparsed arguments: '#{args.join "', '"}') or incorrect usage of stdin)
203
199
  else
204
200
  if ::File.file? file
205
201
  infiles << file
@@ -290,13 +286,13 @@ Example: asciidoctor -b html5 source.asciidoc
290
286
 
291
287
  def print_version os = $stdout
292
288
  os.puts %(Asciidoctor #{::Asciidoctor::VERSION} [https://asciidoctor.org])
293
- if RUBY_MIN_VERSION_1_9
289
+ if ::RUBY_MIN_VERSION_1_9
294
290
  encoding_info = { 'lc' => 'locale', 'fs' => 'filesystem', 'in' => 'internal', 'ex' => 'external' }.map do |k, v|
295
291
  %(#{k}:#{v == 'internal' ? (::File.open(__FILE__) {|f| f.getc }).encoding : (::Encoding.find v)})
296
292
  end
297
- os.puts %(Runtime Environment (#{RUBY_DESCRIPTION}) (#{encoding_info * ' '}))
293
+ os.puts %(Runtime Environment (#{::RUBY_DESCRIPTION}) (#{encoding_info.join ' '}))
298
294
  else
299
- os.puts %(Runtime Environment (#{RUBY_DESCRIPTION}))
295
+ os.puts %(Runtime Environment (#{::RUBY_DESCRIPTION}))
300
296
  end
301
297
  0
302
298
  end
@@ -25,7 +25,7 @@ module Asciidoctor
25
25
  # when 'document'
26
26
  # node.content
27
27
  # when 'section'
28
- # [node.title, node.content] * "\n\n"
28
+ # [node.title, node.content].join "\n\n"
29
29
  # when 'paragraph'
30
30
  # node.content.tr("\n", ' ') << "\n"
31
31
  # else
@@ -77,7 +77,7 @@ module Asciidoctor
77
77
  raise ::ArgumentError, %(Cannot determine backend for converter: #{self.class}) unless @backend
78
78
  base = @backend.sub TrailingDigitsRx, ''
79
79
  if (ext = DEFAULT_EXTENSIONS[base])
80
- type = ext[1..-1]
80
+ type = ext.slice 1, ext.length
81
81
  else
82
82
  # QUESTION should we be forcing the basebackend to html if unknown?
83
83
  base = 'html'