asciidoctor 2.0.16 → 2.0.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +74 -11
- data/README-de.adoc +7 -11
- data/README-fr.adoc +7 -11
- data/README-jp.adoc +8 -12
- data/README-zh_CN.adoc +7 -11
- data/README.adoc +33 -18
- data/asciidoctor.gemspec +2 -2
- data/data/locale/attributes-fr.adoc +2 -2
- data/data/stylesheets/asciidoctor-default.css +9 -10
- data/data/stylesheets/coderay-asciidoctor.css +9 -9
- data/lib/asciidoctor/abstract_block.rb +7 -5
- data/lib/asciidoctor/block.rb +1 -1
- data/lib/asciidoctor/cli/invoker.rb +2 -2
- data/lib/asciidoctor/cli/options.rb +8 -4
- data/lib/asciidoctor/converter/html5.rb +47 -39
- data/lib/asciidoctor/converter/template.rb +1 -1
- data/lib/asciidoctor/converter.rb +1 -1
- data/lib/asciidoctor/core_ext/hash/merge.rb +1 -1
- data/lib/asciidoctor/document.rb +18 -4
- data/lib/asciidoctor/extensions.rb +26 -6
- data/lib/asciidoctor/parser.rb +57 -55
- data/lib/asciidoctor/reader.rb +23 -28
- data/lib/asciidoctor/rx.rb +6 -2
- data/lib/asciidoctor/section.rb +7 -0
- data/lib/asciidoctor/substitutors.rb +4 -4
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +1 -1
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +12 -4
- data/lib/asciidoctor/table.rb +1 -1
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +24 -25
- data/man/asciidoctor.adoc +30 -24
- metadata +5 -5
data/lib/asciidoctor/parser.rb
CHANGED
@@ -89,10 +89,10 @@ class Parser
|
|
89
89
|
#
|
90
90
|
# returns the Document object
|
91
91
|
def self.parse(reader, document, options = {})
|
92
|
-
block_attributes = parse_document_header(reader, document)
|
92
|
+
block_attributes = parse_document_header(reader, document, (header_only = options[:header_only]))
|
93
93
|
|
94
94
|
# NOTE don't use a postfix conditional here as it's known to confuse JRuby in certain circumstances
|
95
|
-
unless
|
95
|
+
unless header_only
|
96
96
|
while reader.has_more_lines?
|
97
97
|
new_section, block_attributes = next_section(reader, document, block_attributes)
|
98
98
|
if new_section
|
@@ -117,7 +117,7 @@ class Parser
|
|
117
117
|
# which are automatically removed by the reader.
|
118
118
|
#
|
119
119
|
# returns the Hash of orphan block attributes captured above the header
|
120
|
-
def self.parse_document_header(reader, document)
|
120
|
+
def self.parse_document_header(reader, document, header_only = false)
|
121
121
|
# capture lines of block-level metadata and plow away comment lines that precede first block
|
122
122
|
block_attrs = reader.skip_blank_lines ? (parse_block_metadata_lines reader, document) : {}
|
123
123
|
doc_attrs = document.attributes
|
@@ -125,6 +125,7 @@ class Parser
|
|
125
125
|
# special case, block title is not allowed above document title,
|
126
126
|
# carry attributes over to the document body
|
127
127
|
if (implicit_doctitle = is_next_line_doctitle? reader, block_attrs, doc_attrs['leveloffset']) && block_attrs['title']
|
128
|
+
doc_attrs['authorcount'] = 0
|
128
129
|
return document.finalize_header block_attrs, false
|
129
130
|
end
|
130
131
|
|
@@ -168,7 +169,7 @@ class Parser
|
|
168
169
|
end
|
169
170
|
block_attrs.clear
|
170
171
|
(modified_attrs = document.instance_variable_get :@attributes_modified).delete 'doctitle'
|
171
|
-
parse_header_metadata reader, document
|
172
|
+
parse_header_metadata reader, document, nil
|
172
173
|
if modified_attrs.include? 'doctitle'
|
173
174
|
if (val = doc_attrs['doctitle']).nil_or_empty? || val == doctitle_attr_val
|
174
175
|
doc_attrs['doctitle'] = doctitle_attr_val
|
@@ -179,10 +180,19 @@ class Parser
|
|
179
180
|
modified_attrs << 'doctitle'
|
180
181
|
end
|
181
182
|
document.register :refs, [doc_id, document] if doc_id
|
183
|
+
elsif (author = doc_attrs['author'])
|
184
|
+
author_metadata = process_authors author, true, false
|
185
|
+
author_metadata.delete 'authorinitials' if doc_attrs['authorinitials']
|
186
|
+
doc_attrs.update author_metadata
|
187
|
+
elsif (author = doc_attrs['authors'])
|
188
|
+
author_metadata = process_authors author, true
|
189
|
+
doc_attrs.update author_metadata
|
190
|
+
else
|
191
|
+
doc_attrs['authorcount'] = 0
|
182
192
|
end
|
183
193
|
|
184
194
|
# parse title and consume name section of manpage document
|
185
|
-
parse_manpage_header reader, document, block_attrs if document.doctype == 'manpage'
|
195
|
+
parse_manpage_header reader, document, block_attrs, header_only if document.doctype == 'manpage'
|
186
196
|
|
187
197
|
# NOTE block_attrs are the block-level attributes (not document attributes) that
|
188
198
|
# precede the first line of content (document title, first section or first block)
|
@@ -192,7 +202,7 @@ class Parser
|
|
192
202
|
# Public: Parses the manpage header of the AsciiDoc source read from the Reader
|
193
203
|
#
|
194
204
|
# returns Nothing
|
195
|
-
def self.parse_manpage_header(reader, document, block_attributes)
|
205
|
+
def self.parse_manpage_header(reader, document, block_attributes, header_only = false)
|
196
206
|
if ManpageTitleVolnumRx =~ (doc_attrs = document.attributes)['doctitle']
|
197
207
|
doc_attrs['manvolnum'] = manvolnum = $2
|
198
208
|
doc_attrs['mantitle'] = (((mantitle = $1).include? ATTR_REF_HEAD) ? (document.sub_attributes mantitle) : mantitle).downcase
|
@@ -209,6 +219,8 @@ class Parser
|
|
209
219
|
doc_attrs['docname'] = manname
|
210
220
|
doc_attrs['outfilesuffix'] = %(.#{manvolnum})
|
211
221
|
end
|
222
|
+
elsif header_only
|
223
|
+
# done
|
212
224
|
else
|
213
225
|
reader.skip_blank_lines
|
214
226
|
reader.save
|
@@ -452,7 +464,7 @@ class Parser
|
|
452
464
|
end
|
453
465
|
|
454
466
|
# The attributes returned here are orphaned attributes that fall at the end
|
455
|
-
# of a section that need to get
|
467
|
+
# of a section that need to get transferred to the next section
|
456
468
|
# see "trailing block attributes transfer to the following section" in
|
457
469
|
# test/attributes_test.rb for an example
|
458
470
|
[section == parent ? nil : section, attributes.merge]
|
@@ -647,7 +659,7 @@ class Parser
|
|
647
659
|
if (default_attrs = ext_config[:default_attrs])
|
648
660
|
attributes.update(default_attrs) {|_, old_v| old_v }
|
649
661
|
end
|
650
|
-
if (block = extension.process_method[parent, target, attributes])
|
662
|
+
if (block = extension.process_method[parent, target, attributes]) && block != parent
|
651
663
|
attributes.replace block.attributes
|
652
664
|
break
|
653
665
|
else
|
@@ -1038,12 +1050,12 @@ class Parser
|
|
1038
1050
|
if (extension = options[:extension])
|
1039
1051
|
# QUESTION do we want to delete the style?
|
1040
1052
|
attributes.delete('style')
|
1041
|
-
if (block = extension.process_method[parent, block_reader || (Reader.new lines), attributes.merge])
|
1053
|
+
if (block = extension.process_method[parent, block_reader || (Reader.new lines), attributes.merge]) && block != parent
|
1042
1054
|
attributes.replace block.attributes
|
1043
|
-
#
|
1044
|
-
#
|
1045
|
-
#
|
1046
|
-
if block.content_model == :compound && !(lines = block.lines).empty?
|
1055
|
+
# NOTE an extension can change the content model from :simple to :compound. It's up to the extension
|
1056
|
+
# to decide which one to use. The extension can consult the cloaked-context attribute to determine
|
1057
|
+
# if the input is a paragraph or delimited block.
|
1058
|
+
if block.content_model == :compound && Block === block && !(lines = block.lines).empty?
|
1047
1059
|
content_model = :compound
|
1048
1060
|
block_reader = Reader.new lines
|
1049
1061
|
end
|
@@ -1510,7 +1522,7 @@ class Parser
|
|
1510
1522
|
break
|
1511
1523
|
end
|
1512
1524
|
else # only dlist in need of item text, so slurp it up!
|
1513
|
-
# pop the blank line so it's not
|
1525
|
+
# pop the blank line so it's not interpreted as a list continuation
|
1514
1526
|
buffer.pop unless within_nested_list
|
1515
1527
|
buffer << this_line
|
1516
1528
|
has_text = true
|
@@ -1769,38 +1781,31 @@ class Parser
|
|
1769
1781
|
# parse_header_metadata(Reader.new data, nil, normalize: true)
|
1770
1782
|
# # => { 'author' => 'Author Name', 'firstname' => 'Author', 'lastname' => 'Name', 'email' => 'author@example.org',
|
1771
1783
|
# # 'revnumber' => '1.0', 'revdate' => '2012-12-21', 'revremark' => 'Coincide w/ end of world.' }
|
1772
|
-
def self.parse_header_metadata
|
1784
|
+
def self.parse_header_metadata reader, document = nil, retrieve = true
|
1773
1785
|
doc_attrs = document && document.attributes
|
1774
1786
|
# NOTE this will discard any comment lines, but not skip blank lines
|
1775
1787
|
process_attribute_entries reader, document
|
1776
1788
|
|
1777
|
-
metadata, implicit_author, implicit_authorinitials = implicit_authors = {}, nil, nil
|
1778
|
-
|
1779
1789
|
if reader.has_more_lines? && !reader.next_line_empty?
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
doc_attrs[key] = ::String === val ? (document.apply_header_subs val) : val unless doc_attrs.key? key
|
1786
|
-
end
|
1787
|
-
|
1788
|
-
implicit_author = doc_attrs['author']
|
1789
|
-
implicit_authorinitials = doc_attrs['authorinitials']
|
1790
|
-
implicit_authors = doc_attrs['authors']
|
1790
|
+
authorcount = (implicit_author_metadata = process_authors reader.read_line).delete 'authorcount'
|
1791
|
+
if document && (doc_attrs['authorcount'] = authorcount) > 0
|
1792
|
+
implicit_author_metadata.each do |key, val|
|
1793
|
+
# apply header subs and assign to document; attributes substitution only relevant for email
|
1794
|
+
doc_attrs[key] = document.apply_header_subs val unless doc_attrs.key? key
|
1791
1795
|
end
|
1792
|
-
|
1793
|
-
|
1796
|
+
implicit_author = doc_attrs['author']
|
1797
|
+
implicit_authorinitials = doc_attrs['authorinitials']
|
1798
|
+
implicit_authors = doc_attrs['authors']
|
1794
1799
|
end
|
1800
|
+
implicit_author_metadata['authorcount'] = authorcount
|
1795
1801
|
|
1796
1802
|
# NOTE this will discard any comment lines, but not skip blank lines
|
1797
1803
|
process_attribute_entries reader, document
|
1798
1804
|
|
1799
|
-
rev_metadata = {}
|
1800
|
-
|
1801
1805
|
if reader.has_more_lines? && !reader.next_line_empty?
|
1802
1806
|
rev_line = reader.read_line
|
1803
|
-
if (match = RevisionInfoLineRx.match
|
1807
|
+
if (match = RevisionInfoLineRx.match rev_line)
|
1808
|
+
rev_metadata = {}
|
1804
1809
|
rev_metadata['revnumber'] = match[1].rstrip if match[1]
|
1805
1810
|
unless (component = match[2].strip).empty?
|
1806
1811
|
# version must begin with 'v' if date is absent
|
@@ -1811,31 +1816,24 @@ class Parser
|
|
1811
1816
|
end
|
1812
1817
|
end
|
1813
1818
|
rev_metadata['revremark'] = match[3].rstrip if match[3]
|
1819
|
+
if document && !rev_metadata.empty?
|
1820
|
+
# apply header subs and assign to document
|
1821
|
+
rev_metadata.each do |key, val|
|
1822
|
+
doc_attrs[key] = document.apply_header_subs val unless doc_attrs.key? key
|
1823
|
+
end
|
1824
|
+
end
|
1814
1825
|
else
|
1815
1826
|
# throw it back
|
1816
1827
|
reader.unshift_line rev_line
|
1817
1828
|
end
|
1818
1829
|
end
|
1819
1830
|
|
1820
|
-
unless rev_metadata.empty?
|
1821
|
-
if document
|
1822
|
-
# apply header subs and assign to document
|
1823
|
-
rev_metadata.each do |key, val|
|
1824
|
-
unless doc_attrs.key? key
|
1825
|
-
doc_attrs[key] = document.apply_header_subs val
|
1826
|
-
end
|
1827
|
-
end
|
1828
|
-
end
|
1829
|
-
|
1830
|
-
metadata.update rev_metadata
|
1831
|
-
end
|
1832
|
-
|
1833
1831
|
# NOTE this will discard any comment lines, but not skip blank lines
|
1834
1832
|
process_attribute_entries reader, document
|
1835
1833
|
|
1836
1834
|
reader.skip_blank_lines
|
1837
1835
|
else
|
1838
|
-
|
1836
|
+
implicit_author_metadata = {}
|
1839
1837
|
end
|
1840
1838
|
|
1841
1839
|
# process author attribute entries that override (or stand in for) the implicit author line
|
@@ -1852,7 +1850,7 @@ class Parser
|
|
1852
1850
|
while doc_attrs.key? author_key
|
1853
1851
|
# only use indexed author attribute if value is different
|
1854
1852
|
# leaves corner case if line matches with underscores converted to spaces; use double space to force
|
1855
|
-
if (author_override = doc_attrs[author_key]) ==
|
1853
|
+
if (author_override = doc_attrs[author_key]) == implicit_author_metadata[author_key]
|
1856
1854
|
authors << nil
|
1857
1855
|
sparse = true
|
1858
1856
|
else
|
@@ -1866,20 +1864,24 @@ class Parser
|
|
1866
1864
|
authors.each_with_index do |author, idx|
|
1867
1865
|
next if author
|
1868
1866
|
authors[idx] = [
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1867
|
+
implicit_author_metadata[%(firstname_#{name_idx = idx + 1})],
|
1868
|
+
implicit_author_metadata[%(middlename_#{name_idx})],
|
1869
|
+
implicit_author_metadata[%(lastname_#{name_idx})]
|
1872
1870
|
].compact.map {|it| it.tr ' ', '_' }.join ' '
|
1873
1871
|
end if sparse
|
1874
1872
|
# process as names only
|
1875
1873
|
author_metadata = process_authors authors, true, false
|
1876
1874
|
else
|
1877
|
-
author_metadata = {}
|
1875
|
+
author_metadata = { 'authorcount' => 0 }
|
1878
1876
|
end
|
1879
1877
|
end
|
1880
1878
|
|
1881
|
-
if author_metadata
|
1882
|
-
|
1879
|
+
if author_metadata['authorcount'] == 0
|
1880
|
+
if authorcount
|
1881
|
+
author_metadata = nil
|
1882
|
+
else
|
1883
|
+
doc_attrs['authorcount'] = 0
|
1884
|
+
end
|
1883
1885
|
else
|
1884
1886
|
doc_attrs.update author_metadata
|
1885
1887
|
|
@@ -1890,7 +1892,7 @@ class Parser
|
|
1890
1892
|
end
|
1891
1893
|
end
|
1892
1894
|
|
1893
|
-
|
1895
|
+
implicit_author_metadata.merge rev_metadata.to_h, author_metadata.to_h if retrieve
|
1894
1896
|
end
|
1895
1897
|
|
1896
1898
|
# Internal: Parse the author line into a Hash of author metadata
|
data/lib/asciidoctor/reader.rb
CHANGED
@@ -690,7 +690,7 @@ class PreprocessorReader < Reader
|
|
690
690
|
# only process lines in AsciiDoc files
|
691
691
|
if (@process_lines = file.end_with?(*ASCIIDOC_EXTENSIONS.keys))
|
692
692
|
# NOTE registering the include with a nil value tracks it while not making it visible to interdocument xrefs
|
693
|
-
@includes[path.slice 0, (path.rindex '.')]
|
693
|
+
@includes[path.slice 0, (path.rindex '.')] ||= attributes['partial-option'] ? nil : true
|
694
694
|
end
|
695
695
|
else
|
696
696
|
@dir = '.'
|
@@ -698,7 +698,7 @@ class PreprocessorReader < Reader
|
|
698
698
|
@process_lines = true
|
699
699
|
if (@path = path)
|
700
700
|
# NOTE registering the include with a nil value tracks it while not making it visible to interdocument xrefs
|
701
|
-
@includes[Helpers.rootname path]
|
701
|
+
@includes[Helpers.rootname path] ||= attributes['partial-option'] ? nil : true
|
702
702
|
else
|
703
703
|
@path = '<stdin>'
|
704
704
|
end
|
@@ -949,7 +949,7 @@ class PreprocessorReader < Reader
|
|
949
949
|
if no_target
|
950
950
|
# the text in brackets must match a conditional expression
|
951
951
|
if text && EvalExpressionRx =~ text.strip
|
952
|
-
# NOTE assignments must happen before call to resolve_expr_val for
|
952
|
+
# NOTE assignments must happen before call to resolve_expr_val for compatibility with Opal
|
953
953
|
lhs = $1
|
954
954
|
# regex enforces a restricted set of math-related operations (==, !=, <=, >=, <, >)
|
955
955
|
op = $2
|
@@ -1035,7 +1035,7 @@ class PreprocessorReader < Reader
|
|
1035
1035
|
# however, be friendly and at least make it a link to the source document
|
1036
1036
|
elsif doc.safe >= SafeMode::SECURE
|
1037
1037
|
# FIXME we don't want to use a link macro if we are in a verbatim context
|
1038
|
-
replace_next_line %(link:#{expanded_target}[])
|
1038
|
+
replace_next_line %(link:#{expanded_target}[role=include])
|
1039
1039
|
elsif @maxdepth
|
1040
1040
|
if @include_stack.size >= @maxdepth[:curr]
|
1041
1041
|
logger.error message_with_context %(maximum include depth of #{@maxdepth[:rel]} exceeded), source_location: cursor
|
@@ -1125,7 +1125,7 @@ class PreprocessorReader < Reader
|
|
1125
1125
|
push_include inc_lines, inc_path, relpath, inc_offset, parsed_attrs
|
1126
1126
|
end
|
1127
1127
|
elsif inc_tags
|
1128
|
-
inc_lines, inc_offset, inc_lineno, tag_stack,
|
1128
|
+
inc_lines, inc_offset, inc_lineno, tag_stack, tags_selected, active_tag = [], nil, 0, [], ::Set.new, nil
|
1129
1129
|
if inc_tags.key? '**'
|
1130
1130
|
select = base_select = inc_tags.delete '**'
|
1131
1131
|
if inc_tags.key? '*'
|
@@ -1164,9 +1164,9 @@ class PreprocessorReader < Reader
|
|
1164
1164
|
end
|
1165
1165
|
end
|
1166
1166
|
elsif inc_tags.key? this_tag
|
1167
|
-
|
1167
|
+
tags_selected << this_tag if (select = inc_tags[this_tag])
|
1168
1168
|
# QUESTION should we prevent tag from being selected when enclosing tag is excluded?
|
1169
|
-
tag_stack << [(active_tag = this_tag),
|
1169
|
+
tag_stack << [(active_tag = this_tag), select, inc_lineno]
|
1170
1170
|
elsif !wildcard.nil?
|
1171
1171
|
select = active_tag && !select ? false : wildcard
|
1172
1172
|
tag_stack << [(active_tag = this_tag), select, inc_lineno]
|
@@ -1187,7 +1187,7 @@ class PreprocessorReader < Reader
|
|
1187
1187
|
logger.warn message_with_context %(detected unclosed tag '#{tag_name}' starting at line #{tag_lineno} of include #{target_type}: #{inc_path}), source_location: cursor, include_location: (create_include_cursor inc_path, expanded_target, tag_lineno)
|
1188
1188
|
end
|
1189
1189
|
end
|
1190
|
-
unless (missing_tags = inc_tags.keys -
|
1190
|
+
unless (missing_tags = inc_tags.keep_if {|_, v| v }.keys - tags_selected.to_a).empty?
|
1191
1191
|
logger.warn message_with_context %(tag#{missing_tags.size > 1 ? 's' : ''} '#{missing_tags.join ', '}' not found in include #{target_type}: #{inc_path}), source_location: cursor
|
1192
1192
|
end
|
1193
1193
|
shift
|
@@ -1232,7 +1232,7 @@ class PreprocessorReader < Reader
|
|
1232
1232
|
def resolve_include_path target, attrlist, attributes
|
1233
1233
|
doc = @document
|
1234
1234
|
if (Helpers.uriish? target) || (::String === @dir ? nil : (target = %(#{@dir}/#{target})))
|
1235
|
-
return replace_next_line %(link:#{target}[
|
1235
|
+
return replace_next_line %(link:#{target}[role=include]) unless doc.attr? 'allow-uri-read'
|
1236
1236
|
if doc.attr? 'cache-uri'
|
1237
1237
|
# caching requires the open-uri-cached gem to be installed
|
1238
1238
|
# processing will be automatically aborted if these libraries can't be opened
|
@@ -1280,27 +1280,22 @@ class PreprocessorReader < Reader
|
|
1280
1280
|
|
1281
1281
|
# Private: Ignore front-matter, commonly used in static site generators
|
1282
1282
|
def skip_front_matter! data, increment_linenos = true
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1283
|
+
return unless (delim = data[0]) == '---'
|
1284
|
+
original_data = data.drop 0
|
1285
|
+
data.shift
|
1286
|
+
front_matter = []
|
1287
|
+
@lineno += 1 if increment_linenos
|
1288
|
+
until (eof = data.empty?) || data[0] == delim
|
1289
|
+
front_matter << data.shift
|
1288
1290
|
@lineno += 1 if increment_linenos
|
1289
|
-
while !data.empty? && data[0] != '---'
|
1290
|
-
front_matter << data.shift
|
1291
|
-
@lineno += 1 if increment_linenos
|
1292
|
-
end
|
1293
|
-
|
1294
|
-
if data.empty?
|
1295
|
-
data.unshift(*original_data)
|
1296
|
-
@lineno = 0 if increment_linenos
|
1297
|
-
front_matter = nil
|
1298
|
-
else
|
1299
|
-
data.shift
|
1300
|
-
@lineno += 1 if increment_linenos
|
1301
|
-
end
|
1302
1291
|
end
|
1303
|
-
|
1292
|
+
if eof
|
1293
|
+
data.unshift(*original_data)
|
1294
|
+
@lineno -= original_data.size if increment_linenos
|
1295
|
+
return
|
1296
|
+
end
|
1297
|
+
data.shift
|
1298
|
+
@lineno += 1 if increment_linenos
|
1304
1299
|
front_matter
|
1305
1300
|
end
|
1306
1301
|
|
data/lib/asciidoctor/rx.rb
CHANGED
@@ -407,7 +407,7 @@ module Asciidoctor
|
|
407
407
|
# gist::123456[]
|
408
408
|
#
|
409
409
|
#--
|
410
|
-
# NOTE we've relaxed the match for target to
|
410
|
+
# NOTE we've relaxed the match for target to accommodate the short format (e.g., name::[attrlist])
|
411
411
|
CustomBlockMacroRx = /^(#{CG_WORD}[#{CC_WORD}-]*)::(|\S|\S#{CC_ANY}*?\S)\[(#{CC_ANY}+)?\]$/
|
412
412
|
|
413
413
|
# Matches an image, video or audio block macro.
|
@@ -716,7 +716,11 @@ module Asciidoctor
|
|
716
716
|
#
|
717
717
|
# not c:/sample.adoc or c:\sample.adoc
|
718
718
|
#
|
719
|
-
|
719
|
+
if RUBY_ENGINE == 'opal'
|
720
|
+
UriSniffRx = %r(^#{CG_ALPHA}[#{CC_ALNUM}.+-]+:/{0,2})
|
721
|
+
else
|
722
|
+
UriSniffRx = %r(\A#{CG_ALPHA}[#{CC_ALNUM}.+-]+:/{0,2})
|
723
|
+
end
|
720
724
|
|
721
725
|
# Detects XML tags
|
722
726
|
XmlSanitizeRx = /<[^>]+>/
|
data/lib/asciidoctor/section.rb
CHANGED
@@ -64,6 +64,13 @@ class Section < AbstractBlock
|
|
64
64
|
Section.generate_id title, @document
|
65
65
|
end
|
66
66
|
|
67
|
+
# Public: Check whether this Section has any child Section objects.
|
68
|
+
#
|
69
|
+
# Returns A [Boolean] to indicate whether this Section has child Section objects
|
70
|
+
def sections?
|
71
|
+
@next_section_index > 0
|
72
|
+
end
|
73
|
+
|
67
74
|
# Public: Get the section number for the current Section
|
68
75
|
#
|
69
76
|
# The section number is a dot-separated String that uniquely describes the position of this
|
@@ -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 = /[<&>]/
|
@@ -940,7 +940,7 @@ module Substitutors
|
|
940
940
|
# process_callouts - a Boolean flag indicating whether callout marks should be located and substituted
|
941
941
|
#
|
942
942
|
# Returns the highlighted source code, if a syntax highlighter is defined on the document, otherwise the source with
|
943
|
-
# verbatim
|
943
|
+
# verbatim substitutions applied
|
944
944
|
def highlight_source source, process_callouts
|
945
945
|
# NOTE the call to highlight? is a defensive check since, normally, we wouldn't arrive here unless it returns true
|
946
946
|
return sub_source source, process_callouts unless (syntax_hl = @document.syntax_highlighter) && syntax_hl.highlight?
|
@@ -1010,7 +1010,7 @@ module Substitutors
|
|
1010
1010
|
|
1011
1011
|
# Public: Extract the passthrough text from the document for reinsertion after processing.
|
1012
1012
|
#
|
1013
|
-
# text - The String from which to extract passthrough
|
1013
|
+
# text - The String from which to extract passthrough fragments
|
1014
1014
|
#
|
1015
1015
|
# Returns the String text with passthrough regions substituted with placeholders
|
1016
1016
|
def extract_passthroughs text
|
@@ -1217,7 +1217,7 @@ module Substitutors
|
|
1217
1217
|
end
|
1218
1218
|
end
|
1219
1219
|
return unless candidates
|
1220
|
-
# 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)
|
1221
1221
|
resolved = candidates & SUB_OPTIONS[type]
|
1222
1222
|
unless (candidates - resolved).empty?
|
1223
1223
|
invalid = candidates - resolved
|
@@ -25,7 +25,7 @@ class SyntaxHighlighter::HighlightJsAdapter < SyntaxHighlighter::Base
|
|
25
25
|
#{(doc.attr? 'highlightjs-languages') ? ((doc.attr 'highlightjs-languages').split ',').map {|lang| %[<script src="#{base_url}/languages/#{lang.lstrip}.min.js"></script>\n] }.join : ''}<script>
|
26
26
|
if (!hljs.initHighlighting.called) {
|
27
27
|
hljs.initHighlighting.called = true
|
28
|
-
;[].slice.call(document.querySelectorAll('pre.highlight > code')).forEach(function (el) { hljs.highlightBlock(el) })
|
28
|
+
;[].slice.call(document.querySelectorAll('pre.highlight > code[data-lang]')).forEach(function (el) { hljs.highlightBlock(el) })
|
29
29
|
}
|
30
30
|
</script>)
|
31
31
|
end
|
@@ -36,7 +36,13 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
36
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
48
|
node.sub_source source, false # handles nil response from ::Pygments::Lexer#highlight
|
@@ -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,7 +129,6 @@ 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
|
@@ -133,8 +139,10 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
133
139
|
include Loader # adds methods to instance
|
134
140
|
|
135
141
|
CodeCellStartTagCs = '<td class="code">'
|
142
|
+
LegacyLinenoSpanStartTagCs = '<span class="lineno">'
|
143
|
+
LegacyLinenoSpanTagRx = %r(#{LegacyLinenoSpanStartTagCs}( *\d+) ?</span>)
|
136
144
|
LinenoColumnStartTagsCs = '<td class="linenos"><div class="linenodiv"><pre>'
|
137
|
-
LinenoSpanTagCs = '<span class="
|
145
|
+
LinenoSpanTagCs = '<span class="linenos">\1</span>'
|
138
146
|
PreTagCs = '<pre>\1</pre>'
|
139
147
|
StyledLinenoColumnStartTagsRx = /<td><div class="linenodiv" style="[^"]+?"><pre style="[^"]+?">/
|
140
148
|
StyledLinenoSpanTagRx = %r((?<=^|<span></span>)<span style="[^"]+">( *\d+) ?</span>)
|
@@ -144,6 +152,6 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
144
152
|
# NOTE initial <span></span> preserves leading blank lines
|
145
153
|
WrapperTagRx = %r(<div class="#{WRAPPER_CLASS}"><pre\b[^>]*?>(.*)</pre></div>\n*)m
|
146
154
|
|
147
|
-
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
|
148
156
|
end
|
149
157
|
end
|
data/lib/asciidoctor/table.rb
CHANGED
@@ -411,7 +411,7 @@ end
|
|
411
411
|
# class are primarily responsible for tracking the buffer of a cell as the parser
|
412
412
|
# moves through the lines of the table using tail recursion. When a cell boundary
|
413
413
|
# is located, the previous cell is closed, an instance of Table::Cell is
|
414
|
-
# instantiated, the row is closed if the cell
|
414
|
+
# instantiated, the row is closed if the cell satisfies the column count and,
|
415
415
|
# finally, a new buffer is allocated to track the next cell.
|
416
416
|
class Table::ParserContext
|
417
417
|
include Logging
|
data/lib/asciidoctor/version.rb
CHANGED
data/man/asciidoctor.1
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
'\" t
|
2
2
|
.\" Title: asciidoctor
|
3
|
-
.\" Author: Dan Allen, Sarah White
|
4
|
-
.\" Generator: Asciidoctor 2.0.
|
5
|
-
.\" Date:
|
3
|
+
.\" Author: Dan Allen, Sarah White
|
4
|
+
.\" Generator: Asciidoctor 2.0.17
|
5
|
+
.\" Date: 2022-01-05
|
6
6
|
.\" Manual: Asciidoctor Manual
|
7
|
-
.\" Source: Asciidoctor 2.0.
|
7
|
+
.\" Source: Asciidoctor 2.0.17
|
8
8
|
.\" Language: English
|
9
9
|
.\"
|
10
|
-
.TH "ASCIIDOCTOR" "1" "
|
10
|
+
.TH "ASCIIDOCTOR" "1" "2022-01-05" "Asciidoctor 2.0.17" "Asciidoctor Manual"
|
11
11
|
.ie \n(.g .ds Aq \(aq
|
12
12
|
.el .ds Aq '
|
13
13
|
.ss \n[.ss] 0
|
@@ -171,8 +171,8 @@ Matching templates found in subsequent directories override ones previously disc
|
|
171
171
|
.sp
|
172
172
|
\fB\-\-failure\-level\fP=\fILEVEL\fP
|
173
173
|
.RS 4
|
174
|
-
|
175
|
-
If this option is not set
|
174
|
+
Set the minimum logging level (default: FATAL) that yields a non\-zero exit code (i.e., failure).
|
175
|
+
If this option is not set, the program exits with a zero exit code even if warnings or errors have been logged.
|
176
176
|
.RE
|
177
177
|
.sp
|
178
178
|
\fB\-q, \-\-quiet\fP
|
@@ -206,6 +206,7 @@ Print timings report to stderr (time to read, parse, and convert).
|
|
206
206
|
Print a help message.
|
207
207
|
Show the command usage if \fITOPIC\fP is not specified or recognized.
|
208
208
|
Dump the Asciidoctor man page (in troff/groff format) if \fITOPIC\fP is \fImanpage\fP.
|
209
|
+
Print an AsciiDoc syntax crib sheet (in AsciiDoc) if \fITOPIC\fP is \fIsyntax\fP.
|
209
210
|
.RE
|
210
211
|
.sp
|
211
212
|
\fB\-V, \-\-version\fP
|
@@ -238,30 +239,28 @@ Refer to the \fBAsciidoctor\fP issue tracker at \c
|
|
238
239
|
.URL "https://github.com/asciidoctor/asciidoctor/issues?q=is%3Aopen" "" "."
|
239
240
|
.SH "AUTHORS"
|
240
241
|
.sp
|
241
|
-
\fBAsciidoctor\fP
|
242
|
+
\fBAsciidoctor\fP is led and maintained by Dan Allen and Sarah White and has received contributions from many individuals in the Asciidoctor community.
|
243
|
+
The project was started in 2012 by Ryan Waldron based on a prototype written by Nick Hengeveld for the Git website.
|
244
|
+
Jason Porter wrote the first implementation of the CLI interface provided by this command.
|
242
245
|
.sp
|
243
|
-
\fBAsciiDoc\fP was
|
246
|
+
\fBAsciiDoc.py\fP was created by Stuart Rackham and has received contributions from many individuals in the AsciiDoc.py community.
|
244
247
|
.SH "RESOURCES"
|
245
248
|
.sp
|
246
|
-
\fBProject
|
249
|
+
\fBProject website:\fP \c
|
247
250
|
.URL "https://asciidoctor.org" "" ""
|
248
251
|
.sp
|
249
|
-
\
|
250
|
-
.URL "https://
|
251
|
-
.sp
|
252
|
-
\fBGitHub organization:\fP \c
|
253
|
-
.URL "https://github.com/asciidoctor" "" ""
|
252
|
+
\fBProject documentation:\fP \c
|
253
|
+
.URL "https://docs.asciidoctor.org" "" ""
|
254
254
|
.sp
|
255
|
-
\
|
256
|
-
.URL "
|
257
|
-
.SH "COPYING"
|
255
|
+
\fBCommunity chat:\fP \c
|
256
|
+
.URL "https://chat.asciidoctor.org" "" ""
|
258
257
|
.sp
|
259
|
-
|
260
|
-
|
261
|
-
.SH "AUTHORS"
|
262
|
-
.sp
|
263
|
-
Dan Allen
|
258
|
+
\fBSource repository:\fP \c
|
259
|
+
.URL "https://github.com/asciidoctor/asciidoctor" "" ""
|
264
260
|
.sp
|
265
|
-
|
261
|
+
\fBMailing list archive:\fP \c
|
262
|
+
.URL "https://discuss.asciidoctor.org" "" ""
|
263
|
+
.SH "COPYING"
|
266
264
|
.sp
|
267
|
-
Ryan Waldron
|
265
|
+
Copyright (C) 2012\-present Dan Allen, Sarah White, Ryan Waldron, and the individual contributors to Asciidoctor.
|
266
|
+
Use of this software is granted under the terms of the MIT License.
|