asciidoctor 1.5.8 → 2.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +162 -17
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +12 -13
  5. data/README-fr.adoc +11 -12
  6. data/README-jp.adoc +11 -12
  7. data/README-zh_CN.adoc +12 -13
  8. data/README.adoc +6 -7
  9. data/asciidoctor.gemspec +19 -24
  10. data/bin/asciidoctor +5 -4
  11. data/data/reference/syntax.adoc +283 -0
  12. data/data/stylesheets/asciidoctor-default.css +56 -52
  13. data/data/stylesheets/coderay-asciidoctor.css +7 -9
  14. data/lib/asciidoctor.rb +171 -232
  15. data/lib/asciidoctor/abstract_block.rb +96 -105
  16. data/lib/asciidoctor/abstract_node.rb +118 -139
  17. data/lib/asciidoctor/attribute_list.rb +10 -14
  18. data/lib/asciidoctor/block.rb +20 -19
  19. data/lib/asciidoctor/callouts.rb +4 -2
  20. data/lib/asciidoctor/cli.rb +3 -2
  21. data/lib/asciidoctor/cli/invoker.rb +14 -21
  22. data/lib/asciidoctor/cli/options.rb +64 -54
  23. data/lib/asciidoctor/converter.rb +357 -185
  24. data/lib/asciidoctor/converter/composite.rb +40 -48
  25. data/lib/asciidoctor/converter/docbook5.rb +604 -640
  26. data/lib/asciidoctor/converter/html5.rb +949 -963
  27. data/lib/asciidoctor/converter/manpage.rb +569 -548
  28. data/lib/asciidoctor/converter/template.rb +231 -272
  29. data/lib/asciidoctor/core_ext.rb +5 -18
  30. data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
  31. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  32. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  33. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  34. data/lib/asciidoctor/document.rb +399 -377
  35. data/lib/asciidoctor/extensions.rb +72 -140
  36. data/lib/asciidoctor/helpers.rb +122 -83
  37. data/lib/asciidoctor/inline.rb +5 -1
  38. data/lib/asciidoctor/list.rb +13 -11
  39. data/lib/asciidoctor/logging.rb +17 -16
  40. data/lib/asciidoctor/parser.rb +390 -423
  41. data/lib/asciidoctor/path_resolver.rb +10 -5
  42. data/lib/asciidoctor/reader.rb +286 -263
  43. data/lib/asciidoctor/rouge_ext.rb +39 -0
  44. data/lib/asciidoctor/section.rb +9 -8
  45. data/lib/asciidoctor/stylesheets.rb +19 -37
  46. data/lib/asciidoctor/substitutors.rb +364 -509
  47. data/lib/asciidoctor/syntax_highlighter.rb +238 -0
  48. data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
  49. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
  50. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  51. data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
  52. data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
  53. data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
  54. data/lib/asciidoctor/table.rb +73 -66
  55. data/lib/asciidoctor/timings.rb +4 -2
  56. data/lib/asciidoctor/version.rb +2 -1
  57. data/lib/asciidoctor/writer.rb +30 -0
  58. data/man/asciidoctor.1 +19 -15
  59. data/man/asciidoctor.adoc +14 -12
  60. metadata +69 -216
  61. data/CONTRIBUTING.adoc +0 -185
  62. data/Gemfile +0 -60
  63. data/Rakefile +0 -129
  64. data/bin/asciidoctor-safe +0 -15
  65. data/features/open_block.feature +0 -92
  66. data/features/pass_block.feature +0 -66
  67. data/features/step_definitions.rb +0 -49
  68. data/features/text_formatting.feature +0 -57
  69. data/features/xref.feature +0 -1039
  70. data/lib/asciidoctor/converter/base.rb +0 -59
  71. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  72. data/lib/asciidoctor/converter/factory.rb +0 -226
  73. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  74. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  75. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  76. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  77. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  78. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  79. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  80. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  81. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  82. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  83. data/test/api_test.rb +0 -1240
  84. data/test/attribute_list_test.rb +0 -242
  85. data/test/attributes_test.rb +0 -1623
  86. data/test/blocks_test.rb +0 -3870
  87. data/test/converter_test.rb +0 -470
  88. data/test/document_test.rb +0 -1853
  89. data/test/extensions_test.rb +0 -1560
  90. data/test/fixtures/asciidoc_index.txt +0 -521
  91. data/test/fixtures/basic-docinfo-footer.html +0 -6
  92. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  93. data/test/fixtures/basic-docinfo.html +0 -1
  94. data/test/fixtures/basic-docinfo.xml +0 -4
  95. data/test/fixtures/basic.asciidoc +0 -5
  96. data/test/fixtures/chapter-a.adoc +0 -3
  97. data/test/fixtures/child-include.adoc +0 -5
  98. data/test/fixtures/circle.svg +0 -9
  99. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  100. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  101. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  102. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  103. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  104. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  105. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  106. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  107. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  108. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  109. data/test/fixtures/docinfo-footer.html +0 -1
  110. data/test/fixtures/docinfo-footer.xml +0 -9
  111. data/test/fixtures/docinfo.html +0 -1
  112. data/test/fixtures/docinfo.xml +0 -3
  113. data/test/fixtures/doctime-localtime.adoc +0 -2
  114. data/test/fixtures/dot.gif +0 -0
  115. data/test/fixtures/encoding.asciidoc +0 -13
  116. data/test/fixtures/file-with-missing-include.adoc +0 -1
  117. data/test/fixtures/grandchild-include.adoc +0 -3
  118. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  119. data/test/fixtures/include-file.asciidoc +0 -24
  120. data/test/fixtures/include-file.jsx +0 -8
  121. data/test/fixtures/include-file.ml +0 -3
  122. data/test/fixtures/include-file.xml +0 -5
  123. data/test/fixtures/lists.adoc +0 -96
  124. data/test/fixtures/master.adoc +0 -5
  125. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  126. data/test/fixtures/other-chapters.adoc +0 -11
  127. data/test/fixtures/outer-include.adoc +0 -5
  128. data/test/fixtures/parent-include-restricted.adoc +0 -5
  129. data/test/fixtures/parent-include.adoc +0 -5
  130. data/test/fixtures/sample.asciidoc +0 -30
  131. data/test/fixtures/section-a.adoc +0 -4
  132. data/test/fixtures/stylesheets/custom.css +0 -3
  133. data/test/fixtures/subdir/index.adoc +0 -3
  134. data/test/fixtures/subdir/inner-include.adoc +0 -3
  135. data/test/fixtures/subdir/middle-include.adoc +0 -5
  136. data/test/fixtures/subs-docinfo.html +0 -2
  137. data/test/fixtures/subs.adoc +0 -6
  138. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  139. data/test/fixtures/tagged-class.rb +0 -23
  140. data/test/fixtures/tip.gif +0 -0
  141. data/test/fixtures/unclosed-tag.adoc +0 -3
  142. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  143. data/test/invoker_test.rb +0 -745
  144. data/test/links_test.rb +0 -855
  145. data/test/lists_test.rb +0 -5151
  146. data/test/logger_test.rb +0 -211
  147. data/test/manpage_test.rb +0 -660
  148. data/test/options_test.rb +0 -262
  149. data/test/paragraphs_test.rb +0 -562
  150. data/test/parser_test.rb +0 -742
  151. data/test/paths_test.rb +0 -395
  152. data/test/preamble_test.rb +0 -173
  153. data/test/reader_test.rb +0 -2161
  154. data/test/sections_test.rb +0 -3575
  155. data/test/substitutions_test.rb +0 -2066
  156. data/test/tables_test.rb +0 -2036
  157. data/test/test_helper.rb +0 -447
  158. data/test/text_test.rb +0 -309
@@ -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 '<', '&lt;'}</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&lt;String, String&gt; <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 &lt; 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 &lt; 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" -&gt; bbb"N"
1599
- f: x |-&gt; 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" -&gt; bbb"N"\$<br>
1618
- \$f: x |-&gt; 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" -&gt; bbb"N"\$<br>
1638
- <br>
1639
- \$f: x |-&gt; 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" -&gt; bbb"N"\$<br>
1660
- <br>
1661
- <br>
1662
- \$f: x |-&gt; 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 &lt; 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 &lt; 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>&#x003C;</mml:mo><mml:mo>&#x00B1;</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>&#x2212;</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 &lt; 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 &lt; 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 &lt; 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&#8217;s &quot;roar&quot; is &lt; a bear&#8217;s &quot;growl&quot;'
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 &gt; 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">&gt;&gt;</a> &lt;1&gt;</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_ &lt;1&gt;'
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