asciidoctor 1.5.8 → 2.0.0.rc.1
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 +162 -17
- data/LICENSE +1 -1
- data/README-de.adoc +12 -13
- data/README-fr.adoc +11 -12
- data/README-jp.adoc +11 -12
- data/README-zh_CN.adoc +12 -13
- data/README.adoc +6 -7
- data/asciidoctor.gemspec +19 -24
- data/bin/asciidoctor +5 -4
- data/data/reference/syntax.adoc +283 -0
- data/data/stylesheets/asciidoctor-default.css +56 -52
- data/data/stylesheets/coderay-asciidoctor.css +7 -9
- data/lib/asciidoctor.rb +171 -232
- data/lib/asciidoctor/abstract_block.rb +96 -105
- data/lib/asciidoctor/abstract_node.rb +118 -139
- data/lib/asciidoctor/attribute_list.rb +10 -14
- data/lib/asciidoctor/block.rb +20 -19
- data/lib/asciidoctor/callouts.rb +4 -2
- data/lib/asciidoctor/cli.rb +3 -2
- data/lib/asciidoctor/cli/invoker.rb +14 -21
- data/lib/asciidoctor/cli/options.rb +64 -54
- data/lib/asciidoctor/converter.rb +357 -185
- data/lib/asciidoctor/converter/composite.rb +40 -48
- data/lib/asciidoctor/converter/docbook5.rb +604 -640
- data/lib/asciidoctor/converter/html5.rb +949 -963
- data/lib/asciidoctor/converter/manpage.rb +569 -548
- data/lib/asciidoctor/converter/template.rb +231 -272
- data/lib/asciidoctor/core_ext.rb +5 -18
- data/lib/asciidoctor/core_ext/float/truncate.rb +19 -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/document.rb +399 -377
- data/lib/asciidoctor/extensions.rb +72 -140
- data/lib/asciidoctor/helpers.rb +122 -83
- data/lib/asciidoctor/inline.rb +5 -1
- data/lib/asciidoctor/list.rb +13 -11
- data/lib/asciidoctor/logging.rb +17 -16
- data/lib/asciidoctor/parser.rb +390 -423
- data/lib/asciidoctor/path_resolver.rb +10 -5
- data/lib/asciidoctor/reader.rb +286 -263
- data/lib/asciidoctor/rouge_ext.rb +39 -0
- data/lib/asciidoctor/section.rb +9 -8
- data/lib/asciidoctor/stylesheets.rb +19 -37
- data/lib/asciidoctor/substitutors.rb +364 -509
- data/lib/asciidoctor/syntax_highlighter.rb +238 -0
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
- data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
- data/lib/asciidoctor/table.rb +73 -66
- data/lib/asciidoctor/timings.rb +4 -2
- data/lib/asciidoctor/version.rb +2 -1
- data/lib/asciidoctor/writer.rb +30 -0
- data/man/asciidoctor.1 +19 -15
- data/man/asciidoctor.adoc +14 -12
- metadata +69 -216
- 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-tweaks/block_paragraph.html.haml +0 -1
- 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/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
data/test/blocks_test.rb
DELETED
@@ -1,3870 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
unless defined? ASCIIDOCTOR_PROJECT_DIR
|
3
|
-
$: << File.dirname(__FILE__); $:.uniq!
|
4
|
-
require 'test_helper'
|
5
|
-
end
|
6
|
-
|
7
|
-
context 'Blocks' do
|
8
|
-
default_logger = Asciidoctor::LoggerManager.logger
|
9
|
-
|
10
|
-
setup do
|
11
|
-
Asciidoctor::LoggerManager.logger = (@logger = Asciidoctor::MemoryLogger.new)
|
12
|
-
end
|
13
|
-
|
14
|
-
teardown do
|
15
|
-
Asciidoctor::LoggerManager.logger = default_logger
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'Layout Breaks' do
|
19
|
-
test 'horizontal rule' do
|
20
|
-
%w(''' '''' '''''').each do |line|
|
21
|
-
output = convert_string_to_embedded line
|
22
|
-
assert_includes output, '<hr>'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
test '< 3 chars does not make horizontal rule' do
|
27
|
-
%w(' '').each do |line|
|
28
|
-
output = convert_string_to_embedded line
|
29
|
-
refute_includes output, '<hr>'
|
30
|
-
assert_includes output, %(<p>#{line}</p>)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
test 'mixed chars does not make horizontal rule' do
|
35
|
-
[%q(''<), %q('''<), %q(' ' ')].each do |line|
|
36
|
-
output = convert_string_to_embedded line
|
37
|
-
refute_includes output, '<hr>'
|
38
|
-
assert_includes output, %(<p>#{line.sub '<', '<'}</p>)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
test 'horizontal rule between blocks' do
|
43
|
-
output = convert_string_to_embedded %(Block above\n\n'''\n\nBlock below)
|
44
|
-
assert_xpath '/hr', output, 1
|
45
|
-
assert_xpath '/hr/preceding-sibling::*', output, 1
|
46
|
-
assert_xpath '/hr/following-sibling::*', output, 1
|
47
|
-
end
|
48
|
-
|
49
|
-
test 'page break' do
|
50
|
-
output = convert_string_to_embedded %(page 1\n\n<<<\n\npage 2)
|
51
|
-
assert_xpath '/*[translate(@style, ";", "")="page-break-after: always"]', output, 1
|
52
|
-
assert_xpath '/*[translate(@style, ";", "")="page-break-after: always"]/preceding-sibling::div/p[text()="page 1"]', output, 1
|
53
|
-
assert_xpath '/*[translate(@style, ";", "")="page-break-after: always"]/following-sibling::div/p[text()="page 2"]', output, 1
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context 'Comments' do
|
58
|
-
test 'line comment between paragraphs offset by blank lines' do
|
59
|
-
input = <<-EOS
|
60
|
-
first paragraph
|
61
|
-
|
62
|
-
// line comment
|
63
|
-
|
64
|
-
second paragraph
|
65
|
-
EOS
|
66
|
-
output = convert_string_to_embedded input
|
67
|
-
refute_match(/line comment/, output)
|
68
|
-
assert_xpath '//p', output, 2
|
69
|
-
end
|
70
|
-
|
71
|
-
test 'adjacent line comment between paragraphs' do
|
72
|
-
input = <<-EOS
|
73
|
-
first line
|
74
|
-
// line comment
|
75
|
-
second line
|
76
|
-
EOS
|
77
|
-
output = convert_string_to_embedded input
|
78
|
-
refute_match(/line comment/, output)
|
79
|
-
assert_xpath '//p', output, 1
|
80
|
-
assert_xpath "//p[1][text()='first line\nsecond line']", output, 1
|
81
|
-
end
|
82
|
-
|
83
|
-
test 'comment block between paragraphs offset by blank lines' do
|
84
|
-
input = <<-EOS
|
85
|
-
first paragraph
|
86
|
-
|
87
|
-
////
|
88
|
-
block comment
|
89
|
-
////
|
90
|
-
|
91
|
-
second paragraph
|
92
|
-
EOS
|
93
|
-
output = convert_string_to_embedded input
|
94
|
-
refute_match(/block comment/, output)
|
95
|
-
assert_xpath '//p', output, 2
|
96
|
-
end
|
97
|
-
|
98
|
-
test 'comment block between paragraphs offset by blank lines inside delimited block' do
|
99
|
-
input = <<-EOS
|
100
|
-
====
|
101
|
-
first paragraph
|
102
|
-
|
103
|
-
////
|
104
|
-
block comment
|
105
|
-
////
|
106
|
-
|
107
|
-
second paragraph
|
108
|
-
====
|
109
|
-
EOS
|
110
|
-
output = convert_string_to_embedded input
|
111
|
-
refute_match(/block comment/, output)
|
112
|
-
assert_xpath '//p', output, 2
|
113
|
-
end
|
114
|
-
|
115
|
-
test 'adjacent comment block between paragraphs' do
|
116
|
-
input = <<-EOS
|
117
|
-
first paragraph
|
118
|
-
////
|
119
|
-
block comment
|
120
|
-
////
|
121
|
-
second paragraph
|
122
|
-
EOS
|
123
|
-
output = convert_string_to_embedded input
|
124
|
-
refute_match(/block comment/, output)
|
125
|
-
assert_xpath '//p', output, 2
|
126
|
-
end
|
127
|
-
|
128
|
-
test "can convert with block comment at end of document with trailing endlines" do
|
129
|
-
input = <<-EOS
|
130
|
-
paragraph
|
131
|
-
|
132
|
-
////
|
133
|
-
block comment
|
134
|
-
////
|
135
|
-
|
136
|
-
|
137
|
-
EOS
|
138
|
-
output = convert_string_to_embedded input
|
139
|
-
refute_match(/block comment/, output)
|
140
|
-
end
|
141
|
-
|
142
|
-
test "trailing endlines after block comment at end of document does not create paragraph" do
|
143
|
-
input = <<-EOS
|
144
|
-
paragraph
|
145
|
-
|
146
|
-
////
|
147
|
-
block comment
|
148
|
-
////
|
149
|
-
|
150
|
-
|
151
|
-
EOS
|
152
|
-
d = document_from_string input
|
153
|
-
assert_equal 1, d.blocks.size
|
154
|
-
assert_xpath '//p', d.convert, 1
|
155
|
-
end
|
156
|
-
|
157
|
-
test 'line starting with three slashes should not be line comment' do
|
158
|
-
input = <<-EOS
|
159
|
-
/// not a line comment
|
160
|
-
EOS
|
161
|
-
|
162
|
-
output = convert_string_to_embedded input
|
163
|
-
refute_empty output.strip, "Line should be emitted => #{input.rstrip}"
|
164
|
-
end
|
165
|
-
|
166
|
-
test 'preprocessor directives should not be processed within comment block within block metadata' do
|
167
|
-
input = <<-EOS
|
168
|
-
.sample title
|
169
|
-
////
|
170
|
-
ifdef::asciidoctor[////]
|
171
|
-
////
|
172
|
-
line should be shown
|
173
|
-
EOS
|
174
|
-
|
175
|
-
output = convert_string_to_embedded input
|
176
|
-
assert_xpath '//p[text() = "line should be shown"]', output, 1
|
177
|
-
end
|
178
|
-
|
179
|
-
test 'preprocessor directives should not be processed within comment block' do
|
180
|
-
input = <<-EOS
|
181
|
-
dummy line
|
182
|
-
|
183
|
-
////
|
184
|
-
ifdef::asciidoctor[////]
|
185
|
-
////
|
186
|
-
|
187
|
-
line should be shown
|
188
|
-
EOS
|
189
|
-
|
190
|
-
output = convert_string_to_embedded input
|
191
|
-
assert_xpath '//p[text() = "line should be shown"]', output, 1
|
192
|
-
end
|
193
|
-
|
194
|
-
test 'should warn if unterminated comment block is detected in body' do
|
195
|
-
input = <<-EOS
|
196
|
-
before comment block
|
197
|
-
|
198
|
-
////
|
199
|
-
content that has been disabled
|
200
|
-
|
201
|
-
supposed to be after comment block, except it got swallowed by block comment
|
202
|
-
EOS
|
203
|
-
|
204
|
-
convert_string_to_embedded input
|
205
|
-
assert_message @logger, :WARN, '<stdin>: line 3: unterminated comment block', Hash
|
206
|
-
end
|
207
|
-
|
208
|
-
test 'should warn if unterminated comment block is detected inside another block' do
|
209
|
-
input = <<-EOS
|
210
|
-
before sidebar block
|
211
|
-
|
212
|
-
****
|
213
|
-
////
|
214
|
-
content that has been disabled
|
215
|
-
****
|
216
|
-
|
217
|
-
supposed to be after sidebar block, except it got swallowed by block comment
|
218
|
-
EOS
|
219
|
-
|
220
|
-
convert_string_to_embedded input
|
221
|
-
assert_message @logger, :WARN, '<stdin>: line 4: unterminated comment block', Hash
|
222
|
-
end
|
223
|
-
|
224
|
-
# WARNING if first line of content is a directive, it will get interpretted before we know it's a comment block
|
225
|
-
# it happens because we always look a line ahead...not sure what we can do about it
|
226
|
-
test 'preprocessor directives should not be processed within comment open block' do
|
227
|
-
input = <<-EOS
|
228
|
-
[comment]
|
229
|
-
--
|
230
|
-
first line of comment
|
231
|
-
ifdef::asciidoctor[--]
|
232
|
-
line should not be shown
|
233
|
-
--
|
234
|
-
|
235
|
-
EOS
|
236
|
-
|
237
|
-
output = convert_string_to_embedded input
|
238
|
-
assert_xpath '//p', output, 0
|
239
|
-
end
|
240
|
-
|
241
|
-
# WARNING this assertion fails if the directive is the first line of the paragraph instead of the second
|
242
|
-
# it happens because we always look a line ahead; not sure what we can do about it
|
243
|
-
test 'preprocessor directives should not be processed on subsequent lines of a comment paragraph' do
|
244
|
-
input = <<-EOS
|
245
|
-
[comment]
|
246
|
-
first line of content
|
247
|
-
ifdef::asciidoctor[////]
|
248
|
-
|
249
|
-
this line should be shown
|
250
|
-
EOS
|
251
|
-
|
252
|
-
output = convert_string_to_embedded input
|
253
|
-
assert_xpath '//p[text() = "this line should be shown"]', output, 1
|
254
|
-
end
|
255
|
-
|
256
|
-
test 'comment style on open block should only skip block' do
|
257
|
-
input = <<-EOS
|
258
|
-
[comment]
|
259
|
-
--
|
260
|
-
skip
|
261
|
-
|
262
|
-
this block
|
263
|
-
--
|
264
|
-
|
265
|
-
not this text
|
266
|
-
EOS
|
267
|
-
result = convert_string_to_embedded input
|
268
|
-
assert_xpath '//p', result, 1
|
269
|
-
assert_xpath '//p[text()="not this text"]', result, 1
|
270
|
-
end
|
271
|
-
|
272
|
-
test 'comment style on paragraph should only skip paragraph' do
|
273
|
-
input = <<-EOS
|
274
|
-
[comment]
|
275
|
-
skip
|
276
|
-
this paragraph
|
277
|
-
|
278
|
-
not this text
|
279
|
-
EOS
|
280
|
-
result = convert_string_to_embedded input
|
281
|
-
assert_xpath '//p', result, 1
|
282
|
-
assert_xpath '//p[text()="not this text"]', result, 1
|
283
|
-
end
|
284
|
-
|
285
|
-
test 'comment style on paragraph should not cause adjacent block to be skipped' do
|
286
|
-
input = <<-EOS
|
287
|
-
[comment]
|
288
|
-
skip
|
289
|
-
this paragraph
|
290
|
-
[example]
|
291
|
-
not this text
|
292
|
-
EOS
|
293
|
-
result = convert_string_to_embedded input
|
294
|
-
assert_xpath '/*[@class="exampleblock"]', result, 1
|
295
|
-
assert_xpath '/*[@class="exampleblock"]//*[normalize-space(text())="not this text"]', result, 1
|
296
|
-
end
|
297
|
-
|
298
|
-
# NOTE this test verifies the nil return value of Parser#next_block
|
299
|
-
test 'should not drop content that follows skipped content inside a delimited block' do
|
300
|
-
input = <<-EOS
|
301
|
-
====
|
302
|
-
paragraph
|
303
|
-
|
304
|
-
[comment#idname]
|
305
|
-
skip
|
306
|
-
|
307
|
-
paragraph
|
308
|
-
====
|
309
|
-
EOS
|
310
|
-
result = convert_string_to_embedded input
|
311
|
-
assert_xpath '/*[@class="exampleblock"]', result, 1
|
312
|
-
assert_xpath '/*[@class="exampleblock"]//*[@class="paragraph"]', result, 2
|
313
|
-
assert_xpath '//*[@class="paragraph"][@id="idname"]', result, 0
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
context 'Quote and Verse Blocks' do
|
318
|
-
test 'quote block with no attribution' do
|
319
|
-
input = <<-EOS
|
320
|
-
____
|
321
|
-
A famous quote.
|
322
|
-
____
|
323
|
-
EOS
|
324
|
-
output = convert_string input
|
325
|
-
assert_css '.quoteblock', output, 1
|
326
|
-
assert_css '.quoteblock > blockquote', output, 1
|
327
|
-
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
328
|
-
assert_css '.quoteblock > .attribution', output, 0
|
329
|
-
assert_xpath '//*[@class = "quoteblock"]//p[text() = "A famous quote."]', output, 1
|
330
|
-
end
|
331
|
-
|
332
|
-
test 'quote block with attribution' do
|
333
|
-
input = <<-EOS
|
334
|
-
[quote, Famous Person, Famous Book (1999)]
|
335
|
-
____
|
336
|
-
A famous quote.
|
337
|
-
____
|
338
|
-
EOS
|
339
|
-
output = convert_string input
|
340
|
-
assert_css '.quoteblock', output, 1
|
341
|
-
assert_css '.quoteblock > blockquote', output, 1
|
342
|
-
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
343
|
-
assert_css '.quoteblock > .attribution', output, 1
|
344
|
-
assert_css '.quoteblock > .attribution > cite', output, 1
|
345
|
-
assert_css '.quoteblock > .attribution > br + cite', output, 1
|
346
|
-
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Book (1999)"]', output, 1
|
347
|
-
attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
|
348
|
-
author = attribution.children.first
|
349
|
-
assert_equal "#{decode_char 8212} Famous Person", author.text.strip
|
350
|
-
end
|
351
|
-
|
352
|
-
test 'quote block with attribute and id and role shorthand' do
|
353
|
-
input = <<-EOS
|
354
|
-
[quote#justice-to-all.solidarity, Martin Luther King, Jr.]
|
355
|
-
____
|
356
|
-
Injustice anywhere is a threat to justice everywhere.
|
357
|
-
____
|
358
|
-
EOS
|
359
|
-
|
360
|
-
output = convert_string_to_embedded input
|
361
|
-
assert_css '.quoteblock', output, 1
|
362
|
-
assert_css '#justice-to-all.quoteblock.solidarity', output, 1
|
363
|
-
assert_css '.quoteblock > .attribution', output, 1
|
364
|
-
end
|
365
|
-
|
366
|
-
test 'setting ID using style shorthand should not reset block style' do
|
367
|
-
input = <<-EOS
|
368
|
-
[quote]
|
369
|
-
[#justice-to-all.solidarity, Martin Luther King, Jr.]
|
370
|
-
____
|
371
|
-
Injustice anywhere is a threat to justice everywhere.
|
372
|
-
____
|
373
|
-
EOS
|
374
|
-
|
375
|
-
output = convert_string_to_embedded input
|
376
|
-
assert_css '.quoteblock', output, 1
|
377
|
-
assert_css '#justice-to-all.quoteblock.solidarity', output, 1
|
378
|
-
assert_css '.quoteblock > .attribution', output, 1
|
379
|
-
end
|
380
|
-
|
381
|
-
test 'quote block with complex content' do
|
382
|
-
input = <<-EOS
|
383
|
-
____
|
384
|
-
A famous quote.
|
385
|
-
|
386
|
-
NOTE: _That_ was inspiring.
|
387
|
-
____
|
388
|
-
EOS
|
389
|
-
output = convert_string input
|
390
|
-
assert_css '.quoteblock', output, 1
|
391
|
-
assert_css '.quoteblock > blockquote', output, 1
|
392
|
-
assert_css '.quoteblock > blockquote > .paragraph', output, 1
|
393
|
-
assert_css '.quoteblock > blockquote > .paragraph + .admonitionblock', output, 1
|
394
|
-
end
|
395
|
-
|
396
|
-
test 'quote block with attribution converted to DocBook' do
|
397
|
-
input = <<-EOS
|
398
|
-
[quote, Famous Person, Famous Book (1999)]
|
399
|
-
____
|
400
|
-
A famous quote.
|
401
|
-
____
|
402
|
-
EOS
|
403
|
-
output = convert_string input, :backend => :docbook
|
404
|
-
assert_css 'blockquote', output, 1
|
405
|
-
assert_css 'blockquote > simpara', output, 1
|
406
|
-
assert_css 'blockquote > attribution', output, 1
|
407
|
-
assert_css 'blockquote > attribution > citetitle', output, 1
|
408
|
-
assert_xpath '//blockquote/attribution/citetitle[text() = "Famous Book (1999)"]', output, 1
|
409
|
-
attribution = xmlnodes_at_xpath '//blockquote/attribution', output, 1
|
410
|
-
author = attribution.children.first
|
411
|
-
assert_equal 'Famous Person', author.text.strip
|
412
|
-
end
|
413
|
-
|
414
|
-
test 'epigraph quote block with attribution converted to DocBook' do
|
415
|
-
input = <<-EOS
|
416
|
-
[.epigraph, Famous Person, Famous Book (1999)]
|
417
|
-
____
|
418
|
-
A famous quote.
|
419
|
-
____
|
420
|
-
EOS
|
421
|
-
output = convert_string input, :backend => :docbook
|
422
|
-
assert_css 'epigraph', output, 1
|
423
|
-
assert_css 'epigraph > simpara', output, 1
|
424
|
-
assert_css 'epigraph > attribution', output, 1
|
425
|
-
assert_css 'epigraph > attribution > citetitle', output, 1
|
426
|
-
assert_xpath '//epigraph/attribution/citetitle[text() = "Famous Book (1999)"]', output, 1
|
427
|
-
attribution = xmlnodes_at_xpath '//epigraph/attribution', output, 1
|
428
|
-
author = attribution.children.first
|
429
|
-
assert_equal 'Famous Person', author.text.strip
|
430
|
-
end
|
431
|
-
|
432
|
-
test 'quote block using air quotes with no attribution' do
|
433
|
-
input = <<-EOS
|
434
|
-
""
|
435
|
-
A famous quote.
|
436
|
-
""
|
437
|
-
EOS
|
438
|
-
output = convert_string input
|
439
|
-
assert_css '.quoteblock', output, 1
|
440
|
-
assert_css '.quoteblock > blockquote', output, 1
|
441
|
-
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
442
|
-
assert_css '.quoteblock > .attribution', output, 0
|
443
|
-
assert_xpath '//*[@class = "quoteblock"]//p[text() = "A famous quote."]', output, 1
|
444
|
-
end
|
445
|
-
|
446
|
-
test 'markdown-style quote block with single paragraph and no attribution' do
|
447
|
-
input = <<-EOS
|
448
|
-
> A famous quote.
|
449
|
-
> Some more inspiring words.
|
450
|
-
EOS
|
451
|
-
output = convert_string input
|
452
|
-
assert_css '.quoteblock', output, 1
|
453
|
-
assert_css '.quoteblock > blockquote', output, 1
|
454
|
-
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
455
|
-
assert_css '.quoteblock > .attribution', output, 0
|
456
|
-
assert_xpath %(//*[@class = "quoteblock"]//p[text() = "A famous quote.\nSome more inspiring words."]), output, 1
|
457
|
-
end
|
458
|
-
|
459
|
-
test 'lazy markdown-style quote block with single paragraph and no attribution' do
|
460
|
-
input = <<-EOS
|
461
|
-
> A famous quote.
|
462
|
-
Some more inspiring words.
|
463
|
-
EOS
|
464
|
-
output = convert_string input
|
465
|
-
assert_css '.quoteblock', output, 1
|
466
|
-
assert_css '.quoteblock > blockquote', output, 1
|
467
|
-
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
468
|
-
assert_css '.quoteblock > .attribution', output, 0
|
469
|
-
assert_xpath %(//*[@class = "quoteblock"]//p[text() = "A famous quote.\nSome more inspiring words."]), output, 1
|
470
|
-
end
|
471
|
-
|
472
|
-
test 'markdown-style quote block with multiple paragraphs and no attribution' do
|
473
|
-
input = <<-EOS
|
474
|
-
> A famous quote.
|
475
|
-
>
|
476
|
-
> Some more inspiring words.
|
477
|
-
EOS
|
478
|
-
output = convert_string input
|
479
|
-
assert_css '.quoteblock', output, 1
|
480
|
-
assert_css '.quoteblock > blockquote', output, 1
|
481
|
-
assert_css '.quoteblock > blockquote > .paragraph > p', output, 2
|
482
|
-
assert_css '.quoteblock > .attribution', output, 0
|
483
|
-
assert_xpath %((//*[@class = "quoteblock"]//p)[1][text() = "A famous quote."]), output, 1
|
484
|
-
assert_xpath %((//*[@class = "quoteblock"]//p)[2][text() = "Some more inspiring words."]), output, 1
|
485
|
-
end
|
486
|
-
|
487
|
-
test 'markdown-style quote block with multiple blocks and no attribution' do
|
488
|
-
input = <<-EOS
|
489
|
-
> A famous quote.
|
490
|
-
>
|
491
|
-
> NOTE: Some more inspiring words.
|
492
|
-
EOS
|
493
|
-
output = convert_string input
|
494
|
-
assert_css '.quoteblock', output, 1
|
495
|
-
assert_css '.quoteblock > blockquote', output, 1
|
496
|
-
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
497
|
-
assert_css '.quoteblock > blockquote > .admonitionblock', output, 1
|
498
|
-
assert_css '.quoteblock > .attribution', output, 0
|
499
|
-
assert_xpath %((//*[@class = "quoteblock"]//p)[1][text() = "A famous quote."]), output, 1
|
500
|
-
assert_xpath %((//*[@class = "quoteblock"]//*[@class = "admonitionblock note"]//*[@class="content"])[1][normalize-space(text()) = "Some more inspiring words."]), output, 1
|
501
|
-
end
|
502
|
-
|
503
|
-
test 'markdown-style quote block with single paragraph and attribution' do
|
504
|
-
input = <<-EOS
|
505
|
-
> A famous quote.
|
506
|
-
> Some more inspiring words.
|
507
|
-
> -- Famous Person, Famous Source, Volume 1 (1999)
|
508
|
-
EOS
|
509
|
-
output = convert_string input
|
510
|
-
assert_css '.quoteblock', output, 1
|
511
|
-
assert_css '.quoteblock > blockquote', output, 1
|
512
|
-
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
513
|
-
assert_xpath %(//*[@class = "quoteblock"]//p[text() = "A famous quote.\nSome more inspiring words."]), output, 1
|
514
|
-
assert_css '.quoteblock > .attribution', output, 1
|
515
|
-
assert_css '.quoteblock > .attribution > cite', output, 1
|
516
|
-
assert_css '.quoteblock > .attribution > br + cite', output, 1
|
517
|
-
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Source, Volume 1 (1999)"]', output, 1
|
518
|
-
attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
|
519
|
-
author = attribution.children.first
|
520
|
-
assert_equal "#{decode_char 8212} Famous Person", author.text.strip
|
521
|
-
end
|
522
|
-
|
523
|
-
test 'should parse credit line in markdown-style quote block like positional block attributes' do
|
524
|
-
input = <<-EOS
|
525
|
-
> I hold it that a little rebellion now and then is a good thing,
|
526
|
-
> and as necessary in the political world as storms in the physical.
|
527
|
-
-- Thomas Jefferson, https://jeffersonpapers.princeton.edu/selected-documents/james-madison-1[The Papers of Thomas Jefferson, Volume 11]
|
528
|
-
EOS
|
529
|
-
|
530
|
-
output = convert_string_to_embedded input
|
531
|
-
assert_css '.quoteblock', output, 1
|
532
|
-
assert_css '.quoteblock cite a[href="https://jeffersonpapers.princeton.edu/selected-documents/james-madison-1"]', output, 1
|
533
|
-
end
|
534
|
-
|
535
|
-
test 'quoted paragraph-style quote block with attribution' do
|
536
|
-
input = <<-EOS
|
537
|
-
"A famous quote.
|
538
|
-
Some more inspiring words."
|
539
|
-
-- Famous Person, Famous Source, Volume 1 (1999)
|
540
|
-
EOS
|
541
|
-
output = convert_string input
|
542
|
-
assert_css '.quoteblock', output, 1
|
543
|
-
assert_css '.quoteblock > blockquote', output, 1
|
544
|
-
assert_xpath %(//*[@class = "quoteblock"]/blockquote[normalize-space(text()) = "A famous quote. Some more inspiring words."]), output, 1
|
545
|
-
assert_css '.quoteblock > .attribution', output, 1
|
546
|
-
assert_css '.quoteblock > .attribution > cite', output, 1
|
547
|
-
assert_css '.quoteblock > .attribution > br + cite', output, 1
|
548
|
-
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Source, Volume 1 (1999)"]', output, 1
|
549
|
-
attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
|
550
|
-
author = attribution.children.first
|
551
|
-
assert_equal "#{decode_char 8212} Famous Person", author.text.strip
|
552
|
-
end
|
553
|
-
|
554
|
-
test 'should parse credit line in quoted paragraph-style quote block like positional block attributes' do
|
555
|
-
input = <<-EOS
|
556
|
-
"I hold it that a little rebellion now and then is a good thing,
|
557
|
-
and as necessary in the political world as storms in the physical."
|
558
|
-
-- Thomas Jefferson, https://jeffersonpapers.princeton.edu/selected-documents/james-madison-1[The Papers of Thomas Jefferson, Volume 11]
|
559
|
-
EOS
|
560
|
-
|
561
|
-
output = convert_string_to_embedded input
|
562
|
-
assert_css '.quoteblock', output, 1
|
563
|
-
assert_css '.quoteblock cite a[href="https://jeffersonpapers.princeton.edu/selected-documents/james-madison-1"]', output, 1
|
564
|
-
end
|
565
|
-
|
566
|
-
test 'single-line verse block without attribution' do
|
567
|
-
input = <<-EOS
|
568
|
-
[verse]
|
569
|
-
____
|
570
|
-
A famous verse.
|
571
|
-
____
|
572
|
-
EOS
|
573
|
-
output = convert_string input
|
574
|
-
assert_css '.verseblock', output, 1
|
575
|
-
assert_css '.verseblock > pre', output, 1
|
576
|
-
assert_css '.verseblock > .attribution', output, 0
|
577
|
-
assert_css '.verseblock p', output, 0
|
578
|
-
assert_xpath '//*[@class = "verseblock"]/pre[normalize-space(text()) = "A famous verse."]', output, 1
|
579
|
-
end
|
580
|
-
|
581
|
-
test 'single-line verse block with attribution' do
|
582
|
-
input = <<-EOS
|
583
|
-
[verse, Famous Poet, Famous Poem]
|
584
|
-
____
|
585
|
-
A famous verse.
|
586
|
-
____
|
587
|
-
EOS
|
588
|
-
output = convert_string input
|
589
|
-
assert_css '.verseblock', output, 1
|
590
|
-
assert_css '.verseblock p', output, 0
|
591
|
-
assert_css '.verseblock > pre', output, 1
|
592
|
-
assert_css '.verseblock > .attribution', output, 1
|
593
|
-
assert_css '.verseblock > .attribution > cite', output, 1
|
594
|
-
assert_css '.verseblock > .attribution > br + cite', output, 1
|
595
|
-
assert_xpath '//*[@class = "verseblock"]/*[@class = "attribution"]/cite[text() = "Famous Poem"]', output, 1
|
596
|
-
attribution = xmlnodes_at_xpath '//*[@class = "verseblock"]/*[@class = "attribution"]', output, 1
|
597
|
-
author = attribution.children.first
|
598
|
-
assert_equal "#{decode_char 8212} Famous Poet", author.text.strip
|
599
|
-
end
|
600
|
-
|
601
|
-
test 'single-line verse block with attribution converted to DocBook' do
|
602
|
-
input = <<-EOS
|
603
|
-
[verse, Famous Poet, Famous Poem]
|
604
|
-
____
|
605
|
-
A famous verse.
|
606
|
-
____
|
607
|
-
EOS
|
608
|
-
output = convert_string input, :backend => :docbook
|
609
|
-
assert_css 'blockquote', output, 1
|
610
|
-
assert_css 'blockquote simpara', output, 0
|
611
|
-
assert_css 'blockquote > literallayout', output, 1
|
612
|
-
assert_css 'blockquote > attribution', output, 1
|
613
|
-
assert_css 'blockquote > attribution > citetitle', output, 1
|
614
|
-
assert_xpath '//blockquote/attribution/citetitle[text() = "Famous Poem"]', output, 1
|
615
|
-
attribution = xmlnodes_at_xpath '//blockquote/attribution', output, 1
|
616
|
-
author = attribution.children.first
|
617
|
-
assert_equal 'Famous Poet', author.text.strip
|
618
|
-
end
|
619
|
-
|
620
|
-
test 'single-line epigraph verse block with attribution converted to DocBook' do
|
621
|
-
input = <<-EOS
|
622
|
-
[verse.epigraph, Famous Poet, Famous Poem]
|
623
|
-
____
|
624
|
-
A famous verse.
|
625
|
-
____
|
626
|
-
EOS
|
627
|
-
output = convert_string input, :backend => :docbook
|
628
|
-
assert_css 'epigraph', output, 1
|
629
|
-
assert_css 'epigraph simpara', output, 0
|
630
|
-
assert_css 'epigraph > literallayout', output, 1
|
631
|
-
assert_css 'epigraph > attribution', output, 1
|
632
|
-
assert_css 'epigraph > attribution > citetitle', output, 1
|
633
|
-
assert_xpath '//epigraph/attribution/citetitle[text() = "Famous Poem"]', output, 1
|
634
|
-
attribution = xmlnodes_at_xpath '//epigraph/attribution', output, 1
|
635
|
-
author = attribution.children.first
|
636
|
-
assert_equal 'Famous Poet', author.text.strip
|
637
|
-
end
|
638
|
-
|
639
|
-
test 'multi-stanza verse block' do
|
640
|
-
input = <<-EOS
|
641
|
-
[verse]
|
642
|
-
____
|
643
|
-
A famous verse.
|
644
|
-
|
645
|
-
Stanza two.
|
646
|
-
____
|
647
|
-
EOS
|
648
|
-
output = convert_string input
|
649
|
-
assert_xpath '//*[@class = "verseblock"]', output, 1
|
650
|
-
assert_xpath '//*[@class = "verseblock"]/pre', output, 1
|
651
|
-
assert_xpath '//*[@class = "verseblock"]//p', output, 0
|
652
|
-
assert_xpath '//*[@class = "verseblock"]/pre[contains(text(), "A famous verse.")]', output, 1
|
653
|
-
assert_xpath '//*[@class = "verseblock"]/pre[contains(text(), "Stanza two.")]', output, 1
|
654
|
-
end
|
655
|
-
|
656
|
-
test 'verse block does not contain block elements' do
|
657
|
-
input = <<-EOS
|
658
|
-
[verse]
|
659
|
-
____
|
660
|
-
A famous verse.
|
661
|
-
|
662
|
-
....
|
663
|
-
not a literal
|
664
|
-
....
|
665
|
-
____
|
666
|
-
EOS
|
667
|
-
output = convert_string input
|
668
|
-
assert_css '.verseblock', output, 1
|
669
|
-
assert_css '.verseblock > pre', output, 1
|
670
|
-
assert_css '.verseblock p', output, 0
|
671
|
-
assert_css '.verseblock .literalblock', output, 0
|
672
|
-
end
|
673
|
-
|
674
|
-
test 'verse should have normal subs' do
|
675
|
-
input = <<-EOS
|
676
|
-
[verse]
|
677
|
-
____
|
678
|
-
A famous verse
|
679
|
-
____
|
680
|
-
EOS
|
681
|
-
|
682
|
-
verse = block_from_string input
|
683
|
-
assert_equal Asciidoctor::Substitutors::NORMAL_SUBS, verse.subs
|
684
|
-
end
|
685
|
-
|
686
|
-
test 'should not recognize callouts in a verse' do
|
687
|
-
input = <<-EOS
|
688
|
-
[verse]
|
689
|
-
____
|
690
|
-
La la la <1>
|
691
|
-
____
|
692
|
-
<1> Not pointing to a callout
|
693
|
-
EOS
|
694
|
-
|
695
|
-
output = convert_string_to_embedded input
|
696
|
-
assert_xpath '//pre[text()="La la la <1>"]', output, 1
|
697
|
-
assert_message @logger, :WARN, '<stdin>: line 5: no callout found for <1>', Hash
|
698
|
-
end
|
699
|
-
|
700
|
-
test 'should perform normal subs on a verse block' do
|
701
|
-
input = <<-EOS
|
702
|
-
[verse]
|
703
|
-
____
|
704
|
-
_GET /groups/link:#group-id[\{group-id\}]_
|
705
|
-
____
|
706
|
-
EOS
|
707
|
-
|
708
|
-
output = convert_string_to_embedded input
|
709
|
-
assert_includes output, '<pre class="content"><em>GET /groups/<a href="#group-id">{group-id}</a></em></pre>'
|
710
|
-
end
|
711
|
-
end
|
712
|
-
|
713
|
-
context "Example Blocks" do
|
714
|
-
test "can convert example block" do
|
715
|
-
input = <<-EOS
|
716
|
-
====
|
717
|
-
This is an example of an example block.
|
718
|
-
|
719
|
-
How crazy is that?
|
720
|
-
====
|
721
|
-
EOS
|
722
|
-
|
723
|
-
output = convert_string input
|
724
|
-
assert_xpath '//*[@class="exampleblock"]//p', output, 2
|
725
|
-
end
|
726
|
-
|
727
|
-
test 'assigns sequential numbered caption to example block with title' do
|
728
|
-
input = <<-EOS
|
729
|
-
.Writing Docs with AsciiDoc
|
730
|
-
====
|
731
|
-
Here's how you write AsciiDoc.
|
732
|
-
|
733
|
-
You just write.
|
734
|
-
====
|
735
|
-
|
736
|
-
.Writing Docs with DocBook
|
737
|
-
====
|
738
|
-
Here's how you write DocBook.
|
739
|
-
|
740
|
-
You futz with XML.
|
741
|
-
====
|
742
|
-
EOS
|
743
|
-
|
744
|
-
doc = document_from_string input
|
745
|
-
assert_equal 1, doc.blocks[0].numeral
|
746
|
-
assert_equal 1, doc.blocks[0].number
|
747
|
-
assert_equal 2, doc.blocks[1].numeral
|
748
|
-
assert_equal 2, doc.blocks[1].number
|
749
|
-
output = doc.convert
|
750
|
-
assert_xpath '(//*[@class="exampleblock"])[1]/*[@class="title"][text()="Example 1. Writing Docs with AsciiDoc"]', output, 1
|
751
|
-
assert_xpath '(//*[@class="exampleblock"])[2]/*[@class="title"][text()="Example 2. Writing Docs with DocBook"]', output, 1
|
752
|
-
assert_equal 2, doc.attributes['example-number']
|
753
|
-
end
|
754
|
-
|
755
|
-
test 'assigns sequential character caption to example block with title' do
|
756
|
-
input = <<-EOS
|
757
|
-
:example-number: @
|
758
|
-
|
759
|
-
.Writing Docs with AsciiDoc
|
760
|
-
====
|
761
|
-
Here's how you write AsciiDoc.
|
762
|
-
|
763
|
-
You just write.
|
764
|
-
====
|
765
|
-
|
766
|
-
.Writing Docs with DocBook
|
767
|
-
====
|
768
|
-
Here's how you write DocBook.
|
769
|
-
|
770
|
-
You futz with XML.
|
771
|
-
====
|
772
|
-
EOS
|
773
|
-
|
774
|
-
doc = document_from_string input
|
775
|
-
assert_equal 'A', doc.blocks[0].numeral
|
776
|
-
assert_equal 'A', doc.blocks[0].number
|
777
|
-
assert_equal 'B', doc.blocks[1].numeral
|
778
|
-
assert_equal 'B', doc.blocks[1].number
|
779
|
-
output = doc.convert
|
780
|
-
assert_xpath '(//*[@class="exampleblock"])[1]/*[@class="title"][text()="Example A. Writing Docs with AsciiDoc"]', output, 1
|
781
|
-
assert_xpath '(//*[@class="exampleblock"])[2]/*[@class="title"][text()="Example B. Writing Docs with DocBook"]', output, 1
|
782
|
-
assert_equal 'B', doc.attributes['example-number']
|
783
|
-
end
|
784
|
-
|
785
|
-
test "explicit caption is used if provided" do
|
786
|
-
input = <<-EOS
|
787
|
-
[caption="Look! "]
|
788
|
-
.Writing Docs with AsciiDoc
|
789
|
-
====
|
790
|
-
Here's how you write AsciiDoc.
|
791
|
-
|
792
|
-
You just write.
|
793
|
-
====
|
794
|
-
EOS
|
795
|
-
|
796
|
-
doc = document_from_string input
|
797
|
-
assert_nil doc.blocks[0].numeral
|
798
|
-
output = doc.convert
|
799
|
-
assert_xpath '(//*[@class="exampleblock"])[1]/*[@class="title"][text()="Look! Writing Docs with AsciiDoc"]', output, 1
|
800
|
-
refute doc.attributes.has_key?('example-number')
|
801
|
-
end
|
802
|
-
|
803
|
-
test 'automatic caption can be turned off and on and modified' do
|
804
|
-
input = <<-EOS
|
805
|
-
.first example
|
806
|
-
====
|
807
|
-
an example
|
808
|
-
====
|
809
|
-
|
810
|
-
:caption:
|
811
|
-
|
812
|
-
.second example
|
813
|
-
====
|
814
|
-
another example
|
815
|
-
====
|
816
|
-
|
817
|
-
:caption!:
|
818
|
-
:example-caption: Exhibit
|
819
|
-
|
820
|
-
.third example
|
821
|
-
====
|
822
|
-
yet another example
|
823
|
-
====
|
824
|
-
EOS
|
825
|
-
|
826
|
-
output = convert_string_to_embedded input
|
827
|
-
assert_xpath '/*[@class="exampleblock"]', output, 3
|
828
|
-
assert_xpath '(/*[@class="exampleblock"])[1]/*[@class="title"][starts-with(text(), "Example ")]', output, 1
|
829
|
-
assert_xpath '(/*[@class="exampleblock"])[2]/*[@class="title"][text()="second example"]', output, 1
|
830
|
-
assert_xpath '(/*[@class="exampleblock"])[3]/*[@class="title"][starts-with(text(), "Exhibit ")]', output, 1
|
831
|
-
end
|
832
|
-
|
833
|
-
test 'should warn if example block is not terminated' do
|
834
|
-
input = <<-EOS
|
835
|
-
outside
|
836
|
-
|
837
|
-
====
|
838
|
-
inside
|
839
|
-
|
840
|
-
still inside
|
841
|
-
|
842
|
-
eof
|
843
|
-
EOS
|
844
|
-
|
845
|
-
output = convert_string_to_embedded input
|
846
|
-
assert_xpath '/*[@class="exampleblock"]', output, 1
|
847
|
-
assert_message @logger, :WARN, '<stdin>: line 3: unterminated example block', Hash
|
848
|
-
end
|
849
|
-
end
|
850
|
-
|
851
|
-
context 'Admonition Blocks' do
|
852
|
-
test 'caption block-level attribute should be used as caption' do
|
853
|
-
input = <<-EOS
|
854
|
-
:tip-caption: Pro Tip
|
855
|
-
|
856
|
-
[caption="Pro Tip"]
|
857
|
-
TIP: Override the caption of an admonition block using an attribute entry
|
858
|
-
EOS
|
859
|
-
|
860
|
-
output = convert_string_to_embedded input
|
861
|
-
assert_xpath '/*[@class="admonitionblock tip"]//*[@class="icon"]/*[@class="title"][text()="Pro Tip"]', output, 1
|
862
|
-
end
|
863
|
-
|
864
|
-
test 'can override caption of admonition block using document attribute' do
|
865
|
-
input = <<-EOS
|
866
|
-
:tip-caption: Pro Tip
|
867
|
-
|
868
|
-
TIP: Override the caption of an admonition block using an attribute entry
|
869
|
-
EOS
|
870
|
-
|
871
|
-
output = convert_string_to_embedded input
|
872
|
-
assert_xpath '/*[@class="admonitionblock tip"]//*[@class="icon"]/*[@class="title"][text()="Pro Tip"]', output, 1
|
873
|
-
end
|
874
|
-
|
875
|
-
test 'blank caption document attribute should not blank admonition block caption' do
|
876
|
-
input = <<-EOS
|
877
|
-
:caption:
|
878
|
-
|
879
|
-
TIP: Override the caption of an admonition block using an attribute entry
|
880
|
-
EOS
|
881
|
-
|
882
|
-
output = convert_string_to_embedded input
|
883
|
-
assert_xpath '/*[@class="admonitionblock tip"]//*[@class="icon"]/*[@class="title"][text()="Tip"]', output, 1
|
884
|
-
end
|
885
|
-
end
|
886
|
-
|
887
|
-
context "Preformatted Blocks" do
|
888
|
-
test 'should separate adjacent paragraphs and listing into blocks' do
|
889
|
-
input = <<-EOS
|
890
|
-
paragraph 1
|
891
|
-
----
|
892
|
-
listing content
|
893
|
-
----
|
894
|
-
paragraph 2
|
895
|
-
EOS
|
896
|
-
|
897
|
-
output = convert_string_to_embedded input
|
898
|
-
assert_xpath '/*[@class="paragraph"]/p', output, 2
|
899
|
-
assert_xpath '/*[@class="listingblock"]', output, 1
|
900
|
-
assert_xpath '(/*[@class="paragraph"]/following-sibling::*)[1][@class="listingblock"]', output, 1
|
901
|
-
end
|
902
|
-
|
903
|
-
test "should preserve endlines in literal block" do
|
904
|
-
input = <<-EOS
|
905
|
-
....
|
906
|
-
line one
|
907
|
-
|
908
|
-
line two
|
909
|
-
|
910
|
-
line three
|
911
|
-
....
|
912
|
-
EOS
|
913
|
-
[true, false].each {|header_footer|
|
914
|
-
output = convert_string input, :header_footer => header_footer
|
915
|
-
assert_xpath '//pre', output, 1
|
916
|
-
assert_xpath '//pre/text()', output, 1
|
917
|
-
text = xmlnodes_at_xpath('//pre/text()', output, 1).text
|
918
|
-
lines = text.lines.entries
|
919
|
-
assert_equal 5, lines.size
|
920
|
-
expected = "line one\n\nline two\n\nline three".lines.entries
|
921
|
-
assert_equal expected, lines
|
922
|
-
blank_lines = output.scan(/\n[ \t]*\n/).size
|
923
|
-
assert blank_lines >= 2
|
924
|
-
}
|
925
|
-
end
|
926
|
-
|
927
|
-
test "should preserve endlines in listing block" do
|
928
|
-
input = <<-EOS
|
929
|
-
[source]
|
930
|
-
----
|
931
|
-
line one
|
932
|
-
|
933
|
-
line two
|
934
|
-
|
935
|
-
line three
|
936
|
-
----
|
937
|
-
EOS
|
938
|
-
[true, false].each {|header_footer|
|
939
|
-
output = convert_string input, header_footer => header_footer
|
940
|
-
assert_xpath '//pre/code', output, 1
|
941
|
-
assert_xpath '//pre/code/text()', output, 1
|
942
|
-
text = xmlnodes_at_xpath('//pre/code/text()', output, 1).text
|
943
|
-
lines = text.lines.entries
|
944
|
-
assert_equal 5, lines.size
|
945
|
-
expected = "line one\n\nline two\n\nline three".lines.entries
|
946
|
-
assert_equal expected, lines
|
947
|
-
blank_lines = output.scan(/\n[ \t]*\n/).size
|
948
|
-
assert blank_lines >= 2
|
949
|
-
}
|
950
|
-
end
|
951
|
-
|
952
|
-
test "should preserve endlines in verse block" do
|
953
|
-
input = <<-EOS
|
954
|
-
--
|
955
|
-
[verse]
|
956
|
-
____
|
957
|
-
line one
|
958
|
-
|
959
|
-
line two
|
960
|
-
|
961
|
-
line three
|
962
|
-
____
|
963
|
-
--
|
964
|
-
EOS
|
965
|
-
[true, false].each {|header_footer|
|
966
|
-
output = convert_string input, :header_footer => header_footer
|
967
|
-
assert_xpath '//*[@class="verseblock"]/pre', output, 1
|
968
|
-
assert_xpath '//*[@class="verseblock"]/pre/text()', output, 1
|
969
|
-
text = xmlnodes_at_xpath('//*[@class="verseblock"]/pre/text()', output, 1).text
|
970
|
-
lines = text.lines.entries
|
971
|
-
assert_equal 5, lines.size
|
972
|
-
expected = "line one\n\nline two\n\nline three".lines.entries
|
973
|
-
assert_equal expected, lines
|
974
|
-
blank_lines = output.scan(/\n[ \t]*\n/).size
|
975
|
-
assert blank_lines >= 2
|
976
|
-
}
|
977
|
-
end
|
978
|
-
|
979
|
-
test 'should strip leading and trailing blank lines when converting verbatim block' do
|
980
|
-
input = <<-EOS
|
981
|
-
[subs="attributes"]
|
982
|
-
....
|
983
|
-
|
984
|
-
|
985
|
-
first line
|
986
|
-
|
987
|
-
last line
|
988
|
-
|
989
|
-
{empty}
|
990
|
-
|
991
|
-
....
|
992
|
-
EOS
|
993
|
-
|
994
|
-
doc = document_from_string input, :header_footer => false
|
995
|
-
block = doc.blocks.first
|
996
|
-
assert_equal ['', '', ' first line', '', 'last line', '', '{empty}', ''], block.lines
|
997
|
-
result = doc.convert
|
998
|
-
assert_xpath %(//pre[text()=" first line\n\nlast line"]), result, 1
|
999
|
-
end
|
1000
|
-
|
1001
|
-
test 'should process block with CRLF endlines' do
|
1002
|
-
input = <<-EOS
|
1003
|
-
[source]\r
|
1004
|
-
----\r
|
1005
|
-
source line 1\r
|
1006
|
-
source line 2\r
|
1007
|
-
----\r
|
1008
|
-
EOS
|
1009
|
-
|
1010
|
-
output = convert_string_to_embedded input
|
1011
|
-
refute_match(/\[source\]/, output)
|
1012
|
-
assert_xpath '/*[@class="listingblock"]//pre', output, 1
|
1013
|
-
assert_xpath '/*[@class="listingblock"]//pre/code', output, 1
|
1014
|
-
assert_xpath %(/*[@class="listingblock"]//pre/code[text()="source line 1\nsource line 2"]), output, 1
|
1015
|
-
end
|
1016
|
-
|
1017
|
-
test 'should remove block indent if indent attribute is 0' do
|
1018
|
-
input = <<-EOS
|
1019
|
-
[indent="0"]
|
1020
|
-
----
|
1021
|
-
def names
|
1022
|
-
|
1023
|
-
@names.split
|
1024
|
-
|
1025
|
-
end
|
1026
|
-
----
|
1027
|
-
EOS
|
1028
|
-
|
1029
|
-
expected = <<-EOS
|
1030
|
-
def names
|
1031
|
-
|
1032
|
-
@names.split
|
1033
|
-
|
1034
|
-
end
|
1035
|
-
EOS
|
1036
|
-
|
1037
|
-
output = convert_string_to_embedded input
|
1038
|
-
assert_css 'pre', output, 1
|
1039
|
-
assert_css '.listingblock pre', output, 1
|
1040
|
-
result = xmlnodes_at_xpath('//pre', output, 1).text
|
1041
|
-
assert_equal expected.chomp, result
|
1042
|
-
end
|
1043
|
-
|
1044
|
-
test 'should not remove block indent if indent attribute is -1' do
|
1045
|
-
input = <<-EOS
|
1046
|
-
[indent="-1"]
|
1047
|
-
----
|
1048
|
-
def names
|
1049
|
-
|
1050
|
-
@names.split
|
1051
|
-
|
1052
|
-
end
|
1053
|
-
----
|
1054
|
-
EOS
|
1055
|
-
|
1056
|
-
expected = <<-EOS
|
1057
|
-
def names
|
1058
|
-
|
1059
|
-
@names.split
|
1060
|
-
|
1061
|
-
end
|
1062
|
-
EOS
|
1063
|
-
|
1064
|
-
output = convert_string_to_embedded input
|
1065
|
-
assert_css 'pre', output, 1
|
1066
|
-
assert_css '.listingblock pre', output, 1
|
1067
|
-
result = xmlnodes_at_xpath('//pre', output, 1).text
|
1068
|
-
assert_equal expected.chomp, result
|
1069
|
-
end
|
1070
|
-
|
1071
|
-
test 'should set block indent to value specified by indent attribute' do
|
1072
|
-
input = <<-EOS
|
1073
|
-
[indent="1"]
|
1074
|
-
----
|
1075
|
-
def names
|
1076
|
-
|
1077
|
-
@names.split
|
1078
|
-
|
1079
|
-
end
|
1080
|
-
----
|
1081
|
-
EOS
|
1082
|
-
|
1083
|
-
expected = <<-EOS
|
1084
|
-
def names
|
1085
|
-
|
1086
|
-
@names.split
|
1087
|
-
|
1088
|
-
end
|
1089
|
-
EOS
|
1090
|
-
|
1091
|
-
output = convert_string_to_embedded input
|
1092
|
-
assert_css 'pre', output, 1
|
1093
|
-
assert_css '.listingblock pre', output, 1
|
1094
|
-
result = xmlnodes_at_xpath('//pre', output, 1).text
|
1095
|
-
assert_equal expected.chomp, result
|
1096
|
-
end
|
1097
|
-
|
1098
|
-
test 'should set block indent to value specified by indent document attribute' do
|
1099
|
-
input = <<-EOS
|
1100
|
-
:source-indent: 1
|
1101
|
-
|
1102
|
-
[source,ruby]
|
1103
|
-
----
|
1104
|
-
def names
|
1105
|
-
|
1106
|
-
@names.split
|
1107
|
-
|
1108
|
-
end
|
1109
|
-
----
|
1110
|
-
EOS
|
1111
|
-
|
1112
|
-
expected = <<-EOS
|
1113
|
-
def names
|
1114
|
-
|
1115
|
-
@names.split
|
1116
|
-
|
1117
|
-
end
|
1118
|
-
EOS
|
1119
|
-
|
1120
|
-
output = convert_string_to_embedded input
|
1121
|
-
assert_css 'pre', output, 1
|
1122
|
-
assert_css '.listingblock pre', output, 1
|
1123
|
-
result = xmlnodes_at_xpath('//pre', output, 1).text
|
1124
|
-
assert_equal expected.chomp, result
|
1125
|
-
end
|
1126
|
-
|
1127
|
-
test 'should expand tabs if tabsize attribute is positive' do
|
1128
|
-
input = <<-EOS
|
1129
|
-
:tabsize: 4
|
1130
|
-
|
1131
|
-
[indent=0]
|
1132
|
-
----
|
1133
|
-
def names
|
1134
|
-
|
1135
|
-
@names.split
|
1136
|
-
|
1137
|
-
end
|
1138
|
-
----
|
1139
|
-
EOS
|
1140
|
-
|
1141
|
-
expected = <<-EOS
|
1142
|
-
def names
|
1143
|
-
|
1144
|
-
@names.split
|
1145
|
-
|
1146
|
-
end
|
1147
|
-
EOS
|
1148
|
-
|
1149
|
-
output = convert_string_to_embedded input
|
1150
|
-
assert_css 'pre', output, 1
|
1151
|
-
assert_css '.listingblock pre', output, 1
|
1152
|
-
result = xmlnodes_at_xpath('//pre', output, 1).text
|
1153
|
-
assert_equal expected.chomp, result
|
1154
|
-
end
|
1155
|
-
|
1156
|
-
test 'literal block should honor nowrap option' do
|
1157
|
-
input = <<-EOS
|
1158
|
-
[options="nowrap"]
|
1159
|
-
----
|
1160
|
-
Do not wrap me if I get too long.
|
1161
|
-
----
|
1162
|
-
EOS
|
1163
|
-
|
1164
|
-
output = convert_string_to_embedded input
|
1165
|
-
assert_css 'pre.nowrap', output, 1
|
1166
|
-
end
|
1167
|
-
|
1168
|
-
test 'literal block should set nowrap class if prewrap document attribute is disabled' do
|
1169
|
-
input = <<-EOS
|
1170
|
-
:prewrap!:
|
1171
|
-
|
1172
|
-
----
|
1173
|
-
Do not wrap me if I get too long.
|
1174
|
-
----
|
1175
|
-
EOS
|
1176
|
-
|
1177
|
-
output = convert_string_to_embedded input
|
1178
|
-
assert_css 'pre.nowrap', output, 1
|
1179
|
-
end
|
1180
|
-
|
1181
|
-
test 'literal block should honor explicit subs list' do
|
1182
|
-
input = <<-EOS
|
1183
|
-
[subs="verbatim,quotes"]
|
1184
|
-
----
|
1185
|
-
Map<String, String> *attributes*; //<1>
|
1186
|
-
----
|
1187
|
-
EOS
|
1188
|
-
|
1189
|
-
block = block_from_string input
|
1190
|
-
assert_equal [:specialcharacters,:callouts,:quotes], block.subs
|
1191
|
-
output = block.convert
|
1192
|
-
assert_includes output, 'Map<String, String> <strong>attributes</strong>;'
|
1193
|
-
assert_xpath '//pre/b[text()="(1)"]', output, 1
|
1194
|
-
end
|
1195
|
-
|
1196
|
-
test 'should be able to disable callouts for literal block' do
|
1197
|
-
input = <<-EOS
|
1198
|
-
[subs="specialcharacters"]
|
1199
|
-
----
|
1200
|
-
No callout here <1>
|
1201
|
-
----
|
1202
|
-
EOS
|
1203
|
-
block = block_from_string input
|
1204
|
-
assert_equal [:specialcharacters], block.subs
|
1205
|
-
output = block.convert
|
1206
|
-
assert_xpath '//pre/b[text()="(1)"]', output, 0
|
1207
|
-
end
|
1208
|
-
|
1209
|
-
test 'listing block should honor explicit subs list' do
|
1210
|
-
input = <<-EOS
|
1211
|
-
[subs="specialcharacters,quotes"]
|
1212
|
-
----
|
1213
|
-
$ *python functional_tests.py*
|
1214
|
-
Traceback (most recent call last):
|
1215
|
-
File "functional_tests.py", line 4, in <module>
|
1216
|
-
assert 'Django' in browser.title
|
1217
|
-
AssertionError
|
1218
|
-
----
|
1219
|
-
EOS
|
1220
|
-
|
1221
|
-
output = convert_string_to_embedded input
|
1222
|
-
|
1223
|
-
assert_css '.listingblock pre', output, 1
|
1224
|
-
assert_css '.listingblock pre strong', output, 1
|
1225
|
-
assert_css '.listingblock pre em', output, 0
|
1226
|
-
|
1227
|
-
input2 = <<-EOS
|
1228
|
-
[subs="specialcharacters,macros"]
|
1229
|
-
----
|
1230
|
-
$ pass:quotes[*python functional_tests.py*]
|
1231
|
-
Traceback (most recent call last):
|
1232
|
-
File "functional_tests.py", line 4, in <module>
|
1233
|
-
assert pass:quotes['Django'] in browser.title
|
1234
|
-
AssertionError
|
1235
|
-
----
|
1236
|
-
EOS
|
1237
|
-
|
1238
|
-
output2 = convert_string_to_embedded input2
|
1239
|
-
# FIXME JRuby is adding extra trailing endlines in the second document,
|
1240
|
-
# for now, rstrip is necessary
|
1241
|
-
assert_equal output.rstrip, output2.rstrip
|
1242
|
-
end
|
1243
|
-
|
1244
|
-
test 'first character of block title may be a period if not followed by space' do
|
1245
|
-
input = <<-EOS
|
1246
|
-
..gitignore
|
1247
|
-
----
|
1248
|
-
/.bundle/
|
1249
|
-
/build/
|
1250
|
-
/Gemfile.lock
|
1251
|
-
----
|
1252
|
-
EOS
|
1253
|
-
|
1254
|
-
output = convert_string_to_embedded input
|
1255
|
-
assert_xpath '//*[@class="title"][text()=".gitignore"]', output
|
1256
|
-
end
|
1257
|
-
|
1258
|
-
test 'listing block without title should generate screen element in docbook' do
|
1259
|
-
input = <<-EOS
|
1260
|
-
----
|
1261
|
-
listing block
|
1262
|
-
----
|
1263
|
-
EOS
|
1264
|
-
|
1265
|
-
output = convert_string_to_embedded input, :backend => 'docbook'
|
1266
|
-
assert_xpath '/screen[text()="listing block"]', output, 1
|
1267
|
-
end
|
1268
|
-
|
1269
|
-
test 'listing block with title should generate screen element inside formalpara element in docbook' do
|
1270
|
-
input = <<-EOS
|
1271
|
-
.title
|
1272
|
-
----
|
1273
|
-
listing block
|
1274
|
-
----
|
1275
|
-
EOS
|
1276
|
-
|
1277
|
-
output = convert_string_to_embedded input, :backend => 'docbook'
|
1278
|
-
assert_xpath '/formalpara', output, 1
|
1279
|
-
assert_xpath '/formalpara/title[text()="title"]', output, 1
|
1280
|
-
assert_xpath '/formalpara/para/screen[text()="listing block"]', output, 1
|
1281
|
-
end
|
1282
|
-
|
1283
|
-
test 'source block with no title or language should generate screen element in docbook' do
|
1284
|
-
input = <<-EOS
|
1285
|
-
[source]
|
1286
|
-
----
|
1287
|
-
listing block
|
1288
|
-
----
|
1289
|
-
EOS
|
1290
|
-
|
1291
|
-
output = convert_string_to_embedded input, :backend => 'docbook'
|
1292
|
-
assert_xpath '/screen[text()="listing block"]', output, 1
|
1293
|
-
end
|
1294
|
-
|
1295
|
-
test 'source block with title and no language should generate screen element inside formalpara element in docbook' do
|
1296
|
-
input = <<-EOS
|
1297
|
-
[source]
|
1298
|
-
.title
|
1299
|
-
----
|
1300
|
-
listing block
|
1301
|
-
----
|
1302
|
-
EOS
|
1303
|
-
|
1304
|
-
output = convert_string_to_embedded input, :backend => 'docbook'
|
1305
|
-
assert_xpath '/formalpara', output, 1
|
1306
|
-
assert_xpath '/formalpara/title[text()="title"]', output, 1
|
1307
|
-
assert_xpath '/formalpara/para/screen[text()="listing block"]', output, 1
|
1308
|
-
end
|
1309
|
-
end
|
1310
|
-
|
1311
|
-
context "Open Blocks" do
|
1312
|
-
test "can convert open block" do
|
1313
|
-
input = <<-EOS
|
1314
|
-
--
|
1315
|
-
This is an open block.
|
1316
|
-
|
1317
|
-
It can span multiple lines.
|
1318
|
-
--
|
1319
|
-
EOS
|
1320
|
-
|
1321
|
-
output = convert_string input
|
1322
|
-
assert_xpath '//*[@class="openblock"]//p', output, 2
|
1323
|
-
end
|
1324
|
-
|
1325
|
-
test "open block can contain another block" do
|
1326
|
-
input = <<-EOS
|
1327
|
-
--
|
1328
|
-
This is an open block.
|
1329
|
-
|
1330
|
-
It can span multiple lines.
|
1331
|
-
|
1332
|
-
____
|
1333
|
-
It can hold great quotes like this one.
|
1334
|
-
____
|
1335
|
-
--
|
1336
|
-
EOS
|
1337
|
-
|
1338
|
-
output = convert_string input
|
1339
|
-
assert_xpath '//*[@class="openblock"]//p', output, 3
|
1340
|
-
assert_xpath '//*[@class="openblock"]//*[@class="quoteblock"]', output, 1
|
1341
|
-
end
|
1342
|
-
|
1343
|
-
test 'should transfer id and reftext on open block to DocBook output' do
|
1344
|
-
input = <<-EOS
|
1345
|
-
Check out that <<open>>!
|
1346
|
-
|
1347
|
-
[[open,Open Block]]
|
1348
|
-
--
|
1349
|
-
This is an open block.
|
1350
|
-
|
1351
|
-
TIP: An open block can have other blocks inside of it.
|
1352
|
-
--
|
1353
|
-
|
1354
|
-
Back to our regularly scheduled programming.
|
1355
|
-
EOS
|
1356
|
-
|
1357
|
-
output = convert_string input, :backend => :docbook, :keep_namespaces => true
|
1358
|
-
assert_css 'article > simpara', output, 2
|
1359
|
-
assert_css 'article > para', output, 1
|
1360
|
-
assert_css 'article > para > simpara', output, 1
|
1361
|
-
assert_css 'article > para > tip', output, 1
|
1362
|
-
open = xmlnodes_at_xpath '/xmlns:article/xmlns:para', output, 1
|
1363
|
-
# nokogiri can't make up its mind
|
1364
|
-
id = open.attribute('id') || open.attribute('xml:id')
|
1365
|
-
refute_nil id
|
1366
|
-
assert_equal 'open', id.value
|
1367
|
-
xreflabel = open.attribute('xreflabel')
|
1368
|
-
refute_nil xreflabel
|
1369
|
-
assert_equal 'Open Block', xreflabel.value
|
1370
|
-
end
|
1371
|
-
|
1372
|
-
test 'should transfer id and reftext on open paragraph to DocBook output' do
|
1373
|
-
input = <<-EOS
|
1374
|
-
[open#openpara,reftext="Open Paragraph"]
|
1375
|
-
This is an open paragraph.
|
1376
|
-
EOS
|
1377
|
-
|
1378
|
-
output = convert_string input, :backend => :docbook, :keep_namespaces => true
|
1379
|
-
assert_css 'article > simpara', output, 1
|
1380
|
-
open = xmlnodes_at_xpath '/xmlns:article/xmlns:simpara', output, 1
|
1381
|
-
open = xmlnodes_at_xpath '/xmlns:article/xmlns:simpara[text()="This is an open paragraph."]', output, 1
|
1382
|
-
# nokogiri can't make up its mind
|
1383
|
-
id = open.attribute('id') || open.attribute('xml:id')
|
1384
|
-
refute_nil id
|
1385
|
-
assert_equal 'openpara', id.value
|
1386
|
-
xreflabel = open.attribute('xreflabel')
|
1387
|
-
refute_nil xreflabel
|
1388
|
-
assert_equal 'Open Paragraph', xreflabel.value
|
1389
|
-
end
|
1390
|
-
|
1391
|
-
test 'should transfer title on open block to DocBook output' do
|
1392
|
-
input = <<-EOS
|
1393
|
-
.Behold the open
|
1394
|
-
--
|
1395
|
-
This is an open block with a title.
|
1396
|
-
--
|
1397
|
-
EOS
|
1398
|
-
|
1399
|
-
output = convert_string input, :backend => :docbook
|
1400
|
-
assert_css 'article > formalpara', output, 1
|
1401
|
-
assert_css 'article > formalpara > *', output, 2
|
1402
|
-
assert_css 'article > formalpara > title', output, 1
|
1403
|
-
assert_xpath '/article/formalpara/title[text()="Behold the open"]', output, 1
|
1404
|
-
assert_css 'article > formalpara > para', output, 1
|
1405
|
-
assert_css 'article > formalpara > para > simpara', output, 1
|
1406
|
-
end
|
1407
|
-
|
1408
|
-
test 'should transfer title on open paragraph to DocBook output' do
|
1409
|
-
input = <<-EOS
|
1410
|
-
.Behold the open
|
1411
|
-
This is an open paragraph with a title.
|
1412
|
-
EOS
|
1413
|
-
|
1414
|
-
output = convert_string input, :backend => :docbook
|
1415
|
-
assert_css 'article > formalpara', output, 1
|
1416
|
-
assert_css 'article > formalpara > *', output, 2
|
1417
|
-
assert_css 'article > formalpara > title', output, 1
|
1418
|
-
assert_xpath '/article/formalpara/title[text()="Behold the open"]', output, 1
|
1419
|
-
assert_css 'article > formalpara > para', output, 1
|
1420
|
-
assert_css 'article > formalpara > para[text()="This is an open paragraph with a title."]', output, 1
|
1421
|
-
end
|
1422
|
-
|
1423
|
-
test 'should transfer role on open block to DocBook output' do
|
1424
|
-
input = <<-EOS
|
1425
|
-
[.container]
|
1426
|
-
--
|
1427
|
-
This is an open block.
|
1428
|
-
It holds stuff.
|
1429
|
-
--
|
1430
|
-
EOS
|
1431
|
-
|
1432
|
-
output = convert_string input, :backend => :docbook
|
1433
|
-
assert_css 'article > para[role=container]', output, 1
|
1434
|
-
assert_css 'article > para[role=container] > simpara', output, 1
|
1435
|
-
end
|
1436
|
-
|
1437
|
-
test 'should transfer role on open paragraph to DocBook output' do
|
1438
|
-
input = <<-EOS
|
1439
|
-
[.container]
|
1440
|
-
This is an open block.
|
1441
|
-
It holds stuff.
|
1442
|
-
EOS
|
1443
|
-
|
1444
|
-
output = convert_string input, :backend => :docbook
|
1445
|
-
assert_css 'article > simpara[role=container]', output, 1
|
1446
|
-
end
|
1447
|
-
end
|
1448
|
-
|
1449
|
-
context 'Passthrough Blocks' do
|
1450
|
-
test 'can parse a passthrough block' do
|
1451
|
-
input = <<-EOS
|
1452
|
-
++++
|
1453
|
-
This is a passthrough block.
|
1454
|
-
++++
|
1455
|
-
EOS
|
1456
|
-
|
1457
|
-
block = block_from_string input
|
1458
|
-
refute_nil block
|
1459
|
-
assert_equal 1, block.lines.size
|
1460
|
-
assert_equal 'This is a passthrough block.', block.source
|
1461
|
-
end
|
1462
|
-
|
1463
|
-
test 'does not perform subs on a passthrough block by default' do
|
1464
|
-
input = <<-EOS
|
1465
|
-
:type: passthrough
|
1466
|
-
|
1467
|
-
++++
|
1468
|
-
This is a '{type}' block.
|
1469
|
-
http://asciidoc.org
|
1470
|
-
image:tiger.png[]
|
1471
|
-
++++
|
1472
|
-
EOS
|
1473
|
-
|
1474
|
-
expected = %(This is a '{type}' block.\nhttp://asciidoc.org\nimage:tiger.png[])
|
1475
|
-
output = convert_string_to_embedded input
|
1476
|
-
assert_equal expected, output.strip
|
1477
|
-
end
|
1478
|
-
|
1479
|
-
test 'does not perform subs on a passthrough block with pass style by default' do
|
1480
|
-
input = <<-EOS
|
1481
|
-
:type: passthrough
|
1482
|
-
|
1483
|
-
[pass]
|
1484
|
-
++++
|
1485
|
-
This is a '{type}' block.
|
1486
|
-
http://asciidoc.org
|
1487
|
-
image:tiger.png[]
|
1488
|
-
++++
|
1489
|
-
EOS
|
1490
|
-
|
1491
|
-
expected = %(This is a '{type}' block.\nhttp://asciidoc.org\nimage:tiger.png[])
|
1492
|
-
output = convert_string_to_embedded input
|
1493
|
-
assert_equal expected, output.strip
|
1494
|
-
end
|
1495
|
-
|
1496
|
-
test 'passthrough block honors explicit subs list' do
|
1497
|
-
input = <<-EOS
|
1498
|
-
:type: passthrough
|
1499
|
-
|
1500
|
-
[subs="attributes,quotes,macros"]
|
1501
|
-
++++
|
1502
|
-
This is a _{type}_ block.
|
1503
|
-
http://asciidoc.org
|
1504
|
-
++++
|
1505
|
-
EOS
|
1506
|
-
|
1507
|
-
expected = %(This is a <em>passthrough</em> block.\n<a href="http://asciidoc.org" class="bare">http://asciidoc.org</a>)
|
1508
|
-
output = convert_string_to_embedded input
|
1509
|
-
assert_equal expected, output.strip
|
1510
|
-
end
|
1511
|
-
|
1512
|
-
test 'should strip leading and trailing blank lines when converting raw block' do
|
1513
|
-
input = <<-EOS
|
1514
|
-
++++
|
1515
|
-
line above
|
1516
|
-
++++
|
1517
|
-
|
1518
|
-
++++
|
1519
|
-
|
1520
|
-
|
1521
|
-
first line
|
1522
|
-
|
1523
|
-
last line
|
1524
|
-
|
1525
|
-
|
1526
|
-
++++
|
1527
|
-
|
1528
|
-
++++
|
1529
|
-
line below
|
1530
|
-
++++
|
1531
|
-
EOS
|
1532
|
-
|
1533
|
-
doc = document_from_string input, :header_footer => false
|
1534
|
-
block = doc.blocks[1]
|
1535
|
-
assert_equal ['', '', ' first line', '', 'last line', '', ''], block.lines
|
1536
|
-
result = doc.convert
|
1537
|
-
assert_equal "line above\n first line\n\nlast line\nline below", result, 1
|
1538
|
-
end
|
1539
|
-
end
|
1540
|
-
|
1541
|
-
context 'Math blocks' do
|
1542
|
-
test 'should add LaTeX math delimiters around latexmath block content' do
|
1543
|
-
input = <<-'EOS'
|
1544
|
-
[latexmath]
|
1545
|
-
++++
|
1546
|
-
\sqrt{3x-1}+(1+x)^2 < y
|
1547
|
-
++++
|
1548
|
-
EOS
|
1549
|
-
|
1550
|
-
output = convert_string_to_embedded input
|
1551
|
-
assert_css '.stemblock', output, 1
|
1552
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output
|
1553
|
-
assert_equal '\[\sqrt{3x-1}+(1+x)^2 < y\]', nodes.first.to_s.strip
|
1554
|
-
end
|
1555
|
-
|
1556
|
-
test 'should not add LaTeX math delimiters around latexmath block content if already present' do
|
1557
|
-
input = <<-'EOS'
|
1558
|
-
[latexmath]
|
1559
|
-
++++
|
1560
|
-
\[\sqrt{3x-1}+(1+x)^2 < y\]
|
1561
|
-
++++
|
1562
|
-
EOS
|
1563
|
-
|
1564
|
-
output = convert_string_to_embedded input
|
1565
|
-
assert_css '.stemblock', output, 1
|
1566
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output
|
1567
|
-
assert_equal '\[\sqrt{3x-1}+(1+x)^2 < y\]', nodes.first.to_s.strip
|
1568
|
-
end
|
1569
|
-
|
1570
|
-
test 'should display latexmath block in alt of equation in DocBook backend' do
|
1571
|
-
input = <<-'EOS'
|
1572
|
-
[latexmath]
|
1573
|
-
++++
|
1574
|
-
\sqrt{3x-1}+(1+x)^2 < y
|
1575
|
-
++++
|
1576
|
-
EOS
|
1577
|
-
|
1578
|
-
expect = <<-'EOS'
|
1579
|
-
<informalequation>
|
1580
|
-
<alt><![CDATA[\sqrt{3x-1}+(1+x)^2 < y]]></alt>
|
1581
|
-
<mathphrase><![CDATA[\sqrt{3x-1}+(1+x)^2 < y]]></mathphrase>
|
1582
|
-
</informalequation>
|
1583
|
-
EOS
|
1584
|
-
|
1585
|
-
output = convert_string_to_embedded input, :backend => :docbook
|
1586
|
-
assert_equal expect.strip, output.strip
|
1587
|
-
end
|
1588
|
-
|
1589
|
-
test 'should not split equation in AsciiMath block at single newline' do
|
1590
|
-
input = <<-'EOS'
|
1591
|
-
[asciimath]
|
1592
|
-
++++
|
1593
|
-
f: bbb"N" -> bbb"N"
|
1594
|
-
f: x |-> x + 1
|
1595
|
-
++++
|
1596
|
-
EOS
|
1597
|
-
expected = <<-'EOS'.chomp
|
1598
|
-
\$f: bbb"N" -> bbb"N"
|
1599
|
-
f: x |-> x + 1\$
|
1600
|
-
EOS
|
1601
|
-
|
1602
|
-
output = convert_string_to_embedded input
|
1603
|
-
assert_css '.stemblock', output, 1
|
1604
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]', output
|
1605
|
-
assert_equal expected, nodes.first.inner_html.strip
|
1606
|
-
end
|
1607
|
-
|
1608
|
-
test 'should split equation in AsciiMath block at escaped newline' do
|
1609
|
-
input = <<-'EOS'
|
1610
|
-
[asciimath]
|
1611
|
-
++++
|
1612
|
-
f: bbb"N" -> bbb"N" \
|
1613
|
-
f: x |-> x + 1
|
1614
|
-
++++
|
1615
|
-
EOS
|
1616
|
-
expected = <<-'EOS'.chomp
|
1617
|
-
\$f: bbb"N" -> bbb"N"\$<br>
|
1618
|
-
\$f: x |-> x + 1\$
|
1619
|
-
EOS
|
1620
|
-
|
1621
|
-
output = convert_string_to_embedded input
|
1622
|
-
assert_css '.stemblock', output, 1
|
1623
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]', output
|
1624
|
-
assert_equal expected, nodes.first.inner_html.strip
|
1625
|
-
end
|
1626
|
-
|
1627
|
-
test 'should split equation in AsciiMath block at sequence of escaped newlines' do
|
1628
|
-
input = <<-'EOS'
|
1629
|
-
[asciimath]
|
1630
|
-
++++
|
1631
|
-
f: bbb"N" -> bbb"N" \
|
1632
|
-
\
|
1633
|
-
f: x |-> x + 1
|
1634
|
-
++++
|
1635
|
-
EOS
|
1636
|
-
expected = <<-'EOS'.chomp
|
1637
|
-
\$f: bbb"N" -> bbb"N"\$<br>
|
1638
|
-
<br>
|
1639
|
-
\$f: x |-> x + 1\$
|
1640
|
-
EOS
|
1641
|
-
|
1642
|
-
output = convert_string_to_embedded input
|
1643
|
-
assert_css '.stemblock', output, 1
|
1644
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]', output
|
1645
|
-
assert_equal expected, nodes.first.inner_html.strip
|
1646
|
-
end
|
1647
|
-
|
1648
|
-
test 'should split equation in AsciiMath block at newline sequence and preserve breaks' do
|
1649
|
-
input = <<-'EOS'
|
1650
|
-
[asciimath]
|
1651
|
-
++++
|
1652
|
-
f: bbb"N" -> bbb"N"
|
1653
|
-
|
1654
|
-
|
1655
|
-
f: x |-> x + 1
|
1656
|
-
++++
|
1657
|
-
EOS
|
1658
|
-
expected = <<-'EOS'.chomp
|
1659
|
-
\$f: bbb"N" -> bbb"N"\$<br>
|
1660
|
-
<br>
|
1661
|
-
<br>
|
1662
|
-
\$f: x |-> x + 1\$
|
1663
|
-
EOS
|
1664
|
-
|
1665
|
-
output = convert_string_to_embedded input
|
1666
|
-
assert_css '.stemblock', output, 1
|
1667
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]', output
|
1668
|
-
assert_equal expected, nodes.first.inner_html.strip
|
1669
|
-
end
|
1670
|
-
|
1671
|
-
test 'should add AsciiMath delimiters around asciimath block content' do
|
1672
|
-
input = <<-'EOS'
|
1673
|
-
[asciimath]
|
1674
|
-
++++
|
1675
|
-
sqrt(3x-1)+(1+x)^2 < y
|
1676
|
-
++++
|
1677
|
-
EOS
|
1678
|
-
|
1679
|
-
output = convert_string_to_embedded input
|
1680
|
-
assert_css '.stemblock', output, 1
|
1681
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output
|
1682
|
-
assert_equal '\$sqrt(3x-1)+(1+x)^2 < y\$', nodes.first.to_s.strip
|
1683
|
-
end
|
1684
|
-
|
1685
|
-
test 'should not add AsciiMath delimiters around asciimath block content if already present' do
|
1686
|
-
input = <<-'EOS'
|
1687
|
-
[asciimath]
|
1688
|
-
++++
|
1689
|
-
\$sqrt(3x-1)+(1+x)^2 < y\$
|
1690
|
-
++++
|
1691
|
-
EOS
|
1692
|
-
|
1693
|
-
output = convert_string_to_embedded input
|
1694
|
-
assert_css '.stemblock', output, 1
|
1695
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output
|
1696
|
-
assert_equal '\$sqrt(3x-1)+(1+x)^2 < y\$', nodes.first.to_s.strip
|
1697
|
-
end
|
1698
|
-
|
1699
|
-
test 'should convert contents of asciimath block to MathML in DocBook output if asciimath gem is available' do
|
1700
|
-
asciimath_available = !(Asciidoctor::Helpers.require_library 'asciimath', true, :ignore).nil?
|
1701
|
-
input = <<-'EOS'
|
1702
|
-
[asciimath]
|
1703
|
-
++++
|
1704
|
-
x+b/(2a)<+-sqrt((b^2)/(4a^2)-c/a)
|
1705
|
-
++++
|
1706
|
-
EOS
|
1707
|
-
|
1708
|
-
expect = %(<informalequation>
|
1709
|
-
<mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"><mml:mi>x</mml:mi><mml:mo>+</mml:mo><mml:mfrac><mml:mi>b</mml:mi><mml:mrow><mml:mn>2</mml:mn><mml:mi>a</mml:mi></mml:mrow></mml:mfrac><mml:mo><</mml:mo><mml:mo>±</mml:mo><mml:msqrt><mml:mrow><mml:mfrac><mml:msup><mml:mi>b</mml:mi><mml:mn>2</mml:mn></mml:msup><mml:mrow><mml:mn>4</mml:mn><mml:msup><mml:mi>a</mml:mi><mml:mn>2</mml:mn></mml:msup></mml:mrow></mml:mfrac><mml:mo>−</mml:mo><mml:mfrac><mml:mi>c</mml:mi><mml:mi>a</mml:mi></mml:mfrac></mml:mrow></mml:msqrt></mml:math>
|
1710
|
-
</informalequation>)
|
1711
|
-
|
1712
|
-
using_memory_logger do |logger|
|
1713
|
-
doc = document_from_string input, :backend => :docbook, :header_footer => false
|
1714
|
-
actual = doc.convert
|
1715
|
-
if asciimath_available
|
1716
|
-
assert_equal expect.strip, actual.strip
|
1717
|
-
assert_equal :loaded, doc.converter.instance_variable_get(:@asciimath)
|
1718
|
-
else
|
1719
|
-
assert_message logger, :WARN, 'optional gem \'asciimath\' is not installed. Functionality disabled.'
|
1720
|
-
assert_equal :unavailable, doc.converter.instance_variable_get(:@asciimath)
|
1721
|
-
end
|
1722
|
-
end
|
1723
|
-
end
|
1724
|
-
|
1725
|
-
test 'should output title for latexmath block if defined' do
|
1726
|
-
input = <<-'EOS'
|
1727
|
-
.The Lorenz Equations
|
1728
|
-
[latexmath]
|
1729
|
-
++++
|
1730
|
-
\begin{aligned}
|
1731
|
-
\dot{x} & = \sigma(y-x) \\
|
1732
|
-
\dot{y} & = \rho x - y - xz \\
|
1733
|
-
\dot{z} & = -\beta z + xy
|
1734
|
-
\end{aligned}
|
1735
|
-
++++
|
1736
|
-
EOS
|
1737
|
-
|
1738
|
-
output = convert_string_to_embedded input
|
1739
|
-
assert_css '.stemblock', output, 1
|
1740
|
-
assert_css '.stemblock .title', output, 1
|
1741
|
-
assert_xpath '//*[@class="title"][text()="The Lorenz Equations"]', output, 1
|
1742
|
-
end
|
1743
|
-
|
1744
|
-
test 'should output title for asciimath block if defined' do
|
1745
|
-
input = <<-'EOS'
|
1746
|
-
.Simple fraction
|
1747
|
-
[asciimath]
|
1748
|
-
++++
|
1749
|
-
a//b
|
1750
|
-
++++
|
1751
|
-
EOS
|
1752
|
-
|
1753
|
-
output = convert_string_to_embedded input
|
1754
|
-
assert_css '.stemblock', output, 1
|
1755
|
-
assert_css '.stemblock .title', output, 1
|
1756
|
-
assert_xpath '//*[@class="title"][text()="Simple fraction"]', output, 1
|
1757
|
-
end
|
1758
|
-
|
1759
|
-
test 'should add AsciiMath delimiters around stem block content if stem attribute is asciimath, empty, or not set' do
|
1760
|
-
input = <<-'EOS'
|
1761
|
-
[stem]
|
1762
|
-
++++
|
1763
|
-
sqrt(3x-1)+(1+x)^2 < y
|
1764
|
-
++++
|
1765
|
-
EOS
|
1766
|
-
|
1767
|
-
[
|
1768
|
-
{},
|
1769
|
-
{'stem' => ''},
|
1770
|
-
{'stem' => 'asciimath'},
|
1771
|
-
{'stem' => 'bogus'}
|
1772
|
-
].each do |attributes|
|
1773
|
-
output = convert_string_to_embedded input, :attributes => attributes
|
1774
|
-
assert_css '.stemblock', output, 1
|
1775
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output
|
1776
|
-
assert_equal '\$sqrt(3x-1)+(1+x)^2 < y\$', nodes.first.to_s.strip
|
1777
|
-
end
|
1778
|
-
end
|
1779
|
-
|
1780
|
-
test 'should add LaTeX math delimiters around stem block content if stem attribute is latexmath, latex, or tex' do
|
1781
|
-
input = <<-'EOS'
|
1782
|
-
[stem]
|
1783
|
-
++++
|
1784
|
-
\sqrt{3x-1}+(1+x)^2 < y
|
1785
|
-
++++
|
1786
|
-
EOS
|
1787
|
-
|
1788
|
-
[
|
1789
|
-
{'stem' => 'latexmath'},
|
1790
|
-
{'stem' => 'latex'},
|
1791
|
-
{'stem' => 'tex'}
|
1792
|
-
].each do |attributes|
|
1793
|
-
output = convert_string_to_embedded input, :attributes => attributes
|
1794
|
-
assert_css '.stemblock', output, 1
|
1795
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output
|
1796
|
-
assert_equal '\[\sqrt{3x-1}+(1+x)^2 < y\]', nodes.first.to_s.strip
|
1797
|
-
end
|
1798
|
-
end
|
1799
|
-
|
1800
|
-
test 'should allow stem style to be set using second positional argument of block attributes' do
|
1801
|
-
input = <<-EOS
|
1802
|
-
:stem: latexmath
|
1803
|
-
|
1804
|
-
[stem,asciimath]
|
1805
|
-
++++
|
1806
|
-
sqrt(3x-1)+(1+x)^2 < y
|
1807
|
-
++++
|
1808
|
-
EOS
|
1809
|
-
|
1810
|
-
doc = document_from_string input
|
1811
|
-
stemblock = doc.blocks[0]
|
1812
|
-
assert_equal :stem, stemblock.context
|
1813
|
-
assert_equal 'asciimath', stemblock.attributes['style']
|
1814
|
-
output = doc.convert :header_footer => false
|
1815
|
-
assert_css '.stemblock', output, 1
|
1816
|
-
nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output
|
1817
|
-
assert_equal '\$sqrt(3x-1)+(1+x)^2 < y\$', nodes.first.to_s.strip
|
1818
|
-
end
|
1819
|
-
end
|
1820
|
-
|
1821
|
-
context 'Metadata' do
|
1822
|
-
test 'block title above section gets carried over to first block in section' do
|
1823
|
-
input = <<-EOS
|
1824
|
-
.Title
|
1825
|
-
== Section
|
1826
|
-
|
1827
|
-
paragraph
|
1828
|
-
EOS
|
1829
|
-
output = convert_string input
|
1830
|
-
assert_xpath '//*[@class="paragraph"]', output, 1
|
1831
|
-
assert_xpath '//*[@class="paragraph"]/*[@class="title"][text() = "Title"]', output, 1
|
1832
|
-
assert_xpath '//*[@class="paragraph"]/p[text() = "paragraph"]', output, 1
|
1833
|
-
end
|
1834
|
-
|
1835
|
-
test 'block title above document title demotes document title to a section title' do
|
1836
|
-
input = <<-EOS
|
1837
|
-
.Block title
|
1838
|
-
= Section Title
|
1839
|
-
|
1840
|
-
section paragraph
|
1841
|
-
EOS
|
1842
|
-
output = convert_string input
|
1843
|
-
assert_xpath '//*[@id="header"]/*', output, 0
|
1844
|
-
assert_xpath '//*[@id="preamble"]/*', output, 0
|
1845
|
-
assert_xpath '//*[@id="content"]/h1[text()="Section Title"]', output, 1
|
1846
|
-
assert_xpath '//*[@class="paragraph"]', output, 1
|
1847
|
-
assert_xpath '//*[@class="paragraph"]/*[@class="title"][text()="Block title"]', output, 1
|
1848
|
-
assert_message @logger, :ERROR, '<stdin>: line 2: level 0 sections can only be used when doctype is book', Hash
|
1849
|
-
end
|
1850
|
-
|
1851
|
-
test 'block title above document title gets carried over to first block in first section if no preamble' do
|
1852
|
-
input = <<-EOS
|
1853
|
-
:doctype: book
|
1854
|
-
.Block title
|
1855
|
-
= Document Title
|
1856
|
-
|
1857
|
-
== First Section
|
1858
|
-
|
1859
|
-
paragraph
|
1860
|
-
EOS
|
1861
|
-
doc = document_from_string input
|
1862
|
-
# NOTE block title demotes document title to level-0 section
|
1863
|
-
refute doc.header?
|
1864
|
-
output = doc.convert
|
1865
|
-
assert_xpath '//*[@class="sect1"]//*[@class="paragraph"]/*[@class="title"][text() = "Block title"]', output, 1
|
1866
|
-
end
|
1867
|
-
|
1868
|
-
test 'empty attribute list should not appear in output' do
|
1869
|
-
input = <<-EOS
|
1870
|
-
[]
|
1871
|
-
--
|
1872
|
-
Block content
|
1873
|
-
--
|
1874
|
-
EOS
|
1875
|
-
|
1876
|
-
output = convert_string_to_embedded input
|
1877
|
-
assert_includes output, 'Block content'
|
1878
|
-
refute_includes output, '[]'
|
1879
|
-
end
|
1880
|
-
|
1881
|
-
test 'empty block anchor should not appear in output' do
|
1882
|
-
input = <<-EOS
|
1883
|
-
[[]]
|
1884
|
-
--
|
1885
|
-
Block content
|
1886
|
-
--
|
1887
|
-
EOS
|
1888
|
-
|
1889
|
-
output = convert_string_to_embedded input
|
1890
|
-
assert_includes output, 'Block content'
|
1891
|
-
refute_includes output, '[[]]'
|
1892
|
-
end
|
1893
|
-
end
|
1894
|
-
|
1895
|
-
context 'Images' do
|
1896
|
-
test 'can convert block image with alt text defined in macro' do
|
1897
|
-
input = <<-EOS
|
1898
|
-
image::images/tiger.png[Tiger]
|
1899
|
-
EOS
|
1900
|
-
|
1901
|
-
output = convert_string_to_embedded input
|
1902
|
-
assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
1903
|
-
end
|
1904
|
-
|
1905
|
-
test 'converts SVG image using img element by default' do
|
1906
|
-
input = <<-EOS
|
1907
|
-
image::tiger.svg[Tiger]
|
1908
|
-
EOS
|
1909
|
-
|
1910
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SERVER
|
1911
|
-
assert_xpath '/*[@class="imageblock"]//img[@src="tiger.svg"][@alt="Tiger"]', output, 1
|
1912
|
-
end
|
1913
|
-
|
1914
|
-
test 'converts interactive SVG image with alt text using object element' do
|
1915
|
-
input = <<-EOS
|
1916
|
-
:imagesdir: images
|
1917
|
-
|
1918
|
-
[%interactive]
|
1919
|
-
image::tiger.svg[Tiger,100]
|
1920
|
-
EOS
|
1921
|
-
|
1922
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SERVER
|
1923
|
-
assert_xpath '/*[@class="imageblock"]//object[@type="image/svg+xml"][@data="images/tiger.svg"][@width="100"]/span[@class="alt"][text()="Tiger"]', output, 1
|
1924
|
-
end
|
1925
|
-
|
1926
|
-
test 'converts SVG image with alt text using img element when safe mode is secure' do
|
1927
|
-
input = <<-EOS
|
1928
|
-
[%interactive]
|
1929
|
-
image::images/tiger.svg[Tiger,100]
|
1930
|
-
EOS
|
1931
|
-
|
1932
|
-
output = convert_string_to_embedded input
|
1933
|
-
assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.svg"][@alt="Tiger"]', output, 1
|
1934
|
-
end
|
1935
|
-
|
1936
|
-
test 'inserts fallback image for SVG inside object element using same dimensions' do
|
1937
|
-
input = <<-EOS
|
1938
|
-
:imagesdir: images
|
1939
|
-
|
1940
|
-
[%interactive]
|
1941
|
-
image::tiger.svg[Tiger,100,fallback=tiger.png]
|
1942
|
-
EOS
|
1943
|
-
|
1944
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SERVER
|
1945
|
-
assert_xpath '/*[@class="imageblock"]//object[@type="image/svg+xml"][@data="images/tiger.svg"][@width="100"]/img[@src="images/tiger.png"][@width="100"]', output, 1
|
1946
|
-
end
|
1947
|
-
|
1948
|
-
test 'detects SVG image URI that contains a query string' do
|
1949
|
-
input = <<-EOS
|
1950
|
-
:imagesdir: images
|
1951
|
-
|
1952
|
-
[%interactive]
|
1953
|
-
image::http://example.org/tiger.svg?foo=bar[Tiger,100]
|
1954
|
-
EOS
|
1955
|
-
|
1956
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SERVER
|
1957
|
-
assert_xpath '/*[@class="imageblock"]//object[@type="image/svg+xml"][@data="http://example.org/tiger.svg?foo=bar"][@width="100"]/span[@class="alt"][text()="Tiger"]', output, 1
|
1958
|
-
end
|
1959
|
-
|
1960
|
-
test 'detects SVG image when format attribute is svg' do
|
1961
|
-
input = <<-EOS
|
1962
|
-
:imagesdir: images
|
1963
|
-
|
1964
|
-
[%interactive]
|
1965
|
-
image::http://example.org/tiger-svg[Tiger,100,format=svg]
|
1966
|
-
EOS
|
1967
|
-
|
1968
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SERVER
|
1969
|
-
assert_xpath '/*[@class="imageblock"]//object[@type="image/svg+xml"][@data="http://example.org/tiger-svg"][@width="100"]/span[@class="alt"][text()="Tiger"]', output, 1
|
1970
|
-
end
|
1971
|
-
|
1972
|
-
test 'converts inline SVG image using svg element' do
|
1973
|
-
input = <<-EOS
|
1974
|
-
:imagesdir: fixtures
|
1975
|
-
|
1976
|
-
[%inline]
|
1977
|
-
image::circle.svg[Tiger,100]
|
1978
|
-
EOS
|
1979
|
-
|
1980
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'docdir' => testdir }
|
1981
|
-
assert_match(/<svg\s[^>]*width="100px"[^>]*>/, output, 1)
|
1982
|
-
refute_match(/<svg\s[^>]*width="500px"[^>]*>/, output)
|
1983
|
-
refute_match(/<svg\s[^>]*height="500px"[^>]*>/, output)
|
1984
|
-
refute_match(/<svg\s[^>]*style="width:500px;height:500px"[^>]*>/, output)
|
1985
|
-
end
|
1986
|
-
|
1987
|
-
test 'converts inline SVG image using svg element even when data-uri is set' do
|
1988
|
-
input = <<-EOS
|
1989
|
-
:imagesdir: fixtures
|
1990
|
-
:data-uri:
|
1991
|
-
|
1992
|
-
[%inline]
|
1993
|
-
image::circle.svg[Tiger,100]
|
1994
|
-
EOS
|
1995
|
-
|
1996
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'docdir' => testdir }
|
1997
|
-
assert_match(/<svg\s[^>]*width="100px">/, output, 1)
|
1998
|
-
end
|
1999
|
-
|
2000
|
-
test 'embeds remote inline SVG when allow-uri-read is set' do
|
2001
|
-
input = <<-EOS
|
2002
|
-
image::http://#{resolve_localhost}:9876/fixtures/circle.svg[Circle,100,100,opts=inline]
|
2003
|
-
EOS
|
2004
|
-
|
2005
|
-
output = using_test_webserver do
|
2006
|
-
convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
|
2007
|
-
end
|
2008
|
-
|
2009
|
-
assert_css 'svg', output, 1
|
2010
|
-
assert_css 'svg[style]', output, 0
|
2011
|
-
assert_css 'svg[width="100px"]', output, 1
|
2012
|
-
assert_css 'svg[height="100px"]', output, 1
|
2013
|
-
assert_css 'svg circle', output, 1
|
2014
|
-
end
|
2015
|
-
|
2016
|
-
test 'converts alt text for inline svg element if svg cannot be read' do
|
2017
|
-
input = <<-EOS
|
2018
|
-
[%inline]
|
2019
|
-
image::no-such-image.svg[Alt Text]
|
2020
|
-
EOS
|
2021
|
-
|
2022
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SERVER
|
2023
|
-
assert_xpath '//span[@class="alt"][text()="Alt Text"]', output, 1
|
2024
|
-
assert_message @logger, :WARN, '~SVG does not exist or cannot be read'
|
2025
|
-
end
|
2026
|
-
|
2027
|
-
test 'can convert block image with alt text defined in macro containing square bracket' do
|
2028
|
-
input = <<-EOS
|
2029
|
-
image::images/tiger.png[A [Bengal] Tiger]
|
2030
|
-
EOS
|
2031
|
-
|
2032
|
-
output = convert_string input
|
2033
|
-
img = xmlnodes_at_xpath '//img', output, 1
|
2034
|
-
assert_equal 'A [Bengal] Tiger', img.attr('alt')
|
2035
|
-
end
|
2036
|
-
|
2037
|
-
test 'can convert block image with target containing spaces' do
|
2038
|
-
input = <<-EOS
|
2039
|
-
image::images/big tiger.png[A Big Tiger]
|
2040
|
-
EOS
|
2041
|
-
|
2042
|
-
output = convert_string input
|
2043
|
-
img = xmlnodes_at_xpath '//img', output, 1
|
2044
|
-
assert_equal 'images/big%20tiger.png', img.attr('src')
|
2045
|
-
assert_equal 'A Big Tiger', img.attr('alt')
|
2046
|
-
end
|
2047
|
-
|
2048
|
-
test 'should not recognize block image if target has leading or trailing spaces' do
|
2049
|
-
[' tiger.png', 'tiger.png '].each do |target|
|
2050
|
-
input = %(image::#{target}[Tiger])
|
2051
|
-
|
2052
|
-
output = convert_string_to_embedded input
|
2053
|
-
assert_xpath '//img', output, 0
|
2054
|
-
end
|
2055
|
-
end
|
2056
|
-
|
2057
|
-
test 'can convert block image with alt text defined in block attribute above macro' do
|
2058
|
-
input = <<-EOS
|
2059
|
-
[Tiger]
|
2060
|
-
image::images/tiger.png[]
|
2061
|
-
EOS
|
2062
|
-
|
2063
|
-
output = convert_string_to_embedded input
|
2064
|
-
assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
2065
|
-
end
|
2066
|
-
|
2067
|
-
test 'alt text in macro overrides alt text above macro' do
|
2068
|
-
input = <<-EOS
|
2069
|
-
[Alt Text]
|
2070
|
-
image::images/tiger.png[Tiger]
|
2071
|
-
EOS
|
2072
|
-
|
2073
|
-
output = convert_string_to_embedded input
|
2074
|
-
assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
2075
|
-
end
|
2076
|
-
|
2077
|
-
test 'should substitute attribute references in alt text defined in image block macro' do
|
2078
|
-
input = <<-EOS
|
2079
|
-
:alt-text: Tiger
|
2080
|
-
|
2081
|
-
image::images/tiger.png[{alt-text}]
|
2082
|
-
EOS
|
2083
|
-
output = convert_string_to_embedded input
|
2084
|
-
assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
2085
|
-
end
|
2086
|
-
|
2087
|
-
test 'should set direction CSS class on image if float attribute is set' do
|
2088
|
-
input = <<-EOS
|
2089
|
-
[float=left]
|
2090
|
-
image::images/tiger.png[Tiger]
|
2091
|
-
EOS
|
2092
|
-
|
2093
|
-
output = convert_string_to_embedded input
|
2094
|
-
assert_css '.imageblock.left', output, 1
|
2095
|
-
assert_css '.imageblock[style]', output, 0
|
2096
|
-
end
|
2097
|
-
|
2098
|
-
test 'should set text alignment CSS class on image if align attribute is set' do
|
2099
|
-
input = <<-EOS
|
2100
|
-
[align=center]
|
2101
|
-
image::images/tiger.png[Tiger]
|
2102
|
-
EOS
|
2103
|
-
|
2104
|
-
output = convert_string_to_embedded input
|
2105
|
-
assert_css '.imageblock.text-center', output, 1
|
2106
|
-
assert_css '.imageblock[style]', output, 0
|
2107
|
-
end
|
2108
|
-
|
2109
|
-
test 'style attribute is dropped from image macro' do
|
2110
|
-
input = <<-EOS
|
2111
|
-
[style=value]
|
2112
|
-
image::images/tiger.png[Tiger]
|
2113
|
-
EOS
|
2114
|
-
|
2115
|
-
doc = document_from_string input
|
2116
|
-
img = doc.blocks[0]
|
2117
|
-
refute(img.attributes.key? 'style')
|
2118
|
-
assert_nil img.style
|
2119
|
-
end
|
2120
|
-
|
2121
|
-
test 'should apply specialcharacters and replacement substitutions to alt text' do
|
2122
|
-
input = 'A tiger\'s "roar" is < a bear\'s "growl"'
|
2123
|
-
expected = 'A tiger’s "roar" is < a bear’s "growl"'
|
2124
|
-
result = convert_string_to_embedded %(image::images/tiger-roar.png[#{input}])
|
2125
|
-
assert_includes result, %(alt="#{expected}")
|
2126
|
-
end
|
2127
|
-
|
2128
|
-
test 'should not encode double quotes in alt text when converting to DocBook' do
|
2129
|
-
input = 'Select "File > Open"'
|
2130
|
-
expected = 'Select "File > Open"'
|
2131
|
-
result = convert_string_to_embedded %(image::images/open.png[#{input}]), :backend => :docbook
|
2132
|
-
assert_includes result, %(<phrase>#{expected}</phrase>)
|
2133
|
-
end
|
2134
|
-
|
2135
|
-
test 'should auto-generate alt text for block image if alt text is not specified' do
|
2136
|
-
input = <<-EOS
|
2137
|
-
image::images/lions-and-tigers.png[]
|
2138
|
-
EOS
|
2139
|
-
|
2140
|
-
image = block_from_string input
|
2141
|
-
assert_equal 'lions and tigers', (image.attr 'alt')
|
2142
|
-
assert_equal 'lions and tigers', (image.attr 'default-alt')
|
2143
|
-
output = image.convert
|
2144
|
-
assert_xpath '/*[@class="imageblock"]//img[@src="images/lions-and-tigers.png"][@alt="lions and tigers"]', output, 1
|
2145
|
-
end
|
2146
|
-
|
2147
|
-
test "can convert block image with alt text and height and width" do
|
2148
|
-
input = <<-EOS
|
2149
|
-
image::images/tiger.png[Tiger, 200, 300]
|
2150
|
-
EOS
|
2151
|
-
|
2152
|
-
output = convert_string_to_embedded input
|
2153
|
-
assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"][@width="200"][@height="300"]', output, 1
|
2154
|
-
end
|
2155
|
-
|
2156
|
-
test "can convert block image with link" do
|
2157
|
-
input = <<-EOS
|
2158
|
-
image::images/tiger.png[Tiger, link='http://en.wikipedia.org/wiki/Tiger']
|
2159
|
-
EOS
|
2160
|
-
|
2161
|
-
output = convert_string_to_embedded input
|
2162
|
-
assert_xpath '/*[@class="imageblock"]//a[@class="image"][@href="http://en.wikipedia.org/wiki/Tiger"]/img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
2163
|
-
end
|
2164
|
-
|
2165
|
-
test 'adds rel=noopener attribute to block image with link that targets _blank window' do
|
2166
|
-
input = <<-EOS
|
2167
|
-
image::images/tiger.png[Tiger,link=http://en.wikipedia.org/wiki/Tiger,window=_blank]
|
2168
|
-
EOS
|
2169
|
-
|
2170
|
-
output = convert_string_to_embedded input
|
2171
|
-
assert_xpath '/*[@class="imageblock"]//a[@class="image"][@href="http://en.wikipedia.org/wiki/Tiger"][@target="_blank"][@rel="noopener"]/img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
2172
|
-
end
|
2173
|
-
|
2174
|
-
test 'adds rel=noopener attribute to block image with link that targets name window when the noopener option is set' do
|
2175
|
-
input = <<-EOS
|
2176
|
-
image::images/tiger.png[Tiger,link=http://en.wikipedia.org/wiki/Tiger,window=name,opts=noopener]
|
2177
|
-
EOS
|
2178
|
-
|
2179
|
-
output = convert_string_to_embedded input
|
2180
|
-
assert_xpath '/*[@class="imageblock"]//a[@class="image"][@href="http://en.wikipedia.org/wiki/Tiger"][@target="name"][@rel="noopener"]/img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
2181
|
-
end
|
2182
|
-
|
2183
|
-
test 'adds rel=nofollow attribute to block image with a link when the nofollow option is set' do
|
2184
|
-
input = <<-EOS
|
2185
|
-
image::images/tiger.png[Tiger,link=http://en.wikipedia.org/wiki/Tiger,opts=nofollow]
|
2186
|
-
EOS
|
2187
|
-
|
2188
|
-
output = convert_string_to_embedded input
|
2189
|
-
assert_xpath '/*[@class="imageblock"]//a[@class="image"][@href="http://en.wikipedia.org/wiki/Tiger"][@rel="nofollow"]/img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
2190
|
-
end
|
2191
|
-
|
2192
|
-
test 'can convert block image with caption' do
|
2193
|
-
input = <<-EOS
|
2194
|
-
.The AsciiDoc Tiger
|
2195
|
-
image::images/tiger.png[Tiger]
|
2196
|
-
EOS
|
2197
|
-
|
2198
|
-
doc = document_from_string input
|
2199
|
-
assert_equal 1, doc.blocks[0].numeral
|
2200
|
-
output = doc.convert
|
2201
|
-
assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
2202
|
-
assert_xpath '//*[@class="imageblock"]/*[@class="title"][text() = "Figure 1. The AsciiDoc Tiger"]', output, 1
|
2203
|
-
assert_equal 1, doc.attributes['figure-number']
|
2204
|
-
end
|
2205
|
-
|
2206
|
-
test 'can convert block image with explicit caption' do
|
2207
|
-
input = <<-EOS
|
2208
|
-
[caption="Voila! "]
|
2209
|
-
.The AsciiDoc Tiger
|
2210
|
-
image::images/tiger.png[Tiger]
|
2211
|
-
EOS
|
2212
|
-
|
2213
|
-
doc = document_from_string input
|
2214
|
-
assert_nil doc.blocks[0].numeral
|
2215
|
-
output = doc.convert
|
2216
|
-
assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
2217
|
-
assert_xpath '//*[@class="imageblock"]/*[@class="title"][text() = "Voila! The AsciiDoc Tiger"]', output, 1
|
2218
|
-
refute doc.attributes.has_key?('figure-number')
|
2219
|
-
end
|
2220
|
-
|
2221
|
-
test 'can align image in DocBook backend' do
|
2222
|
-
input = <<-EOS
|
2223
|
-
image::images/sunset.jpg[Sunset,align=right]
|
2224
|
-
EOS
|
2225
|
-
|
2226
|
-
output = convert_string_to_embedded input, :backend => :docbook
|
2227
|
-
assert_xpath '//imagedata', output, 1
|
2228
|
-
assert_xpath '//imagedata[@align="right"]', output, 1
|
2229
|
-
end
|
2230
|
-
|
2231
|
-
test 'should set content width and depth in DocBook backend if no scaling' do
|
2232
|
-
input = <<-EOS
|
2233
|
-
image::images/sunset.jpg[Sunset,500,332]
|
2234
|
-
EOS
|
2235
|
-
|
2236
|
-
output = convert_string_to_embedded input, :backend => :docbook
|
2237
|
-
assert_xpath '//imagedata', output, 1
|
2238
|
-
assert_xpath '//imagedata[@contentwidth="500"]', output, 1
|
2239
|
-
assert_xpath '//imagedata[@contentdepth="332"]', output, 1
|
2240
|
-
assert_xpath '//imagedata[@width]', output, 0
|
2241
|
-
assert_xpath '//imagedata[@depth]', output, 0
|
2242
|
-
end
|
2243
|
-
|
2244
|
-
test 'can scale image in DocBook backend' do
|
2245
|
-
input = <<-EOS
|
2246
|
-
image::images/sunset.jpg[Sunset,500,332,scale=200]
|
2247
|
-
EOS
|
2248
|
-
|
2249
|
-
output = convert_string_to_embedded input, :backend => :docbook
|
2250
|
-
assert_xpath '//imagedata', output, 1
|
2251
|
-
assert_xpath '//imagedata[@scale="200"]', output, 1
|
2252
|
-
assert_xpath '//imagedata[@width]', output, 0
|
2253
|
-
assert_xpath '//imagedata[@depth]', output, 0
|
2254
|
-
assert_xpath '//imagedata[@contentwidth]', output, 0
|
2255
|
-
assert_xpath '//imagedata[@contentdepth]', output, 0
|
2256
|
-
end
|
2257
|
-
|
2258
|
-
test 'scale image width in DocBook backend' do
|
2259
|
-
input = <<-EOS
|
2260
|
-
image::images/sunset.jpg[Sunset,500,332,scaledwidth=25%]
|
2261
|
-
EOS
|
2262
|
-
|
2263
|
-
output = convert_string_to_embedded input, :backend => :docbook
|
2264
|
-
assert_xpath '//imagedata', output, 1
|
2265
|
-
assert_xpath '//imagedata[@width="25%"]', output, 1
|
2266
|
-
assert_xpath '//imagedata[@depth]', output, 0
|
2267
|
-
assert_xpath '//imagedata[@contentwidth]', output, 0
|
2268
|
-
assert_xpath '//imagedata[@contentdepth]', output, 0
|
2269
|
-
end
|
2270
|
-
|
2271
|
-
test 'adds % to scaled width if no units given in DocBook backend ' do
|
2272
|
-
input = <<-EOS
|
2273
|
-
image::images/sunset.jpg[Sunset,scaledwidth=25]
|
2274
|
-
EOS
|
2275
|
-
|
2276
|
-
output = convert_string_to_embedded input, :backend => :docbook
|
2277
|
-
assert_xpath '//imagedata', output, 1
|
2278
|
-
assert_xpath '//imagedata[@width="25%"]', output, 1
|
2279
|
-
end
|
2280
|
-
|
2281
|
-
test 'keeps line unprocessed if image target is missing attribute reference and attribute-missing is skip' do
|
2282
|
-
input = <<-EOS
|
2283
|
-
:attribute-missing: skip
|
2284
|
-
|
2285
|
-
image::{bogus}[]
|
2286
|
-
EOS
|
2287
|
-
|
2288
|
-
output = convert_string_to_embedded input
|
2289
|
-
assert_includes output, 'image::{bogus}[]'
|
2290
|
-
assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: bogus'
|
2291
|
-
end
|
2292
|
-
|
2293
|
-
test 'drops line if image target is missing attribute reference and attribute-missing is drop' do
|
2294
|
-
input = <<-EOS
|
2295
|
-
:attribute-missing: drop
|
2296
|
-
|
2297
|
-
image::{bogus}[]
|
2298
|
-
EOS
|
2299
|
-
|
2300
|
-
output = convert_string_to_embedded input
|
2301
|
-
assert_empty output.strip
|
2302
|
-
assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: bogus'
|
2303
|
-
end
|
2304
|
-
|
2305
|
-
test 'drops line if image target is missing attribute reference and attribute-missing is drop-line' do
|
2306
|
-
input = <<-EOS
|
2307
|
-
:attribute-missing: drop-line
|
2308
|
-
|
2309
|
-
image::{bogus}[]
|
2310
|
-
EOS
|
2311
|
-
|
2312
|
-
output = convert_string_to_embedded input
|
2313
|
-
assert_empty output.strip
|
2314
|
-
assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: bogus'
|
2315
|
-
end
|
2316
|
-
|
2317
|
-
test 'dropped image does not break processing of following section and attribute-missing is drop-line' do
|
2318
|
-
input = <<-EOS
|
2319
|
-
:attribute-missing: drop-line
|
2320
|
-
|
2321
|
-
image::{bogus}[]
|
2322
|
-
|
2323
|
-
== Section Title
|
2324
|
-
EOS
|
2325
|
-
|
2326
|
-
output = convert_string_to_embedded input
|
2327
|
-
assert_css 'img', output, 0
|
2328
|
-
assert_css 'h2', output, 1
|
2329
|
-
refute_includes output, '== Section Title'
|
2330
|
-
assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: bogus'
|
2331
|
-
end
|
2332
|
-
|
2333
|
-
test 'should pass through image that references uri' do
|
2334
|
-
input = <<-EOS
|
2335
|
-
:imagesdir: images
|
2336
|
-
|
2337
|
-
image::http://asciidoc.org/images/tiger.png[Tiger]
|
2338
|
-
EOS
|
2339
|
-
|
2340
|
-
output = convert_string_to_embedded input
|
2341
|
-
assert_xpath '/*[@class="imageblock"]//img[@src="http://asciidoc.org/images/tiger.png"][@alt="Tiger"]', output, 1
|
2342
|
-
end
|
2343
|
-
|
2344
|
-
test 'should encode spaces in image target if value is a URI' do
|
2345
|
-
input = <<-EOS
|
2346
|
-
image::http://example.org/svg?digraph=digraph G { a -> b; }[diagram]
|
2347
|
-
EOS
|
2348
|
-
|
2349
|
-
output = convert_string_to_embedded input
|
2350
|
-
assert_xpath %(/*[@class="imageblock"]//img[@src="http://example.org/svg?digraph=digraph%20G%20{%20a%20-#{decode_char 62}%20b;%20}"]), output, 1
|
2351
|
-
end
|
2352
|
-
|
2353
|
-
test 'can resolve image relative to imagesdir' do
|
2354
|
-
input = <<-EOS
|
2355
|
-
:imagesdir: images
|
2356
|
-
|
2357
|
-
image::tiger.png[Tiger]
|
2358
|
-
EOS
|
2359
|
-
|
2360
|
-
output = convert_string_to_embedded input
|
2361
|
-
assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
2362
|
-
end
|
2363
|
-
|
2364
|
-
test 'embeds base64-encoded data uri for image when data-uri attribute is set' do
|
2365
|
-
input = <<-EOS
|
2366
|
-
:data-uri:
|
2367
|
-
:imagesdir: fixtures
|
2368
|
-
|
2369
|
-
image::dot.gif[Dot]
|
2370
|
-
EOS
|
2371
|
-
|
2372
|
-
doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => testdir }
|
2373
|
-
assert_equal 'fixtures', doc.attributes['imagesdir']
|
2374
|
-
output = doc.convert
|
2375
|
-
assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
|
2376
|
-
end
|
2377
|
-
|
2378
|
-
test 'embeds empty base64-encoded data uri for unreadable image when data-uri attribute is set' do
|
2379
|
-
input = <<-EOS
|
2380
|
-
:data-uri:
|
2381
|
-
:imagesdir: fixtures
|
2382
|
-
|
2383
|
-
image::unreadable.gif[Dot]
|
2384
|
-
EOS
|
2385
|
-
|
2386
|
-
doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => testdir }
|
2387
|
-
assert_equal 'fixtures', doc.attributes['imagesdir']
|
2388
|
-
output = doc.convert
|
2389
|
-
assert_xpath '//img[@src="data:image/gif;base64,"]', output, 1
|
2390
|
-
assert_message @logger, :WARN, '~image to embed not found or not readable'
|
2391
|
-
end
|
2392
|
-
|
2393
|
-
test 'embeds base64-encoded data uri for remote image when data-uri attribute is set' do
|
2394
|
-
input = <<-EOS
|
2395
|
-
:data-uri:
|
2396
|
-
|
2397
|
-
image::http://#{resolve_localhost}:9876/fixtures/dot.gif[Dot]
|
2398
|
-
EOS
|
2399
|
-
|
2400
|
-
output = using_test_webserver do
|
2401
|
-
convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
|
2402
|
-
end
|
2403
|
-
|
2404
|
-
assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
|
2405
|
-
end
|
2406
|
-
|
2407
|
-
test 'embeds base64-encoded data uri for remote image when imagesdir is a URI and data-uri attribute is set' do
|
2408
|
-
input = <<-EOS
|
2409
|
-
:data-uri:
|
2410
|
-
:imagesdir: http://#{resolve_localhost}:9876/fixtures
|
2411
|
-
|
2412
|
-
image::dot.gif[Dot]
|
2413
|
-
EOS
|
2414
|
-
|
2415
|
-
output = using_test_webserver do
|
2416
|
-
convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
|
2417
|
-
end
|
2418
|
-
|
2419
|
-
assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
|
2420
|
-
end
|
2421
|
-
|
2422
|
-
test 'uses remote image uri when data-uri attribute is set and image cannot be retrieved' do
|
2423
|
-
image_uri = "http://#{resolve_localhost}:9876/fixtures/missing-image.gif"
|
2424
|
-
input = <<-EOS
|
2425
|
-
:data-uri:
|
2426
|
-
|
2427
|
-
image::#{image_uri}[Missing image]
|
2428
|
-
EOS
|
2429
|
-
|
2430
|
-
output = using_test_webserver do
|
2431
|
-
convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
|
2432
|
-
end
|
2433
|
-
|
2434
|
-
assert_xpath %(/*[@class="imageblock"]//img[@src="#{image_uri}"][@alt="Missing image"]), output, 1
|
2435
|
-
assert_message @logger, :WARN, '~could not retrieve image data from URI'
|
2436
|
-
end
|
2437
|
-
|
2438
|
-
test 'uses remote image uri when data-uri attribute is set and allow-uri-read is not set' do
|
2439
|
-
image_uri = "http://#{resolve_localhost}:9876/fixtures/dot.gif"
|
2440
|
-
input = <<-EOS
|
2441
|
-
:data-uri:
|
2442
|
-
|
2443
|
-
image::#{image_uri}[Dot]
|
2444
|
-
EOS
|
2445
|
-
|
2446
|
-
output = using_test_webserver do
|
2447
|
-
convert_string_to_embedded input, :safe => :safe
|
2448
|
-
end
|
2449
|
-
|
2450
|
-
assert_xpath %(/*[@class="imageblock"]//img[@src="#{image_uri}"][@alt="Dot"]), output, 1
|
2451
|
-
end
|
2452
|
-
|
2453
|
-
test 'can handle embedded data uri images' do
|
2454
|
-
input = <<-EOS
|
2455
|
-
image::data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=[Dot]
|
2456
|
-
EOS
|
2457
|
-
|
2458
|
-
output = convert_string_to_embedded input
|
2459
|
-
assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
|
2460
|
-
end
|
2461
|
-
|
2462
|
-
test 'can handle embedded data uri images when data-uri attribute is set' do
|
2463
|
-
input = <<-EOS
|
2464
|
-
:data-uri:
|
2465
|
-
|
2466
|
-
image::data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=[Dot]
|
2467
|
-
EOS
|
2468
|
-
|
2469
|
-
output = convert_string_to_embedded input
|
2470
|
-
assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
|
2471
|
-
end
|
2472
|
-
|
2473
|
-
test 'cleans reference to ancestor directories in imagesdir before reading image if safe mode level is at least SAFE' do
|
2474
|
-
input = <<-EOS
|
2475
|
-
:data-uri:
|
2476
|
-
:imagesdir: ../..//fixtures/./../../fixtures
|
2477
|
-
|
2478
|
-
image::dot.gif[Dot]
|
2479
|
-
EOS
|
2480
|
-
|
2481
|
-
doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => testdir }
|
2482
|
-
assert_equal '../..//fixtures/./../../fixtures', doc.attributes['imagesdir']
|
2483
|
-
output = doc.convert
|
2484
|
-
# image target resolves to fixtures/dot.gif relative to docdir (which is explicitly set to the directory of this file)
|
2485
|
-
# the reference cannot fall outside of the document directory in safe mode
|
2486
|
-
assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
|
2487
|
-
assert_message @logger, :WARN, 'image has illegal reference to ancestor of jail; recovering automatically'
|
2488
|
-
end
|
2489
|
-
|
2490
|
-
test 'cleans reference to ancestor directories in target before reading image if safe mode level is at least SAFE' do
|
2491
|
-
input = <<-EOS
|
2492
|
-
:data-uri:
|
2493
|
-
:imagesdir: ./
|
2494
|
-
|
2495
|
-
image::../..//fixtures/./../../fixtures/dot.gif[Dot]
|
2496
|
-
EOS
|
2497
|
-
|
2498
|
-
doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'docdir' => testdir }
|
2499
|
-
assert_equal './', doc.attributes['imagesdir']
|
2500
|
-
output = doc.convert
|
2501
|
-
# image target resolves to fixtures/dot.gif relative to docdir (which is explicitly set to the directory of this file)
|
2502
|
-
# the reference cannot fall outside of the document directory in safe mode
|
2503
|
-
assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
|
2504
|
-
assert_message @logger, :WARN, 'image has illegal reference to ancestor of jail; recovering automatically'
|
2505
|
-
end
|
2506
|
-
end
|
2507
|
-
|
2508
|
-
context 'Media' do
|
2509
|
-
test 'should detect and convert video macro' do
|
2510
|
-
input = <<-EOS
|
2511
|
-
video::cats-vs-dogs.avi[]
|
2512
|
-
EOS
|
2513
|
-
|
2514
|
-
output = convert_string_to_embedded input
|
2515
|
-
assert_css 'video', output, 1
|
2516
|
-
assert_css 'video[src="cats-vs-dogs.avi"]', output, 1
|
2517
|
-
end
|
2518
|
-
|
2519
|
-
test 'should detect and convert video macro with positional attributes for poster and dimensions' do
|
2520
|
-
input = <<-EOS
|
2521
|
-
video::cats-vs-dogs.avi[cats-and-dogs.png, 200, 300]
|
2522
|
-
EOS
|
2523
|
-
|
2524
|
-
output = convert_string_to_embedded input
|
2525
|
-
assert_css 'video', output, 1
|
2526
|
-
assert_css 'video[src="cats-vs-dogs.avi"]', output, 1
|
2527
|
-
assert_css 'video[poster="cats-and-dogs.png"]', output, 1
|
2528
|
-
assert_css 'video[width="200"]', output, 1
|
2529
|
-
assert_css 'video[height="300"]', output, 1
|
2530
|
-
end
|
2531
|
-
|
2532
|
-
test 'should set direction CSS class on video block if float attribute is set' do
|
2533
|
-
input = <<-EOS
|
2534
|
-
video::cats-vs-dogs.avi[cats-and-dogs.png,float=right]
|
2535
|
-
EOS
|
2536
|
-
|
2537
|
-
output = convert_string_to_embedded input
|
2538
|
-
assert_css 'video', output, 1
|
2539
|
-
assert_css 'video[src="cats-vs-dogs.avi"]', output, 1
|
2540
|
-
assert_css '.videoblock.right', output, 1
|
2541
|
-
end
|
2542
|
-
|
2543
|
-
test 'should set text alignment CSS class on video block if align attribute is set' do
|
2544
|
-
input = <<-EOS
|
2545
|
-
video::cats-vs-dogs.avi[cats-and-dogs.png,align=center]
|
2546
|
-
EOS
|
2547
|
-
|
2548
|
-
output = convert_string_to_embedded input
|
2549
|
-
assert_css 'video', output, 1
|
2550
|
-
assert_css 'video[src="cats-vs-dogs.avi"]', output, 1
|
2551
|
-
assert_css '.videoblock.text-center', output, 1
|
2552
|
-
end
|
2553
|
-
|
2554
|
-
test 'video macro should honor all options' do
|
2555
|
-
input = <<-EOS
|
2556
|
-
video::cats-vs-dogs.avi[options="autoplay,nocontrols,loop",preload="metadata"]
|
2557
|
-
EOS
|
2558
|
-
|
2559
|
-
output = convert_string_to_embedded input
|
2560
|
-
assert_css 'video', output, 1
|
2561
|
-
assert_css 'video[autoplay]', output, 1
|
2562
|
-
assert_css 'video:not([controls])', output, 1
|
2563
|
-
assert_css 'video[loop]', output, 1
|
2564
|
-
assert_css 'video[preload=metadata]', output, 1
|
2565
|
-
end
|
2566
|
-
|
2567
|
-
test 'video macro should add time range anchor with start time if start attribute is set' do
|
2568
|
-
input = <<-EOS
|
2569
|
-
video::cats-vs-dogs.avi[start="30"]
|
2570
|
-
EOS
|
2571
|
-
|
2572
|
-
output = convert_string_to_embedded input
|
2573
|
-
assert_css 'video', output, 1
|
2574
|
-
assert_xpath '//video[@src="cats-vs-dogs.avi#t=30"]', output, 1
|
2575
|
-
end
|
2576
|
-
|
2577
|
-
test 'video macro should add time range anchor with end time if end attribute is set' do
|
2578
|
-
input = <<-EOS
|
2579
|
-
video::cats-vs-dogs.avi[end="30"]
|
2580
|
-
EOS
|
2581
|
-
|
2582
|
-
output = convert_string_to_embedded input
|
2583
|
-
assert_css 'video', output, 1
|
2584
|
-
assert_xpath '//video[@src="cats-vs-dogs.avi#t=,30"]', output, 1
|
2585
|
-
end
|
2586
|
-
|
2587
|
-
test 'video macro should add time range anchor with start and end time if start and end attributes are set' do
|
2588
|
-
input = <<-EOS
|
2589
|
-
video::cats-vs-dogs.avi[start="30",end="60"]
|
2590
|
-
EOS
|
2591
|
-
|
2592
|
-
output = convert_string_to_embedded input
|
2593
|
-
assert_css 'video', output, 1
|
2594
|
-
assert_xpath '//video[@src="cats-vs-dogs.avi#t=30,60"]', output, 1
|
2595
|
-
end
|
2596
|
-
|
2597
|
-
test 'video macro should use imagesdir attribute to resolve target and poster' do
|
2598
|
-
input = <<-EOS
|
2599
|
-
:imagesdir: assets
|
2600
|
-
|
2601
|
-
video::cats-vs-dogs.avi[cats-and-dogs.png, 200, 300]
|
2602
|
-
EOS
|
2603
|
-
|
2604
|
-
output = convert_string_to_embedded input
|
2605
|
-
assert_css 'video', output, 1
|
2606
|
-
assert_css 'video[src="assets/cats-vs-dogs.avi"]', output, 1
|
2607
|
-
assert_css 'video[poster="assets/cats-and-dogs.png"]', output, 1
|
2608
|
-
assert_css 'video[width="200"]', output, 1
|
2609
|
-
assert_css 'video[height="300"]', output, 1
|
2610
|
-
end
|
2611
|
-
|
2612
|
-
test 'video macro should not use imagesdir attribute to resolve target if target is a URL' do
|
2613
|
-
input = <<-EOS
|
2614
|
-
:imagesdir: assets
|
2615
|
-
|
2616
|
-
video::http://example.org/videos/cats-vs-dogs.avi[]
|
2617
|
-
EOS
|
2618
|
-
|
2619
|
-
output = convert_string_to_embedded input
|
2620
|
-
assert_css 'video', output, 1
|
2621
|
-
assert_css 'video[src="http://example.org/videos/cats-vs-dogs.avi"]', output, 1
|
2622
|
-
end
|
2623
|
-
|
2624
|
-
test 'video macro should output custom HTML with iframe for vimeo service' do
|
2625
|
-
input = <<-EOS
|
2626
|
-
video::67480300[vimeo, 400, 300, start=60, options=autoplay]
|
2627
|
-
EOS
|
2628
|
-
output = convert_string_to_embedded input
|
2629
|
-
assert_css 'video', output, 0
|
2630
|
-
assert_css 'iframe', output, 1
|
2631
|
-
assert_css 'iframe[src="https://player.vimeo.com/video/67480300#at=60?autoplay=1"]', output, 1
|
2632
|
-
assert_css 'iframe[width="400"]', output, 1
|
2633
|
-
assert_css 'iframe[height="300"]', output, 1
|
2634
|
-
end
|
2635
|
-
|
2636
|
-
test 'video macro should output custom HTML with iframe for youtube service' do
|
2637
|
-
input = <<-EOS
|
2638
|
-
video::U8GBXvdmHT4/PLg7s6cbtAD15Das5LK9mXt_g59DLWxKUe[youtube, 640, 360, start=60, options="autoplay,modest", theme=light]
|
2639
|
-
EOS
|
2640
|
-
output = convert_string_to_embedded input
|
2641
|
-
assert_css 'video', output, 0
|
2642
|
-
assert_css 'iframe', output, 1
|
2643
|
-
assert_css 'iframe[src="https://www.youtube.com/embed/U8GBXvdmHT4?rel=0&start=60&autoplay=1&list=PLg7s6cbtAD15Das5LK9mXt_g59DLWxKUe&modestbranding=1&theme=light"]', output, 1
|
2644
|
-
assert_css 'iframe[width="640"]', output, 1
|
2645
|
-
assert_css 'iframe[height="360"]', output, 1
|
2646
|
-
end
|
2647
|
-
|
2648
|
-
test 'video macro should output custom HTML with iframe for youtube service with dynamic playlist' do
|
2649
|
-
input = <<-EOS
|
2650
|
-
video::SCZF6I-Rc4I,AsKGOeonbIs,HwrPhOp6-aM[youtube, 640, 360, start=60, options=autoplay]
|
2651
|
-
EOS
|
2652
|
-
output = convert_string_to_embedded input
|
2653
|
-
assert_css 'video', output, 0
|
2654
|
-
assert_css 'iframe', output, 1
|
2655
|
-
assert_css 'iframe[src="https://www.youtube.com/embed/SCZF6I-Rc4I?rel=0&start=60&autoplay=1&playlist=AsKGOeonbIs,HwrPhOp6-aM"]', output, 1
|
2656
|
-
assert_css 'iframe[width="640"]', output, 1
|
2657
|
-
assert_css 'iframe[height="360"]', output, 1
|
2658
|
-
end
|
2659
|
-
|
2660
|
-
test 'should detect and convert audio macro' do
|
2661
|
-
input = <<-EOS
|
2662
|
-
audio::podcast.mp3[]
|
2663
|
-
EOS
|
2664
|
-
|
2665
|
-
output = convert_string_to_embedded input
|
2666
|
-
assert_css 'audio', output, 1
|
2667
|
-
assert_css 'audio[src="podcast.mp3"]', output, 1
|
2668
|
-
end
|
2669
|
-
|
2670
|
-
test 'audio macro should use imagesdir attribute to resolve target' do
|
2671
|
-
input = <<-EOS
|
2672
|
-
:imagesdir: assets
|
2673
|
-
|
2674
|
-
audio::podcast.mp3[]
|
2675
|
-
EOS
|
2676
|
-
|
2677
|
-
output = convert_string_to_embedded input
|
2678
|
-
assert_css 'audio', output, 1
|
2679
|
-
assert_css 'audio[src="assets/podcast.mp3"]', output, 1
|
2680
|
-
end
|
2681
|
-
|
2682
|
-
test 'audio macro should not use imagesdir attribute to resolve target if target is a URL' do
|
2683
|
-
input = <<-EOS
|
2684
|
-
:imagesdir: assets
|
2685
|
-
|
2686
|
-
video::http://example.org/podcast.mp3[]
|
2687
|
-
EOS
|
2688
|
-
|
2689
|
-
output = convert_string_to_embedded input
|
2690
|
-
assert_css 'video', output, 1
|
2691
|
-
assert_css 'video[src="http://example.org/podcast.mp3"]', output, 1
|
2692
|
-
end
|
2693
|
-
|
2694
|
-
test 'audio macro should honor all options' do
|
2695
|
-
input = <<-EOS
|
2696
|
-
audio::podcast.mp3[options="autoplay,nocontrols,loop"]
|
2697
|
-
EOS
|
2698
|
-
|
2699
|
-
output = convert_string_to_embedded input
|
2700
|
-
assert_css 'audio', output, 1
|
2701
|
-
assert_css 'audio[autoplay]', output, 1
|
2702
|
-
assert_css 'audio:not([controls])', output, 1
|
2703
|
-
assert_css 'audio[loop]', output, 1
|
2704
|
-
end
|
2705
|
-
|
2706
|
-
test 'audio macro should support start and end time' do
|
2707
|
-
input = <<-EOS
|
2708
|
-
audio::podcast.mp3[start=1,end=2]
|
2709
|
-
EOS
|
2710
|
-
|
2711
|
-
output = convert_string_to_embedded input
|
2712
|
-
assert_css 'audio', output, 1
|
2713
|
-
assert_css 'audio[controls]', output, 1
|
2714
|
-
assert_css 'audio[src="podcast.mp3#t=1,2"]', output, 1
|
2715
|
-
end
|
2716
|
-
end
|
2717
|
-
|
2718
|
-
context 'Admonition icons' do
|
2719
|
-
test 'can resolve icon relative to default iconsdir' do
|
2720
|
-
input = <<-EOS
|
2721
|
-
:icons:
|
2722
|
-
|
2723
|
-
[TIP]
|
2724
|
-
You can use icons for admonitions by setting the 'icons' attribute.
|
2725
|
-
EOS
|
2726
|
-
|
2727
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SERVER
|
2728
|
-
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="./images/icons/tip.png"][@alt="Tip"]', output, 1
|
2729
|
-
end
|
2730
|
-
|
2731
|
-
test 'can resolve icon relative to custom iconsdir' do
|
2732
|
-
input = <<-EOS
|
2733
|
-
:icons:
|
2734
|
-
:iconsdir: icons
|
2735
|
-
|
2736
|
-
[TIP]
|
2737
|
-
You can use icons for admonitions by setting the 'icons' attribute.
|
2738
|
-
EOS
|
2739
|
-
|
2740
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SERVER
|
2741
|
-
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="icons/tip.png"][@alt="Tip"]', output, 1
|
2742
|
-
end
|
2743
|
-
|
2744
|
-
test 'should add file extension to custom icon if not specified' do
|
2745
|
-
input = <<-EOS
|
2746
|
-
:icons: font
|
2747
|
-
:iconsdir: images/icons
|
2748
|
-
|
2749
|
-
[TIP,icon=a]
|
2750
|
-
Override the icon of an admonition block using an attribute
|
2751
|
-
EOS
|
2752
|
-
|
2753
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SERVER
|
2754
|
-
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="images/icons/a.png"]', output, 1
|
2755
|
-
end
|
2756
|
-
|
2757
|
-
test 'embeds base64-encoded data uri of icon when data-uri attribute is set and safe mode level is less than SECURE' do
|
2758
|
-
input = <<-EOS
|
2759
|
-
:icons:
|
2760
|
-
:iconsdir: fixtures
|
2761
|
-
:icontype: gif
|
2762
|
-
:data-uri:
|
2763
|
-
|
2764
|
-
[TIP]
|
2765
|
-
You can use icons for admonitions by setting the 'icons' attribute.
|
2766
|
-
EOS
|
2767
|
-
|
2768
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'docdir' => testdir }
|
2769
|
-
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
|
2770
|
-
end
|
2771
|
-
|
2772
|
-
test 'should embed base64-encoded data uri of custom icon when data-uri attribute is set' do
|
2773
|
-
input = <<-EOS
|
2774
|
-
:icons:
|
2775
|
-
:iconsdir: fixtures
|
2776
|
-
:icontype: gif
|
2777
|
-
:data-uri:
|
2778
|
-
|
2779
|
-
[TIP,icon=tip]
|
2780
|
-
You can set a custom icon using the icon attribute on the block.
|
2781
|
-
EOS
|
2782
|
-
|
2783
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'docdir' => testdir }
|
2784
|
-
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
|
2785
|
-
end
|
2786
|
-
|
2787
|
-
test 'does not embed base64-encoded data uri of icon when safe mode level is SECURE or greater' do
|
2788
|
-
input = <<-EOS
|
2789
|
-
:icons:
|
2790
|
-
:iconsdir: fixtures
|
2791
|
-
:icontype: gif
|
2792
|
-
:data-uri:
|
2793
|
-
|
2794
|
-
[TIP]
|
2795
|
-
You can use icons for admonitions by setting the 'icons' attribute.
|
2796
|
-
EOS
|
2797
|
-
|
2798
|
-
output = convert_string input, :attributes => {'icons' => ''}
|
2799
|
-
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="fixtures/tip.gif"][@alt="Tip"]', output, 1
|
2800
|
-
end
|
2801
|
-
|
2802
|
-
test 'cleans reference to ancestor directories before reading icon if safe mode level is at least SAFE' do
|
2803
|
-
input = <<-EOS
|
2804
|
-
:icons:
|
2805
|
-
:iconsdir: ../fixtures
|
2806
|
-
:icontype: gif
|
2807
|
-
:data-uri:
|
2808
|
-
|
2809
|
-
[TIP]
|
2810
|
-
You can use icons for admonitions by setting the 'icons' attribute.
|
2811
|
-
EOS
|
2812
|
-
|
2813
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'docdir' => testdir }
|
2814
|
-
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
|
2815
|
-
assert_message @logger, :WARN, 'image has illegal reference to ancestor of jail; recovering automatically'
|
2816
|
-
end
|
2817
|
-
|
2818
|
-
test 'should import Font Awesome and use font-based icons when value of icons attribute is font' do
|
2819
|
-
input = <<-EOS
|
2820
|
-
:icons: font
|
2821
|
-
|
2822
|
-
[TIP]
|
2823
|
-
You can use icons for admonitions by setting the 'icons' attribute.
|
2824
|
-
EOS
|
2825
|
-
|
2826
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SERVER
|
2827
|
-
assert_css %(html > head > link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/#{Asciidoctor::FONT_AWESOME_VERSION}/css/font-awesome.min.css"]), output, 1
|
2828
|
-
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/i[@class="fa icon-tip"]', output, 1
|
2829
|
-
end
|
2830
|
-
|
2831
|
-
test 'font-based icon should not override icon specified on admonition' do
|
2832
|
-
input = <<-EOS
|
2833
|
-
:icons: font
|
2834
|
-
:iconsdir: images/icons
|
2835
|
-
|
2836
|
-
[TIP,icon=a.png]
|
2837
|
-
Override the icon of an admonition block using an attribute
|
2838
|
-
EOS
|
2839
|
-
|
2840
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SERVER
|
2841
|
-
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/i[@class="fa icon-tip"]', output, 0
|
2842
|
-
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="images/icons/a.png"]', output, 1
|
2843
|
-
end
|
2844
|
-
|
2845
|
-
test 'should use http uri scheme for assets when asset-uri-scheme is http' do
|
2846
|
-
input = <<-EOS
|
2847
|
-
:asset-uri-scheme: http
|
2848
|
-
:icons: font
|
2849
|
-
:source-highlighter: highlightjs
|
2850
|
-
|
2851
|
-
TIP: You can control the URI scheme used for assets with the asset-uri-scheme attribute
|
2852
|
-
|
2853
|
-
[source,ruby]
|
2854
|
-
puts "AsciiDoc, FTW!"
|
2855
|
-
EOS
|
2856
|
-
|
2857
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE
|
2858
|
-
assert_css %(html > head > link[rel="stylesheet"][href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/#{Asciidoctor::FONT_AWESOME_VERSION}/css/font-awesome.min.css"]), output, 1
|
2859
|
-
assert_css 'html > body > script[src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js"]', output, 1
|
2860
|
-
end
|
2861
|
-
|
2862
|
-
test 'should use no uri scheme for assets when asset-uri-scheme is blank' do
|
2863
|
-
input = <<-EOS
|
2864
|
-
:asset-uri-scheme:
|
2865
|
-
:icons: font
|
2866
|
-
:source-highlighter: highlightjs
|
2867
|
-
|
2868
|
-
TIP: You can control the URI scheme used for assets with the asset-uri-scheme attribute
|
2869
|
-
|
2870
|
-
[source,ruby]
|
2871
|
-
puts "AsciiDoc, FTW!"
|
2872
|
-
EOS
|
2873
|
-
|
2874
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE
|
2875
|
-
assert_css %(html > head > link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/#{Asciidoctor::FONT_AWESOME_VERSION}/css/font-awesome.min.css"]), output, 1
|
2876
|
-
assert_css 'html > body > script[src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js"]', output, 1
|
2877
|
-
end
|
2878
|
-
end
|
2879
|
-
|
2880
|
-
context 'Image paths' do
|
2881
|
-
test 'restricts access to ancestor directories when safe mode level is at least SAFE' do
|
2882
|
-
input = <<-EOS
|
2883
|
-
image::asciidoctor.png[Asciidoctor]
|
2884
|
-
EOS
|
2885
|
-
basedir = testdir
|
2886
|
-
block = block_from_string input, :attributes => {'docdir' => basedir}
|
2887
|
-
doc = block.document
|
2888
|
-
assert doc.safe >= Asciidoctor::SafeMode::SAFE
|
2889
|
-
|
2890
|
-
assert_equal File.join(basedir, 'images'), block.normalize_asset_path('images')
|
2891
|
-
assert_equal File.join(basedir, 'etc/images'), block.normalize_asset_path("#{disk_root}etc/images")
|
2892
|
-
assert_equal File.join(basedir, 'images'), block.normalize_asset_path('../../images')
|
2893
|
-
end
|
2894
|
-
|
2895
|
-
test 'does not restrict access to ancestor directories when safe mode is disabled' do
|
2896
|
-
input = <<-EOS
|
2897
|
-
image::asciidoctor.png[Asciidoctor]
|
2898
|
-
EOS
|
2899
|
-
basedir = testdir
|
2900
|
-
block = block_from_string input, :safe => Asciidoctor::SafeMode::UNSAFE, :attributes => {'docdir' => basedir}
|
2901
|
-
doc = block.document
|
2902
|
-
assert doc.safe == Asciidoctor::SafeMode::UNSAFE
|
2903
|
-
|
2904
|
-
assert_equal File.join(basedir, 'images'), block.normalize_asset_path('images')
|
2905
|
-
absolute_path = "#{disk_root}etc/images"
|
2906
|
-
assert_equal absolute_path, block.normalize_asset_path(absolute_path)
|
2907
|
-
assert_equal File.expand_path(File.join(basedir, '../../images')), block.normalize_asset_path('../../images')
|
2908
|
-
end
|
2909
|
-
|
2910
|
-
end
|
2911
|
-
|
2912
|
-
context 'Source code' do
|
2913
|
-
test 'should support fenced code block using backticks' do
|
2914
|
-
input = <<-EOS
|
2915
|
-
```
|
2916
|
-
puts "Hello, World!"
|
2917
|
-
```
|
2918
|
-
EOS
|
2919
|
-
|
2920
|
-
output = convert_string_to_embedded input
|
2921
|
-
assert_css '.listingblock', output, 1
|
2922
|
-
assert_css '.listingblock pre code', output, 1
|
2923
|
-
assert_css '.listingblock pre code:not([class])', output, 1
|
2924
|
-
end
|
2925
|
-
|
2926
|
-
test 'should not recognize fenced code blocks with more than three delimiters' do
|
2927
|
-
input = <<-EOS
|
2928
|
-
````ruby
|
2929
|
-
puts "Hello, World!"
|
2930
|
-
````
|
2931
|
-
|
2932
|
-
~~~~ javascript
|
2933
|
-
alert("Hello, World!")
|
2934
|
-
~~~~
|
2935
|
-
EOS
|
2936
|
-
|
2937
|
-
output = convert_string_to_embedded input
|
2938
|
-
assert_css '.listingblock', output, 0
|
2939
|
-
end
|
2940
|
-
|
2941
|
-
test 'should support fenced code blocks with languages' do
|
2942
|
-
input = <<-EOS
|
2943
|
-
```ruby
|
2944
|
-
puts "Hello, World!"
|
2945
|
-
```
|
2946
|
-
|
2947
|
-
``` javascript
|
2948
|
-
alert("Hello, World!")
|
2949
|
-
```
|
2950
|
-
EOS
|
2951
|
-
|
2952
|
-
output = convert_string_to_embedded input
|
2953
|
-
assert_css '.listingblock', output, 2
|
2954
|
-
assert_css '.listingblock pre code.language-ruby[data-lang=ruby]', output, 1
|
2955
|
-
assert_css '.listingblock pre code.language-javascript[data-lang=javascript]', output, 1
|
2956
|
-
end
|
2957
|
-
|
2958
|
-
test 'should support fenced code blocks with languages and numbering' do
|
2959
|
-
input = <<-EOS
|
2960
|
-
```ruby,numbered
|
2961
|
-
puts "Hello, World!"
|
2962
|
-
```
|
2963
|
-
|
2964
|
-
``` javascript, numbered
|
2965
|
-
alert("Hello, World!")
|
2966
|
-
```
|
2967
|
-
EOS
|
2968
|
-
|
2969
|
-
output = convert_string_to_embedded input
|
2970
|
-
assert_css '.listingblock', output, 2
|
2971
|
-
assert_css '.listingblock pre code.language-ruby[data-lang=ruby]', output, 1
|
2972
|
-
assert_css '.listingblock pre code.language-javascript[data-lang=javascript]', output, 1
|
2973
|
-
end
|
2974
|
-
|
2975
|
-
test 'should highlight source if source-highlighter attribute is coderay' do
|
2976
|
-
input = <<-EOS
|
2977
|
-
:source-highlighter: coderay
|
2978
|
-
|
2979
|
-
[source, ruby]
|
2980
|
-
----
|
2981
|
-
require 'coderay'
|
2982
|
-
|
2983
|
-
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
2984
|
-
----
|
2985
|
-
EOS
|
2986
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE, :linkcss_default => true
|
2987
|
-
assert_xpath '//pre[@class="CodeRay highlight"]/code[@data-lang="ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
|
2988
|
-
assert_match(/\.CodeRay *\{/, output)
|
2989
|
-
end
|
2990
|
-
|
2991
|
-
test 'should number lines if third positional attribute is set' do
|
2992
|
-
input = <<-EOS
|
2993
|
-
:source-highlighter: coderay
|
2994
|
-
|
2995
|
-
[source,ruby,linenums]
|
2996
|
-
----
|
2997
|
-
puts 'Hello, World!'
|
2998
|
-
----
|
2999
|
-
EOS
|
3000
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SAFE
|
3001
|
-
assert_xpath '//td[@class="line-numbers"]', output, 1
|
3002
|
-
end
|
3003
|
-
|
3004
|
-
test 'should number lines if linenums option is set on source block' do
|
3005
|
-
input = <<-EOS
|
3006
|
-
:source-highlighter: coderay
|
3007
|
-
|
3008
|
-
[source%linenums,ruby]
|
3009
|
-
----
|
3010
|
-
puts 'Hello, World!'
|
3011
|
-
----
|
3012
|
-
EOS
|
3013
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SAFE
|
3014
|
-
assert_xpath '//td[@class="line-numbers"]', output, 1
|
3015
|
-
end
|
3016
|
-
|
3017
|
-
test 'should number lines of source block if source-linenums-option document attribute is set' do
|
3018
|
-
input = <<-EOS
|
3019
|
-
:source-highlighter: coderay
|
3020
|
-
:source-linenums-option:
|
3021
|
-
|
3022
|
-
[source,ruby]
|
3023
|
-
----
|
3024
|
-
puts 'Hello, World!'
|
3025
|
-
----
|
3026
|
-
EOS
|
3027
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SAFE
|
3028
|
-
assert_xpath '//td[@class="line-numbers"]', output, 1
|
3029
|
-
end
|
3030
|
-
|
3031
|
-
test 'should set starting line number in HTML output if linenums option is enabled and start attribute is set' do
|
3032
|
-
input = <<-EOS
|
3033
|
-
:source-highlighter: coderay
|
3034
|
-
:coderay-linenums-mode: inline
|
3035
|
-
|
3036
|
-
[source%linenums,ruby,start=10]
|
3037
|
-
----
|
3038
|
-
puts 'Hello, World!'
|
3039
|
-
----
|
3040
|
-
EOS
|
3041
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SAFE
|
3042
|
-
assert_xpath '//span[@class="line-numbers"]', output, 1
|
3043
|
-
assert_xpath '//span[@class="line-numbers"][text()="10"]', output, 1
|
3044
|
-
end
|
3045
|
-
|
3046
|
-
test 'should set starting line number in DocBook output if linenums option is enabled and start attribute is set' do
|
3047
|
-
input = <<-EOS
|
3048
|
-
[source%linenums,java,start=3]
|
3049
|
-
----
|
3050
|
-
public class HelloWorld {
|
3051
|
-
public static void main(String[] args) {
|
3052
|
-
out.println("Hello, World!");
|
3053
|
-
}
|
3054
|
-
}
|
3055
|
-
----
|
3056
|
-
EOS
|
3057
|
-
|
3058
|
-
output = convert_string_to_embedded input, :backend => :docbook, :safe => Asciidoctor::SafeMode::SAFE
|
3059
|
-
assert_css 'programlisting[startinglinenumber]', output, 1
|
3060
|
-
assert_css 'programlisting[startinglinenumber="3"]', output, 1
|
3061
|
-
end
|
3062
|
-
|
3063
|
-
test 'should highlight lines specified in highlight attribute if linenums is set and source-highlighter is coderay' do
|
3064
|
-
%w(highlight="1,4-6" highlight=1;4..6 highlight=1;4..;!7).each do |highlight_attr|
|
3065
|
-
input = <<-EOS
|
3066
|
-
:source-highlighter: coderay
|
3067
|
-
|
3068
|
-
[source%linenums,java,#{highlight_attr}]
|
3069
|
-
----
|
3070
|
-
import static java.lang.System.out;
|
3071
|
-
|
3072
|
-
public class HelloWorld {
|
3073
|
-
public static void main(String[] args) {
|
3074
|
-
out.println("Hello, World!");
|
3075
|
-
}
|
3076
|
-
}
|
3077
|
-
----
|
3078
|
-
EOS
|
3079
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SAFE
|
3080
|
-
assert_css 'strong.highlighted', output, 4
|
3081
|
-
assert_xpath '//strong[@class="highlighted"][text()="1"]', output, 1
|
3082
|
-
assert_xpath '//strong[@class="highlighted"][text()="2"]', output, 0
|
3083
|
-
assert_xpath '//strong[@class="highlighted"][text()="3"]', output, 0
|
3084
|
-
assert_xpath '//strong[@class="highlighted"][text()="4"]', output, 1
|
3085
|
-
assert_xpath '//strong[@class="highlighted"][text()="5"]', output, 1
|
3086
|
-
assert_xpath '//strong[@class="highlighted"][text()="6"]', output, 1
|
3087
|
-
assert_xpath '//strong[@class="highlighted"][text()="7"]', output, 0
|
3088
|
-
end
|
3089
|
-
end
|
3090
|
-
|
3091
|
-
test 'should read source language from source-language document attribute if not specified on source block' do
|
3092
|
-
input = <<-EOS
|
3093
|
-
:source-highlighter: coderay
|
3094
|
-
:source-language: ruby
|
3095
|
-
|
3096
|
-
[source]
|
3097
|
-
----
|
3098
|
-
require 'coderay'
|
3099
|
-
|
3100
|
-
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
3101
|
-
----
|
3102
|
-
EOS
|
3103
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SAFE, :linkcss_default => true
|
3104
|
-
assert_xpath '//pre[@class="CodeRay highlight"]/code[@data-lang="ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
|
3105
|
-
end
|
3106
|
-
|
3107
|
-
test 'should rename document attribute named language to source-language when compat-mode is enabled' do
|
3108
|
-
input = <<-EOS
|
3109
|
-
:language: ruby
|
3110
|
-
|
3111
|
-
{source-language}
|
3112
|
-
EOS
|
3113
|
-
|
3114
|
-
assert_equal 'ruby', (convert_inline_string input, :attributes => {'compat-mode' => ''})
|
3115
|
-
|
3116
|
-
input = <<-EOS
|
3117
|
-
:language: ruby
|
3118
|
-
|
3119
|
-
{source-language}
|
3120
|
-
EOS
|
3121
|
-
|
3122
|
-
assert_equal '{source-language}', (convert_inline_string input)
|
3123
|
-
end
|
3124
|
-
|
3125
|
-
test 'should replace callout marks but not highlight them if source-highlighter attribute is coderay' do
|
3126
|
-
input = <<-EOS
|
3127
|
-
:source-highlighter: coderay
|
3128
|
-
|
3129
|
-
[source, ruby]
|
3130
|
-
----
|
3131
|
-
require 'coderay' # <1>
|
3132
|
-
|
3133
|
-
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table) # <2>
|
3134
|
-
puts html # <3> <4>
|
3135
|
-
exit 0 # <5><6>
|
3136
|
-
----
|
3137
|
-
<1> Load library
|
3138
|
-
<2> Highlight source
|
3139
|
-
<3> Print to stdout
|
3140
|
-
<4> Redirect to a file to capture output
|
3141
|
-
<5> Exit program
|
3142
|
-
<6> Reports success
|
3143
|
-
EOS
|
3144
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SAFE
|
3145
|
-
assert_match(/<span class="content">coderay<\/span>.* # <b class="conum">\(1\)<\/b>$/, output)
|
3146
|
-
assert_match(/<span class="content">puts 'Hello, world!'<\/span>.* # <b class="conum">\(2\)<\/b>$/, output)
|
3147
|
-
assert_match(/puts html.* # <b class="conum">\(3\)<\/b> <b class="conum">\(4\)<\/b>$/, output)
|
3148
|
-
assert_match(/exit.* # <b class="conum">\(5\)<\/b> <b class="conum">\(6\)<\/b><\/code>/, output)
|
3149
|
-
end
|
3150
|
-
|
3151
|
-
test 'should support autonumbered callout marks if source-highlighter attribute is coderay' do
|
3152
|
-
input = <<-EOS
|
3153
|
-
:source-highlighter: coderay
|
3154
|
-
|
3155
|
-
[source, ruby]
|
3156
|
-
----
|
3157
|
-
require 'coderay' # <.><.>
|
3158
|
-
|
3159
|
-
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table) # <.>
|
3160
|
-
puts html # <.>
|
3161
|
-
----
|
3162
|
-
<.> Load library
|
3163
|
-
<.> Gem must be installed
|
3164
|
-
<.> Highlight source
|
3165
|
-
<.> Print to stdout
|
3166
|
-
EOS
|
3167
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SAFE
|
3168
|
-
assert_match(/<span class="content">coderay<\/span>.* # <b class="conum">\(1\)<\/b> <b class="conum">\(2\)<\/b>$/, output)
|
3169
|
-
assert_match(/<span class="content">puts 'Hello, world!'<\/span>.* # <b class="conum">\(3\)<\/b>$/, output)
|
3170
|
-
assert_match(/puts html.* # <b class="conum">\(4\)<\/b><\/code>/, output)
|
3171
|
-
assert_css '.colist ol', output, 1
|
3172
|
-
assert_css '.colist ol li', output, 4
|
3173
|
-
end
|
3174
|
-
|
3175
|
-
test 'should restore callout marks to correct lines if source highlighter is coderay and table line numbering is enabled' do
|
3176
|
-
input = <<-EOS
|
3177
|
-
:source-highlighter: coderay
|
3178
|
-
:coderay-linenums-mode: table
|
3179
|
-
|
3180
|
-
[source, ruby, numbered]
|
3181
|
-
----
|
3182
|
-
require 'coderay' # <1>
|
3183
|
-
|
3184
|
-
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table) # <2>
|
3185
|
-
puts html # <3> <4>
|
3186
|
-
exit 0 # <5><6>
|
3187
|
-
----
|
3188
|
-
<1> Load library
|
3189
|
-
<2> Highlight source
|
3190
|
-
<3> Print to stdout
|
3191
|
-
<4> Redirect to a file to capture output
|
3192
|
-
<5> Exit program
|
3193
|
-
<6> Reports success
|
3194
|
-
EOS
|
3195
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SAFE
|
3196
|
-
assert_match(/<span class="content">coderay<\/span>.* # <b class="conum">\(1\)<\/b>$/, output)
|
3197
|
-
assert_match(/<span class="content">puts 'Hello, world!'<\/span>.* # <b class="conum">\(2\)<\/b>$/, output)
|
3198
|
-
assert_match(/puts html.* # <b class="conum">\(3\)<\/b> <b class="conum">\(4\)<\/b>$/, output)
|
3199
|
-
assert_match(/exit.* # <b class="conum">\(5\)<\/b> <b class="conum">\(6\)<\/b><\/pre>/, output)
|
3200
|
-
end
|
3201
|
-
|
3202
|
-
test 'should preserve space before callout on final line' do
|
3203
|
-
inputs = []
|
3204
|
-
|
3205
|
-
inputs << <<-EOS
|
3206
|
-
[source,yaml]
|
3207
|
-
----
|
3208
|
-
a: 'a'
|
3209
|
-
key: 'value' #<1>
|
3210
|
-
----
|
3211
|
-
<1> key-value pair
|
3212
|
-
EOS
|
3213
|
-
|
3214
|
-
inputs << <<-EOS
|
3215
|
-
[source,ruby]
|
3216
|
-
----
|
3217
|
-
puts 'hi'
|
3218
|
-
puts 'value' #<1>
|
3219
|
-
----
|
3220
|
-
<1> print to stdout
|
3221
|
-
EOS
|
3222
|
-
|
3223
|
-
inputs << <<-EOS
|
3224
|
-
[source,python]
|
3225
|
-
----
|
3226
|
-
print 'hi'
|
3227
|
-
print 'value' #<1>
|
3228
|
-
----
|
3229
|
-
<1> print to stdout
|
3230
|
-
EOS
|
3231
|
-
|
3232
|
-
inputs.each do |input|
|
3233
|
-
output = convert_string_to_embedded input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'source-highlighter' => 'coderay' }
|
3234
|
-
output = output.gsub(/<\/?span.*?>/, '')
|
3235
|
-
assert_includes output, '\'value\' #<b class="conum">(1)</b>'
|
3236
|
-
end
|
3237
|
-
end
|
3238
|
-
|
3239
|
-
test 'should preserve passthrough placeholders when highlighting source using coderay' do
|
3240
|
-
input = <<-EOS
|
3241
|
-
:source-highlighter: coderay
|
3242
|
-
|
3243
|
-
[source,java]
|
3244
|
-
[subs="specialcharacters,macros,callouts"]
|
3245
|
-
----
|
3246
|
-
public class Printer {
|
3247
|
-
public static void main(String[] args) {
|
3248
|
-
System.pass:quotes[_out_].println("*asterisks* make text pass:quotes[*bold*]");
|
3249
|
-
}
|
3250
|
-
}
|
3251
|
-
----
|
3252
|
-
EOS
|
3253
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE
|
3254
|
-
assert_match(/\.<em>out<\/em>\./, output, 1)
|
3255
|
-
assert_match(/\*asterisks\*/, output, 1)
|
3256
|
-
assert_match(/<strong>bold<\/strong>/, output, 1)
|
3257
|
-
refute_includes output, Asciidoctor::Substitutors::PASS_START
|
3258
|
-
end
|
3259
|
-
|
3260
|
-
test 'should link to CodeRay stylesheet if source-highlighter is coderay and linkcss is set' do
|
3261
|
-
input = <<-EOS
|
3262
|
-
:source-highlighter: coderay
|
3263
|
-
|
3264
|
-
[source, ruby]
|
3265
|
-
----
|
3266
|
-
require 'coderay'
|
3267
|
-
|
3268
|
-
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
3269
|
-
----
|
3270
|
-
EOS
|
3271
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss' => ''}
|
3272
|
-
assert_xpath '//pre[@class="CodeRay highlight"]/code[@data-lang="ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
|
3273
|
-
assert_css 'link[rel="stylesheet"][href="./coderay-asciidoctor.css"]', output, 1
|
3274
|
-
end
|
3275
|
-
|
3276
|
-
test 'should highlight source inline if source-highlighter attribute is coderay and coderay-css is style' do
|
3277
|
-
input = <<-EOS
|
3278
|
-
:source-highlighter: coderay
|
3279
|
-
:coderay-css: style
|
3280
|
-
|
3281
|
-
[source, ruby]
|
3282
|
-
----
|
3283
|
-
require 'coderay'
|
3284
|
-
|
3285
|
-
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
3286
|
-
----
|
3287
|
-
EOS
|
3288
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE, :linkcss_default => true
|
3289
|
-
assert_xpath '//pre[@class="CodeRay highlight"]/code[@data-lang="ruby"]//span[@style = "color:#036;font-weight:bold"][text() = "CodeRay"]', output, 1
|
3290
|
-
refute_match(/\.CodeRay \{/, output)
|
3291
|
-
end
|
3292
|
-
|
3293
|
-
test 'should include remote highlight.js assets if source-highlighter attribute is highlightjs' do
|
3294
|
-
input = <<-EOS
|
3295
|
-
:source-highlighter: highlightjs
|
3296
|
-
|
3297
|
-
[source, javascript]
|
3298
|
-
----
|
3299
|
-
<link rel="stylesheet" href="styles/default.css">
|
3300
|
-
<script src="highlight.pack.js"></script>
|
3301
|
-
<script>hljs.initHighlightingOnLoad();</script>
|
3302
|
-
----
|
3303
|
-
EOS
|
3304
|
-
output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE
|
3305
|
-
assert_match(/<link .*highlight\.js/, output)
|
3306
|
-
assert_match(/<script .*highlight\.js/, output)
|
3307
|
-
assert_match(/hljs.initHighlightingOnLoad/, output)
|
3308
|
-
end
|
3309
|
-
|
3310
|
-
test 'should add language classes to child code element when source-highlighter is prettify' do
|
3311
|
-
input = <<-EOS
|
3312
|
-
[source,ruby]
|
3313
|
-
----
|
3314
|
-
puts "foo"
|
3315
|
-
----
|
3316
|
-
EOS
|
3317
|
-
|
3318
|
-
output = convert_string_to_embedded input, :attributes => {'source-highlighter' => 'prettify'}
|
3319
|
-
assert_css 'pre[class="prettyprint highlight"]', output, 1
|
3320
|
-
assert_css 'pre > code.language-ruby[data-lang="ruby"]', output, 1
|
3321
|
-
end
|
3322
|
-
|
3323
|
-
test 'should set lang attribute on pre when source-highlighter is html-pipeline' do
|
3324
|
-
input = <<-EOS
|
3325
|
-
[source,ruby]
|
3326
|
-
----
|
3327
|
-
filters = [
|
3328
|
-
HTML::Pipeline::AsciiDocFilter,
|
3329
|
-
HTML::Pipeline::SanitizationFilter,
|
3330
|
-
HTML::Pipeline::SyntaxHighlightFilter
|
3331
|
-
]
|
3332
|
-
|
3333
|
-
puts HTML::Pipeline.new(filters, {}).call(input)[:output]
|
3334
|
-
----
|
3335
|
-
EOS
|
3336
|
-
|
3337
|
-
output = convert_string input, :attributes => {'source-highlighter' => 'html-pipeline'}
|
3338
|
-
assert_css 'pre[lang="ruby"]', output, 1
|
3339
|
-
assert_css 'pre[lang="ruby"] > code', output, 1
|
3340
|
-
assert_css 'pre[class]', output, 0
|
3341
|
-
assert_css 'code[class]', output, 0
|
3342
|
-
end
|
3343
|
-
|
3344
|
-
test 'document cannot turn on source highlighting if safe mode is at least SERVER' do
|
3345
|
-
input = <<-EOS
|
3346
|
-
:source-highlighter: coderay
|
3347
|
-
EOS
|
3348
|
-
doc = document_from_string input, :safe => Asciidoctor::SafeMode::SERVER
|
3349
|
-
assert_nil doc.attributes['source-highlighter']
|
3350
|
-
end
|
3351
|
-
|
3352
|
-
test 'should warn if listing block is not terminated' do
|
3353
|
-
input = <<-EOS
|
3354
|
-
outside
|
3355
|
-
|
3356
|
-
----
|
3357
|
-
inside
|
3358
|
-
|
3359
|
-
still inside
|
3360
|
-
|
3361
|
-
eof
|
3362
|
-
EOS
|
3363
|
-
|
3364
|
-
output = convert_string_to_embedded input
|
3365
|
-
assert_xpath '/*[@class="listingblock"]', output, 1
|
3366
|
-
assert_message @logger, :WARN, '<stdin>: line 3: unterminated listing block', Hash
|
3367
|
-
end
|
3368
|
-
end
|
3369
|
-
|
3370
|
-
context 'Abstract and Part Intro' do
|
3371
|
-
test 'should make abstract on open block without title a quote block for article' do
|
3372
|
-
input = <<-EOS
|
3373
|
-
= Article
|
3374
|
-
|
3375
|
-
[abstract]
|
3376
|
-
--
|
3377
|
-
This article is about stuff.
|
3378
|
-
|
3379
|
-
And other stuff.
|
3380
|
-
--
|
3381
|
-
|
3382
|
-
== Section One
|
3383
|
-
|
3384
|
-
content
|
3385
|
-
EOS
|
3386
|
-
|
3387
|
-
output = convert_string input
|
3388
|
-
assert_css '.quoteblock', output, 1
|
3389
|
-
assert_css '.quoteblock.abstract', output, 1
|
3390
|
-
assert_css '#preamble .quoteblock', output, 1
|
3391
|
-
assert_css '.quoteblock > blockquote', output, 1
|
3392
|
-
assert_css '.quoteblock > blockquote > .paragraph', output, 2
|
3393
|
-
end
|
3394
|
-
|
3395
|
-
test 'should make abstract on open block with title a quote block with title for article' do
|
3396
|
-
input = <<-EOS
|
3397
|
-
= Article
|
3398
|
-
|
3399
|
-
.My abstract
|
3400
|
-
[abstract]
|
3401
|
-
--
|
3402
|
-
This article is about stuff.
|
3403
|
-
--
|
3404
|
-
|
3405
|
-
== Section One
|
3406
|
-
|
3407
|
-
content
|
3408
|
-
EOS
|
3409
|
-
|
3410
|
-
output = convert_string input
|
3411
|
-
assert_css '.quoteblock', output, 1
|
3412
|
-
assert_css '.quoteblock.abstract', output, 1
|
3413
|
-
assert_css '#preamble .quoteblock', output, 1
|
3414
|
-
assert_css '.quoteblock > .title', output, 1
|
3415
|
-
assert_css '.quoteblock > .title + blockquote', output, 1
|
3416
|
-
assert_css '.quoteblock > .title + blockquote > .paragraph', output, 1
|
3417
|
-
end
|
3418
|
-
|
3419
|
-
test 'should allow abstract in document with title if doctype is book' do
|
3420
|
-
input = <<-EOS
|
3421
|
-
= Book
|
3422
|
-
:doctype: book
|
3423
|
-
|
3424
|
-
[abstract]
|
3425
|
-
Abstract for book with title is valid
|
3426
|
-
EOS
|
3427
|
-
|
3428
|
-
output = convert_string input
|
3429
|
-
assert_css '.abstract', output, 1
|
3430
|
-
end
|
3431
|
-
|
3432
|
-
test 'should not allow abstract as direct child of document if doctype is book' do
|
3433
|
-
input = <<-EOS
|
3434
|
-
:doctype: book
|
3435
|
-
|
3436
|
-
[abstract]
|
3437
|
-
Abstract for book without title is invalid.
|
3438
|
-
EOS
|
3439
|
-
|
3440
|
-
output = convert_string input
|
3441
|
-
assert_css '.abstract', output, 0
|
3442
|
-
assert_message @logger, :WARN, 'abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
|
3443
|
-
end
|
3444
|
-
|
3445
|
-
test 'should make abstract on open block without title converted to DocBook' do
|
3446
|
-
input = <<-EOS
|
3447
|
-
= Article
|
3448
|
-
|
3449
|
-
[abstract]
|
3450
|
-
--
|
3451
|
-
This article is about stuff.
|
3452
|
-
|
3453
|
-
And other stuff.
|
3454
|
-
--
|
3455
|
-
EOS
|
3456
|
-
|
3457
|
-
output = convert_string input, :backend => 'docbook'
|
3458
|
-
assert_css 'abstract', output, 1
|
3459
|
-
assert_css 'abstract > simpara', output, 2
|
3460
|
-
end
|
3461
|
-
|
3462
|
-
test 'should make abstract on open block with title converted to DocBook' do
|
3463
|
-
input = <<-EOS
|
3464
|
-
= Article
|
3465
|
-
|
3466
|
-
.My abstract
|
3467
|
-
[abstract]
|
3468
|
-
--
|
3469
|
-
This article is about stuff.
|
3470
|
-
--
|
3471
|
-
EOS
|
3472
|
-
|
3473
|
-
output = convert_string input, :backend => 'docbook'
|
3474
|
-
assert_css 'abstract', output, 1
|
3475
|
-
assert_css 'abstract > title', output, 1
|
3476
|
-
assert_css 'abstract > title + simpara', output, 1
|
3477
|
-
end
|
3478
|
-
|
3479
|
-
test 'should allow abstract in document with title if doctype is book converted to DocBook' do
|
3480
|
-
input = <<-EOS
|
3481
|
-
= Book
|
3482
|
-
:doctype: book
|
3483
|
-
|
3484
|
-
[abstract]
|
3485
|
-
Abstract for book with title is valid
|
3486
|
-
EOS
|
3487
|
-
|
3488
|
-
output = convert_string input, :backend => 'docbook'
|
3489
|
-
assert_css 'abstract', output, 1
|
3490
|
-
end
|
3491
|
-
|
3492
|
-
test 'should not allow abstract as direct child of document if doctype is book converted to DocBook' do
|
3493
|
-
input = <<-EOS
|
3494
|
-
:doctype: book
|
3495
|
-
|
3496
|
-
[abstract]
|
3497
|
-
Abstract for book is invalid.
|
3498
|
-
EOS
|
3499
|
-
|
3500
|
-
output = convert_string input, :backend => 'docbook'
|
3501
|
-
assert_css 'abstract', output, 0
|
3502
|
-
assert_message @logger, :WARN, 'abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
|
3503
|
-
end
|
3504
|
-
|
3505
|
-
# TODO partintro shouldn't be recognized if doctype is not book, should be in proper place
|
3506
|
-
test 'should accept partintro on open block without title' do
|
3507
|
-
input = <<-EOS
|
3508
|
-
= Book
|
3509
|
-
:doctype: book
|
3510
|
-
|
3511
|
-
= Part 1
|
3512
|
-
|
3513
|
-
[partintro]
|
3514
|
-
--
|
3515
|
-
This is a part intro.
|
3516
|
-
|
3517
|
-
It can have multiple paragraphs.
|
3518
|
-
--
|
3519
|
-
|
3520
|
-
== Chapter 1
|
3521
|
-
|
3522
|
-
content
|
3523
|
-
EOS
|
3524
|
-
|
3525
|
-
output = convert_string input
|
3526
|
-
assert_css '.openblock', output, 1
|
3527
|
-
assert_css '.openblock.partintro', output, 1
|
3528
|
-
assert_css '.openblock .title', output, 0
|
3529
|
-
assert_css '.openblock .content', output, 1
|
3530
|
-
assert_xpath %(//h1[@id="_part_1"]/following-sibling::*[#{contains_class(:openblock)}]), output, 1
|
3531
|
-
assert_xpath %(//*[#{contains_class(:openblock)}]/*[@class="content"]/*[@class="paragraph"]), output, 2
|
3532
|
-
end
|
3533
|
-
|
3534
|
-
test 'should accept partintro on open block with title' do
|
3535
|
-
input = <<-EOS
|
3536
|
-
= Book
|
3537
|
-
:doctype: book
|
3538
|
-
|
3539
|
-
= Part 1
|
3540
|
-
|
3541
|
-
.Intro title
|
3542
|
-
[partintro]
|
3543
|
-
--
|
3544
|
-
This is a part intro with a title.
|
3545
|
-
--
|
3546
|
-
|
3547
|
-
== Chapter 1
|
3548
|
-
|
3549
|
-
content
|
3550
|
-
EOS
|
3551
|
-
|
3552
|
-
output = convert_string input
|
3553
|
-
assert_css '.openblock', output, 1
|
3554
|
-
assert_css '.openblock.partintro', output, 1
|
3555
|
-
assert_css '.openblock .title', output, 1
|
3556
|
-
assert_css '.openblock .content', output, 1
|
3557
|
-
assert_xpath %(//h1[@id="_part_1"]/following-sibling::*[#{contains_class(:openblock)}]), output, 1
|
3558
|
-
assert_xpath %(//*[#{contains_class(:openblock)}]/*[@class="title"][text() = "Intro title"]), output, 1
|
3559
|
-
assert_xpath %(//*[#{contains_class(:openblock)}]/*[@class="content"]/*[@class="paragraph"]), output, 1
|
3560
|
-
end
|
3561
|
-
|
3562
|
-
test 'should exclude partintro if not a child of part' do
|
3563
|
-
input = <<-EOS
|
3564
|
-
= Book
|
3565
|
-
:doctype: book
|
3566
|
-
|
3567
|
-
[partintro]
|
3568
|
-
part intro paragraph
|
3569
|
-
EOS
|
3570
|
-
|
3571
|
-
output = convert_string input
|
3572
|
-
assert_css '.partintro', output, 0
|
3573
|
-
assert_message @logger, :ERROR, 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
3574
|
-
end
|
3575
|
-
|
3576
|
-
test 'should not allow partintro unless doctype is book' do
|
3577
|
-
input = <<-EOS
|
3578
|
-
[partintro]
|
3579
|
-
part intro paragraph
|
3580
|
-
EOS
|
3581
|
-
|
3582
|
-
output = convert_string input
|
3583
|
-
assert_css '.partintro', output, 0
|
3584
|
-
assert_message @logger, :ERROR, 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
3585
|
-
end
|
3586
|
-
|
3587
|
-
test 'should accept partintro on open block without title converted to DocBook' do
|
3588
|
-
input = <<-EOS
|
3589
|
-
= Book
|
3590
|
-
:doctype: book
|
3591
|
-
|
3592
|
-
= Part 1
|
3593
|
-
|
3594
|
-
[partintro]
|
3595
|
-
--
|
3596
|
-
This is a part intro.
|
3597
|
-
|
3598
|
-
It can have multiple paragraphs.
|
3599
|
-
--
|
3600
|
-
|
3601
|
-
== Chapter 1
|
3602
|
-
|
3603
|
-
content
|
3604
|
-
EOS
|
3605
|
-
|
3606
|
-
output = convert_string input, :backend => 'docbook45'
|
3607
|
-
assert_css 'partintro', output, 1
|
3608
|
-
assert_css 'part#_part_1 > partintro', output, 1
|
3609
|
-
assert_css 'partintro > simpara', output, 2
|
3610
|
-
end
|
3611
|
-
|
3612
|
-
test 'should accept partintro on open block with title converted to DocBook' do
|
3613
|
-
input = <<-EOS
|
3614
|
-
= Book
|
3615
|
-
:doctype: book
|
3616
|
-
|
3617
|
-
= Part 1
|
3618
|
-
|
3619
|
-
.Intro title
|
3620
|
-
[partintro]
|
3621
|
-
--
|
3622
|
-
This is a part intro with a title.
|
3623
|
-
--
|
3624
|
-
|
3625
|
-
== Chapter 1
|
3626
|
-
|
3627
|
-
content
|
3628
|
-
EOS
|
3629
|
-
|
3630
|
-
output = convert_string input, :backend => 'docbook45'
|
3631
|
-
assert_css 'partintro', output, 1
|
3632
|
-
assert_css 'part#_part_1 > partintro', output, 1
|
3633
|
-
assert_css 'partintro > title', output, 1
|
3634
|
-
assert_css 'partintro > title + simpara', output, 1
|
3635
|
-
end
|
3636
|
-
|
3637
|
-
test 'should exclude partintro if not a child of part converted to DocBook' do
|
3638
|
-
input = <<-EOS
|
3639
|
-
= Book
|
3640
|
-
:doctype: book
|
3641
|
-
|
3642
|
-
[partintro]
|
3643
|
-
part intro paragraph
|
3644
|
-
EOS
|
3645
|
-
|
3646
|
-
output = convert_string input, :backend => 'docbook'
|
3647
|
-
assert_css 'partintro', output, 0
|
3648
|
-
assert_message @logger, :ERROR, 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
3649
|
-
end
|
3650
|
-
|
3651
|
-
test 'should not allow partintro unless doctype is book converted to DocBook' do
|
3652
|
-
input = <<-EOS
|
3653
|
-
[partintro]
|
3654
|
-
part intro paragraph
|
3655
|
-
EOS
|
3656
|
-
|
3657
|
-
output = convert_string input, :backend => 'docbook'
|
3658
|
-
assert_css 'partintro', output, 0
|
3659
|
-
assert_message @logger, :ERROR, 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
3660
|
-
end
|
3661
|
-
end
|
3662
|
-
|
3663
|
-
context 'Substitutions' do
|
3664
|
-
test 'processor should not crash if subs are empty' do
|
3665
|
-
input = <<-EOS
|
3666
|
-
[subs=","]
|
3667
|
-
....
|
3668
|
-
content
|
3669
|
-
....
|
3670
|
-
EOS
|
3671
|
-
|
3672
|
-
doc = document_from_string input
|
3673
|
-
block = doc.blocks.first
|
3674
|
-
assert_equal [], block.subs
|
3675
|
-
end
|
3676
|
-
|
3677
|
-
test 'should be able to append subs to default block substitution list' do
|
3678
|
-
input = <<-EOS
|
3679
|
-
:application: Asciidoctor
|
3680
|
-
|
3681
|
-
[subs="+attributes,+macros"]
|
3682
|
-
....
|
3683
|
-
{application}
|
3684
|
-
....
|
3685
|
-
EOS
|
3686
|
-
|
3687
|
-
doc = document_from_string input
|
3688
|
-
block = doc.blocks.first
|
3689
|
-
assert_equal [:specialcharacters, :attributes, :macros], block.subs
|
3690
|
-
end
|
3691
|
-
|
3692
|
-
test 'should be able to prepend subs to default block substitution list' do
|
3693
|
-
input = <<-EOS
|
3694
|
-
:application: Asciidoctor
|
3695
|
-
|
3696
|
-
[subs="attributes+"]
|
3697
|
-
....
|
3698
|
-
{application}
|
3699
|
-
....
|
3700
|
-
EOS
|
3701
|
-
|
3702
|
-
doc = document_from_string input
|
3703
|
-
block = doc.blocks.first
|
3704
|
-
assert_equal [:attributes, :specialcharacters], block.subs
|
3705
|
-
end
|
3706
|
-
|
3707
|
-
test 'should be able to remove subs to default block substitution list' do
|
3708
|
-
input = <<-EOS
|
3709
|
-
[subs="-quotes,-replacements"]
|
3710
|
-
content
|
3711
|
-
EOS
|
3712
|
-
|
3713
|
-
doc = document_from_string input
|
3714
|
-
block = doc.blocks.first
|
3715
|
-
assert_equal [:specialcharacters, :attributes, :macros, :post_replacements], block.subs
|
3716
|
-
end
|
3717
|
-
|
3718
|
-
test 'should be able to prepend, append and remove subs from default block substitution list' do
|
3719
|
-
input = <<-EOS
|
3720
|
-
:application: asciidoctor
|
3721
|
-
|
3722
|
-
[subs="attributes+,-verbatim,+specialcharacters,+macros"]
|
3723
|
-
....
|
3724
|
-
https://{application}.org[{gt}{gt}] <1>
|
3725
|
-
....
|
3726
|
-
EOS
|
3727
|
-
|
3728
|
-
doc = document_from_string input, :header_footer => false
|
3729
|
-
block = doc.blocks.first
|
3730
|
-
assert_equal [:attributes, :specialcharacters, :macros], block.subs
|
3731
|
-
result = doc.convert
|
3732
|
-
assert_includes result, '<pre><a href="https://asciidoctor.org">>></a> <1></pre>'
|
3733
|
-
end
|
3734
|
-
|
3735
|
-
test 'should be able to set subs then modify them' do
|
3736
|
-
input = <<-EOS
|
3737
|
-
[subs="verbatim,-callouts"]
|
3738
|
-
_hey now_ <1>
|
3739
|
-
EOS
|
3740
|
-
|
3741
|
-
doc = document_from_string input, :header_footer => false
|
3742
|
-
block = doc.blocks.first
|
3743
|
-
assert_equal [:specialcharacters], block.subs
|
3744
|
-
result = doc.convert
|
3745
|
-
assert_includes result, '_hey now_ <1>'
|
3746
|
-
end
|
3747
|
-
end
|
3748
|
-
|
3749
|
-
context 'References' do
|
3750
|
-
test 'should not recognize block anchor with illegal id characters' do
|
3751
|
-
input = <<-EOS
|
3752
|
-
[[illegal$id,Reference Text]]
|
3753
|
-
----
|
3754
|
-
content
|
3755
|
-
----
|
3756
|
-
EOS
|
3757
|
-
|
3758
|
-
doc = document_from_string input
|
3759
|
-
block = doc.blocks.first
|
3760
|
-
assert_nil block.id
|
3761
|
-
assert_nil(block.attr 'reftext')
|
3762
|
-
refute doc.catalog[:ids].has_key?('illegal$id')
|
3763
|
-
end
|
3764
|
-
|
3765
|
-
test 'should not recognize block anchor that starts with digit' do
|
3766
|
-
input = <<-EOS
|
3767
|
-
[[3-blind-mice]]
|
3768
|
-
--
|
3769
|
-
see how they run
|
3770
|
-
--
|
3771
|
-
EOS
|
3772
|
-
|
3773
|
-
output = convert_string_to_embedded input
|
3774
|
-
assert_includes output, '[[3-blind-mice]]'
|
3775
|
-
assert_xpath '/*[@id = ":3-blind-mice"]', output, 0
|
3776
|
-
end
|
3777
|
-
|
3778
|
-
test 'should recognize block anchor that starts with colon' do
|
3779
|
-
input = <<-EOS
|
3780
|
-
[[:idname]]
|
3781
|
-
--
|
3782
|
-
content
|
3783
|
-
--
|
3784
|
-
EOS
|
3785
|
-
|
3786
|
-
output = convert_string_to_embedded input
|
3787
|
-
assert_xpath '/*[@id = ":idname"]', output, 1
|
3788
|
-
end
|
3789
|
-
|
3790
|
-
test 'should use specified id and reftext when registering block reference' do
|
3791
|
-
input = <<-EOS
|
3792
|
-
[[debian,Debian Install]]
|
3793
|
-
.Installation on Debian
|
3794
|
-
----
|
3795
|
-
$ apt-get install asciidoctor
|
3796
|
-
----
|
3797
|
-
EOS
|
3798
|
-
|
3799
|
-
doc = document_from_string input
|
3800
|
-
reftext = doc.catalog[:ids]['debian']
|
3801
|
-
refute_nil reftext
|
3802
|
-
assert_equal 'Debian Install', reftext
|
3803
|
-
end
|
3804
|
-
|
3805
|
-
test 'should allow square brackets in block reference text' do
|
3806
|
-
input = <<-EOS
|
3807
|
-
[[debian,[Debian] Install]]
|
3808
|
-
.Installation on Debian
|
3809
|
-
----
|
3810
|
-
$ apt-get install asciidoctor
|
3811
|
-
----
|
3812
|
-
EOS
|
3813
|
-
|
3814
|
-
doc = document_from_string input
|
3815
|
-
reftext = doc.catalog[:ids]['debian']
|
3816
|
-
refute_nil reftext
|
3817
|
-
assert_equal '[Debian] Install', reftext
|
3818
|
-
end
|
3819
|
-
|
3820
|
-
test 'should allow comma in block reference text' do
|
3821
|
-
input = <<-EOS
|
3822
|
-
[[debian, Debian, Ubuntu]]
|
3823
|
-
.Installation on Debian
|
3824
|
-
----
|
3825
|
-
$ apt-get install asciidoctor
|
3826
|
-
----
|
3827
|
-
EOS
|
3828
|
-
|
3829
|
-
doc = document_from_string input
|
3830
|
-
reftext = doc.catalog[:ids]['debian']
|
3831
|
-
refute_nil reftext
|
3832
|
-
assert_equal 'Debian, Ubuntu', reftext
|
3833
|
-
end
|
3834
|
-
|
3835
|
-
test 'should substitute attribute references in reftext when registering block reference' do
|
3836
|
-
input = <<-EOS
|
3837
|
-
:label-tiger: Tiger
|
3838
|
-
|
3839
|
-
[[tiger-evolution,Evolution of the {label-tiger}]]
|
3840
|
-
****
|
3841
|
-
Information about the evolution of the tiger.
|
3842
|
-
****
|
3843
|
-
EOS
|
3844
|
-
|
3845
|
-
doc = document_from_string input
|
3846
|
-
reftext = doc.catalog[:ids]['tiger-evolution']
|
3847
|
-
refute_nil reftext
|
3848
|
-
assert_equal 'Evolution of the Tiger', reftext
|
3849
|
-
ref = doc.catalog[:refs]['tiger-evolution']
|
3850
|
-
refute_nil ref
|
3851
|
-
assert_equal 'Evolution of the Tiger', ref.attributes['reftext']
|
3852
|
-
end
|
3853
|
-
|
3854
|
-
test 'should use specified reftext when registering block reference' do
|
3855
|
-
input = <<-EOS
|
3856
|
-
[[debian]]
|
3857
|
-
[reftext="Debian Install"]
|
3858
|
-
.Installation on Debian
|
3859
|
-
----
|
3860
|
-
$ apt-get install asciidoctor
|
3861
|
-
----
|
3862
|
-
EOS
|
3863
|
-
|
3864
|
-
doc = document_from_string input
|
3865
|
-
reftext = doc.catalog[:ids]['debian']
|
3866
|
-
refute_nil reftext
|
3867
|
-
assert_equal 'Debian Install', reftext
|
3868
|
-
end
|
3869
|
-
end
|
3870
|
-
end
|