asciidoctor 2.0.10 → 2.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +294 -30
- data/LICENSE +1 -1
- data/README-de.adoc +16 -20
- data/README-fr.adoc +15 -22
- data/README-jp.adoc +15 -26
- data/README-zh_CN.adoc +21 -25
- data/README.adoc +161 -138
- data/asciidoctor.gemspec +6 -13
- data/data/locale/attributes-ar.adoc +4 -3
- data/data/locale/attributes-be.adoc +23 -0
- data/data/locale/attributes-bg.adoc +4 -3
- data/data/locale/attributes-ca.adoc +6 -5
- data/data/locale/attributes-cs.adoc +4 -3
- data/data/locale/attributes-da.adoc +6 -5
- data/data/locale/attributes-de.adoc +4 -4
- data/data/locale/attributes-en.adoc +4 -4
- data/data/locale/attributes-es.adoc +6 -5
- data/data/locale/attributes-fa.adoc +4 -3
- data/data/locale/attributes-fi.adoc +4 -3
- data/data/locale/attributes-fr.adoc +8 -7
- data/data/locale/attributes-hu.adoc +4 -3
- data/data/locale/attributes-id.adoc +4 -3
- data/data/locale/attributes-it.adoc +6 -5
- data/data/locale/attributes-ja.adoc +4 -3
- data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
- data/data/locale/attributes-nb.adoc +4 -3
- data/data/locale/attributes-nl.adoc +6 -5
- data/data/locale/attributes-nn.adoc +4 -3
- data/data/locale/attributes-pl.adoc +8 -7
- data/data/locale/attributes-pt.adoc +6 -5
- data/data/locale/attributes-pt_BR.adoc +6 -5
- data/data/locale/attributes-ro.adoc +4 -3
- data/data/locale/attributes-ru.adoc +6 -5
- data/data/locale/attributes-sr.adoc +4 -4
- data/data/locale/attributes-sr_Latn.adoc +4 -4
- data/data/locale/attributes-sv.adoc +4 -4
- data/data/locale/attributes-th.adoc +23 -0
- data/data/locale/attributes-tr.adoc +4 -3
- data/data/locale/attributes-uk.adoc +6 -5
- data/data/locale/attributes-vi.adoc +23 -0
- data/data/locale/attributes-zh_CN.adoc +4 -3
- data/data/locale/attributes-zh_TW.adoc +4 -3
- data/data/reference/syntax.adoc +14 -7
- data/data/stylesheets/asciidoctor-default.css +76 -76
- data/data/stylesheets/coderay-asciidoctor.css +9 -9
- data/lib/asciidoctor/abstract_block.rb +20 -13
- data/lib/asciidoctor/abstract_node.rb +23 -12
- data/lib/asciidoctor/attribute_list.rb +64 -72
- data/lib/asciidoctor/block.rb +6 -6
- data/lib/asciidoctor/cli/invoker.rb +3 -2
- data/lib/asciidoctor/cli/options.rb +32 -31
- data/lib/asciidoctor/convert.rb +168 -162
- data/lib/asciidoctor/converter/docbook5.rb +49 -34
- data/lib/asciidoctor/converter/html5.rb +180 -139
- data/lib/asciidoctor/converter/manpage.rb +118 -90
- data/lib/asciidoctor/converter/template.rb +15 -13
- data/lib/asciidoctor/converter.rb +19 -16
- data/lib/asciidoctor/core_ext/hash/merge.rb +1 -1
- data/lib/asciidoctor/document.rb +77 -86
- data/lib/asciidoctor/extensions.rb +22 -16
- data/lib/asciidoctor/helpers.rb +20 -15
- data/lib/asciidoctor/list.rb +2 -6
- data/lib/asciidoctor/load.rb +103 -101
- data/lib/asciidoctor/logging.rb +10 -8
- data/lib/asciidoctor/parser.rb +211 -220
- data/lib/asciidoctor/path_resolver.rb +17 -15
- data/lib/asciidoctor/reader.rb +87 -79
- data/lib/asciidoctor/rx.rb +9 -7
- data/lib/asciidoctor/section.rb +7 -0
- data/lib/asciidoctor/substitutors.rb +167 -148
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +3 -2
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +13 -5
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +7 -4
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +19 -11
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +35 -20
- data/lib/asciidoctor/syntax_highlighter.rb +16 -16
- data/lib/asciidoctor/table.rb +70 -43
- data/lib/asciidoctor/timings.rb +3 -3
- data/lib/asciidoctor/version.rb +1 -1
- data/lib/asciidoctor.rb +45 -19
- data/man/asciidoctor.1 +29 -31
- data/man/asciidoctor.adoc +35 -29
- metadata +17 -70
data/lib/asciidoctor/document.rb
CHANGED
@@ -198,7 +198,7 @@ class Document < AbstractBlock
|
|
198
198
|
# Public: Get the document catalog Hash
|
199
199
|
attr_reader :catalog
|
200
200
|
|
201
|
-
# Public: Alias catalog property as references for backwards
|
201
|
+
# Public: Alias catalog property as references for backwards compatibility
|
202
202
|
alias references catalog
|
203
203
|
|
204
204
|
# Public: Get the Hash of document counters
|
@@ -259,12 +259,14 @@ class Document < AbstractBlock
|
|
259
259
|
options[:catalog_assets] = true if parent_doc.options[:catalog_assets]
|
260
260
|
@catalog = parent_doc.catalog.merge footnotes: []
|
261
261
|
# QUESTION should we support setting attribute in parent document from nested document?
|
262
|
-
|
263
|
-
@attribute_overrides = attr_overrides = parent_doc.attributes.merge
|
264
|
-
parent_doctype = attr_overrides.delete 'doctype'
|
262
|
+
@attribute_overrides = attr_overrides = (parent_doc.instance_variable_get :@attribute_overrides).merge parent_doc.attributes
|
265
263
|
attr_overrides.delete 'compat-mode'
|
264
|
+
parent_doctype = attr_overrides.delete 'doctype'
|
265
|
+
attr_overrides.delete 'notitle'
|
266
|
+
attr_overrides.delete 'showtitle'
|
267
|
+
# QUESTION if toc is hard unset in parent document, should it be hard unset in nested document?
|
266
268
|
attr_overrides.delete 'toc'
|
267
|
-
attr_overrides.delete 'toc-placement'
|
269
|
+
@attributes['toc-placement'] = (attr_overrides.delete 'toc-placement') || 'auto'
|
268
270
|
attr_overrides.delete 'toc-position'
|
269
271
|
@safe = parent_doc.safe
|
270
272
|
@attributes['compat-mode'] = '' if (@compat_mode = parent_doc.compat_mode)
|
@@ -284,7 +286,6 @@ class Document < AbstractBlock
|
|
284
286
|
footnotes: [],
|
285
287
|
links: [],
|
286
288
|
images: [],
|
287
|
-
#indexterms: [],
|
288
289
|
callouts: Callouts.new,
|
289
290
|
includes: {},
|
290
291
|
}
|
@@ -309,7 +310,7 @@ class Document < AbstractBlock
|
|
309
310
|
end
|
310
311
|
attr_overrides[key.downcase] = val
|
311
312
|
end
|
312
|
-
if (to_file = options[:to_file])
|
313
|
+
if ::String === (to_file = options[:to_file])
|
313
314
|
attr_overrides['outfilesuffix'] = Helpers.extname to_file
|
314
315
|
end
|
315
316
|
# safely resolve the safe mode from const, int or string
|
@@ -326,8 +327,8 @@ class Document < AbstractBlock
|
|
326
327
|
@sourcemap = options[:sourcemap]
|
327
328
|
@timings = options.delete :timings
|
328
329
|
@path_resolver = PathResolver.new
|
329
|
-
initialize_extensions = (defined? ::Asciidoctor::Extensions) ?
|
330
|
-
@extensions = nil # initialize
|
330
|
+
initialize_extensions = (defined? ::Asciidoctor::Extensions) || (options.key? :extensions) ? ::Asciidoctor::Extensions : nil
|
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,61 +340,46 @@ class Document < AbstractBlock
|
|
339
340
|
(@options = options).freeze
|
340
341
|
|
341
342
|
attrs = @attributes
|
342
|
-
|
343
|
-
|
344
|
-
|
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
|
350
|
+
|
345
351
|
if standalone
|
346
|
-
attrs['copycss'] = ''
|
347
352
|
# sync embedded attribute with :standalone option value
|
348
353
|
attr_overrides['embedded'] = nil
|
354
|
+
attrs['copycss'] = ''
|
355
|
+
attrs['iconfont-remote'] = ''
|
356
|
+
attrs['stylesheet'] = ''
|
357
|
+
attrs['webfonts'] = ''
|
349
358
|
else
|
350
|
-
attrs['notitle'] = ''
|
351
359
|
# sync embedded attribute with :standalone option value
|
352
360
|
attr_overrides['embedded'] = ''
|
361
|
+
if (attr_overrides.key? 'showtitle') && (attr_overrides.keys & %w(notitle showtitle))[-1] == 'showtitle'
|
362
|
+
attr_overrides['notitle'] = { nil => '', false => '@', '@' => false }[attr_overrides['showtitle']]
|
363
|
+
elsif attr_overrides.key? 'notitle'
|
364
|
+
attr_overrides['showtitle'] = { nil => '', false => '@', '@' => false }[attr_overrides['notitle']]
|
365
|
+
else
|
366
|
+
attrs['notitle'] = ''
|
367
|
+
end
|
353
368
|
end
|
354
|
-
attrs['stylesheet'] = ''
|
355
|
-
attrs['webfonts'] = ''
|
356
|
-
attrs['prewrap'] = ''
|
357
|
-
attrs['attribute-undefined'] = Compliance.attribute_undefined
|
358
|
-
attrs['attribute-missing'] = Compliance.attribute_missing
|
359
|
-
attrs['iconfont-remote'] = ''
|
360
|
-
|
361
|
-
# language strings
|
362
|
-
# TODO load these based on language settings
|
363
|
-
attrs['caution-caption'] = 'Caution'
|
364
|
-
attrs['important-caption'] = 'Important'
|
365
|
-
attrs['note-caption'] = 'Note'
|
366
|
-
attrs['tip-caption'] = 'Tip'
|
367
|
-
attrs['warning-caption'] = 'Warning'
|
368
|
-
attrs['example-caption'] = 'Example'
|
369
|
-
attrs['figure-caption'] = 'Figure'
|
370
|
-
#attrs['listing-caption'] = 'Listing'
|
371
|
-
attrs['table-caption'] = 'Table'
|
372
|
-
attrs['toc-title'] = 'Table of Contents'
|
373
|
-
#attrs['preface-title'] = 'Preface'
|
374
|
-
attrs['section-refsig'] = 'Section'
|
375
|
-
attrs['part-refsig'] = 'Part'
|
376
|
-
attrs['chapter-refsig'] = 'Chapter'
|
377
|
-
attrs['appendix-caption'] = attrs['appendix-refsig'] = 'Appendix'
|
378
|
-
attrs['untitled-label'] = 'Untitled'
|
379
|
-
attrs['version-label'] = 'Version'
|
380
|
-
attrs['last-update-label'] = 'Last updated'
|
381
369
|
|
382
370
|
attr_overrides['asciidoctor'] = ''
|
383
371
|
attr_overrides['asciidoctor-version'] = ::Asciidoctor::VERSION
|
384
372
|
|
385
373
|
attr_overrides['safe-mode-name'] = (safe_mode_name = SafeMode.name_for_value @safe)
|
386
|
-
attr_overrides[
|
374
|
+
attr_overrides[%(safe-mode-#{safe_mode_name})] = ''
|
387
375
|
attr_overrides['safe-mode-level'] = @safe
|
388
376
|
|
389
|
-
# the only way to set the max-include-depth attribute is via the API; default to 64 like AsciiDoc
|
377
|
+
# the only way to set the max-include-depth attribute is via the API; default to 64 like AsciiDoc.py
|
390
378
|
attr_overrides['max-include-depth'] ||= 64
|
391
379
|
|
392
380
|
# the only way to set the allow-uri-read attribute is via the API; disabled by default
|
393
381
|
attr_overrides['allow-uri-read'] ||= nil
|
394
382
|
|
395
|
-
attr_overrides['user-home'] = USER_HOME
|
396
|
-
|
397
383
|
# remap legacy attribute names
|
398
384
|
attr_overrides['sectnums'] = attr_overrides.delete 'numbered' if attr_overrides.key? 'numbered'
|
399
385
|
attr_overrides['hardbreaks-option'] = attr_overrides.delete 'hardbreaks' if attr_overrides.key? 'hardbreaks'
|
@@ -412,11 +398,11 @@ class Document < AbstractBlock
|
|
412
398
|
|
413
399
|
# allow common attributes backend and doctype to be set using options hash, coerce values to string
|
414
400
|
if (backend_val = options[:backend])
|
415
|
-
attr_overrides['backend'] =
|
401
|
+
attr_overrides['backend'] = backend_val.to_s
|
416
402
|
end
|
417
403
|
|
418
404
|
if (doctype_val = options[:doctype])
|
419
|
-
attr_overrides['doctype'] =
|
405
|
+
attr_overrides['doctype'] = doctype_val.to_s
|
420
406
|
end
|
421
407
|
|
422
408
|
if @safe >= SafeMode::SERVER
|
@@ -429,7 +415,7 @@ class Document < AbstractBlock
|
|
429
415
|
attr_overrides['docfile'] = attr_overrides['docfile'][(attr_overrides['docdir'].length + 1)..-1]
|
430
416
|
end
|
431
417
|
attr_overrides['docdir'] = ''
|
432
|
-
attr_overrides['user-home']
|
418
|
+
attr_overrides['user-home'] ||= '.'
|
433
419
|
if @safe >= SafeMode::SECURE
|
434
420
|
attr_overrides['max-attribute-value-size'] = 4096 unless attr_overrides.key? 'max-attribute-value-size'
|
435
421
|
# assign linkcss (preventing css embedding) unless explicitly disabled from the commandline or API
|
@@ -438,6 +424,8 @@ class Document < AbstractBlock
|
|
438
424
|
# restrict document from enabling icons
|
439
425
|
attr_overrides['icons'] ||= nil
|
440
426
|
end
|
427
|
+
else
|
428
|
+
attr_overrides['user-home'] ||= USER_HOME
|
441
429
|
end
|
442
430
|
|
443
431
|
# the only way to set the max-attribute-value-size attribute is via the API; disabled by default
|
@@ -505,10 +493,10 @@ class Document < AbstractBlock
|
|
505
493
|
::AsciidoctorJ::Extensions::ExtensionRegistry === ext_registry)
|
506
494
|
@extensions = ext_registry.activate self
|
507
495
|
end
|
508
|
-
elsif
|
496
|
+
elsif (ext_block = options[:extensions]).nil?
|
497
|
+
@extensions = Extensions::Registry.new.activate self unless Extensions.groups.empty?
|
498
|
+
elsif ::Proc === ext_block
|
509
499
|
@extensions = Extensions.create(&ext_block).activate self
|
510
|
-
elsif !Extensions.groups.empty?
|
511
|
-
@extensions = Extensions::Registry.new.activate self
|
512
500
|
end
|
513
501
|
end
|
514
502
|
|
@@ -577,13 +565,15 @@ class Document < AbstractBlock
|
|
577
565
|
# returns the next number in the sequence for the specified counter
|
578
566
|
def counter name, seed = nil
|
579
567
|
return @parent_document.counter name, seed if @parent_document
|
580
|
-
if (
|
581
|
-
|
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
|
582
570
|
elsif seed
|
583
|
-
|
571
|
+
next_val = @counters[name] = seed == seed.to_i.to_s ? seed.to_i : seed
|
584
572
|
else
|
585
|
-
|
573
|
+
next_val = @counters[name] = 1
|
586
574
|
end
|
575
|
+
@attributes[name] = next_val unless locked
|
576
|
+
next_val
|
587
577
|
end
|
588
578
|
|
589
579
|
# Public: Increment the specified counter and store it in the block's attributes
|
@@ -625,15 +615,29 @@ class Document < AbstractBlock
|
|
625
615
|
# @reftexts is set eagerly to prevent nested lazy init
|
626
616
|
(@reftexts = {}).tap {|accum| @catalog[:refs].each {|id, ref| accum[ref.xreftext] ||= id } }[text]
|
627
617
|
else
|
628
|
-
# @reftexts is set eagerly to prevent nested lazy init
|
629
618
|
resolved_id = nil
|
630
|
-
#
|
631
|
-
|
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
|
632
629
|
@reftexts = nil
|
633
630
|
resolved_id
|
634
631
|
end
|
635
632
|
end
|
636
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
|
+
|
637
641
|
def footnotes?
|
638
642
|
@catalog[:footnotes].empty? ? false : true
|
639
643
|
end
|
@@ -686,7 +690,7 @@ class Document < AbstractBlock
|
|
686
690
|
#
|
687
691
|
# title - the String title to assign as the title of the document header
|
688
692
|
#
|
689
|
-
# Returns the
|
693
|
+
# Returns the specified [String] title
|
690
694
|
def title= title
|
691
695
|
unless (sect = @header)
|
692
696
|
(sect = (@header = Section.new self, 0)).sectname = 'header'
|
@@ -772,7 +776,7 @@ class Document < AbstractBlock
|
|
772
776
|
end
|
773
777
|
|
774
778
|
def notitle
|
775
|
-
|
779
|
+
@attributes.key? 'notitle'
|
776
780
|
end
|
777
781
|
|
778
782
|
def noheader
|
@@ -968,8 +972,14 @@ class Document < AbstractBlock
|
|
968
972
|
|
969
973
|
# Public: Write the output to the specified file
|
970
974
|
#
|
971
|
-
# If the converter responds to :write, delegate the work of writing the
|
972
|
-
# 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.
|
973
983
|
#
|
974
984
|
# Returns nothing
|
975
985
|
def write output, target
|
@@ -995,25 +1005,6 @@ class Document < AbstractBlock
|
|
995
1005
|
nil
|
996
1006
|
end
|
997
1007
|
|
998
|
-
=begin
|
999
|
-
def convert_to target, opts = {}
|
1000
|
-
start = ::Time.now.to_f if (monitor = opts[:monitor])
|
1001
|
-
output = (r = converter opts).convert
|
1002
|
-
monitor[:convert] = ::Time.now.to_f - start if monitor
|
1003
|
-
|
1004
|
-
unless target.respond_to? :write
|
1005
|
-
@attributes['outfile'] = target = ::File.expand_path target
|
1006
|
-
@attributes['outdir'] = ::File.dirname target
|
1007
|
-
end
|
1008
|
-
|
1009
|
-
start = ::Time.now.to_f if monitor
|
1010
|
-
r.write output, target
|
1011
|
-
monitor[:write] = ::Time.now.to_f - start if monitor
|
1012
|
-
|
1013
|
-
output
|
1014
|
-
end
|
1015
|
-
=end
|
1016
|
-
|
1017
1008
|
def content
|
1018
1009
|
# NOTE per AsciiDoc-spec, remove the title before converting the body
|
1019
1010
|
@attributes.delete('title')
|
@@ -1035,7 +1026,7 @@ class Document < AbstractBlock
|
|
1035
1026
|
def docinfo location = :head, suffix = nil
|
1036
1027
|
if safe < SafeMode::SECURE
|
1037
1028
|
qualifier = %(-#{location}) unless location == :head
|
1038
|
-
suffix
|
1029
|
+
suffix ||= @outfilesuffix
|
1039
1030
|
|
1040
1031
|
if (docinfo = @attributes['docinfo']).nil_or_empty?
|
1041
1032
|
if @attributes.key? 'docinfo2'
|
@@ -1092,7 +1083,7 @@ class Document < AbstractBlock
|
|
1092
1083
|
end
|
1093
1084
|
|
1094
1085
|
def to_s
|
1095
|
-
%(#<#{self.class}@#{object_id} {doctype: #{doctype.inspect}, doctitle: #{(@header
|
1086
|
+
%(#<#{self.class}@#{object_id} {doctype: #{doctype.inspect}, doctitle: #{(@header && @header.title).inspect}, blocks: #{@blocks.size}}>)
|
1096
1087
|
end
|
1097
1088
|
|
1098
1089
|
private
|
@@ -1221,8 +1212,8 @@ class Document < AbstractBlock
|
|
1221
1212
|
end
|
1222
1213
|
end
|
1223
1214
|
|
1224
|
-
if (@compat_mode = attrs.key? 'compat-mode')
|
1225
|
-
attrs['source-language'] = attrs['language']
|
1215
|
+
if (@compat_mode = attrs.key? 'compat-mode') && (attrs.key? 'language')
|
1216
|
+
attrs['source-language'] = attrs['language']
|
1226
1217
|
end
|
1227
1218
|
|
1228
1219
|
unless @parent_document
|
@@ -1395,7 +1386,7 @@ class Document < AbstractBlock
|
|
1395
1386
|
attrs[%(basebackend-#{current_basebackend}-doctype-#{new_doctype})] = '' if current_basebackend
|
1396
1387
|
end
|
1397
1388
|
attrs[%(doctype-#{new_doctype})] = ''
|
1398
|
-
|
1389
|
+
@doctype = attrs['doctype'] = new_doctype
|
1399
1390
|
end
|
1400
1391
|
end
|
1401
1392
|
end
|
@@ -134,14 +134,14 @@ module Extensions
|
|
134
134
|
if opts.fetch :numbered, (style == 'appendix')
|
135
135
|
sect.numbered = true
|
136
136
|
elsif !(opts.key? :numbered) && (doc.attr? 'sectnums', 'all')
|
137
|
-
sect.numbered = book && level == 1 ? :chapter : true
|
137
|
+
sect.numbered = (book && level == 1 ? :chapter : true)
|
138
138
|
end
|
139
139
|
elsif level > 0
|
140
140
|
if opts.fetch :numbered, (doc.attr? 'sectnums')
|
141
141
|
sect.numbered = sect.special ? parent.numbered && true : true
|
142
142
|
end
|
143
|
-
|
144
|
-
sect.numbered = true
|
143
|
+
elsif opts.fetch :numbered, (book && (doc.attr? 'partnums'))
|
144
|
+
sect.numbered = true
|
145
145
|
end
|
146
146
|
if (id = attrs['id']) == false
|
147
147
|
attrs.delete 'id'
|
@@ -229,7 +229,7 @@ module Extensions
|
|
229
229
|
def parse_attributes block, attrlist, opts = {}
|
230
230
|
return {} if attrlist ? attrlist.empty? : true
|
231
231
|
attrlist = block.sub_attributes attrlist if opts[:sub_attributes] && (attrlist.include? ATTR_REF_HEAD)
|
232
|
-
(AttributeList.new attrlist).parse
|
232
|
+
(AttributeList.new attrlist).parse opts[:positional_attributes] || []
|
233
233
|
end
|
234
234
|
|
235
235
|
# TODO fill out remaining methods
|
@@ -425,7 +425,7 @@ module Extensions
|
|
425
425
|
# TIP: Postprocessors can also be used to relocate assets needed by the published
|
426
426
|
# document.
|
427
427
|
#
|
428
|
-
# Postprocessor implementations must Postprocessor.
|
428
|
+
# Postprocessor implementations must extend Postprocessor.
|
429
429
|
class Postprocessor < Processor
|
430
430
|
def process document, output
|
431
431
|
raise ::NotImplementedError, %(#{Postprocessor} subclass #{self.class} must implement the ##{__method__} method)
|
@@ -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
|
@@ -610,7 +618,7 @@ module Extensions
|
|
610
618
|
#--
|
611
619
|
# TODO break this out into different pattern types
|
612
620
|
# for example, FullInlineMacro, ShortInlineMacro (no target) and other patterns
|
613
|
-
# FIXME for inline
|
621
|
+
# FIXME for inline macro, we need to have some way to specify the text as a passthrough
|
614
622
|
class InlineMacroProcessor < MacroProcessor
|
615
623
|
@@rx_cache = {}
|
616
624
|
|
@@ -666,7 +674,7 @@ module Extensions
|
|
666
674
|
|
667
675
|
# Public: A specialization of the Extension proxy that additionally stores a
|
668
676
|
# reference to the {Processor#process} method. By storing this reference, its
|
669
|
-
# possible to
|
677
|
+
# possible to accommodate both concrete extension implementations and Procs.
|
670
678
|
class ProcessorExtension < Extension
|
671
679
|
attr_reader :process_method
|
672
680
|
|
@@ -954,7 +962,7 @@ module Extensions
|
|
954
962
|
end
|
955
963
|
|
956
964
|
# Public: Registers an {DocinfoProcessor} with the extension registry to
|
957
|
-
# add
|
965
|
+
# add additional docinfo to the document.
|
958
966
|
#
|
959
967
|
# The DocinfoProcessor may be one of four types:
|
960
968
|
#
|
@@ -1021,8 +1029,6 @@ module Extensions
|
|
1021
1029
|
else
|
1022
1030
|
@docinfo_processor_extensions
|
1023
1031
|
end
|
1024
|
-
else
|
1025
|
-
nil
|
1026
1032
|
end
|
1027
1033
|
end
|
1028
1034
|
|
@@ -1201,7 +1207,7 @@ module Extensions
|
|
1201
1207
|
# name - the String or Symbol (coersed to a Symbol) macro name
|
1202
1208
|
#
|
1203
1209
|
# Returns the [Extension] object stored in the registry that proxies the
|
1204
|
-
#
|
1210
|
+
# corresponding BlockMacroProcessor or nil if a match is not found.
|
1205
1211
|
def find_block_macro_extension name
|
1206
1212
|
@block_macro_extensions[name.to_sym]
|
1207
1213
|
end
|
@@ -1288,7 +1294,7 @@ module Extensions
|
|
1288
1294
|
# name - the String or Symbol (coersed to a Symbol) macro name
|
1289
1295
|
#
|
1290
1296
|
# Returns the [Extension] object stored in the registry that proxies the
|
1291
|
-
#
|
1297
|
+
# corresponding InlineMacroProcessor or nil if a match is not found.
|
1292
1298
|
def find_inline_macro_extension name
|
1293
1299
|
@inline_macro_extensions[name.to_sym]
|
1294
1300
|
end
|
@@ -1330,7 +1336,7 @@ module Extensions
|
|
1330
1336
|
kind_java_class = (defined? ::AsciidoctorJ) ? (::AsciidoctorJ::Extensions.const_get kind_class_symbol, false) : nil
|
1331
1337
|
kind_store = instance_variable_get(%(@#{kind}_extensions).to_sym) || instance_variable_set(%(@#{kind}_extensions).to_sym, [])
|
1332
1338
|
# style 1: specified as block
|
1333
|
-
|
1339
|
+
if block_given?
|
1334
1340
|
config = resolve_args args, 1
|
1335
1341
|
(processor = kind_class.new config).singleton_class.enable_dsl
|
1336
1342
|
if block.arity == 0
|
@@ -1342,7 +1348,7 @@ module Extensions
|
|
1342
1348
|
raise ::ArgumentError, %(No block specified to process #{kind_name} extension at #{block.source_location})
|
1343
1349
|
end
|
1344
1350
|
processor.freeze
|
1345
|
-
ProcessorExtension.new kind, processor
|
1351
|
+
extension = ProcessorExtension.new kind, processor
|
1346
1352
|
else
|
1347
1353
|
processor, config = resolve_args args, 2
|
1348
1354
|
# style 2: specified as Class or String class name
|
@@ -1352,12 +1358,12 @@ module Extensions
|
|
1352
1358
|
end
|
1353
1359
|
processor_instance = processor_class.new config
|
1354
1360
|
processor_instance.freeze
|
1355
|
-
ProcessorExtension.new kind, processor_instance
|
1361
|
+
extension = ProcessorExtension.new kind, processor_instance
|
1356
1362
|
# style 3: specified as instance
|
1357
1363
|
elsif kind_class === processor || (kind_java_class && kind_java_class === processor)
|
1358
1364
|
processor.update_config config
|
1359
1365
|
processor.freeze
|
1360
|
-
ProcessorExtension.new kind, processor
|
1366
|
+
extension = ProcessorExtension.new kind, processor
|
1361
1367
|
else
|
1362
1368
|
raise ::ArgumentError, %(Invalid arguments specified for registering #{kind_name} extension: #{args})
|
1363
1369
|
end
|
data/lib/asciidoctor/helpers.rb
CHANGED
@@ -56,25 +56,27 @@ module Helpers
|
|
56
56
|
# If a BOM is found at the beginning of the data, a best attempt is made to
|
57
57
|
# encode it to UTF-8 from the specified source encoding.
|
58
58
|
#
|
59
|
-
# data
|
59
|
+
# data - the source data Array to prepare (no nil entries allowed)
|
60
|
+
# trim_end - whether to trim whitespace from the end of each line;
|
61
|
+
# (true cleans all whitespace; false only removes trailing newline) (default: true)
|
60
62
|
#
|
61
63
|
# returns a String Array of prepared lines
|
62
|
-
def prepare_source_array data
|
64
|
+
def prepare_source_array data, trim_end = true
|
63
65
|
return [] if data.empty?
|
64
66
|
if (leading_2_bytes = (leading_bytes = (first = data[0]).unpack 'C3').slice 0, 2) == BOM_BYTES_UTF_16LE
|
65
67
|
data[0] = first.byteslice 2, first.bytesize
|
66
68
|
# NOTE you can't split a UTF-16LE string using .lines when encoding is UTF-8; doing so will cause this line to fail
|
67
|
-
return data.map {|line| (line.encode UTF_8, ::Encoding::UTF_16LE).rstrip }
|
69
|
+
return trim_end ? data.map {|line| (line.encode UTF_8, ::Encoding::UTF_16LE).rstrip } : data.map {|line| (line.encode UTF_8, ::Encoding::UTF_16LE).chomp }
|
68
70
|
elsif leading_2_bytes == BOM_BYTES_UTF_16BE
|
69
71
|
data[0] = first.byteslice 2, first.bytesize
|
70
|
-
return data.map {|line| (line.encode UTF_8, ::Encoding::UTF_16BE).rstrip }
|
72
|
+
return trim_end ? data.map {|line| (line.encode UTF_8, ::Encoding::UTF_16BE).rstrip } : data.map {|line| (line.encode UTF_8, ::Encoding::UTF_16BE).chomp }
|
71
73
|
elsif leading_bytes == BOM_BYTES_UTF_8
|
72
74
|
data[0] = first.byteslice 3, first.bytesize
|
73
75
|
end
|
74
76
|
if first.encoding == UTF_8
|
75
|
-
data.map {|line| line.rstrip }
|
77
|
+
trim_end ? data.map {|line| line.rstrip } : data.map {|line| line.chomp }
|
76
78
|
else
|
77
|
-
data.map {|line| (line.encode UTF_8).rstrip }
|
79
|
+
trim_end ? data.map {|line| (line.encode UTF_8).rstrip } : data.map {|line| (line.encode UTF_8).chomp }
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
@@ -86,10 +88,12 @@ module Helpers
|
|
86
88
|
# If a BOM is found at the beginning of the data, a best attempt is made to
|
87
89
|
# encode it to UTF-8 from the specified source encoding.
|
88
90
|
#
|
89
|
-
# data
|
91
|
+
# data - the source data String to prepare
|
92
|
+
# trim_end - whether to trim whitespace from the end of each line;
|
93
|
+
# (true cleans all whitespace; false only removes trailing newline) (default: true)
|
90
94
|
#
|
91
95
|
# returns a String Array of prepared lines
|
92
|
-
def prepare_source_string data
|
96
|
+
def prepare_source_string data, trim_end = true
|
93
97
|
return [] if data.nil_or_empty?
|
94
98
|
if (leading_2_bytes = (leading_bytes = data.unpack 'C3').slice 0, 2) == BOM_BYTES_UTF_16LE
|
95
99
|
data = (data.byteslice 2, data.bytesize).encode UTF_8, ::Encoding::UTF_16LE
|
@@ -101,7 +105,11 @@ module Helpers
|
|
101
105
|
elsif data.encoding != UTF_8
|
102
106
|
data = data.encode UTF_8
|
103
107
|
end
|
104
|
-
|
108
|
+
if trim_end
|
109
|
+
[].tap {|lines| data.each_line {|line| lines << line.rstrip } }
|
110
|
+
else
|
111
|
+
[].tap {|lines| data.each_line {|line| lines << line.chomp } }
|
112
|
+
end
|
105
113
|
end
|
106
114
|
|
107
115
|
# Internal: Efficiently checks whether the specified String resembles a URI
|
@@ -266,13 +274,10 @@ module Helpers
|
|
266
274
|
def nextval current
|
267
275
|
if ::Integer === current
|
268
276
|
current + 1
|
277
|
+
elsif (intval = current.to_i).to_s == current.to_s
|
278
|
+
intval + 1
|
269
279
|
else
|
270
|
-
|
271
|
-
if intval.to_s != current.to_s
|
272
|
-
(current[0].ord + 1).chr
|
273
|
-
else
|
274
|
-
intval + 1
|
275
|
-
end
|
280
|
+
current.succ
|
276
281
|
end
|
277
282
|
end
|
278
283
|
|
data/lib/asciidoctor/list.rb
CHANGED
@@ -80,12 +80,8 @@ class ListItem < AbstractBlock
|
|
80
80
|
@text && (apply_subs @text, @subs)
|
81
81
|
end
|
82
82
|
|
83
|
-
# Public: Set the String text
|
84
|
-
|
85
|
-
# Returns the new String text assigned to this ListItem
|
86
|
-
def text= val
|
87
|
-
@text = val
|
88
|
-
end
|
83
|
+
# Public: Set the String text assigned to this ListItem
|
84
|
+
attr_writer :text
|
89
85
|
|
90
86
|
# Check whether this list item has simple content (no nested blocks aside from a single outline list).
|
91
87
|
# Primarily relevant for outline lists.
|