asciidoctor 1.5.8 → 2.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +11 -0
- data/CHANGELOG.adoc +628 -45
- data/LICENSE +2 -1
- data/README-de.adoc +28 -38
- data/README-fr.adoc +30 -43
- data/README-jp.adoc +255 -201
- data/README-zh_CN.adoc +40 -44
- data/README.adoc +170 -143
- data/asciidoctor.gemspec +22 -34
- data/bin/asciidoctor +5 -4
- 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 +6 -5
- 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 +296 -0
- data/data/stylesheets/asciidoctor-default.css +120 -114
- data/data/stylesheets/coderay-asciidoctor.css +15 -17
- data/lib/asciidoctor/abstract_block.rb +146 -140
- data/lib/asciidoctor/abstract_node.rb +152 -170
- data/lib/asciidoctor/attribute_list.rb +77 -89
- data/lib/asciidoctor/block.rb +29 -28
- data/lib/asciidoctor/callouts.rb +4 -2
- data/lib/asciidoctor/cli/invoker.rb +20 -24
- data/lib/asciidoctor/cli/options.rb +107 -96
- data/lib/asciidoctor/cli.rb +3 -2
- data/lib/asciidoctor/convert.rb +199 -0
- data/lib/asciidoctor/converter/composite.rb +40 -48
- data/lib/asciidoctor/converter/docbook5.rb +627 -644
- data/lib/asciidoctor/converter/html5.rb +1053 -951
- data/lib/asciidoctor/converter/manpage.rb +581 -532
- data/lib/asciidoctor/converter/template.rb +232 -271
- data/lib/asciidoctor/converter.rb +370 -185
- data/lib/asciidoctor/core_ext/float/truncate.rb +20 -0
- data/lib/asciidoctor/core_ext/hash/merge.rb +8 -0
- data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
- data/lib/asciidoctor/core_ext.rb +8 -17
- data/lib/asciidoctor/document.rb +503 -461
- data/lib/asciidoctor/extensions.rb +127 -174
- data/lib/asciidoctor/helpers.rb +184 -107
- data/lib/asciidoctor/inline.rb +9 -12
- data/lib/asciidoctor/list.rb +11 -29
- data/lib/asciidoctor/load.rb +119 -0
- data/lib/asciidoctor/logging.rb +22 -17
- data/lib/asciidoctor/parser.rb +673 -719
- data/lib/asciidoctor/path_resolver.rb +48 -33
- data/lib/asciidoctor/reader.rb +383 -338
- data/lib/asciidoctor/rouge_ext.rb +39 -0
- data/lib/asciidoctor/rx.rb +723 -0
- data/lib/asciidoctor/section.rb +17 -16
- data/lib/asciidoctor/stylesheets.rb +19 -37
- data/lib/asciidoctor/substitutors.rb +926 -1022
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +88 -0
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +34 -0
- data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +30 -0
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +157 -0
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +143 -0
- data/lib/asciidoctor/syntax_highlighter.rb +253 -0
- data/lib/asciidoctor/table.rb +152 -114
- data/lib/asciidoctor/timings.rb +7 -5
- data/lib/asciidoctor/version.rb +2 -1
- data/lib/asciidoctor/writer.rb +30 -0
- data/lib/asciidoctor.rb +266 -1340
- data/man/asciidoctor.1 +49 -47
- data/man/asciidoctor.adoc +54 -45
- metadata +50 -245
- data/CONTRIBUTING.adoc +0 -185
- data/Gemfile +0 -60
- data/Rakefile +0 -129
- data/bin/asciidoctor-safe +0 -15
- data/features/open_block.feature +0 -92
- data/features/pass_block.feature +0 -66
- data/features/step_definitions.rb +0 -49
- data/features/text_formatting.feature +0 -57
- data/features/xref.feature +0 -1039
- data/lib/asciidoctor/converter/base.rb +0 -59
- data/lib/asciidoctor/converter/docbook45.rb +0 -93
- data/lib/asciidoctor/converter/factory.rb +0 -226
- data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
- data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
- data/test/api_test.rb +0 -1240
- data/test/attribute_list_test.rb +0 -242
- data/test/attributes_test.rb +0 -1623
- data/test/blocks_test.rb +0 -3870
- data/test/converter_test.rb +0 -470
- data/test/document_test.rb +0 -1853
- data/test/extensions_test.rb +0 -1560
- data/test/fixtures/asciidoc_index.txt +0 -521
- data/test/fixtures/basic-docinfo-footer.html +0 -6
- data/test/fixtures/basic-docinfo-footer.xml +0 -8
- data/test/fixtures/basic-docinfo.html +0 -1
- data/test/fixtures/basic-docinfo.xml +0 -4
- data/test/fixtures/basic.asciidoc +0 -5
- data/test/fixtures/chapter-a.adoc +0 -3
- data/test/fixtures/child-include.adoc +0 -5
- data/test/fixtures/circle.svg +0 -9
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
- data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
- data/test/fixtures/docinfo-footer.html +0 -1
- data/test/fixtures/docinfo-footer.xml +0 -9
- data/test/fixtures/docinfo.html +0 -1
- data/test/fixtures/docinfo.xml +0 -3
- data/test/fixtures/doctime-localtime.adoc +0 -2
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +0 -13
- data/test/fixtures/file-with-missing-include.adoc +0 -1
- data/test/fixtures/grandchild-include.adoc +0 -3
- data/test/fixtures/hello-asciidoctor.pdf +0 -69
- data/test/fixtures/include-file.asciidoc +0 -24
- data/test/fixtures/include-file.jsx +0 -8
- data/test/fixtures/include-file.ml +0 -3
- data/test/fixtures/include-file.xml +0 -5
- data/test/fixtures/lists.adoc +0 -96
- data/test/fixtures/master.adoc +0 -5
- data/test/fixtures/mismatched-end-tag.adoc +0 -7
- data/test/fixtures/other-chapters.adoc +0 -11
- data/test/fixtures/outer-include.adoc +0 -5
- data/test/fixtures/parent-include-restricted.adoc +0 -5
- data/test/fixtures/parent-include.adoc +0 -5
- data/test/fixtures/sample.asciidoc +0 -30
- data/test/fixtures/section-a.adoc +0 -4
- data/test/fixtures/stylesheets/custom.css +0 -3
- data/test/fixtures/subdir/index.adoc +0 -3
- data/test/fixtures/subdir/inner-include.adoc +0 -3
- data/test/fixtures/subdir/middle-include.adoc +0 -5
- data/test/fixtures/subs-docinfo.html +0 -2
- data/test/fixtures/subs.adoc +0 -6
- data/test/fixtures/tagged-class-enclosed.rb +0 -25
- data/test/fixtures/tagged-class.rb +0 -23
- data/test/fixtures/tip.gif +0 -0
- data/test/fixtures/unclosed-tag.adoc +0 -3
- data/test/fixtures/unexpected-end-tag.adoc +0 -4
- data/test/invoker_test.rb +0 -745
- data/test/links_test.rb +0 -855
- data/test/lists_test.rb +0 -5151
- data/test/logger_test.rb +0 -211
- data/test/manpage_test.rb +0 -660
- data/test/options_test.rb +0 -262
- data/test/paragraphs_test.rb +0 -562
- data/test/parser_test.rb +0 -742
- data/test/paths_test.rb +0 -395
- data/test/preamble_test.rb +0 -173
- data/test/reader_test.rb +0 -2161
- data/test/sections_test.rb +0 -3575
- data/test/substitutions_test.rb +0 -2066
- data/test/tables_test.rb +0 -2036
- data/test/test_helper.rb +0 -447
- data/test/text_test.rb +0 -309
@@ -1,40 +1,41 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
3
|
# Public: Handles parsing AsciiDoc attribute lists into a Hash of key/value
|
4
4
|
# pairs. By default, attributes must each be separated by a comma and quotes
|
5
5
|
# may be used around the value. If a key is not detected, the value is assigned
|
6
6
|
# to a 1-based positional key, The positional attributes can be "rekeyed" when
|
7
|
-
# given a
|
7
|
+
# given a positional_attrs array either during parsing or after the fact.
|
8
8
|
#
|
9
9
|
# Examples
|
10
10
|
#
|
11
11
|
# attrlist = Asciidoctor::AttributeList.new('astyle')
|
12
12
|
#
|
13
13
|
# attrlist.parse
|
14
|
-
# => {0 => 'astyle'}
|
14
|
+
# => { 0 => 'astyle' }
|
15
15
|
#
|
16
16
|
# attrlist.rekey(['style'])
|
17
|
-
# => {'style' => 'astyle'}
|
17
|
+
# => { 'style' => 'astyle' }
|
18
18
|
#
|
19
19
|
# attrlist = Asciidoctor::AttributeList.new('quote, Famous Person, Famous Book (2001)')
|
20
20
|
#
|
21
21
|
# attrlist.parse(['style', 'attribution', 'citetitle'])
|
22
|
-
# => {'style' => 'quote', 'attribution' => 'Famous Person', 'citetitle' => 'Famous Book (2001)'}
|
22
|
+
# => { 'style' => 'quote', 'attribution' => 'Famous Person', 'citetitle' => 'Famous Book (2001)' }
|
23
23
|
#
|
24
24
|
class AttributeList
|
25
|
-
BACKSLASH = '\\'
|
26
25
|
APOS = '\''
|
26
|
+
BACKSLASH = '\\'
|
27
|
+
QUOT = '"'
|
27
28
|
|
28
29
|
# Public: Regular expressions for detecting the boundary of a value
|
29
|
-
|
30
|
-
|
30
|
+
BoundaryRx = {
|
31
|
+
QUOT => /.*?[^\\](?=")/,
|
31
32
|
APOS => /.*?[^\\](?=')/,
|
32
33
|
',' => /.*?(?=[ \t]*(,|$))/
|
33
34
|
}
|
34
35
|
|
35
36
|
# Public: Regular expressions for unescaping quoted characters
|
36
37
|
EscapedQuotes = {
|
37
|
-
|
38
|
+
QUOT => '\\"',
|
38
39
|
APOS => '\\\''
|
39
40
|
}
|
40
41
|
|
@@ -44,9 +45,8 @@ class AttributeList
|
|
44
45
|
|
45
46
|
BlankRx = /[ \t]+/
|
46
47
|
|
47
|
-
# Public: Regular expressions for skipping
|
48
|
-
|
49
|
-
:blank => BlankRx,
|
48
|
+
# Public: Regular expressions for skipping delimiters
|
49
|
+
SkipRx = {
|
50
50
|
',' => /[ \t]*(,|$)/
|
51
51
|
}
|
52
52
|
|
@@ -54,25 +54,23 @@ class AttributeList
|
|
54
54
|
@scanner = ::StringScanner.new source
|
55
55
|
@block = block
|
56
56
|
@delimiter = delimiter
|
57
|
-
@delimiter_skip_pattern =
|
58
|
-
@delimiter_boundary_pattern =
|
57
|
+
@delimiter_skip_pattern = SkipRx[delimiter]
|
58
|
+
@delimiter_boundary_pattern = BoundaryRx[delimiter]
|
59
59
|
@attributes = nil
|
60
60
|
end
|
61
61
|
|
62
|
-
def parse_into attributes,
|
63
|
-
attributes.update
|
62
|
+
def parse_into attributes, positional_attrs = []
|
63
|
+
attributes.update parse positional_attrs
|
64
64
|
end
|
65
65
|
|
66
|
-
def parse
|
66
|
+
def parse positional_attrs = []
|
67
67
|
# return if already parsed
|
68
68
|
return @attributes if @attributes
|
69
69
|
|
70
70
|
@attributes = {}
|
71
|
-
# QUESTION do we want to store the attribute list as the zero-index attribute?
|
72
|
-
#attributes[0] = @scanner.string
|
73
71
|
index = 0
|
74
72
|
|
75
|
-
while parse_attribute index,
|
73
|
+
while parse_attribute index, positional_attrs
|
76
74
|
break if @scanner.eos?
|
77
75
|
skip_delimiter
|
78
76
|
index += 1
|
@@ -81,90 +79,88 @@ class AttributeList
|
|
81
79
|
@attributes
|
82
80
|
end
|
83
81
|
|
84
|
-
def rekey
|
85
|
-
AttributeList.rekey @attributes,
|
82
|
+
def rekey positional_attrs
|
83
|
+
AttributeList.rekey @attributes, positional_attrs
|
86
84
|
end
|
87
85
|
|
88
|
-
def self.rekey attributes,
|
89
|
-
|
90
|
-
|
91
|
-
pos = index + 1
|
92
|
-
if (val = attributes[pos])
|
86
|
+
def self.rekey attributes, positional_attrs
|
87
|
+
positional_attrs.each_with_index do |key, index|
|
88
|
+
if key && (val = attributes[index + 1])
|
93
89
|
# QUESTION should we delete the positional key?
|
94
90
|
attributes[key] = val
|
95
91
|
end
|
96
92
|
end
|
97
|
-
|
98
93
|
attributes
|
99
94
|
end
|
100
95
|
|
101
|
-
|
102
|
-
|
96
|
+
private
|
97
|
+
|
98
|
+
def parse_attribute index, positional_attrs
|
99
|
+
continue = true
|
103
100
|
skip_blank
|
104
|
-
|
105
|
-
|
101
|
+
case @scanner.peek 1
|
102
|
+
# example: "quote" || "foo
|
103
|
+
when QUOT
|
106
104
|
name = parse_attribute_value @scanner.get_byte
|
107
|
-
|
108
|
-
|
109
|
-
elsif first == APOS
|
105
|
+
# example: 'quote' || 'foo
|
106
|
+
when APOS
|
110
107
|
name = parse_attribute_value @scanner.get_byte
|
111
|
-
|
112
|
-
single_quoted_value = true unless name.start_with? APOS
|
108
|
+
single_quoted = true unless name.start_with? APOS
|
113
109
|
else
|
114
|
-
name = scan_name
|
115
|
-
|
116
|
-
skipped = 0
|
117
|
-
c = nil
|
110
|
+
skipped = ((name = scan_name) && skip_blank) || 0
|
118
111
|
if @scanner.eos?
|
119
|
-
return
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
else
|
133
|
-
skip_blank
|
134
|
-
if @scanner.peek(1)
|
135
|
-
# example: foo="bar" || foo="ba\"zaar"
|
136
|
-
if (c = @scanner.get_byte) == '"'
|
112
|
+
return unless name || (@scanner.string.rstrip.end_with? @delimiter)
|
113
|
+
# example: quote (at eos)
|
114
|
+
continue = nil
|
115
|
+
# example: quote,
|
116
|
+
elsif (c = @scanner.get_byte) == @delimiter
|
117
|
+
@scanner.unscan
|
118
|
+
elsif name
|
119
|
+
# example: foo=...
|
120
|
+
if c == '='
|
121
|
+
skip_blank
|
122
|
+
case (c = @scanner.get_byte)
|
123
|
+
# example: foo="bar" || foo="ba\"zaar" || foo="bar
|
124
|
+
when QUOT
|
137
125
|
value = parse_attribute_value c
|
138
|
-
# example: foo='bar' || foo='ba\'zaar' || foo='ba"zaar'
|
139
|
-
|
126
|
+
# example: foo='bar' || foo='ba\'zaar' || foo='ba"zaar' || foo='bar
|
127
|
+
when APOS
|
140
128
|
value = parse_attribute_value c
|
141
|
-
|
129
|
+
single_quoted = true unless value.start_with? APOS
|
142
130
|
# example: foo=,
|
143
|
-
|
131
|
+
when @delimiter
|
144
132
|
value = ''
|
145
|
-
|
133
|
+
@scanner.unscan
|
134
|
+
# example: foo= (at eos)
|
135
|
+
when nil
|
136
|
+
value = ''
|
137
|
+
# example: foo=bar || foo=None
|
146
138
|
else
|
147
139
|
value = %(#{c}#{scan_to_delimiter})
|
148
140
|
return true if value == 'None'
|
149
141
|
end
|
142
|
+
# example: foo bar
|
143
|
+
else
|
144
|
+
name = %(#{name}#{' ' * skipped}#{c}#{scan_to_delimiter})
|
150
145
|
end
|
146
|
+
# example: =foo= || !foo
|
147
|
+
else
|
148
|
+
name = %(#{c}#{scan_to_delimiter})
|
151
149
|
end
|
152
150
|
end
|
153
151
|
|
154
152
|
if value
|
155
|
-
# example: options="opt1,opt2,opt3"
|
156
|
-
# opts is an alias for options
|
153
|
+
# example: options="opt1,opt2,opt3" || opts="opts1,opt2,opt3"
|
157
154
|
case name
|
158
155
|
when 'options', 'opts'
|
159
156
|
if value.include? ','
|
160
157
|
value = value.delete ' ' if value.include? ' '
|
161
158
|
(value.split ',').each {|opt| @attributes[%(#{opt}-option)] = '' unless opt.empty? }
|
162
159
|
else
|
163
|
-
@attributes[%(#{value
|
160
|
+
@attributes[%(#{value}-option)] = '' unless value.empty?
|
164
161
|
end
|
165
|
-
@attributes['options'] = value
|
166
162
|
else
|
167
|
-
if
|
163
|
+
if single_quoted && @block
|
168
164
|
case name
|
169
165
|
when 'title', 'reftext'
|
170
166
|
@attributes[name] = value
|
@@ -176,33 +172,26 @@ class AttributeList
|
|
176
172
|
end
|
177
173
|
end
|
178
174
|
else
|
179
|
-
|
180
|
-
if (
|
181
|
-
@attributes[
|
175
|
+
name = @block.apply_subs name if single_quoted && @block
|
176
|
+
if (positional_attr_name = positional_attrs[index]) && name
|
177
|
+
@attributes[positional_attr_name] = name
|
182
178
|
end
|
183
|
-
# QUESTION should we
|
184
|
-
@attributes[index + 1] =
|
185
|
-
# QUESTION should we assign the resolved name as an attribute?
|
186
|
-
#@attributes[resolved_name] = nil
|
179
|
+
# QUESTION should we assign the positional key even when it's claimed by a positional attribute?
|
180
|
+
@attributes[index + 1] = name
|
187
181
|
end
|
188
182
|
|
189
|
-
|
183
|
+
continue
|
190
184
|
end
|
191
185
|
|
192
186
|
def parse_attribute_value quote
|
193
187
|
# empty quoted value
|
194
|
-
if @scanner.peek
|
188
|
+
if (@scanner.peek 1) == quote
|
195
189
|
@scanner.get_byte
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
if (value = scan_to_quote quote)
|
190
|
+
''
|
191
|
+
elsif (value = scan_to_quote quote)
|
200
192
|
@scanner.get_byte
|
201
|
-
|
202
|
-
|
203
|
-
else
|
204
|
-
value
|
205
|
-
end
|
193
|
+
(value.include? BACKSLASH) ? (value.gsub EscapedQuotes[quote], quote) : value
|
194
|
+
# leading quote only
|
206
195
|
else
|
207
196
|
%(#{quote}#{scan_to_delimiter})
|
208
197
|
end
|
@@ -225,8 +214,7 @@ class AttributeList
|
|
225
214
|
end
|
226
215
|
|
227
216
|
def scan_to_quote quote
|
228
|
-
@scanner.scan
|
217
|
+
@scanner.scan BoundaryRx[quote]
|
229
218
|
end
|
230
|
-
|
231
219
|
end
|
232
220
|
end
|
data/lib/asciidoctor/block.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
|
-
# Public: Methods for managing
|
3
|
+
# Public: Methods for managing AsciiDoc content blocks.
|
4
4
|
#
|
5
5
|
# Examples
|
6
6
|
#
|
7
|
-
# block = Asciidoctor::Block.new(parent, :paragraph, :
|
7
|
+
# block = Asciidoctor::Block.new(parent, :paragraph, source: '_This_ is a <test>')
|
8
8
|
# block.content
|
9
9
|
# => "<em>This</em> is a <test>"
|
10
10
|
class Block < AbstractBlock
|
11
11
|
|
12
12
|
(DEFAULT_CONTENT_MODEL = {
|
13
13
|
# TODO should probably fill in all known blocks
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
14
|
+
audio: :empty,
|
15
|
+
image: :empty,
|
16
|
+
listing: :verbatim,
|
17
|
+
literal: :verbatim,
|
18
|
+
stem: :raw,
|
19
|
+
open: :compound,
|
20
|
+
page_break: :empty,
|
21
|
+
pass: :raw,
|
22
|
+
thematic_break: :empty,
|
23
|
+
video: :empty,
|
24
24
|
}).default = :simple
|
25
25
|
|
26
26
|
# Public: Create alias for context to be consistent w/ AsciiDoc
|
@@ -40,10 +40,10 @@ class Block < AbstractBlock
|
|
40
40
|
# * :source a String or Array of raw source for this Block. (default: nil)
|
41
41
|
#
|
42
42
|
# IMPORTANT: If you don't specify the `:subs` option, you must explicitly call
|
43
|
-
# the `
|
43
|
+
# the `commit_subs` method to resolve and assign the substitutions to this
|
44
44
|
# block (which are resolved from the `subs` attribute, if specified, or the
|
45
45
|
# default substitutions based on this block's context). If you want to use the
|
46
|
-
# default subs for a block, pass the option
|
46
|
+
# default subs for a block, pass the option `subs: :default`. You can
|
47
47
|
# override the default subs using the `:default_subs` option.
|
48
48
|
#--
|
49
49
|
# QUESTION should we store source_data as lines for blocks that have compound content models?
|
@@ -51,28 +51,29 @@ class Block < AbstractBlock
|
|
51
51
|
super
|
52
52
|
@content_model = opts[:content_model] || DEFAULT_CONTENT_MODEL[context]
|
53
53
|
if opts.key? :subs
|
54
|
-
# FIXME feels funky; we have to be defensive to get
|
54
|
+
# FIXME feels funky; we have to be defensive to get commit_subs to honor override
|
55
55
|
# FIXME does not resolve substitution groups inside Array (e.g., [:normal])
|
56
56
|
if (subs = opts[:subs])
|
57
|
-
|
57
|
+
case subs
|
58
|
+
# e.g., subs: :default
|
58
59
|
# subs attribute is honored; falls back to opts[:default_subs], then built-in defaults based on context
|
59
|
-
|
60
|
+
when :default
|
60
61
|
@default_subs = opts[:default_subs]
|
61
|
-
# e.g., :
|
62
|
+
# e.g., subs: [:quotes]
|
62
63
|
# subs attribute is not honored
|
63
|
-
|
64
|
+
when ::Array
|
64
65
|
@default_subs = subs.drop 0
|
65
66
|
@attributes.delete 'subs'
|
66
|
-
# e.g., :
|
67
|
+
# e.g., subs: :normal or subs: 'normal'
|
67
68
|
# subs attribute is not honored
|
68
69
|
else
|
69
70
|
@default_subs = nil
|
70
|
-
|
71
|
-
@attributes['subs'] = %(#{subs})
|
71
|
+
@attributes['subs'] = subs.to_s
|
72
72
|
end
|
73
73
|
# resolve the subs eagerly only if subs option is specified
|
74
|
-
|
75
|
-
|
74
|
+
# QUESTION should we skip subsequent calls to commit_subs?
|
75
|
+
commit_subs
|
76
|
+
# e.g., subs: nil
|
76
77
|
else
|
77
78
|
# NOTE @subs is initialized as empty array by super constructor
|
78
79
|
# prevent subs from being resolved
|
@@ -88,7 +89,7 @@ class Block < AbstractBlock
|
|
88
89
|
if (raw_source = opts[:source]).nil_or_empty?
|
89
90
|
@lines = []
|
90
91
|
elsif ::String === raw_source
|
91
|
-
@lines = Helpers.
|
92
|
+
@lines = Helpers.prepare_source_string raw_source
|
92
93
|
else
|
93
94
|
@lines = raw_source.drop 0
|
94
95
|
end
|
@@ -101,7 +102,7 @@ class Block < AbstractBlock
|
|
101
102
|
#
|
102
103
|
# doc = Asciidoctor::Document.new
|
103
104
|
# block = Asciidoctor::Block.new(doc, :paragraph,
|
104
|
-
# :
|
105
|
+
# source: '_This_ is what happens when you <meet> a stranger in the <alps>!')
|
105
106
|
# block.content
|
106
107
|
# => "<em>This</em> is what happens when you <meet> a stranger in the <alps>!"
|
107
108
|
def content
|
@@ -122,7 +123,7 @@ class Block < AbstractBlock
|
|
122
123
|
result.join LF
|
123
124
|
end
|
124
125
|
else
|
125
|
-
logger.warn %(Unknown content model '#{@content_model}' for block: #{
|
126
|
+
logger.warn %(Unknown content model '#{@content_model}' for block: #{self}) unless @content_model == :empty
|
126
127
|
nil
|
127
128
|
end
|
128
129
|
end
|
data/lib/asciidoctor/callouts.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
3
|
# Public: Maintains a catalog of callouts and their associations.
|
4
4
|
class Callouts
|
@@ -28,7 +28,7 @@ class Callouts
|
|
28
28
|
#
|
29
29
|
# Returns The unique String id of this callout
|
30
30
|
def register li_ordinal
|
31
|
-
current_list << { :
|
31
|
+
current_list << { ordinal: li_ordinal.to_i, id: (id = generate_next_callout_id) }
|
32
32
|
@co_index += 1
|
33
33
|
id
|
34
34
|
end
|
@@ -93,6 +93,8 @@ class Callouts
|
|
93
93
|
nil
|
94
94
|
end
|
95
95
|
|
96
|
+
private
|
97
|
+
|
96
98
|
# Internal: Generate a unique id for the callout based on the internal indexes
|
97
99
|
#
|
98
100
|
# Returns A unique String id for this callout
|
@@ -1,8 +1,9 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
3
|
module Cli
|
4
4
|
# Public Invocation class for starting Asciidoctor via CLI
|
5
5
|
class Invoker
|
6
|
+
include Logging
|
6
7
|
|
7
8
|
attr_reader :options
|
8
9
|
attr_reader :documents
|
@@ -32,8 +33,8 @@ module Asciidoctor
|
|
32
33
|
def invoke!
|
33
34
|
return unless @options
|
34
35
|
|
35
|
-
old_verbose = $VERBOSE
|
36
36
|
old_logger = old_logger_level = nil
|
37
|
+
old_verbose, $VERBOSE = $VERBOSE, @options[:warnings]
|
37
38
|
opts = {}
|
38
39
|
infiles = []
|
39
40
|
outfile = nil
|
@@ -41,6 +42,8 @@ module Asciidoctor
|
|
41
42
|
non_posix_env = ::File::ALT_SEPARATOR == RS
|
42
43
|
err = @err || $stderr
|
43
44
|
show_timings = false
|
45
|
+
# NOTE in Ruby 2.7, RubyGems sets SOURCE_DATE_EPOCH if it's not set
|
46
|
+
::ENV.delete 'SOURCE_DATE_EPOCH' if (::ENV.key? 'IGNORE_SOURCE_DATE_EPOCH') && (::Gem.respond_to? :source_date_epoch)
|
44
47
|
|
45
48
|
@options.map do |key, val|
|
46
49
|
case key
|
@@ -61,18 +64,14 @@ module Asciidoctor
|
|
61
64
|
when :timings
|
62
65
|
show_timings = val
|
63
66
|
when :trace
|
64
|
-
#
|
67
|
+
# no assignment
|
65
68
|
when :verbose
|
66
69
|
case val
|
67
70
|
when 0
|
68
71
|
$VERBOSE = nil
|
69
|
-
old_logger =
|
70
|
-
LoggerManager.logger = NullLogger.new
|
71
|
-
when 1
|
72
|
-
$VERBOSE = false
|
72
|
+
old_logger, LoggerManager.logger = logger, NullLogger.new
|
73
73
|
when 2
|
74
|
-
|
75
|
-
old_logger_level, LoggerManager.logger.level = LoggerManager.logger.level, ::Logger::Severity::DEBUG
|
74
|
+
old_logger_level, logger.level = logger.level, ::Logger::Severity::DEBUG
|
76
75
|
end
|
77
76
|
else
|
78
77
|
opts[key] = val unless val.nil?
|
@@ -89,7 +88,7 @@ module Asciidoctor
|
|
89
88
|
end
|
90
89
|
|
91
90
|
if outfile == '-'
|
92
|
-
tofile = @out || $stdout
|
91
|
+
(tofile = @out) || ((tofile = $stdout).set_encoding UTF_8)
|
93
92
|
elsif outfile
|
94
93
|
opts[:mkdirs] = true
|
95
94
|
tofile = outfile
|
@@ -100,17 +99,18 @@ module Asciidoctor
|
|
100
99
|
|
101
100
|
if stdin
|
102
101
|
# allows use of block to supply stdin, particularly useful for tests
|
103
|
-
|
104
|
-
|
102
|
+
# NOTE set_encoding returns nil on JRuby 9.1
|
103
|
+
block_given? ? (input = yield) : ((input = $stdin).set_encoding UTF_8, UTF_8)
|
104
|
+
input_opts = opts.merge to_file: tofile
|
105
105
|
if show_timings
|
106
|
-
@documents << (::Asciidoctor.convert input, (input_opts.merge :
|
106
|
+
@documents << (::Asciidoctor.convert input, (input_opts.merge timings: (timings = Timings.new)))
|
107
107
|
timings.print_report err, '-'
|
108
108
|
else
|
109
109
|
@documents << (::Asciidoctor.convert input, input_opts)
|
110
110
|
end
|
111
111
|
else
|
112
112
|
infiles.each do |infile|
|
113
|
-
input_opts = opts.merge :
|
113
|
+
input_opts = opts.merge to_file: tofile
|
114
114
|
if abs_srcdir_posix && (input_opts.key? :to_dir)
|
115
115
|
abs_indir = ::File.dirname ::File.expand_path infile
|
116
116
|
if non_posix_env
|
@@ -123,30 +123,26 @@ module Asciidoctor
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
if show_timings
|
126
|
-
@documents << (::Asciidoctor.convert_file infile, (input_opts.merge :
|
126
|
+
@documents << (::Asciidoctor.convert_file infile, (input_opts.merge timings: (timings = Timings.new)))
|
127
127
|
timings.print_report err, infile
|
128
128
|
else
|
129
129
|
@documents << (::Asciidoctor.convert_file infile, input_opts)
|
130
130
|
end
|
131
131
|
end
|
132
132
|
end
|
133
|
-
@code = 1 if (
|
133
|
+
@code = 1 if (logger.respond_to? :max_severity) && logger.max_severity && logger.max_severity >= opts[:failure_level]
|
134
134
|
rescue ::Exception => e
|
135
135
|
if ::SignalException === e
|
136
136
|
@code = e.signo
|
137
|
-
# add extra
|
137
|
+
# add extra newline if Ctrl+C is used
|
138
138
|
err.puts if ::Interrupt === e
|
139
139
|
else
|
140
140
|
@code = (e.respond_to? :status) ? e.status : 1
|
141
141
|
if @options[:trace]
|
142
142
|
raise e
|
143
143
|
else
|
144
|
-
|
145
|
-
|
146
|
-
else
|
147
|
-
err.puts e.message
|
148
|
-
end
|
149
|
-
err.puts ' Use --trace for backtrace'
|
144
|
+
err.puts ::RuntimeError === e ? %(#{e.message} (#{e.class})) : e.message
|
145
|
+
err.puts ' Use --trace to show backtrace'
|
150
146
|
end
|
151
147
|
end
|
152
148
|
nil
|
@@ -155,7 +151,7 @@ module Asciidoctor
|
|
155
151
|
if old_logger
|
156
152
|
LoggerManager.logger = old_logger
|
157
153
|
elsif old_logger_level
|
158
|
-
|
154
|
+
logger.level = old_logger_level
|
159
155
|
end
|
160
156
|
end
|
161
157
|
|