asciidoctor 1.5.5 → 1.5.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +216 -1
- data/CONTRIBUTING.adoc +2 -2
- data/Gemfile +20 -1
- data/LICENSE.adoc +1 -1
- data/README-fr.adoc +4 -3
- data/README-jp.adoc +11 -10
- data/README-zh_CN.adoc +4 -3
- data/README.adoc +17 -202
- data/Rakefile +41 -25
- data/asciidoctor.gemspec +9 -10
- data/data/locale/attributes.adoc +216 -34
- data/data/stylesheets/asciidoctor-default.css +23 -16
- data/features/step_definitions.rb +15 -19
- data/features/xref.feature +584 -20
- data/lib/asciidoctor.rb +292 -278
- data/lib/asciidoctor/abstract_block.rb +155 -94
- data/lib/asciidoctor/abstract_node.rb +108 -94
- data/lib/asciidoctor/attribute_list.rb +30 -22
- data/lib/asciidoctor/block.rb +7 -7
- data/lib/asciidoctor/cli/invoker.rb +47 -34
- data/lib/asciidoctor/cli/options.rb +22 -11
- data/lib/asciidoctor/converter.rb +3 -3
- data/lib/asciidoctor/converter/base.rb +2 -2
- data/lib/asciidoctor/converter/composite.rb +1 -1
- data/lib/asciidoctor/converter/docbook45.rb +2 -2
- data/lib/asciidoctor/converter/docbook5.rb +132 -87
- data/lib/asciidoctor/converter/factory.rb +0 -1
- data/lib/asciidoctor/converter/html5.rb +116 -98
- data/lib/asciidoctor/converter/manpage.rb +51 -52
- data/lib/asciidoctor/converter/template.rb +47 -36
- data/lib/asciidoctor/core_ext.rb +8 -2
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +4 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +5 -0
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +1 -1
- data/lib/asciidoctor/core_ext/1.8.7/string/{limit.rb → limit_bytesize.rb} +7 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +1 -1
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +5 -5
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +3 -0
- data/lib/asciidoctor/core_ext/string/{limit.rb → limit_bytesize.rb} +2 -2
- data/lib/asciidoctor/document.rb +216 -213
- data/lib/asciidoctor/extensions.rb +318 -185
- data/lib/asciidoctor/helpers.rb +35 -35
- data/lib/asciidoctor/inline.rb +32 -1
- data/lib/asciidoctor/list.rb +22 -6
- data/lib/asciidoctor/parser.rb +1008 -1038
- data/lib/asciidoctor/path_resolver.rb +46 -50
- data/lib/asciidoctor/reader.rb +275 -251
- data/lib/asciidoctor/section.rb +86 -58
- data/lib/asciidoctor/stylesheets.rb +6 -6
- data/lib/asciidoctor/substitutors.rb +567 -649
- data/lib/asciidoctor/table.rb +163 -108
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +18 -16
- data/man/asciidoctor.adoc +15 -13
- data/test/attributes_test.rb +138 -22
- data/test/blocks_test.rb +377 -97
- data/test/converter_test.rb +13 -0
- data/test/document_test.rb +244 -34
- data/test/extensions_test.rb +409 -42
- data/test/fixtures/asciidoc_index.txt +521 -0
- data/test/fixtures/basic-docinfo-footer.html +6 -0
- data/test/fixtures/basic-docinfo-footer.xml +8 -0
- data/test/fixtures/basic-docinfo.html +1 -0
- data/test/fixtures/basic-docinfo.xml +4 -0
- data/test/fixtures/basic.asciidoc +5 -0
- data/test/fixtures/chapter-a.adoc +3 -0
- data/test/fixtures/child-include.adoc +5 -0
- data/test/fixtures/circle.svg +9 -0
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +1 -0
- data/test/fixtures/custom-docinfodir/docinfo.html +1 -0
- data/test/fixtures/docinfo-footer.html +1 -0
- data/test/fixtures/docinfo-footer.xml +9 -0
- data/test/fixtures/docinfo.html +1 -0
- data/test/fixtures/docinfo.xml +3 -0
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +13 -0
- data/test/fixtures/grandchild-include.adoc +3 -0
- data/test/fixtures/hello-asciidoctor.pdf +69 -0
- data/test/fixtures/include-file.asciidoc +24 -0
- data/test/fixtures/include-file.ml +3 -0
- data/test/fixtures/include-file.xml +5 -0
- data/test/fixtures/master.adoc +5 -0
- data/test/fixtures/mismatched-end-tag.adoc +7 -0
- data/test/fixtures/parent-include-restricted.adoc +5 -0
- data/test/fixtures/parent-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +26 -0
- data/test/fixtures/stylesheets/custom.css +3 -0
- data/test/fixtures/subs-docinfo.html +2 -0
- data/test/fixtures/subs.adoc +7 -0
- data/test/fixtures/tagged-class-enclosed.rb +26 -0
- data/test/fixtures/tagged-class.rb +23 -0
- data/test/fixtures/tip.gif +0 -0
- data/test/invoker_test.rb +82 -4
- data/test/links_test.rb +312 -37
- data/test/lists_test.rb +204 -25
- data/test/manpage_test.rb +191 -4
- data/test/options_test.rb +18 -1
- data/test/paragraphs_test.rb +32 -7
- data/test/parser_test.rb +150 -30
- data/test/paths_test.rb +47 -13
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +366 -126
- data/test/sections_test.rb +203 -56
- data/test/substitutions_test.rb +339 -131
- data/test/tables_test.rb +315 -15
- data/test/test_helper.rb +400 -0
- data/test/text_test.rb +5 -5
- metadata +110 -22
data/test/options_test.rb
CHANGED
@@ -6,7 +6,7 @@ end
|
|
6
6
|
require 'asciidoctor/cli/options'
|
7
7
|
|
8
8
|
context 'Options' do
|
9
|
-
test 'should return error code 0 when help flag is present' do
|
9
|
+
test 'should print usage and return error code 0 when help flag is present' do
|
10
10
|
redirect_streams do |stdout, stderr|
|
11
11
|
exitval = Asciidoctor::Cli::Options.parse!(%w(-h))
|
12
12
|
assert_equal 0, exitval
|
@@ -14,6 +14,23 @@ context 'Options' do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
test 'should print usage and return error code 0 when help flag is unknown' do
|
18
|
+
exitval, output = redirect_streams do |out, _|
|
19
|
+
[Asciidoctor::Cli::Options.parse!(%w(-h unknown)), out.string]
|
20
|
+
end
|
21
|
+
assert_equal 0, exitval
|
22
|
+
assert_match(/^Usage:/, output)
|
23
|
+
end
|
24
|
+
|
25
|
+
test 'should dump man page and return error code 0 when help topic is manpage' do
|
26
|
+
exitval, output = redirect_streams do |out, _|
|
27
|
+
[Asciidoctor::Cli::Options.parse!(%w(-h manpage)), out.string]
|
28
|
+
end
|
29
|
+
assert_equal 0, exitval
|
30
|
+
assert_includes output, 'Manual: Asciidoctor Manual'
|
31
|
+
assert_includes output, '.TH "ASCIIDOCTOR"'
|
32
|
+
end
|
33
|
+
|
17
34
|
test 'should return error code 1 when invalid option present' do
|
18
35
|
redirect_streams do |stdout, stderr|
|
19
36
|
exitval = Asciidoctor::Cli::Options.parse!(%w(--foobar))
|
data/test/paragraphs_test.rb
CHANGED
@@ -156,29 +156,29 @@ Note that multi-entry terms generate separate index entries.
|
|
156
156
|
|
157
157
|
output = render_embedded_string input, :attributes => {'backend' => 'docbook45'}
|
158
158
|
assert_xpath '/simpara', output, 1
|
159
|
-
term1 =
|
159
|
+
term1 = xmlnodes_at_xpath '(//indexterm)[1]', output, 1
|
160
160
|
assert_equal '<indexterm><primary>tigers</primary></indexterm>', term1.to_s
|
161
161
|
assert term1.next.content.start_with?('tigers')
|
162
162
|
|
163
|
-
term2 =
|
163
|
+
term2 = xmlnodes_at_xpath '(//indexterm)[2]', output, 1
|
164
164
|
term2_elements = term2.elements
|
165
165
|
assert_equal 3, term2_elements.size
|
166
166
|
assert_equal '<primary>Big cats</primary>', term2_elements[0].to_s
|
167
167
|
assert_equal '<secondary>Tigers</secondary>', term2_elements[1].to_s
|
168
168
|
assert_equal '<tertiary>Siberian Tiger</tertiary>', term2_elements[2].to_s
|
169
169
|
|
170
|
-
term3 =
|
170
|
+
term3 = xmlnodes_at_xpath '(//indexterm)[3]', output, 1
|
171
171
|
term3_elements = term3.elements
|
172
172
|
assert_equal 2, term3_elements.size
|
173
173
|
assert_equal '<primary>Tigers</primary>', term3_elements[0].to_s
|
174
174
|
assert_equal '<secondary>Siberian Tiger</secondary>', term3_elements[1].to_s
|
175
175
|
|
176
|
-
term4 =
|
176
|
+
term4 = xmlnodes_at_xpath '(//indexterm)[4]', output, 1
|
177
177
|
term4_elements = term4.elements
|
178
178
|
assert_equal 1, term4_elements.size
|
179
179
|
assert_equal '<primary>Siberian Tiger</primary>', term4_elements[0].to_s
|
180
180
|
|
181
|
-
term5 =
|
181
|
+
term5 = xmlnodes_at_xpath '(//indexterm)[5]', output, 1
|
182
182
|
assert_equal '<indexterm><primary>Linux</primary></indexterm>', term5.to_s
|
183
183
|
assert term5.next.content.start_with?('Linux')
|
184
184
|
|
@@ -418,6 +418,26 @@ Content goes here
|
|
418
418
|
assert_xpath "//*[@class='sidebarblock']//p", result, 1
|
419
419
|
end
|
420
420
|
|
421
|
+
test 'should process preprocessor conditional in paragrpah content' do
|
422
|
+
input = <<-EOS
|
423
|
+
ifdef::asciidoctor-version[]
|
424
|
+
[sidebar]
|
425
|
+
First line of sidebar.
|
426
|
+
ifdef::backend[The backend is {backend}.]
|
427
|
+
Last line of sidebar.
|
428
|
+
endif::[]
|
429
|
+
EOS
|
430
|
+
|
431
|
+
result = render_embedded_string input
|
432
|
+
assert_equal %(<div class="sidebarblock">
|
433
|
+
<div class="content">
|
434
|
+
First line of sidebar.
|
435
|
+
The backend is html5.
|
436
|
+
Last line of sidebar.
|
437
|
+
</div>
|
438
|
+
</div>), result
|
439
|
+
end
|
440
|
+
|
421
441
|
context 'Styled Paragraphs' do
|
422
442
|
test 'should wrap text in simpara for styled paragraphs when rendered to DocBook' do
|
423
443
|
input = <<-EOS
|
@@ -514,10 +534,15 @@ Wise words from a wise person.
|
|
514
534
|
assert_equal '<a href="http://asciidoc.org">AsciiDoc</a> is a <em>lightweight</em> markup language…​', output
|
515
535
|
end
|
516
536
|
|
517
|
-
test 'should output nil if first block is not a paragraph' do
|
537
|
+
test 'should output nil and warn if first block is not a paragraph' do
|
518
538
|
input = '* bullet'
|
519
|
-
output =
|
539
|
+
output = nil
|
540
|
+
warnings = redirect_streams do |_, err|
|
541
|
+
output = render_string input, :doctype => 'inline'
|
542
|
+
err.string
|
543
|
+
end
|
520
544
|
assert output.nil?
|
545
|
+
assert_includes warnings, 'no inline candidate'
|
521
546
|
end
|
522
547
|
end
|
523
548
|
end
|
data/test/parser_test.rb
CHANGED
@@ -17,6 +17,85 @@ context "Parser" do
|
|
17
17
|
assert_equal 'foo3-bar', Asciidoctor::Parser.sanitize_attribute_name("Foo 3^ # - Bar[")
|
18
18
|
end
|
19
19
|
|
20
|
+
test 'store attribute with value' do
|
21
|
+
attr_name, attr_value = Asciidoctor::Parser.store_attribute 'foo', 'bar'
|
22
|
+
assert_equal 'foo', attr_name
|
23
|
+
assert_equal 'bar', attr_value
|
24
|
+
end
|
25
|
+
|
26
|
+
test 'store attribute with negated value' do
|
27
|
+
{ 'foo!' => nil, '!foo' => nil, 'foo' => nil }.each do |name, value|
|
28
|
+
attr_name, attr_value = Asciidoctor::Parser.store_attribute name, value
|
29
|
+
assert_equal name.sub('!', ''), attr_name
|
30
|
+
assert_nil attr_value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
test 'store accessible attribute on document with value' do
|
35
|
+
doc = empty_document
|
36
|
+
doc.set_attribute 'foo', 'baz'
|
37
|
+
attrs = {}
|
38
|
+
attr_name, attr_value = Asciidoctor::Parser.store_attribute 'foo', 'bar', doc, attrs
|
39
|
+
assert_equal 'foo', attr_name
|
40
|
+
assert_equal 'bar', attr_value
|
41
|
+
assert_equal 'bar', (doc.attr 'foo')
|
42
|
+
assert attrs.key?(:attribute_entries)
|
43
|
+
assert_equal 1, attrs[:attribute_entries].size
|
44
|
+
assert_equal 'foo', attrs[:attribute_entries][0].name
|
45
|
+
assert_equal 'bar', attrs[:attribute_entries][0].value
|
46
|
+
end
|
47
|
+
|
48
|
+
test 'store accessible attribute on document with value that contains attribute reference' do
|
49
|
+
doc = empty_document
|
50
|
+
doc.set_attribute 'foo', 'baz'
|
51
|
+
doc.set_attribute 'release', 'ultramega'
|
52
|
+
attrs = {}
|
53
|
+
attr_name, attr_value = Asciidoctor::Parser.store_attribute 'foo', '{release}', doc, attrs
|
54
|
+
assert_equal 'foo', attr_name
|
55
|
+
assert_equal 'ultramega', attr_value
|
56
|
+
assert_equal 'ultramega', (doc.attr 'foo')
|
57
|
+
assert attrs.key?(:attribute_entries)
|
58
|
+
assert_equal 1, attrs[:attribute_entries].size
|
59
|
+
assert_equal 'foo', attrs[:attribute_entries][0].name
|
60
|
+
assert_equal 'ultramega', attrs[:attribute_entries][0].value
|
61
|
+
end
|
62
|
+
|
63
|
+
test 'store inaccessible attribute on document with value' do
|
64
|
+
doc = empty_document :attributes => { 'foo' => 'baz' }
|
65
|
+
attrs = {}
|
66
|
+
attr_name, attr_value = Asciidoctor::Parser.store_attribute 'foo', 'bar', doc, attrs
|
67
|
+
assert_equal 'foo', attr_name
|
68
|
+
assert_equal 'bar', attr_value
|
69
|
+
assert_equal 'baz', (doc.attr 'foo')
|
70
|
+
refute attrs.key?(:attribute_entries)
|
71
|
+
end
|
72
|
+
|
73
|
+
test 'store accessible attribute on document with negated value' do
|
74
|
+
{ 'foo!' => nil, '!foo' => nil, 'foo' => nil }.each do |name, value|
|
75
|
+
doc = empty_document
|
76
|
+
doc.set_attribute 'foo', 'baz'
|
77
|
+
attrs = {}
|
78
|
+
attr_name, attr_value = Asciidoctor::Parser.store_attribute name, value, doc, attrs
|
79
|
+
assert_equal name.sub('!', ''), attr_name
|
80
|
+
assert_nil attr_value
|
81
|
+
assert attrs.key?(:attribute_entries)
|
82
|
+
assert_equal 1, attrs[:attribute_entries].size
|
83
|
+
assert_equal 'foo', attrs[:attribute_entries][0].name
|
84
|
+
assert_nil attrs[:attribute_entries][0].value
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
test 'store inaccessible attribute on document with negated value' do
|
89
|
+
{ 'foo!' => nil, '!foo' => nil, 'foo' => nil }.each do |name, value|
|
90
|
+
doc = empty_document :attributes => { 'foo' => 'baz' }
|
91
|
+
attrs = {}
|
92
|
+
attr_name, attr_value = Asciidoctor::Parser.store_attribute name, value, doc, attrs
|
93
|
+
assert_equal name.sub('!', ''), attr_name
|
94
|
+
assert_nil attr_value
|
95
|
+
refute attrs.key?(:attribute_entries)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
20
99
|
test "collect unnamed attribute" do
|
21
100
|
attributes = {}
|
22
101
|
line = 'quote'
|
@@ -172,7 +251,7 @@ context "Parser" do
|
|
172
251
|
test "collect options attribute" do
|
173
252
|
attributes = {}
|
174
253
|
line = "quote, options='opt1,opt2 , opt3'"
|
175
|
-
expected = {1 => 'quote', 'options' => 'opt1,opt2
|
254
|
+
expected = {1 => 'quote', 'options' => 'opt1,opt2,opt3', 'opt1-option' => '', 'opt2-option' => '', 'opt3-option' => ''}
|
176
255
|
Asciidoctor::AttributeList.new(line).parse_into(attributes)
|
177
256
|
assert_equal expected, attributes
|
178
257
|
end
|
@@ -180,7 +259,7 @@ context "Parser" do
|
|
180
259
|
test "collect opts attribute as options" do
|
181
260
|
attributes = {}
|
182
261
|
line = "quote, opts='opt1,opt2 , opt3'"
|
183
|
-
expected = {1 => 'quote', 'options' => 'opt1,opt2
|
262
|
+
expected = {1 => 'quote', 'options' => 'opt1,opt2,opt3', 'opt1-option' => '', 'opt2-option' => '', 'opt3-option' => ''}
|
184
263
|
Asciidoctor::AttributeList.new(line).parse_into(attributes)
|
185
264
|
assert_equal expected, attributes
|
186
265
|
end
|
@@ -202,9 +281,8 @@ context "Parser" do
|
|
202
281
|
|
203
282
|
test 'parse style attribute with id and role' do
|
204
283
|
attributes = {1 => 'style#id.role'}
|
205
|
-
style
|
284
|
+
style = Asciidoctor::Parser.parse_style_attribute(attributes)
|
206
285
|
assert_equal 'style', style
|
207
|
-
assert_nil original_style
|
208
286
|
assert_equal 'style', attributes['style']
|
209
287
|
assert_equal 'id', attributes['id']
|
210
288
|
assert_equal 'role', attributes['role']
|
@@ -213,9 +291,8 @@ context "Parser" do
|
|
213
291
|
|
214
292
|
test 'parse style attribute with style, role, id and option' do
|
215
293
|
attributes = {1 => 'style.role#id%fragment'}
|
216
|
-
style
|
294
|
+
style = Asciidoctor::Parser.parse_style_attribute(attributes)
|
217
295
|
assert_equal 'style', style
|
218
|
-
assert_nil original_style
|
219
296
|
assert_equal 'style', attributes['style']
|
220
297
|
assert_equal 'id', attributes['id']
|
221
298
|
assert_equal 'role', attributes['role']
|
@@ -226,9 +303,8 @@ context "Parser" do
|
|
226
303
|
|
227
304
|
test 'parse style attribute with style, id and multiple roles' do
|
228
305
|
attributes = {1 => 'style#id.role1.role2'}
|
229
|
-
style
|
306
|
+
style = Asciidoctor::Parser.parse_style_attribute(attributes)
|
230
307
|
assert_equal 'style', style
|
231
|
-
assert_nil original_style
|
232
308
|
assert_equal 'style', attributes['style']
|
233
309
|
assert_equal 'id', attributes['id']
|
234
310
|
assert_equal 'role1 role2', attributes['role']
|
@@ -237,9 +313,8 @@ context "Parser" do
|
|
237
313
|
|
238
314
|
test 'parse style attribute with style, multiple roles and id' do
|
239
315
|
attributes = {1 => 'style.role1.role2#id'}
|
240
|
-
style
|
316
|
+
style = Asciidoctor::Parser.parse_style_attribute(attributes)
|
241
317
|
assert_equal 'style', style
|
242
|
-
assert_nil original_style
|
243
318
|
assert_equal 'style', attributes['style']
|
244
319
|
assert_equal 'id', attributes['id']
|
245
320
|
assert_equal 'role1 role2', attributes['role']
|
@@ -248,18 +323,16 @@ context "Parser" do
|
|
248
323
|
|
249
324
|
test 'parse style attribute with positional and original style' do
|
250
325
|
attributes = {1 => 'new_style', 'style' => 'original_style'}
|
251
|
-
style
|
326
|
+
style = Asciidoctor::Parser.parse_style_attribute(attributes)
|
252
327
|
assert_equal 'new_style', style
|
253
|
-
assert_equal 'original_style', original_style
|
254
328
|
assert_equal 'new_style', attributes['style']
|
255
329
|
assert_equal 'new_style', attributes[1]
|
256
330
|
end
|
257
331
|
|
258
332
|
test 'parse style attribute with id and role only' do
|
259
333
|
attributes = {1 => '#id.role'}
|
260
|
-
style
|
334
|
+
style = Asciidoctor::Parser.parse_style_attribute(attributes)
|
261
335
|
assert_nil style
|
262
|
-
assert_nil original_style
|
263
336
|
assert_equal 'id', attributes['id']
|
264
337
|
assert_equal 'role', attributes['role']
|
265
338
|
assert_equal '#id.role', attributes[1]
|
@@ -267,9 +340,8 @@ context "Parser" do
|
|
267
340
|
|
268
341
|
test 'parse empty style attribute' do
|
269
342
|
attributes = {1 => nil}
|
270
|
-
style
|
343
|
+
style = Asciidoctor::Parser.parse_style_attribute(attributes)
|
271
344
|
assert_nil style
|
272
|
-
assert_nil original_style
|
273
345
|
assert_nil attributes['id']
|
274
346
|
assert_nil attributes['role']
|
275
347
|
assert_nil attributes[1]
|
@@ -277,9 +349,8 @@ context "Parser" do
|
|
277
349
|
|
278
350
|
test 'parse style attribute with option should preserve existing options' do
|
279
351
|
attributes = {1 => '%header', 'options' => 'footer', 'footer-option' => ''}
|
280
|
-
style
|
352
|
+
style = Asciidoctor::Parser.parse_style_attribute(attributes)
|
281
353
|
assert_nil style
|
282
|
-
assert_nil original_style
|
283
354
|
assert_equal 'header,footer', attributes['options']
|
284
355
|
assert_equal '', attributes['header-option']
|
285
356
|
assert_equal '', attributes['footer-option']
|
@@ -455,6 +526,56 @@ context "Parser" do
|
|
455
526
|
assert_equal 'John Smith', metadata['author_2']
|
456
527
|
end
|
457
528
|
|
529
|
+
test 'parse name with more than 3 parts in author attribute' do
|
530
|
+
doc = empty_document
|
531
|
+
parse_header_metadata ':author: Leroy Harold Scherer, Jr.', doc
|
532
|
+
assert_equal 'Leroy Harold Scherer, Jr.', doc.attributes['author']
|
533
|
+
assert_equal 'Leroy', doc.attributes['firstname']
|
534
|
+
assert_equal 'Harold', doc.attributes['middlename']
|
535
|
+
assert_equal 'Scherer, Jr.', doc.attributes['lastname']
|
536
|
+
end
|
537
|
+
|
538
|
+
test 'does not drop name joiner when using multiple authors' do
|
539
|
+
input = <<-EOS
|
540
|
+
Kismet Chameleon; Lazarus het_Draeke
|
541
|
+
EOS
|
542
|
+
doc = empty_document
|
543
|
+
parse_header_metadata input, doc
|
544
|
+
assert_equal 2, doc.attributes['authorcount']
|
545
|
+
assert_equal 'Kismet Chameleon, Lazarus het Draeke', doc.attributes['authors']
|
546
|
+
assert_equal 'Kismet Chameleon', doc.attributes['author_1']
|
547
|
+
assert_equal 'Lazarus het Draeke', doc.attributes['author_2']
|
548
|
+
assert_equal 'het Draeke', doc.attributes['lastname_2']
|
549
|
+
end
|
550
|
+
|
551
|
+
test 'allows authors to be overridden using explicit author attributes' do
|
552
|
+
input = <<-EOS
|
553
|
+
Kismet Chameleon; Johnny Bravo; Lazarus het_Draeke
|
554
|
+
:author_2: Danger Mouse
|
555
|
+
EOS
|
556
|
+
doc = empty_document
|
557
|
+
parse_header_metadata input, doc
|
558
|
+
assert_equal 3, doc.attributes['authorcount']
|
559
|
+
assert_equal 'Kismet Chameleon, Danger Mouse, Lazarus het Draeke', doc.attributes['authors']
|
560
|
+
assert_equal 'Kismet Chameleon', doc.attributes['author_1']
|
561
|
+
assert_equal 'Danger Mouse', doc.attributes['author_2']
|
562
|
+
assert_equal 'Lazarus het Draeke', doc.attributes['author_3']
|
563
|
+
assert_equal 'het Draeke', doc.attributes['lastname_3']
|
564
|
+
end
|
565
|
+
|
566
|
+
test 'removes formatting before partitioning author defined using author attribute' do
|
567
|
+
input = <<-EOS
|
568
|
+
:author: pass:n[http://example.org/community/team.html[Ze_**Project** team]]
|
569
|
+
EOS
|
570
|
+
|
571
|
+
doc = empty_document
|
572
|
+
parse_header_metadata input, doc
|
573
|
+
assert_equal 1, doc.attributes['authorcount']
|
574
|
+
assert_equal '<a href="http://example.org/community/team.html">Ze <strong>Project</strong> team</a>', doc.attributes['authors']
|
575
|
+
assert_equal 'Ze Project', doc.attributes['firstname']
|
576
|
+
assert_equal 'team', doc.attributes['lastname']
|
577
|
+
end
|
578
|
+
|
458
579
|
test "parse rev number date remark" do
|
459
580
|
input = <<-EOS
|
460
581
|
Ryan Waldron
|
@@ -591,19 +712,18 @@ v0.0.7, 2013-12-18
|
|
591
712
|
assert_equal '2013-12-18', metadata['revdate']
|
592
713
|
end
|
593
714
|
|
594
|
-
test
|
595
|
-
|
596
|
-
|
597
|
-
metadata = Asciidoctor::Parser.parse_header_metadata(reader, blankdoc)
|
715
|
+
test 'attribute entry overrides generated author initials' do
|
716
|
+
doc = empty_document
|
717
|
+
metadata, _ = parse_header_metadata %(Stuart Rackham <founder@asciidoc.org>\n:Author Initials: SJR), doc
|
598
718
|
assert_equal 'SR', metadata['authorinitials']
|
599
|
-
assert_equal 'SJR',
|
719
|
+
assert_equal 'SJR', doc.attributes['authorinitials']
|
600
720
|
end
|
601
721
|
|
602
722
|
test 'adjust indentation to 0' do
|
603
723
|
input = <<-EOS.chomp
|
604
724
|
def names
|
605
725
|
|
606
|
-
@name.split
|
726
|
+
@name.split
|
607
727
|
|
608
728
|
end
|
609
729
|
EOS
|
@@ -611,7 +731,7 @@ v0.0.7, 2013-12-18
|
|
611
731
|
expected = <<-EOS.chomp
|
612
732
|
def names
|
613
733
|
|
614
|
-
@name.split
|
734
|
+
@name.split
|
615
735
|
|
616
736
|
end
|
617
737
|
EOS
|
@@ -625,7 +745,7 @@ end
|
|
625
745
|
input = <<-EOS.chomp
|
626
746
|
def names
|
627
747
|
|
628
|
-
\t @name.split
|
748
|
+
\t @name.split
|
629
749
|
|
630
750
|
end
|
631
751
|
EOS
|
@@ -633,7 +753,7 @@ end
|
|
633
753
|
expected = <<-EOS.chomp
|
634
754
|
def names
|
635
755
|
|
636
|
-
@name.split
|
756
|
+
@name.split
|
637
757
|
|
638
758
|
end
|
639
759
|
EOS
|
@@ -667,7 +787,7 @@ devtmpfs 3.9G 0 3.9G 0% /dev
|
|
667
787
|
input = <<-EOS.chomp
|
668
788
|
def names
|
669
789
|
|
670
|
-
@name.split
|
790
|
+
@name.split
|
671
791
|
|
672
792
|
end
|
673
793
|
EOS
|
@@ -675,7 +795,7 @@ devtmpfs 3.9G 0 3.9G 0% /dev
|
|
675
795
|
expected = <<-EOS.chomp
|
676
796
|
def names
|
677
797
|
|
678
|
-
@name.split
|
798
|
+
@name.split
|
679
799
|
|
680
800
|
end
|
681
801
|
EOS
|
@@ -689,7 +809,7 @@ devtmpfs 3.9G 0 3.9G 0% /dev
|
|
689
809
|
input = <<-EOS
|
690
810
|
def names
|
691
811
|
|
692
|
-
@name.split
|
812
|
+
@name.split
|
693
813
|
|
694
814
|
end
|
695
815
|
EOS
|
data/test/paths_test.rb
CHANGED
@@ -88,13 +88,17 @@ context 'Path Resolver' do
|
|
88
88
|
assert_equal 'assets/images', @resolver.web_path(nil, 'assets/images')
|
89
89
|
end
|
90
90
|
|
91
|
-
test '
|
91
|
+
test 'posixifies windows paths' do
|
92
92
|
assert_equal '/images', @resolver.web_path('\\images')
|
93
93
|
assert_equal '../images', @resolver.web_path('..\\images')
|
94
94
|
assert_equal '/images', @resolver.web_path('\\..\\images')
|
95
95
|
assert_equal 'assets/images', @resolver.web_path('assets\\images')
|
96
96
|
assert_equal '../assets/images', @resolver.web_path('assets\\images', '..\\images\\..')
|
97
97
|
end
|
98
|
+
|
99
|
+
test 'URL encode spaces in path' do
|
100
|
+
assert_equal 'assets%20and%20stuff/lots%20of%20images', @resolver.web_path('lots of images', 'assets and stuff')
|
101
|
+
end
|
98
102
|
end
|
99
103
|
|
100
104
|
context 'System Paths' do
|
@@ -105,9 +109,23 @@ context 'Path Resolver' do
|
|
105
109
|
end
|
106
110
|
|
107
111
|
test 'prevents access to paths outside of jail' do
|
108
|
-
|
109
|
-
|
110
|
-
|
112
|
+
result, warnings = redirect_streams do |_, err|
|
113
|
+
[(@resolver.system_path '../../../../../css', %(#{JAIL}/assets/stylesheets), JAIL), err.string]
|
114
|
+
end
|
115
|
+
assert_equal %(#{JAIL}/css), result
|
116
|
+
assert_includes warnings, 'path has illegal reference to ancestor of jail'
|
117
|
+
|
118
|
+
result, warnings = redirect_streams do |_, err|
|
119
|
+
[(@resolver.system_path '/../../../../../css', %(#{JAIL}/assets/stylesheets), JAIL), err.string]
|
120
|
+
end
|
121
|
+
assert_equal %(#{JAIL}/css), result
|
122
|
+
assert_includes warnings, 'path has illegal reference to ancestor of jail'
|
123
|
+
|
124
|
+
result, warnings = redirect_streams do |_, err|
|
125
|
+
[(@resolver.system_path '../../../css', '../../..', JAIL), err.string]
|
126
|
+
end
|
127
|
+
assert_equal %(#{JAIL}/css), result
|
128
|
+
assert_includes warnings, 'path has illegal reference to ancestor of jail'
|
111
129
|
end
|
112
130
|
|
113
131
|
test 'throws exception for illegal path access if recover is false' do
|
@@ -181,6 +199,7 @@ context 'Path Resolver' do
|
|
181
199
|
pwd = File.expand_path(Dir.pwd)
|
182
200
|
assert_equal "#{pwd}/images/tiger.png", @resolver.system_path('images/tiger.png', '')
|
183
201
|
assert_equal "#{pwd}/images/tiger.png", @resolver.system_path('images/tiger.png', nil)
|
202
|
+
assert_equal "#{pwd}/images/tiger.png", @resolver.system_path('images/tiger.png')
|
184
203
|
end
|
185
204
|
|
186
205
|
test 'resolves relative hidden target relative to current directory if start is empty' do
|
@@ -190,22 +209,37 @@ context 'Path Resolver' do
|
|
190
209
|
end
|
191
210
|
|
192
211
|
test 'resolves and normalizes start with target is empty' do
|
193
|
-
pwd = File.expand_path
|
194
|
-
assert_equal '/home/doctor/docs', @resolver.system_path
|
195
|
-
assert_equal '/home/doctor/docs', @resolver.system_path
|
196
|
-
assert_equal
|
197
|
-
|
212
|
+
pwd = File.expand_path Dir.pwd
|
213
|
+
assert_equal '/home/doctor/docs', (@resolver.system_path '', '/home/doctor/docs')
|
214
|
+
assert_equal '/home/doctor/docs', (@resolver.system_path nil, '/home/doctor/docs')
|
215
|
+
assert_equal %(#{pwd}/assets/images), (@resolver.system_path nil, 'assets/images')
|
216
|
+
result, warnings = redirect_streams do |_, err|
|
217
|
+
[(@resolver.system_path '', '../assets/images', JAIL), err.string]
|
218
|
+
end
|
219
|
+
assert_equal %(#{JAIL}/assets/images), result
|
220
|
+
assert_includes warnings, 'path has illegal reference to ancestor of jail'
|
198
221
|
end
|
199
222
|
|
200
|
-
test '
|
223
|
+
test 'posixifies windows paths' do
|
201
224
|
assert_equal "#{JAIL}/assets/css", @resolver.system_path('..\\css', 'assets\\stylesheets', JAIL)
|
202
225
|
end
|
203
226
|
|
204
227
|
test 'resolves windows paths when file separator is backlash' do
|
205
228
|
@resolver.file_separator = '\\'
|
206
|
-
|
207
|
-
assert_equal 'C:/data/docs', @resolver.system_path
|
208
|
-
|
229
|
+
|
230
|
+
assert_equal 'C:/data/docs', (@resolver.system_path '..', 'C:\\data\\docs\\assets', 'C:\\data\\docs')
|
231
|
+
|
232
|
+
result, warnings = redirect_streams do |_, err|
|
233
|
+
[(@resolver.system_path '..\\..', 'C:\\data\\docs\\assets', 'C:\\data\\docs'), err.string]
|
234
|
+
end
|
235
|
+
assert_equal 'C:/data/docs', result
|
236
|
+
assert_includes warnings, 'path has illegal reference to ancestor of jail'
|
237
|
+
|
238
|
+
result, warnings = redirect_streams do |_, err|
|
239
|
+
[(@resolver.system_path '..\\..\\css', 'C:\\data\\docs\\assets', 'C:\\data\\docs'), err.string]
|
240
|
+
end
|
241
|
+
assert_equal 'C:/data/docs/css', result
|
242
|
+
assert_includes warnings, 'path has illegal reference to ancestor of jail'
|
209
243
|
end
|
210
244
|
|
211
245
|
test 'should calculate relative path' do
|