asciidoctor 1.5.4 → 1.5.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of asciidoctor might be problematic. Click here for more details.

Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +72 -5
  3. data/CONTRIBUTING.adoc +3 -3
  4. data/Gemfile +23 -0
  5. data/README-fr.adoc +416 -0
  6. data/README-jp.adoc +395 -0
  7. data/README-zh_CN.adoc +414 -0
  8. data/README.adoc +134 -72
  9. data/asciidoctor.gemspec +49 -0
  10. data/data/locale/attributes.adoc +470 -0
  11. data/data/stylesheets/asciidoctor-default.css +6 -5
  12. data/lib/asciidoctor.rb +22 -19
  13. data/lib/asciidoctor/abstract_block.rb +20 -10
  14. data/lib/asciidoctor/abstract_node.rb +3 -14
  15. data/lib/asciidoctor/cli/invoker.rb +5 -4
  16. data/lib/asciidoctor/cli/options.rb +1 -1
  17. data/lib/asciidoctor/converter/docbook5.rb +1 -1
  18. data/lib/asciidoctor/converter/factory.rb +1 -5
  19. data/lib/asciidoctor/converter/html5.rb +36 -31
  20. data/lib/asciidoctor/converter/manpage.rb +14 -9
  21. data/lib/asciidoctor/converter/template.rb +8 -4
  22. data/lib/asciidoctor/core_ext.rb +7 -6
  23. data/lib/asciidoctor/core_ext/{string → 1.8.7/string}/chr.rb +1 -1
  24. data/lib/asciidoctor/core_ext/1.8.7/string/limit.rb +28 -0
  25. data/lib/asciidoctor/core_ext/{symbol → 1.8.7/symbol}/length.rb +1 -1
  26. data/lib/asciidoctor/core_ext/nil_or_empty.rb +23 -0
  27. data/lib/asciidoctor/core_ext/string/limit.rb +10 -0
  28. data/lib/asciidoctor/document.rb +33 -26
  29. data/lib/asciidoctor/extensions.rb +16 -16
  30. data/lib/asciidoctor/helpers.rb +1 -1
  31. data/lib/asciidoctor/list.rb +3 -0
  32. data/lib/asciidoctor/parser.rb +47 -43
  33. data/lib/asciidoctor/path_resolver.rb +3 -1
  34. data/lib/asciidoctor/reader.rb +15 -14
  35. data/lib/asciidoctor/section.rb +2 -2
  36. data/lib/asciidoctor/stylesheets.rb +2 -1
  37. data/lib/asciidoctor/substitutors.rb +44 -46
  38. data/lib/asciidoctor/table.rb +41 -38
  39. data/lib/asciidoctor/version.rb +1 -1
  40. data/man/asciidoctor.1 +11 -4
  41. data/man/asciidoctor.adoc +7 -1
  42. data/test/attributes_test.rb +52 -0
  43. data/test/blocks_test.rb +8 -8
  44. data/test/document_test.rb +13 -1
  45. data/test/extensions_test.rb +38 -0
  46. data/test/invoker_test.rb +15 -0
  47. data/test/lists_test.rb +78 -53
  48. data/test/manpage_test.rb +15 -0
  49. data/test/paths_test.rb +3 -0
  50. data/test/reader_test.rb +2 -2
  51. data/test/sections_test.rb +10 -0
  52. data/test/substitutions_test.rb +12 -6
  53. data/test/tables_test.rb +76 -2
  54. metadata +16 -45
  55. data/lib/asciidoctor/core_ext/object/nil_or_empty.rb +0 -23
  56. data/test/fixtures/asciidoc_index.txt +0 -521
  57. data/test/fixtures/basic-docinfo-footer.html +0 -6
  58. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  59. data/test/fixtures/basic-docinfo.html +0 -1
  60. data/test/fixtures/basic-docinfo.xml +0 -4
  61. data/test/fixtures/basic.asciidoc +0 -5
  62. data/test/fixtures/chapter-a.adoc +0 -3
  63. data/test/fixtures/child-include.adoc +0 -5
  64. data/test/fixtures/circle.svg +0 -8
  65. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  66. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  67. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  68. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  69. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  70. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  71. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  72. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  73. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  74. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  75. data/test/fixtures/docinfo-footer.html +0 -1
  76. data/test/fixtures/docinfo-footer.xml +0 -9
  77. data/test/fixtures/docinfo.html +0 -1
  78. data/test/fixtures/docinfo.xml +0 -3
  79. data/test/fixtures/dot.gif +0 -0
  80. data/test/fixtures/encoding.asciidoc +0 -13
  81. data/test/fixtures/grandchild-include.adoc +0 -3
  82. data/test/fixtures/hello-asciidoctor.pdf +0 -0
  83. data/test/fixtures/include-file.asciidoc +0 -24
  84. data/test/fixtures/include-file.xml +0 -5
  85. data/test/fixtures/master.adoc +0 -5
  86. data/test/fixtures/parent-include-restricted.adoc +0 -5
  87. data/test/fixtures/parent-include.adoc +0 -5
  88. data/test/fixtures/sample.asciidoc +0 -26
  89. data/test/fixtures/stylesheets/custom.css +0 -3
  90. data/test/fixtures/subs-docinfo.html +0 -2
  91. data/test/fixtures/subs.adoc +0 -7
  92. data/test/fixtures/tip.gif +0 -0
  93. data/test/test_helper.rb +0 -399
