asciidoctor 2.0.13 → 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 +151 -30
- data/LICENSE +1 -1
- data/README-de.adoc +9 -12
- data/README-fr.adoc +9 -12
- data/README-jp.adoc +10 -13
- data/README-zh_CN.adoc +9 -12
- data/README.adoc +40 -19
- data/asciidoctor.gemspec +2 -9
- data/data/locale/attributes-fr.adoc +2 -2
- data/data/locale/attributes-th.adoc +23 -0
- data/data/locale/attributes-vi.adoc +23 -0
- data/data/stylesheets/asciidoctor-default.css +54 -53
- data/data/stylesheets/coderay-asciidoctor.css +9 -9
- data/lib/asciidoctor/abstract_block.rb +11 -9
- data/lib/asciidoctor/abstract_node.rb +9 -8
- data/lib/asciidoctor/attribute_list.rb +1 -1
- data/lib/asciidoctor/block.rb +6 -6
- data/lib/asciidoctor/cli/invoker.rb +1 -2
- data/lib/asciidoctor/cli/options.rb +25 -25
- data/lib/asciidoctor/convert.rb +1 -0
- data/lib/asciidoctor/converter/docbook5.rb +45 -26
- data/lib/asciidoctor/converter/html5.rb +130 -102
- data/lib/asciidoctor/converter/manpage.rb +69 -64
- data/lib/asciidoctor/converter/template.rb +12 -13
- data/lib/asciidoctor/converter.rb +6 -4
- data/lib/asciidoctor/core_ext/hash/merge.rb +1 -1
- data/lib/asciidoctor/document.rb +61 -57
- data/lib/asciidoctor/extensions.rb +20 -12
- data/lib/asciidoctor/list.rb +2 -6
- data/lib/asciidoctor/load.rb +11 -9
- data/lib/asciidoctor/logging.rb +10 -8
- data/lib/asciidoctor/parser.rb +177 -193
- data/lib/asciidoctor/path_resolver.rb +3 -3
- data/lib/asciidoctor/reader.rb +73 -72
- data/lib/asciidoctor/rx.rb +5 -4
- data/lib/asciidoctor/section.rb +7 -0
- data/lib/asciidoctor/substitutors.rb +121 -121
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +2 -1
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +1 -1
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +16 -7
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +2 -1
- data/lib/asciidoctor/syntax_highlighter.rb +8 -11
- data/lib/asciidoctor/table.rb +18 -20
- data/lib/asciidoctor/timings.rb +3 -3
- data/lib/asciidoctor/version.rb +1 -1
- data/lib/asciidoctor.rb +10 -10
- data/man/asciidoctor.1 +26 -28
- data/man/asciidoctor.adoc +33 -27
- metadata +8 -62
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
3
|
# Public: Methods to perform substitutions on lines of AsciiDoc text. This module
|
4
|
-
# is
|
4
|
+
# is intended to be mixed-in to Section and Block to provide operations for performing
|
5
5
|
# the necessary substitutions.
|
6
6
|
module Substitutors
|
7
7
|
SpecialCharsRx = /[<&>]/
|
@@ -330,13 +330,13 @@ module Substitutors
|
|
330
330
|
# NOTE for convenience, map content (unparsed attrlist) to target when format is short
|
331
331
|
target ||= ext_config[:format] == :short ? content : target
|
332
332
|
end
|
333
|
-
if
|
334
|
-
if (inline_subs = replacement.attributes.delete 'subs')
|
335
|
-
replacement.text = apply_subs replacement.text,
|
333
|
+
if Inline === (replacement = extension.process_method[self, target, attributes])
|
334
|
+
if (inline_subs = replacement.attributes.delete 'subs') && (inline_subs = expand_subs inline_subs, 'custom inline macro')
|
335
|
+
replacement.text = apply_subs replacement.text, inline_subs
|
336
336
|
end
|
337
337
|
replacement.convert
|
338
338
|
elsif replacement
|
339
|
-
logger.info %(expected substitution value for custom inline macro to be of type Inline; got #{replacement.class}: #{match})
|
339
|
+
logger.info { %(expected substitution value for custom inline macro to be of type Inline; got #{replacement.class}: #{match}) }
|
340
340
|
replacement
|
341
341
|
else
|
342
342
|
''
|
@@ -445,23 +445,16 @@ module Substitutors
|
|
445
445
|
# indexterm:[Tigers,Big cats]
|
446
446
|
if (attrlist = normalize_text $2, true, true).include? '='
|
447
447
|
if (primary = (attrs = (AttributeList.new attrlist, self).parse)[1])
|
448
|
-
attrs['terms'] =
|
449
|
-
if (secondary = attrs[2])
|
450
|
-
terms << secondary
|
451
|
-
if (tertiary = attrs[3])
|
452
|
-
terms << tertiary
|
453
|
-
end
|
454
|
-
end
|
448
|
+
attrs['terms'] = [primary]
|
455
449
|
if (see_also = attrs['see-also'])
|
456
450
|
attrs['see-also'] = (see_also.include? ',') ? (see_also.split ',').map {|it| it.lstrip } : [see_also]
|
457
451
|
end
|
458
452
|
else
|
459
|
-
attrs = { 'terms' =>
|
453
|
+
attrs = { 'terms' => attrlist }
|
460
454
|
end
|
461
455
|
else
|
462
|
-
attrs = { 'terms' => (
|
456
|
+
attrs = { 'terms' => (split_simple_csv attrlist) }
|
463
457
|
end
|
464
|
-
#doc.register :indexterms, terms
|
465
458
|
(Inline.new self, :indexterm, nil, attributes: attrs).convert
|
466
459
|
when 'indexterm2'
|
467
460
|
# honor the escape
|
@@ -474,34 +467,33 @@ module Substitutors
|
|
474
467
|
attrs['see-also'] = (see_also.include? ',') ? (see_also.split ',').map {|it| it.lstrip } : [see_also]
|
475
468
|
end
|
476
469
|
end
|
477
|
-
#doc.register :indexterms, [term]
|
478
470
|
(Inline.new self, :indexterm, term, attributes: attrs, type: :visible).convert
|
479
471
|
else
|
480
|
-
|
472
|
+
encl_text = $3
|
481
473
|
# honor the escape
|
482
474
|
if $&.start_with? RS
|
483
475
|
# escape concealed index term, but process nested flow index term
|
484
|
-
if (
|
485
|
-
|
476
|
+
if (encl_text.start_with? '(') && (encl_text.end_with? ')')
|
477
|
+
encl_text = encl_text.slice 1, encl_text.length - 2
|
486
478
|
visible, before, after = true, '(', ')'
|
487
479
|
else
|
488
480
|
next $&.slice 1, $&.length
|
489
481
|
end
|
490
482
|
else
|
491
483
|
visible = true
|
492
|
-
if
|
493
|
-
if
|
494
|
-
|
484
|
+
if encl_text.start_with? '('
|
485
|
+
if encl_text.end_with? ')'
|
486
|
+
encl_text, visible = (encl_text.slice 1, encl_text.length - 2), false
|
495
487
|
else
|
496
|
-
|
488
|
+
encl_text, before, after = (encl_text.slice 1, encl_text.length), '(', ''
|
497
489
|
end
|
498
|
-
elsif
|
499
|
-
|
490
|
+
elsif encl_text.end_with? ')'
|
491
|
+
encl_text, before, after = encl_text.chop, '', ')'
|
500
492
|
end
|
501
493
|
end
|
502
494
|
if visible
|
503
495
|
# ((Tigers))
|
504
|
-
if (term = normalize_text
|
496
|
+
if (term = normalize_text encl_text, true).include? ';&'
|
505
497
|
if term.include? ' >> '
|
506
498
|
term, _, see = term.partition ' >> '
|
507
499
|
attrs = { 'see' => see }
|
@@ -510,12 +502,11 @@ module Substitutors
|
|
510
502
|
attrs = { 'see-also' => see_also }
|
511
503
|
end
|
512
504
|
end
|
513
|
-
#doc.register :indexterms, [term]
|
514
505
|
subbed_term = (Inline.new self, :indexterm, term, attributes: attrs, type: :visible).convert
|
515
506
|
else
|
516
507
|
# (((Tigers,Big cats)))
|
517
508
|
attrs = {}
|
518
|
-
if (terms = normalize_text
|
509
|
+
if (terms = normalize_text encl_text, true).include? ';&'
|
519
510
|
if terms.include? ' >> '
|
520
511
|
terms, _, see = terms.partition ' >> '
|
521
512
|
attrs['see'] = see
|
@@ -524,8 +515,7 @@ module Substitutors
|
|
524
515
|
attrs['see-also'] = see_also
|
525
516
|
end
|
526
517
|
end
|
527
|
-
attrs['terms'] =
|
528
|
-
#doc.register :indexterms, terms
|
518
|
+
attrs['terms'] = split_simple_csv terms
|
529
519
|
subbed_term = (Inline.new self, :indexterm, nil, attributes: attrs).convert
|
530
520
|
end
|
531
521
|
before ? %(#{before}#{subbed_term}#{after}) : subbed_term
|
@@ -545,7 +535,7 @@ module Substitutors
|
|
545
535
|
# NOTE if $4 is set, we're looking at a formal macro (e.g., https://example.org[])
|
546
536
|
if $4
|
547
537
|
prefix = '' if prefix == 'link:'
|
548
|
-
|
538
|
+
link_text = nil if (link_text = $4).empty?
|
549
539
|
else
|
550
540
|
# invalid macro syntax (link: prefix w/o trailing square brackets or enclosed in double quotes)
|
551
541
|
# FIXME we probably shouldn't even get here when the link: prefix is present; the regex is doing too much
|
@@ -553,12 +543,13 @@ module Substitutors
|
|
553
543
|
when 'link:', ?", ?'
|
554
544
|
next $&
|
555
545
|
end
|
556
|
-
text = ''
|
557
546
|
case $3
|
558
|
-
when ')'
|
559
|
-
# move trailing ) out of URL
|
547
|
+
when ')', '?', '!'
|
560
548
|
target = target.chop
|
561
|
-
suffix = ')'
|
549
|
+
if (suffix = $3) == ')' && (target.end_with? '.', '?', '!')
|
550
|
+
suffix = target[-1] + suffix
|
551
|
+
target = target.chop
|
552
|
+
end
|
562
553
|
# NOTE handle case when modified target is a URI scheme (e.g., http://)
|
563
554
|
next $& if target.end_with? '://'
|
564
555
|
when ';'
|
@@ -591,27 +582,37 @@ module Substitutors
|
|
591
582
|
end
|
592
583
|
|
593
584
|
attrs, link_opts = nil, { type: :link }
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
585
|
+
|
586
|
+
if link_text
|
587
|
+
new_link_text = link_text = link_text.gsub ESC_R_SB, R_SB if link_text.include? R_SB
|
588
|
+
if !doc.compat_mode && (link_text.include? '=')
|
589
|
+
# NOTE if an equals sign (=) is present, extract attributes from link text
|
590
|
+
link_text, attrs = extract_attributes_from_text link_text, ''
|
591
|
+
new_link_text = link_text
|
599
592
|
link_opts[:id] = attrs['id']
|
600
593
|
end
|
601
594
|
|
602
|
-
if
|
603
|
-
|
595
|
+
if link_text.end_with? '^'
|
596
|
+
new_link_text = link_text = link_text.chop
|
604
597
|
if attrs
|
605
598
|
attrs['window'] ||= '_blank'
|
606
599
|
else
|
607
600
|
attrs = { 'window' => '_blank' }
|
608
601
|
end
|
609
602
|
end
|
610
|
-
end
|
611
603
|
|
612
|
-
|
604
|
+
if new_link_text && new_link_text.empty?
|
605
|
+
# NOTE it's not possible for the URI scheme to be bare in this case
|
606
|
+
link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
|
607
|
+
bare = true
|
608
|
+
end
|
609
|
+
else
|
613
610
|
# NOTE it's not possible for the URI scheme to be bare in this case
|
614
|
-
|
611
|
+
link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
|
612
|
+
bare = true
|
613
|
+
end
|
614
|
+
|
615
|
+
if bare
|
615
616
|
if attrs
|
616
617
|
attrs['role'] = (attrs.key? 'role') ? %(bare #{attrs['role']}) : 'bare'
|
617
618
|
else
|
@@ -621,7 +622,7 @@ module Substitutors
|
|
621
622
|
|
622
623
|
doc.register :links, (link_opts[:target] = target)
|
623
624
|
link_opts[:attributes] = attrs if attrs
|
624
|
-
%(#{prefix}#{(Inline.new self, :anchor,
|
625
|
+
%(#{prefix}#{(Inline.new self, :anchor, link_text, link_opts).convert}#{suffix})
|
625
626
|
end
|
626
627
|
end
|
627
628
|
|
@@ -637,12 +638,12 @@ module Substitutors
|
|
637
638
|
target = $2
|
638
639
|
end
|
639
640
|
attrs, link_opts = nil, { type: :link }
|
640
|
-
unless (
|
641
|
-
|
641
|
+
unless (link_text = $3).empty?
|
642
|
+
link_text = link_text.gsub ESC_R_SB, R_SB if link_text.include? R_SB
|
642
643
|
if mailto
|
643
|
-
if !doc.compat_mode && (
|
644
|
-
# NOTE if a comma (,) is present, extract attributes from text
|
645
|
-
|
644
|
+
if !doc.compat_mode && (link_text.include? ',')
|
645
|
+
# NOTE if a comma (,) is present, extract attributes from link text
|
646
|
+
link_text, attrs = extract_attributes_from_text link_text, ''
|
646
647
|
link_opts[:id] = attrs['id']
|
647
648
|
if attrs.key? 2
|
648
649
|
if attrs.key? 3
|
@@ -652,14 +653,14 @@ module Substitutors
|
|
652
653
|
end
|
653
654
|
end
|
654
655
|
end
|
655
|
-
elsif !doc.compat_mode && (
|
656
|
-
# NOTE if an equals sign (=) is present, extract attributes from text
|
657
|
-
|
656
|
+
elsif !doc.compat_mode && (link_text.include? '=')
|
657
|
+
# NOTE if an equals sign (=) is present, extract attributes from link text
|
658
|
+
link_text, attrs = extract_attributes_from_text link_text, ''
|
658
659
|
link_opts[:id] = attrs['id']
|
659
660
|
end
|
660
661
|
|
661
|
-
if
|
662
|
-
|
662
|
+
if link_text.end_with? '^'
|
663
|
+
link_text = link_text.chop
|
663
664
|
if attrs
|
664
665
|
attrs['window'] ||= '_blank'
|
665
666
|
else
|
@@ -668,17 +669,17 @@ module Substitutors
|
|
668
669
|
end
|
669
670
|
end
|
670
671
|
|
671
|
-
if
|
672
|
+
if link_text.empty?
|
672
673
|
# mailto is a special case, already processed
|
673
674
|
if mailto
|
674
|
-
|
675
|
+
link_text = mailto_text
|
675
676
|
else
|
676
677
|
if doc_attrs.key? 'hide-uri-scheme'
|
677
|
-
if (
|
678
|
-
|
678
|
+
if (link_text = target.sub UriSniffRx, '').empty?
|
679
|
+
link_text = target
|
679
680
|
end
|
680
681
|
else
|
681
|
-
|
682
|
+
link_text = target
|
682
683
|
end
|
683
684
|
if attrs
|
684
685
|
attrs['role'] = (attrs.key? 'role') ? %(bare #{attrs['role']}) : 'bare'
|
@@ -691,7 +692,7 @@ module Substitutors
|
|
691
692
|
# QUESTION should a mailto be registered as an e-mail address?
|
692
693
|
doc.register :links, (link_opts[:target] = target)
|
693
694
|
link_opts[:attributes] = attrs if attrs
|
694
|
-
Inline.new(self, :anchor,
|
695
|
+
Inline.new(self, :anchor, link_text, link_opts).convert
|
695
696
|
end
|
696
697
|
end
|
697
698
|
|
@@ -738,15 +739,17 @@ module Substitutors
|
|
738
739
|
|
739
740
|
attrs = {}
|
740
741
|
if (refid = $1)
|
741
|
-
|
742
|
-
|
742
|
+
if refid.include? ','
|
743
|
+
refid, _, link_text = refid.partition ','
|
744
|
+
link_text = nil if (link_text = link_text.lstrip).empty?
|
745
|
+
end
|
743
746
|
else
|
744
747
|
macro = true
|
745
748
|
refid = $2
|
746
|
-
if (
|
747
|
-
|
748
|
-
# NOTE if an equals sign (=) is present, extract attributes from text
|
749
|
-
|
749
|
+
if (link_text = $3)
|
750
|
+
link_text = link_text.gsub ESC_R_SB, R_SB if link_text.include? R_SB
|
751
|
+
# NOTE if an equals sign (=) is present, extract attributes from link text
|
752
|
+
link_text, attrs = extract_attributes_from_text link_text if !doc.compat_mode && (link_text.include? '=')
|
750
753
|
end
|
751
754
|
end
|
752
755
|
|
@@ -800,7 +803,7 @@ module Substitutors
|
|
800
803
|
refid, path, target = nil, nil, '#'
|
801
804
|
end
|
802
805
|
else
|
803
|
-
refid, path = path, %(#{doc.attributes['relfileprefix']}#{path}#{src2src ? (doc.attributes.fetch 'relfilesuffix', doc.outfilesuffix) : ''})
|
806
|
+
refid, path = path, %(#{doc.attributes['relfileprefix'] || ''}#{path}#{src2src ? (doc.attributes.fetch 'relfilesuffix', doc.outfilesuffix) : ''})
|
804
807
|
if fragment
|
805
808
|
refid, target = %(#{refid}##{fragment}), %(#{path}##{fragment})
|
806
809
|
else
|
@@ -825,7 +828,7 @@ module Substitutors
|
|
825
828
|
attrs['path'] = path
|
826
829
|
attrs['fragment'] = fragment
|
827
830
|
attrs['refid'] = refid
|
828
|
-
Inline.new(self, :anchor,
|
831
|
+
Inline.new(self, :anchor, link_text, type: :xref, target: target, attributes: attrs).convert
|
829
832
|
end
|
830
833
|
end
|
831
834
|
|
@@ -837,7 +840,7 @@ module Substitutors
|
|
837
840
|
# footnoteref
|
838
841
|
if $1
|
839
842
|
if $3
|
840
|
-
id,
|
843
|
+
id, content = $3.split ',', 2
|
841
844
|
logger.warn %(found deprecated footnoteref macro: #{$&}; use footnote macro with target instead) unless doc.compat_mode
|
842
845
|
else
|
843
846
|
next $&
|
@@ -845,31 +848,31 @@ module Substitutors
|
|
845
848
|
# footnote
|
846
849
|
else
|
847
850
|
id = $2
|
848
|
-
|
851
|
+
content = $3
|
849
852
|
end
|
850
853
|
|
851
854
|
if id
|
852
855
|
if (footnote = doc.footnotes.find {|candidate| candidate.id == id })
|
853
|
-
index,
|
856
|
+
index, content = footnote.index, footnote.text
|
854
857
|
type, target, id = :xref, id, nil
|
855
|
-
elsif
|
856
|
-
|
858
|
+
elsif content
|
859
|
+
content = restore_passthroughs(normalize_text content, true, true)
|
857
860
|
index = doc.counter('footnote-number')
|
858
|
-
doc.register(:footnotes, Document::Footnote.new(index, id,
|
861
|
+
doc.register(:footnotes, Document::Footnote.new(index, id, content))
|
859
862
|
type, target = :ref, nil
|
860
863
|
else
|
861
864
|
logger.warn %(invalid footnote reference: #{id})
|
862
|
-
type, target,
|
865
|
+
type, target, content, id = :xref, id, id, nil
|
863
866
|
end
|
864
|
-
elsif
|
865
|
-
|
867
|
+
elsif content
|
868
|
+
content = restore_passthroughs(normalize_text content, true, true)
|
866
869
|
index = doc.counter('footnote-number')
|
867
|
-
doc.register(:footnotes, Document::Footnote.new(index, id,
|
870
|
+
doc.register(:footnotes, Document::Footnote.new(index, id, content))
|
868
871
|
type = target = nil
|
869
872
|
else
|
870
873
|
next $&
|
871
874
|
end
|
872
|
-
Inline.new(self, :footnote,
|
875
|
+
Inline.new(self, :footnote, content, attributes: { 'index' => index }, id: id, target: target, type: type).convert
|
873
876
|
end
|
874
877
|
end
|
875
878
|
|
@@ -937,7 +940,7 @@ module Substitutors
|
|
937
940
|
# process_callouts - a Boolean flag indicating whether callout marks should be located and substituted
|
938
941
|
#
|
939
942
|
# Returns the highlighted source code, if a syntax highlighter is defined on the document, otherwise the source with
|
940
|
-
# verbatim
|
943
|
+
# verbatim substitutions applied
|
941
944
|
def highlight_source source, process_callouts
|
942
945
|
# NOTE the call to highlight? is a defensive check since, normally, we wouldn't arrive here unless it returns true
|
943
946
|
return sub_source source, process_callouts unless (syntax_hl = @document.syntax_highlighter) && syntax_hl.highlight?
|
@@ -946,8 +949,9 @@ module Substitutors
|
|
946
949
|
|
947
950
|
doc_attrs = @document.attributes
|
948
951
|
syntax_hl_name = syntax_hl.name
|
949
|
-
if (linenums_mode = (attr? 'linenums') ? (doc_attrs[%(#{syntax_hl_name}-linenums-mode)] || :table).to_sym : nil)
|
950
|
-
|
952
|
+
if (linenums_mode = (attr? 'linenums') ? (doc_attrs[%(#{syntax_hl_name}-linenums-mode)] || :table).to_sym : nil) &&
|
953
|
+
(start_line_number = (attr 'start', 1).to_i) < 1
|
954
|
+
start_line_number = 1
|
951
955
|
end
|
952
956
|
highlight_lines = resolve_lines_to_highlight source, (attr 'highlight'), start_line_number if attr? 'highlight'
|
953
957
|
|
@@ -984,7 +988,7 @@ module Substitutors
|
|
984
988
|
negate = true
|
985
989
|
end
|
986
990
|
if (delim = (entry.include? '..') ? '..' : ((entry.include? '-') ? '-' : nil))
|
987
|
-
from,
|
991
|
+
from, _, to = entry.partition delim
|
988
992
|
to = (source.count LF) + 1 if to.empty? || (to = to.to_i) < 0
|
989
993
|
if negate
|
990
994
|
lines -= (from.to_i..to).to_a
|
@@ -1006,7 +1010,7 @@ module Substitutors
|
|
1006
1010
|
|
1007
1011
|
# Public: Extract the passthrough text from the document for reinsertion after processing.
|
1008
1012
|
#
|
1009
|
-
# text - The String from which to extract passthrough
|
1013
|
+
# text - The String from which to extract passthrough fragments
|
1010
1014
|
#
|
1011
1015
|
# Returns the String text with passthrough regions substituted with placeholders
|
1012
1016
|
def extract_passthroughs text
|
@@ -1118,7 +1122,7 @@ module Substitutors
|
|
1118
1122
|
end
|
1119
1123
|
subs = $2
|
1120
1124
|
content = normalize_text $3, nil, true
|
1121
|
-
# NOTE drop enclosing $ signs around latexmath for backwards compatibility with AsciiDoc
|
1125
|
+
# NOTE drop enclosing $ signs around latexmath for backwards compatibility with AsciiDoc.py
|
1122
1126
|
content = content.slice 1, content.length - 2 if type == :latexmath && (content.start_with? '$') && (content.end_with? '$')
|
1123
1127
|
subs = subs ? (resolve_pass_subs subs) : ((@document.basebackend? 'html') ? BASIC_SUBS : nil)
|
1124
1128
|
passthrus[passthru_key = passthrus.size] = { text: content, subs: subs, type: type }
|
@@ -1213,7 +1217,7 @@ module Substitutors
|
|
1213
1217
|
end
|
1214
1218
|
end
|
1215
1219
|
return unless candidates
|
1216
|
-
# weed out invalid options and remove duplicates (order is preserved; first
|
1220
|
+
# weed out invalid options and remove duplicates (order is preserved; first occurrence wins)
|
1217
1221
|
resolved = candidates & SUB_OPTIONS[type]
|
1218
1222
|
unless (candidates - resolved).empty?
|
1219
1223
|
invalid = candidates - resolved
|
@@ -1232,17 +1236,17 @@ module Substitutors
|
|
1232
1236
|
resolve_subs subs, :inline, nil, 'passthrough macro'
|
1233
1237
|
end
|
1234
1238
|
|
1235
|
-
# Public: Expand all groups in the subs list and return. If no subs are
|
1239
|
+
# Public: Expand all groups in the subs list and return. If no subs are resolved, return nil.
|
1236
1240
|
#
|
1237
|
-
# subs - The substitutions to expand; can be a Symbol, Symbol Array or
|
1241
|
+
# subs - The substitutions to expand; can be a Symbol, Symbol Array, or String
|
1242
|
+
# subject - The String to use in log messages to communicate the subject for which subs are being resolved (default: nil)
|
1238
1243
|
#
|
1239
1244
|
# Returns a Symbol Array of substitutions to pass to apply_subs or nil if no substitutions were resolved.
|
1240
|
-
def expand_subs subs
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
else
|
1245
|
+
def expand_subs subs, subject = nil
|
1246
|
+
case subs
|
1247
|
+
when ::Symbol
|
1248
|
+
subs == :none ? nil : SUB_GROUPS[subs] || [subs]
|
1249
|
+
when ::Array
|
1246
1250
|
expanded_subs = []
|
1247
1251
|
subs.each do |key|
|
1248
1252
|
unless key == :none
|
@@ -1253,8 +1257,9 @@ module Substitutors
|
|
1253
1257
|
end
|
1254
1258
|
end
|
1255
1259
|
end
|
1256
|
-
|
1257
1260
|
expanded_subs.empty? ? nil : expanded_subs
|
1261
|
+
else
|
1262
|
+
resolve_subs subs, :inline, nil, subject
|
1258
1263
|
end
|
1259
1264
|
end
|
1260
1265
|
|
@@ -1276,7 +1281,7 @@ module Substitutors
|
|
1276
1281
|
# NOTE :literal with listparagraph-option gets folded into text of list item later
|
1277
1282
|
default_subs = @context == :verse ? NORMAL_SUBS : VERBATIM_SUBS
|
1278
1283
|
when :raw
|
1279
|
-
# TODO make pass subs a compliance setting; AsciiDoc
|
1284
|
+
# TODO make pass subs a compliance setting; AsciiDoc.py performs :attributes and :macros on a pass block
|
1280
1285
|
default_subs = @context == :stem ? BASIC_SUBS : NO_SUBS
|
1281
1286
|
else
|
1282
1287
|
return @subs
|
@@ -1472,33 +1477,28 @@ module Substitutors
|
|
1472
1477
|
#
|
1473
1478
|
# Returns a Hash of attributes (role and id only)
|
1474
1479
|
def parse_quoted_text_attributes str
|
1475
|
-
return {} if (str = str.rstrip).empty?
|
1476
1480
|
# NOTE attributes are typically resolved after quoted text, so substitute eagerly
|
1477
1481
|
str = sub_attributes str if str.include? ATTR_REF_HEAD
|
1478
1482
|
# for compliance, only consider first positional attribute (very unlikely)
|
1479
1483
|
str = str.slice 0, (str.index ',') if str.include? ','
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1484
|
+
if (str = str.strip).empty?
|
1485
|
+
{}
|
1486
|
+
elsif (str.start_with? '.', '#') && Compliance.shorthand_property_syntax
|
1487
|
+
before, _, after = str.partition '#'
|
1488
|
+
attrs = {}
|
1489
|
+
if after.empty?
|
1490
|
+
attrs['role'] = (before.tr '.', ' ').lstrip if before.length > 1
|
1486
1491
|
else
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
roles.concat more_roles
|
1492
|
+
id, _, roles = after.partition '.'
|
1493
|
+
attrs['id'] = id unless id.empty?
|
1494
|
+
if roles.empty?
|
1495
|
+
attrs['role'] = (before.tr '.', ' ').lstrip if before.length > 1
|
1496
|
+
elsif before.length > 1
|
1497
|
+
attrs['role'] = ((before + '.' + roles).tr '.', ' ').lstrip
|
1498
|
+
else
|
1499
|
+
attrs['role'] = roles.tr '.', ' '
|
1500
|
+
end
|
1497
1501
|
end
|
1498
|
-
|
1499
|
-
attrs = {}
|
1500
|
-
attrs['id'] = id if id
|
1501
|
-
attrs['role'] = roles.join ' ' unless roles.empty?
|
1502
1502
|
attrs
|
1503
1503
|
else
|
1504
1504
|
{ 'role' => str }
|
@@ -1532,7 +1532,7 @@ module Substitutors
|
|
1532
1532
|
case c
|
1533
1533
|
when ','
|
1534
1534
|
if quote_open
|
1535
|
-
accum
|
1535
|
+
accum += c
|
1536
1536
|
else
|
1537
1537
|
values << accum.strip
|
1538
1538
|
accum = ''
|
@@ -1540,7 +1540,7 @@ module Substitutors
|
|
1540
1540
|
when '"'
|
1541
1541
|
quote_open = !quote_open
|
1542
1542
|
else
|
1543
|
-
accum
|
1543
|
+
accum += c
|
1544
1544
|
end
|
1545
1545
|
end
|
1546
1546
|
values << accum.strip
|
@@ -78,7 +78,8 @@ class SyntaxHighlighter::CodeRayAdapter < SyntaxHighlighter::Base
|
|
78
78
|
end
|
79
79
|
|
80
80
|
extend Styles # exports static methods
|
81
|
-
include
|
81
|
+
include Styles # adds methods to instance
|
82
|
+
include Loader # adds methods to instance
|
82
83
|
|
83
84
|
CodeCellStartTagCs = '<td class="code"><pre>'
|
84
85
|
|
@@ -9,7 +9,7 @@ class SyntaxHighlighter::HighlightJsAdapter < SyntaxHighlighter::Base
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def format node, lang, opts
|
12
|
-
super node, lang, (opts.merge transform: proc {|_, code| code['class'] = %(language-#{lang || 'none'} hljs) }
|
12
|
+
super node, lang, (opts.merge transform: proc {|_, code| code['class'] = %(language-#{lang || 'none'} hljs) })
|
13
13
|
end
|
14
14
|
|
15
15
|
def docinfo? location
|
@@ -33,13 +33,19 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
33
33
|
highlighted = highlighted.sub WrapperTagRx, PreTagCs
|
34
34
|
opts[:callouts] ? [highlighted, (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil] : highlighted
|
35
35
|
else
|
36
|
-
node.
|
36
|
+
node.sub_source source, false # handles nil response from ::Pygments::Lexer#highlight
|
37
37
|
end
|
38
38
|
elsif (highlighted = lexer.highlight source, options: highlight_opts)
|
39
|
-
|
39
|
+
if linenos
|
40
|
+
if noclasses
|
41
|
+
highlighted = highlighted.gsub StyledLinenoSpanTagRx, LinenoSpanTagCs
|
42
|
+
elsif highlighted.include? LegacyLinenoSpanStartTagCs
|
43
|
+
highlighted = highlighted.gsub LegacyLinenoSpanTagRx, LinenoSpanTagCs
|
44
|
+
end
|
45
|
+
end
|
40
46
|
highlighted.sub WrapperTagRx, '\1'
|
41
47
|
else
|
42
|
-
node.
|
48
|
+
node.sub_source source, false # handles nil response from ::Pygments::Lexer#highlight
|
43
49
|
end
|
44
50
|
end
|
45
51
|
|
@@ -114,6 +120,7 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
114
120
|
end
|
115
121
|
@@stylesheet_cache = ::Hash.new do |cache, key|
|
116
122
|
if (stylesheet = ::Pygments.css BASE_SELECTOR, classprefix: TOKEN_CLASS_PREFIX, style: key)
|
123
|
+
stylesheet = stylesheet.slice (stylesheet.index BASE_SELECTOR), stylesheet.length unless stylesheet.start_with? BASE_SELECTOR
|
117
124
|
@@stylesheet_cache = cache.merge key => stylesheet
|
118
125
|
stylesheet
|
119
126
|
end
|
@@ -122,18 +129,20 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
122
129
|
DEFAULT_STYLE = 'default'
|
123
130
|
BASE_SELECTOR = 'pre.pygments'
|
124
131
|
TOKEN_CLASS_PREFIX = 'tok-'
|
125
|
-
|
126
132
|
BaseStyleRx = /^#{BASE_SELECTOR.gsub '.', '\\.'} +\{([^}]+?)\}/
|
127
133
|
|
128
134
|
private_constant :BASE_SELECTOR, :TOKEN_CLASS_PREFIX, :BaseStyleRx
|
129
135
|
end
|
130
136
|
|
131
137
|
extend Styles # exports static methods
|
132
|
-
include
|
138
|
+
include Styles # adds methods to instance
|
139
|
+
include Loader # adds methods to instance
|
133
140
|
|
134
141
|
CodeCellStartTagCs = '<td class="code">'
|
142
|
+
LegacyLinenoSpanStartTagCs = '<span class="lineno">'
|
143
|
+
LegacyLinenoSpanTagRx = %r(#{LegacyLinenoSpanStartTagCs}( *\d+) ?</span>)
|
135
144
|
LinenoColumnStartTagsCs = '<td class="linenos"><div class="linenodiv"><pre>'
|
136
|
-
LinenoSpanTagCs = '<span class="
|
145
|
+
LinenoSpanTagCs = '<span class="linenos">\1</span>'
|
137
146
|
PreTagCs = '<pre>\1</pre>'
|
138
147
|
StyledLinenoColumnStartTagsRx = /<td><div class="linenodiv" style="[^"]+?"><pre style="[^"]+?">/
|
139
148
|
StyledLinenoSpanTagRx = %r((?<=^|<span></span>)<span style="[^"]+">( *\d+) ?</span>)
|
@@ -143,6 +152,6 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
143
152
|
# NOTE initial <span></span> preserves leading blank lines
|
144
153
|
WrapperTagRx = %r(<div class="#{WRAPPER_CLASS}"><pre\b[^>]*?>(.*)</pre></div>\n*)m
|
145
154
|
|
146
|
-
private_constant :CodeCellStartTagCs, :LinenoColumnStartTagsCs, :LinenoSpanTagCs, :PreTagCs, :StyledLinenoColumnStartTagsRx, :StyledLinenoSpanTagRx, :WrapperTagRx, :WRAPPER_CLASS
|
155
|
+
private_constant :CodeCellStartTagCs, :LegacyLinenoSpanStartTagCs, :LegacyLinenoSpanTagRx, :LinenoColumnStartTagsCs, :LinenoSpanTagCs, :PreTagCs, :StyledLinenoColumnStartTagsRx, :StyledLinenoSpanTagRx, :WrapperTagRx, :WRAPPER_CLASS
|
147
156
|
end
|
148
157
|
end
|
@@ -133,7 +133,8 @@ class SyntaxHighlighter::RougeAdapter < SyntaxHighlighter::Base
|
|
133
133
|
end
|
134
134
|
|
135
135
|
extend Styles # exports static methods
|
136
|
-
include
|
136
|
+
include Styles # adds methods to instance
|
137
|
+
include Loader # adds methods to instance
|
137
138
|
|
138
139
|
CodeCellStartTagCs = '<td class="code">'
|
139
140
|
|