@@ -14,6 +14,13 @@ module Asciidoctor
14
14
  ESC_BS = %(#{ESC}\\) # escaped backslash (indicates troff formatting sequence)
15
15
  ESC_FS = %(#{ESC}.) # escaped full stop (indicates troff macro)
16
16
 
17
+ LiteralBackslashRx = /(?:\A|[^#{ESC}])\\/
18
+ LeadingPeriodRx = /^\./
19
+ EscapedMacroRx = /^(?:#{ESC}\\c\n)?#{ESC}\.((?:URL|MTO) ".*?" ".*?" )( |[^\s]*)(.*?)(?: *#{ESC}\\c)?$/
20
+ MockBoundaryRx = /<\/?BOUNDARY>/
21
+ EmDashCharRefRx = /&#8212(?:;&#8203;)?/
22
+ EllipsisCharRefRx = /&#8230;(?:&#8203;)?/
23
+
17
24
  # Converts HTML entity references back to their original form, escapes
18
25
  # special man characters and strips trailing whitespace.
19
26
  #
@@ -26,12 +33,10 @@ module Asciidoctor
26
33
  # * :append_newline a Boolean that indicates whether to append an endline to the result (default: false)
27
34
  def manify str, opts = {}
28
35
  str = ((opts.fetch :preserve_space, true) ? (str.gsub TAB, ET) : (str.tr_s WHITESPACE, ' ')).
29
- gsub(/(?:\A|[^#{ESC}])\\/, '\&(rs'). # literal backslash (not a troff escape sequence)
30
- gsub(/^\./, '\\\&.'). # leading . is used in troff for macro call or other formatting; replace with \&.
36
+ gsub(LiteralBackslashRx, '\&(rs'). # literal backslash (not a troff escape sequence)
37
+ gsub(LeadingPeriodRx, '\\\&.'). # leading . is used in troff for macro call or other formatting; replace with \&.
31
38
  # drop orphaned \c escape lines, unescape troff macro, quote adjacent character, isolate macro line
32
- gsub(/^(?:#{ESC}\\c\n)?#{ESC}\.((?:URL|MTO) ".*?" ".*?" )( |[^\s]*)(.*?)(?: *#{ESC}\\c)?$/) {
33
- (rest = $3.lstrip).empty? ? %(.#$1"#$2") : %(.#$1"#$2"#{LF}#{rest})
34
- }.
39
+ gsub(EscapedMacroRx) { (rest = $3.lstrip).empty? ? %(.#$1"#$2") : %(.#$1"#$2"#{LF}#{rest}) }.
35
40
  gsub('-', '\-').
36
41
  gsub('&lt;', '<').
37
42
  gsub('&gt;', '>').
@@ -41,20 +46,20 @@ module Asciidoctor
41
46
  gsub('&#8482;', '\(tm'). # trademark sign
42
47
  gsub('&#8201;', ' '). # thin space
43
48
  gsub('&#8211;', '\(en'). # en dash
44
- gsub(/&#8212(?:;&#8203;)?/, '\(em'). # em dash
49
+ gsub(EmDashCharRefRx, '\(em'). # em dash
45
50
  gsub('&#8216;', '\(oq'). # left single quotation mark
46
51
  gsub('&#8217;', '\(cq'). # right single quotation mark
47
52
  gsub('&#8220;', '\(lq'). # left double quotation mark
48
53
  gsub('&#8221;', '\(rq'). # right double quotation mark
49
- gsub(/&#8230;(?:&#8203;)?/, '...'). # horizontal ellipsis
54
+ gsub(EllipsisCharRefRx, '...'). # horizontal ellipsis
50
55
  gsub('&#8592;', '\(<-'). # leftwards arrow
51
56
  gsub('&#8594;', '\(->'). # rightwards arrow
52
57
  gsub('&#8656;', '\(lA'). # leftwards double arrow
53
58
  gsub('&#8658;', '\(rA'). # rightwards double arrow
54
59
  gsub('&#8203;', '\:'). # zero width space
55
60
  gsub('\'', '\(aq'). # apostrophe-quote
56
- gsub(/<\/?BOUNDARY>/, '').# artificial boundary
57
- gsub(ESC_BS, '\\'). # unescape troff backslash (NOTE update if more escaped are added)
61
+ gsub(MockBoundaryRx, ''). # mock boundary
62
+ gsub(ESC_BS, '\\'). # unescape troff backslash (NOTE update if more escapes are added)
58
63
  rstrip # strip trailing space
59
64
  opts[:append_newline] ? %(#{str}#{LF}) : str
60
65
  end
@@ -246,20 +246,24 @@ module Asciidoctor
246
246
  elsif name.start_with? 'block_'
247
247
  name = name[6..-1]
248
248
  end
249
- ext_name = path_segments[-1]
249
+
250
250
  template_class = ::Tilt
251
251
  extra_engine_options = {}
252
- if ext_name == 'slim'
252
+ case (ext_name = path_segments[-1])
253
+ when 'slim'
253
254
  # slim doesn't get loaded by Tilt, so we have to load it explicitly
254
255
  Helpers.require_library 'slim' unless defined? ::Slim
255
256
  # align safe mode of AsciiDoc embedded in Slim template with safe mode of current document
256
257
  (@engine_options[:slim][:asciidoc] ||= {})[:safe] ||= @safe if @safe && ::Slim::VERSION >= '3.0'
257
258
  # load include plugin when using Slim >= 2.1
258
259
  require 'slim/include' unless (defined? ::Slim::Include) || ::Slim::VERSION < '2.1'
259
- elsif ext_name == 'erb'
260
+ when 'erb'
260
261
  template_class, extra_engine_options = (eruby_loaded ||= load_eruby(@eruby))
262
+ when 'rb'
263
+ next
264
+ else
265
+ next unless ::Tilt.registered? ext_name
261
266
  end
262
- next unless ::Tilt.registered? ext_name
263
267
  unless template_cache && (template = template_cache[file])
264
268
  template = template_class.new file, 1, (@engine_options[ext_name.to_sym] || {}).merge(extra_engine_options)
265
269
  end
@@ -1,7 +1,8 @@
1
- require 'asciidoctor/core_ext/object/nil_or_empty'
2
- unless RUBY_ENGINE == 'opal'
3
- unless RUBY_MIN_VERSION_1_9
4
- require 'asciidoctor/core_ext/string/chr'
5
- require 'asciidoctor/core_ext/symbol/length'
6
- end
1
+ require 'asciidoctor/core_ext/nil_or_empty'
2
+ if RUBY_MIN_VERSION_1_9
3
+ require 'asciidoctor/core_ext/string/limit'
4
+ elsif RUBY_ENGINE != 'opal'
5
+ require 'asciidoctor/core_ext/1.8.7/string/chr'
6
+ require 'asciidoctor/core_ext/1.8.7/string/limit'
7
+ require 'asciidoctor/core_ext/1.8.7/symbol/length'
7
8
  end
@@ -2,5 +2,5 @@
2
2
  class String
3
3
  def chr
4
4
  self[0..0]
5
- end unless respond_to? :chr
5
+ end unless method_defined? :chr
6
6
  end
@@ -0,0 +1,28 @@
1
+ if RUBY_ENGINE_JRUBY
2
+ class String
3
+ # Safely truncate the string to the specified number of bytes.
4
+ # If a multibyte char gets split, the dangling fragment is removed.
5
+ def limit size
6
+ return self unless size < bytesize
7
+ result = (unpack %(a#{size}))[0]
8
+ begin
9
+ result.unpack 'U*'
10
+ rescue ArgumentError
11
+ result.chop!
12
+ retry
13
+ end
14
+ result
15
+ end unless method_defined? :limit
16
+ end
17
+ else
18
+ class String
19
+ # Safely truncate the string to the specified number of bytes.
20
+ # If a multibyte char gets split, the dangling fragment is removed.
21
+ def limit size
22
+ return self unless size < bytesize
23
+ result = (unpack %(a#{size}))[0]
24
+ result.chop! until result.empty? || /.$/u =~ result
25
+ result
26
+ end unless method_defined? :limit
27
+ end
28
+ end
@@ -2,5 +2,5 @@
2
2
  class Symbol
3
3
  def length
4
4
  to_s.length
5
- end unless respond_to? :length
5
+ end unless method_defined? :length
6
6
  end
@@ -0,0 +1,23 @@
1
+ # A core library extension that defines the method nil_or_empty? as an alias to
2
+ # optimize checks for nil? or empty? on common object types such as NilClass,
3
+ # String, Array, Hash, and Numeric.
4
+
5
+ class NilClass
6
+ alias :nil_or_empty? :nil? unless method_defined? :nil_or_empty?
7
+ end
8
+
9
+ class String
10
+ alias :nil_or_empty? :empty? unless method_defined? :nil_or_empty?
11
+ end
12
+
13
+ class Array
14
+ alias :nil_or_empty? :empty? unless method_defined? :nil_or_empty?
15
+ end
16
+
17
+ class Hash
18
+ alias :nil_or_empty? :empty? unless method_defined? :nil_or_empty?
19
+ end
20
+
21
+ class Numeric
22
+ alias :nil_or_empty? :nil? unless method_defined? :nil_or_empty?
23
+ end
@@ -0,0 +1,10 @@
1
+ class String
2
+ # Safely truncate the string to the specified number of bytes.
3
+ # If a multibyte char gets split, the dangling fragment is removed.
4
+ def limit size
5
+ return self unless size < bytesize
6
+ # NOTE JRuby 1.7 & Rubinius fail to detect invalid encoding unless encoding is forced; impact is marginal.
7
+ size -= 1 until ((result = byteslice 0, size).force_encoding ::Encoding::UTF_8).valid_encoding?
8
+ result
9
+ end unless method_defined? :limit
10
+ end
@@ -225,7 +225,7 @@ class Document < AbstractBlock
225
225
  # safely resolve the safe mode from const, int or string
226
226
  if !(safe_mode = options[:safe])
227
227
  @safe = SafeMode::SECURE
228
- elsif ::Fixnum === safe_mode
228
+ elsif ::Integer === safe_mode
229
229
  # be permissive in case API user wants to define new levels
230
230
  @safe = safe_mode
231
231
  else
@@ -236,8 +236,8 @@ class Document < AbstractBlock
236
236
  @safe = SafeMode::SECURE
237
237
  end
238
238
  end
239
+ @compat_mode = attr_overrides.key? 'compat-mode'
239
240
  @sourcemap = options[:sourcemap]
240
- @compat_mode = false
241
241
  @converter = nil
242
242
  initialize_extensions = defined? ::Asciidoctor::Extensions
243
243
  @extensions = nil # initialize furthur down
@@ -287,7 +287,7 @@ class Document < AbstractBlock
287
287
  attr_overrides['asciidoctor'] = ''
288
288
  attr_overrides['asciidoctor-version'] = VERSION
289
289
 
290
- safe_mode_name = SafeMode.constants.detect {|l| SafeMode.const_get(l) == @safe }.to_s.downcase
290
+ safe_mode_name = SafeMode.constants.find {|l| SafeMode.const_get(l) == @safe }.to_s.downcase
291
291
  attr_overrides['safe-mode-name'] = safe_mode_name
292
292
  attr_overrides["safe-mode-#{safe_mode_name}"] = ''
293
293
  attr_overrides['safe-mode-level'] = @safe
@@ -295,14 +295,11 @@ class Document < AbstractBlock
295
295
  # sync the embedded attribute w/ the value of options...do not allow override
296
296
  attr_overrides['embedded'] = header_footer ? nil : ''
297
297
 
298
- # the only way to set the max-include-depth attribute is via the document options
299
- # 64 is the AsciiDoc default
298
+ # the only way to set the max-include-depth attribute is via the API; default to 64 like AsciiDoc Python
300
299
  attr_overrides['max-include-depth'] ||= 64
301
300
 
302
- # the only way to enable uri reads is via the document options, disabled by default
303
- unless !attr_overrides['allow-uri-read'].nil?
304
- attr_overrides['allow-uri-read'] = nil
305
- end
301
+ # the only way to set the allow-uri-read attribute is via the API; disabled by default
302
+ attr_overrides['allow-uri-read'] ||= nil
306
303
 
307
304
  attr_overrides['user-home'] = USER_HOME
308
305
 
@@ -344,6 +341,7 @@ class Document < AbstractBlock
344
341
  attr_overrides['docdir'] = ''
345
342
  attr_overrides['user-home'] = '.'
346
343
  if @safe >= SafeMode::SECURE
344
+ attr_overrides['max-attribute-value-size'] = 4096 unless attr_overrides.key? 'max-attribute-value-size'
347
345
  # assign linkcss (preventing css embedding) unless explicitly disabled from the commandline or API
348
346
  # effectively the same has "has key 'linkcss' and value == nil"
349
347
  unless attr_overrides.fetch('linkcss', '').nil?
@@ -354,6 +352,9 @@ class Document < AbstractBlock
354
352
  end
355
353
  end
356
354
 
355
+ # the only way to set the max-attribute-value-size attribute is via the API; disabled by default
356
+ @max_attribute_value_size = (val = (attr_overrides['max-attribute-value-size'] ||= nil)) ? val.to_i.abs : nil
357
+
357
358
  attr_overrides.delete_if do |key, val|
358
359
  verdict = false
359
360
  # a nil value undefines the attribute
@@ -371,8 +372,6 @@ class Document < AbstractBlock
371
372
  verdict
372
373
  end
373
374
 
374
- @compat_mode = true if attrs.key? 'compat-mode'
375
-
376
375
  if parent_doc
377
376
  # setup default doctype (backend is fixed)
378
377
  attrs['doctype'] ||= DEFAULT_DOCTYPE
@@ -401,13 +400,15 @@ class Document < AbstractBlock
401
400
  #attrs['infile'] = attrs['docfile']
402
401
 
403
402
  # dynamic intrinstic attribute values
404
- now = ::Time.now
403
+
404
+ # See https://reproducible-builds.org/specs/source-date-epoch/
405
+ now = ::ENV['SOURCE_DATE_EPOCH'] ? (::Time.at ::ENV['SOURCE_DATE_EPOCH'].to_i).utc : ::Time.now
405
406
  localdate = (attrs['localdate'] ||= now.strftime('%Y-%m-%d'))
406
407
  unless (localtime = attrs['localtime'])
407
408
  begin
408
409
  localtime = attrs['localtime'] = now.strftime('%H:%M:%S %Z')
409
- rescue
410
- localtime = attrs['localtime'] = now.strftime('%H:%M:%S')
410
+ rescue # Asciidoctor.js fails if timezone string has characters outside basic Latin (see asciidoctor.js#23)
411
+ localtime = attrs['localtime'] = now.strftime('%H:%M:%S %z')
411
412
  end
412
413
  end
413
414
  attrs['localdatetime'] ||= %(#{localdate} #{localtime})
@@ -679,7 +680,7 @@ class Document < AbstractBlock
679
680
 
680
681
  # QUESTION move to AbstractBlock?
681
682
  def first_section
682
- has_header? ? @header : (@blocks || []).detect{|e| e.context == :section }
683
+ has_header? ? @header : (@blocks || []).find {|e| e.context == :section }
683
684
  end
684
685
 
685
686
  def has_header?
@@ -835,13 +836,18 @@ class Document < AbstractBlock
835
836
  if attribute_locked?(name)
836
837
  false
837
838
  else
839
+ if @max_attribute_value_size
840
+ resolved_value = (apply_attribute_value_subs value).limit @max_attribute_value_size
841
+ else
842
+ resolved_value = apply_attribute_value_subs value
843
+ end
838
844
  case name
839
845
  when 'backend'
840
- update_backend_attributes apply_attribute_value_subs(value), !!@attributes_modified.delete?('htmlsyntax')
846
+ update_backend_attributes resolved_value, !!@attributes_modified.delete?('htmlsyntax')
841
847
  when 'doctype'
842
- update_doctype_attributes apply_attribute_value_subs(value)
848
+ update_doctype_attributes resolved_value
843
849
  else
844
- @attributes[name] = apply_attribute_value_subs(value)
850
+ @attributes[name] = resolved_value
845
851
  end
846
852
  @attributes_modified << name
847
853
  true
@@ -1110,17 +1116,18 @@ class Document < AbstractBlock
1110
1116
  # attribute is set, read the doc-name.docinfo.ext file. If the docinfo2
1111
1117
  # attribute is set, read both files in that order.
1112
1118
  #
1113
- # location - The Symbol location of the docinfo, either :header or :footer. (default: :header)
1114
- # ext - The extension of the docinfo file(s). If not set, the extension
1115
- # will be determined based on the basebackend. (default: nil)
1119
+ # location - The Symbol location of the docinfo (e.g., :head, :footer, etc). (default: :head)
1120
+ # suffix - The suffix of the docinfo file(s). If not set, the extension
1121
+ # will be set to the outfilesuffix. (default: nil)
1116
1122
  #
1117
- # returns The contents of the docinfo file(s)
1118
- def docinfo(location = :head, ext = nil)
1123
+ # returns The contents of the docinfo file(s) or empty string if no files are
1124
+ # found or the safe mode is secure or greater.
1125
+ def docinfo location = :head, suffix = nil
1119
1126
  if safe >= SafeMode::SECURE
1120
1127
  ''
1121
1128
  else
1122
- qualifier = (location == :footer ? '-footer' : nil)
1123
- ext = @outfilesuffix unless ext
1129
+ qualifier = location == :head ? nil : %(-#{location})
1130
+ suffix = @outfilesuffix unless suffix
1124
1131
  docinfodir = @attributes['docinfodir']
1125
1132
 
1126
1133
  content = nil
@@ -1138,7 +1145,7 @@ class Document < AbstractBlock
1138
1145
  end
1139
1146
 
1140
1147
  if docinfo
1141
- docinfo_filename = %(docinfo#{qualifier}#{ext})
1148
+ docinfo_filename = %(docinfo#{qualifier}#{suffix})
1142
1149
  unless (docinfo & ['shared', %(shared-#{location})]).empty?
1143
1150
  docinfo_path = normalize_system_path(docinfo_filename, docinfodir)
1144
1151
  # NOTE normalizing the lines is essential if we're performing substitutions
@@ -106,16 +106,16 @@ module Extensions
106
106
 
107
107
  # Public: Parses blocks in the content and attaches the block to the parent.
108
108
  #
109
- # Returns nothing
109
+ # Returns The parent node into which the blocks are parsed.
110
110
  #--
111
111
  # QUESTION is parse_content the right method name? should we wrap in open block automatically?
112
- def parse_content parent, content, attributes = {}
113
- reader = (content.is_a? Reader) ? content : (Reader.new content)
112
+ def parse_content parent, content, attributes = nil
113
+ reader = Reader === content ? content : (Reader.new content)
114
114
  while reader.has_more_lines?
115
- block = Parser.next_block reader, parent, attributes
115
+ block = Parser.next_block reader, parent, (attributes ? attributes.dup : {})
116
116
  parent << block if block
117
117
  end
118
- nil
118
+ parent
119
119
  end
120
120
 
121
121
  # TODO fill out remaining methods
@@ -145,7 +145,7 @@ module Extensions
145
145
  def process *args, &block
146
146
  # need to check for both block/proc and lambda
147
147
  # TODO need test for this!
148
- #if block_given? || (args.size == 1 && ((block = args[0]).is_a? ::Proc))
148
+ #if block_given? || (args.size == 1 && ::Proc === (block = args[0]))
149
149
  if block_given?
150
150
  @process_block = block
151
151
  elsif @process_block
@@ -326,7 +326,7 @@ module Extensions
326
326
 
327
327
  # FIXME this isn't the prettiest thing
328
328
  def named value
329
- if self.is_a? Processor
329
+ if Processor === self
330
330
  @name = value
331
331
  else
332
332
  option :name, value
@@ -379,7 +379,7 @@ module Extensions
379
379
  # QUESTION perhaps include a SyntaxDsl?
380
380
 
381
381
  def named value
382
- if self.is_a? Processor
382
+ if Processor === self
383
383
  @name = value
384
384
  else
385
385
  option :name, value
@@ -803,7 +803,7 @@ module Extensions
803
803
  def docinfo_processors? location = nil
804
804
  if @docinfo_processor_extensions
805
805
  if location
806
- @docinfo_processor_extensions.find {|ext| ext.config[:location] == location }
806
+ @docinfo_processor_extensions.any? {|ext| ext.config[:location] == location }
807
807
  else
808
808
  true
809
809
  end
@@ -1133,7 +1133,7 @@ module Extensions
1133
1133
  else
1134
1134
  processor, config = resolve_args args, 2
1135
1135
  # style 2: specified as class or class name
1136
- if (processor.is_a? ::Class) || ((processor.is_a? ::String) && (processor = Extensions.class_for_name processor))
1136
+ if ::Class === processor || (::String === processor && (processor = Extensions.class_for_name processor))
1137
1137
  unless processor < kind_class || (kind_java_class && processor < kind_java_class)
1138
1138
  raise ::ArgumentError.new %(Invalid type for #{kind_name} extension: #{processor})
1139
1139
  end
@@ -1141,7 +1141,7 @@ module Extensions
1141
1141
  processor_instance.freeze
1142
1142
  ProcessorExtension.new kind, processor_instance
1143
1143
  # style 3: specified as instance
1144
- elsif (processor.is_a? kind_class) || (kind_java_class && (processor.is_a? kind_java_class))
1144
+ elsif kind_class === processor || (kind_java_class && kind_java_class === processor)
1145
1145
  processor.update_config config
1146
1146
  processor.freeze
1147
1147
  ProcessorExtension.new kind, processor
@@ -1190,7 +1190,7 @@ module Extensions
1190
1190
  else
1191
1191
  processor, name, config = resolve_args args, 3
1192
1192
  # style 2: specified as class or class name
1193
- if (processor.is_a? ::Class) || ((processor.is_a? ::String) && (processor = Extensions.class_for_name processor))
1193
+ if ::Class === processor || (::String === processor && (processor = Extensions.class_for_name processor))
1194
1194
  unless processor < kind_class || (kind_java_class && processor < kind_java_class)
1195
1195
  raise ::ArgumentError.new %(Class specified for #{kind_name} extension does not inherit from #{kind_class}: #{processor})
1196
1196
  end
@@ -1201,7 +1201,7 @@ module Extensions
1201
1201
  processor.freeze
1202
1202
  kind_store[name] = ProcessorExtension.new kind, processor_instance
1203
1203
  # style 3: specified as instance
1204
- elsif (processor.is_a? kind_class) || (kind_java_class && (processor.is_a? kind_java_class))
1204
+ elsif kind_class === processor || (kind_java_class && kind_java_class === processor)
1205
1205
  processor.update_config config
1206
1206
  # TODO need a test for this override!
1207
1207
  unless (name = name ? (processor.name = as_symbol name) : (as_symbol processor.name))
@@ -1216,7 +1216,7 @@ module Extensions
1216
1216
  end
1217
1217
 
1218
1218
  def resolve_args args, expect
1219
- opts = (args[-1].is_a? ::Hash) ? args.pop : {}
1219
+ opts = ::Hash === args[-1] ? args.pop : {}
1220
1220
  return opts if expect == 1
1221
1221
  num_args = args.size
1222
1222
  if (missing = expect - 1 - num_args) > 0
@@ -1229,7 +1229,7 @@ module Extensions
1229
1229
  end
1230
1230
 
1231
1231
  def as_symbol name
1232
- name ? ((name.is_a? ::Symbol) ? name : name.to_sym) : nil
1232
+ name ? name.to_sym : nil
1233
1233
  end
1234
1234
  end
1235
1235
 
@@ -1323,7 +1323,7 @@ module Extensions
1323
1323
 
1324
1324
  # unused atm, but tested
1325
1325
  def resolve_class object
1326
- (object.is_a? ::Class) ? object : (class_for_name object.to_s)
1326
+ ::Class === object ? object : (class_for_name object.to_s)
1327
1327
  end
1328
1328
 
1329
1329
  # Public: Resolves the Class object for the qualified name.