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,2161 +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
- class ReaderTest < Minitest::Test
8
- DIRNAME = File.expand_path File.dirname __FILE__
9
-
10
- SAMPLE_DATA = <<-EOS.chomp.split(::Asciidoctor::LF)
11
- first line
12
- second line
13
- third line
14
- EOS
15
-
16
- context 'Reader' do
17
- context 'Prepare lines' do
18
- test 'should prepare lines from Array data' do
19
- reader = Asciidoctor::Reader.new SAMPLE_DATA
20
- assert_equal SAMPLE_DATA, reader.lines
21
- end
22
-
23
- test 'should prepare lines from String data' do
24
- reader = Asciidoctor::Reader.new SAMPLE_DATA
25
- assert_equal SAMPLE_DATA, reader.lines
26
- end
27
-
28
- test 'should remove UTF-8 BOM from first line of String data' do
29
- data = "\xef\xbb\xbf#{SAMPLE_DATA.join ::Asciidoctor::LF}"
30
- reader = Asciidoctor::Reader.new data, nil, :normalize => true
31
- assert_equal 'f', reader.lines.first.chr
32
- assert_equal SAMPLE_DATA, reader.lines
33
- end
34
-
35
- test 'should remove UTF-8 BOM from first line of Array data' do
36
- data = SAMPLE_DATA.dup
37
- data[0] = "\xef\xbb\xbf#{data.first}"
38
- reader = Asciidoctor::Reader.new data, nil, :normalize => true
39
- assert_equal 'f', reader.lines.first.chr
40
- assert_equal SAMPLE_DATA, reader.lines
41
- end
42
-
43
- if Asciidoctor::COERCE_ENCODING
44
- test 'should encode UTF-16LE string to UTF-8 when BOM is found' do
45
- data = "\ufeff#{SAMPLE_DATA.join ::Asciidoctor::LF}".encode('UTF-16LE').force_encoding('UTF-8')
46
- reader = Asciidoctor::Reader.new data, nil, :normalize => true
47
- assert_equal 'f', reader.lines.first.chr
48
- assert_equal SAMPLE_DATA, reader.lines
49
- end
50
-
51
- test 'should encode UTF-16LE string array to UTF-8 when BOM is found' do
52
- data = "\ufeff#{SAMPLE_DATA.join ::Asciidoctor::LF}".encode('UTF-16LE').force_encoding('UTF-8').lines.to_a
53
- reader = Asciidoctor::Reader.new data, nil, :normalize => true
54
- assert_equal 'f', reader.lines.first.chr
55
- assert_equal SAMPLE_DATA, reader.lines
56
- end
57
-
58
- test 'should encode UTF-16BE string to UTF-8 when BOM is found' do
59
- data = "\ufeff#{SAMPLE_DATA.join ::Asciidoctor::LF}".encode('UTF-16BE').force_encoding('UTF-8')
60
- reader = Asciidoctor::Reader.new data, nil, :normalize => true
61
- assert_equal 'f', reader.lines.first.chr
62
- assert_equal SAMPLE_DATA, reader.lines
63
- end
64
-
65
- test 'should encode UTF-16BE string array to UTF-8 when BOM is found' do
66
- data = "\ufeff#{SAMPLE_DATA.join ::Asciidoctor::LF}".encode('UTF-16BE').force_encoding('UTF-8').lines.to_a
67
- reader = Asciidoctor::Reader.new data, nil, :normalize => true
68
- assert_equal 'f', reader.lines.first.chr
69
- assert_equal SAMPLE_DATA, reader.lines
70
- end
71
- end
72
- end
73
-
74
- context 'With empty data' do
75
- test 'has_more_lines? should return false with empty data' do
76
- refute Asciidoctor::Reader.new.has_more_lines?
77
- end
78
-
79
- test 'empty? should return true with empty data' do
80
- assert Asciidoctor::Reader.new.empty?
81
- assert Asciidoctor::Reader.new.eof?
82
- end
83
-
84
- test 'next_line_empty? should return true with empty data' do
85
- assert Asciidoctor::Reader.new.next_line_empty?
86
- end
87
-
88
- test 'peek_line should return nil with empty data' do
89
- assert_nil Asciidoctor::Reader.new.peek_line
90
- end
91
-
92
- test 'peek_lines should return empty Array with empty data' do
93
- assert_equal [], Asciidoctor::Reader.new.peek_lines(1)
94
- end
95
-
96
- test 'read_line should return nil with empty data' do
97
- assert_nil Asciidoctor::Reader.new.read_line
98
- #assert_nil Asciidoctor::Reader.new.get_line
99
- end
100
-
101
- test 'read_lines should return empty Array with empty data' do
102
- assert_equal [], Asciidoctor::Reader.new.read_lines
103
- #assert_equal [], Asciidoctor::Reader.new.get_lines
104
- end
105
- end
106
-
107
- context 'With data' do
108
- test 'has_more_lines? should return true if there are lines remaining' do
109
- reader = Asciidoctor::Reader.new SAMPLE_DATA
110
- assert reader.has_more_lines?
111
- end
112
-
113
- test 'empty? should return false if there are lines remaining' do
114
- reader = Asciidoctor::Reader.new SAMPLE_DATA
115
- refute reader.empty?
116
- refute reader.eof?
117
- end
118
-
119
- test 'next_line_empty? should return false if next line is not blank' do
120
- reader = Asciidoctor::Reader.new SAMPLE_DATA
121
- refute reader.next_line_empty?
122
- end
123
-
124
- test 'next_line_empty? should return true if next line is blank' do
125
- reader = Asciidoctor::Reader.new ['', 'second line']
126
- assert reader.next_line_empty?
127
- end
128
-
129
- test 'peek_line should return next line if there are lines remaining' do
130
- reader = Asciidoctor::Reader.new SAMPLE_DATA
131
- assert_equal SAMPLE_DATA.first, reader.peek_line
132
- end
133
-
134
- test 'peek_line should not consume line or increment line number' do
135
- reader = Asciidoctor::Reader.new SAMPLE_DATA
136
- assert_equal SAMPLE_DATA.first, reader.peek_line
137
- assert_equal SAMPLE_DATA.first, reader.peek_line
138
- assert_equal 1, reader.lineno
139
- end
140
-
141
- test 'peek_line should return next lines if there are lines remaining' do
142
- reader = Asciidoctor::Reader.new SAMPLE_DATA
143
- assert_equal SAMPLE_DATA[0..1], reader.peek_lines(2)
144
- end
145
-
146
- test 'peek_lines should not consume lines or increment line number' do
147
- reader = Asciidoctor::Reader.new SAMPLE_DATA
148
- assert_equal SAMPLE_DATA[0..1], reader.peek_lines(2)
149
- assert_equal SAMPLE_DATA[0..1], reader.peek_lines(2)
150
- assert_equal 1, reader.lineno
151
- end
152
-
153
- test 'peek_lines should not increment line number if reader overruns buffer' do
154
- reader = Asciidoctor::Reader.new SAMPLE_DATA
155
- assert_equal SAMPLE_DATA, (reader.peek_lines SAMPLE_DATA.size * 2)
156
- assert_equal 1, reader.lineno
157
- end
158
-
159
- test 'peek_lines should peek all lines if no arguments are given' do
160
- reader = Asciidoctor::Reader.new SAMPLE_DATA
161
- assert_equal SAMPLE_DATA, reader.peek_lines
162
- assert_equal 1, reader.lineno
163
- end
164
-
165
- test 'peek_lines should not invert order of lines' do
166
- reader = Asciidoctor::Reader.new SAMPLE_DATA
167
- assert_equal SAMPLE_DATA, reader.lines
168
- reader.peek_lines 3
169
- assert_equal SAMPLE_DATA, reader.lines
170
- end
171
-
172
- test 'read_line should return next line if there are lines remaining' do
173
- reader = Asciidoctor::Reader.new SAMPLE_DATA
174
- assert_equal SAMPLE_DATA.first, reader.read_line
175
- end
176
-
177
- test 'read_line should consume next line and increment line number' do
178
- reader = Asciidoctor::Reader.new SAMPLE_DATA
179
- assert_equal SAMPLE_DATA[0], reader.read_line
180
- assert_equal SAMPLE_DATA[1], reader.read_line
181
- assert_equal 3, reader.lineno
182
- end
183
-
184
- test 'advance should consume next line and return a Boolean indicating if a line was consumed' do
185
- reader = Asciidoctor::Reader.new SAMPLE_DATA
186
- assert reader.advance
187
- assert reader.advance
188
- assert reader.advance
189
- refute reader.advance
190
- end
191
-
192
- test 'read_lines should return all lines' do
193
- reader = Asciidoctor::Reader.new SAMPLE_DATA
194
- assert_equal SAMPLE_DATA, reader.read_lines
195
- end
196
-
197
- test 'read should return all lines joined as String' do
198
- reader = Asciidoctor::Reader.new SAMPLE_DATA
199
- assert_equal SAMPLE_DATA.join(::Asciidoctor::LF), reader.read
200
- end
201
-
202
- test 'has_more_lines? should return false after read_lines is invoked' do
203
- reader = Asciidoctor::Reader.new SAMPLE_DATA
204
- reader.read_lines
205
- refute reader.has_more_lines?
206
- end
207
-
208
- test 'unshift puts line onto Reader as next line to read' do
209
- reader = Asciidoctor::Reader.new SAMPLE_DATA, nil, :normalize => true
210
- reader.unshift 'line zero'
211
- assert_equal 'line zero', reader.peek_line
212
- assert_equal 'line zero', reader.read_line
213
- assert_equal 1, reader.lineno
214
- end
215
-
216
- test 'terminate should consume all lines and update line number' do
217
- reader = Asciidoctor::Reader.new SAMPLE_DATA
218
- reader.terminate
219
- assert reader.eof?
220
- assert_equal 4, reader.lineno
221
- end
222
-
223
- test 'skip_blank_lines should skip blank lines' do
224
- reader = Asciidoctor::Reader.new ['', ''].concat(SAMPLE_DATA)
225
- reader.skip_blank_lines
226
- assert_equal SAMPLE_DATA.first, reader.peek_line
227
- end
228
-
229
- test 'lines should return remaining lines' do
230
- reader = Asciidoctor::Reader.new SAMPLE_DATA
231
- reader.read_line
232
- assert_equal SAMPLE_DATA[1..-1], reader.lines
233
- end
234
-
235
- test 'source_lines should return copy of original data Array' do
236
- reader = Asciidoctor::Reader.new SAMPLE_DATA
237
- reader.read_lines
238
- assert_equal SAMPLE_DATA, reader.source_lines
239
- end
240
-
241
- test 'source should return original data Array joined as String' do
242
- reader = Asciidoctor::Reader.new SAMPLE_DATA
243
- reader.read_lines
244
- assert_equal SAMPLE_DATA.join(::Asciidoctor::LF), reader.source
245
- end
246
-
247
- end
248
-
249
- context 'Line context' do
250
- test 'to_s should return file name and line number of current line' do
251
- reader = Asciidoctor::Reader.new SAMPLE_DATA, 'sample.adoc'
252
- reader.read_line
253
- assert_equal 'sample.adoc: line 2', reader.to_s
254
- end
255
-
256
- test 'line_info should return file name and line number of current line' do
257
- reader = Asciidoctor::Reader.new SAMPLE_DATA, 'sample.adoc'
258
- reader.read_line
259
- assert_equal 'sample.adoc: line 2', reader.line_info
260
- assert_equal 'sample.adoc: line 2', reader.cursor.to_s
261
- end
262
-
263
- test 'cursor_at_prev_line should return file name and line number of previous line read' do
264
- reader = Asciidoctor::Reader.new SAMPLE_DATA, 'sample.adoc'
265
- reader.read_line
266
- assert_equal 'sample.adoc: line 1', reader.cursor_at_prev_line.to_s
267
- end
268
- end
269
-
270
- context 'Read lines until' do
271
- test 'Read lines until until end' do
272
- lines = <<-EOS.lines.entries
273
- This is one paragraph.
274
-
275
- This is another paragraph.
276
- EOS
277
-
278
- reader = Asciidoctor::Reader.new lines, nil, :normalize => true
279
- result = reader.read_lines_until
280
- assert_equal 3, result.size
281
- assert_equal lines.map {|l| l.chomp }, result
282
- refute reader.has_more_lines?
283
- assert reader.eof?
284
- end
285
-
286
- test 'Read lines until until blank line' do
287
- lines = <<-EOS.lines.entries
288
- This is one paragraph.
289
-
290
- This is another paragraph.
291
- EOS
292
-
293
- reader = Asciidoctor::Reader.new lines, nil, :normalize => true
294
- result = reader.read_lines_until :break_on_blank_lines => true
295
- assert_equal 1, result.size
296
- assert_equal lines.first.chomp, result.first
297
- assert_equal lines.last.chomp, reader.peek_line
298
- end
299
-
300
- test 'Read lines until until blank line preserving last line' do
301
- lines = <<-EOS.chomp.split(::Asciidoctor::LF)
302
- This is one paragraph.
303
-
304
- This is another paragraph.
305
- EOS
306
-
307
- reader = Asciidoctor::Reader.new lines
308
- result = reader.read_lines_until :break_on_blank_lines => true, :preserve_last_line => true
309
- assert_equal 1, result.size
310
- assert_equal lines.first.chomp, result.first
311
- assert reader.next_line_empty?
312
- end
313
-
314
- test 'Read lines until until condition is true' do
315
- lines = <<-EOS.chomp.split(::Asciidoctor::LF)
316
- --
317
- This is one paragraph inside the block.
318
-
319
- This is another paragraph inside the block.
320
- --
321
-
322
- This is a paragraph outside the block.
323
- EOS
324
-
325
- reader = Asciidoctor::Reader.new lines
326
- reader.read_line
327
- result = reader.read_lines_until {|line| line == '--' }
328
- assert_equal 3, result.size
329
- assert_equal lines[1, 3], result
330
- assert reader.next_line_empty?
331
- end
332
-
333
- test 'Read lines until until condition is true, taking last line' do
334
- lines = <<-EOS.chomp.split(::Asciidoctor::LF)
335
- --
336
- This is one paragraph inside the block.
337
-
338
- This is another paragraph inside the block.
339
- --
340
-
341
- This is a paragraph outside the block.
342
- EOS
343
-
344
- reader = Asciidoctor::Reader.new lines
345
- reader.read_line
346
- result = reader.read_lines_until(:read_last_line => true) {|line| line == '--' }
347
- assert_equal 4, result.size
348
- assert_equal lines[1, 4], result
349
- assert reader.next_line_empty?
350
- end
351
-
352
- test 'Read lines until until condition is true, taking and preserving last line' do
353
- lines = <<-EOS.chomp.split(::Asciidoctor::LF)
354
- --
355
- This is one paragraph inside the block.
356
-
357
- This is another paragraph inside the block.
358
- --
359
-
360
- This is a paragraph outside the block.
361
- EOS
362
-
363
- reader = Asciidoctor::Reader.new lines
364
- reader.read_line
365
- result = reader.read_lines_until(:read_last_line => true, :preserve_last_line => true) {|line| line == '--' }
366
- assert_equal 4, result.size
367
- assert_equal lines[1, 4], result
368
- assert_equal '--', reader.peek_line
369
- end
370
-
371
- test 'read lines until terminator' do
372
- lines = <<-EOS.each_line.to_a
373
- ****
374
- captured
375
-
376
- also captured
377
- ****
378
-
379
- not captured
380
- EOS
381
-
382
- expected = ['captured', '', 'also captured']
383
-
384
- doc = empty_safe_document :base_dir => DIRNAME
385
- reader = Asciidoctor::PreprocessorReader.new doc, lines, nil, :normalize => true
386
- terminator = reader.read_line
387
- result = reader.read_lines_until :terminator => terminator, :skip_processing => true
388
- assert_equal expected, result
389
- refute reader.unterminated
390
- end
391
-
392
- test 'should flag reader as unterminated if reader reaches end of source without finding terminator' do
393
- lines = <<-EOS.each_line.to_a
394
- ****
395
- captured
396
-
397
- also captured
398
-
399
- captured yet again
400
- EOS
401
-
402
- expected = lines[1..-1].map {|l| l.chomp }
403
-
404
- using_memory_logger do |logger|
405
- doc = empty_safe_document :base_dir => DIRNAME
406
- reader = Asciidoctor::PreprocessorReader.new doc, lines, nil, :normalize => true
407
- terminator = reader.peek_line
408
- result = reader.read_lines_until :terminator => terminator, :skip_first_line => true, :skip_processing => true
409
- assert_equal expected, result
410
- assert reader.unterminated
411
- assert_message logger, :WARN, '<stdin>: line 1: unterminated **** block', Hash
412
- end
413
- end
414
- end
415
- end
416
-
417
- context 'PreprocessorReader' do
418
- context 'Type hierarchy' do
419
- test 'PreprocessorReader should extend from Reader' do
420
- reader = empty_document.reader
421
- assert_kind_of Asciidoctor::PreprocessorReader, reader
422
- end
423
-
424
- test 'PreprocessorReader should invoke or emulate Reader initializer' do
425
- doc = Asciidoctor::Document.new SAMPLE_DATA
426
- reader = doc.reader
427
- assert_equal SAMPLE_DATA, reader.lines
428
- assert_equal 1, reader.lineno
429
- end
430
- end
431
-
432
- context 'Prepare lines' do
433
- test 'should prepare and normalize lines from Array data' do
434
- data = SAMPLE_DATA.map {|line| line.chomp}
435
- data.unshift ''
436
- data.push ''
437
- doc = Asciidoctor::Document.new data
438
- reader = doc.reader
439
- assert_equal SAMPLE_DATA, reader.lines
440
- end
441
-
442
- test 'should prepare and normalize lines from String data' do
443
- data = SAMPLE_DATA.map {|line| line.chomp}
444
- data.unshift ' '
445
- data.push ' '
446
- data_as_string = data * ::Asciidoctor::LF
447
- doc = Asciidoctor::Document.new data_as_string
448
- reader = doc.reader
449
- assert_equal SAMPLE_DATA, reader.lines
450
- end
451
-
452
- test 'should clean CRLF from end of lines' do
453
- input = <<-EOS
454
- source\r
455
- with\r
456
- CRLF\r
457
- endlines\r
458
- EOS
459
-
460
- [input, input.lines.to_a, input.split(::Asciidoctor::LF), input.split(::Asciidoctor::LF).join(::Asciidoctor::LF)].each do |lines|
461
- doc = Asciidoctor::Document.new lines
462
- reader = doc.reader
463
- reader.lines.each do |line|
464
- refute line.end_with?("\r"), "CRLF not properly cleaned for source lines: #{lines.inspect}"
465
- refute line.end_with?("\r\n"), "CRLF not properly cleaned for source lines: #{lines.inspect}"
466
- refute line.end_with?("\n"), "CRLF not properly cleaned for source lines: #{lines.inspect}"
467
- end
468
- end
469
- end
470
-
471
- test 'should not skip front matter by default' do
472
- input = <<-EOS
473
- ---
474
- layout: post
475
- title: Document Title
476
- author: username
477
- tags: [ first, second ]
478
- ---
479
- = Document Title
480
- Author Name
481
-
482
- preamble
483
- EOS
484
-
485
- doc = Asciidoctor::Document.new input
486
- reader = doc.reader
487
- refute doc.attributes.key?('front-matter')
488
- assert_equal '---', reader.peek_line
489
- end
490
-
491
- test 'should skip front matter if specified by skip-front-matter attribute' do
492
- front_matter = %(layout: post
493
- title: Document Title
494
- author: username
495
- tags: [ first, second ])
496
- input = <<-EOS
497
- ---
498
- #{front_matter}
499
- ---
500
- = Document Title
501
- Author Name
502
-
503
- preamble
504
- EOS
505
-
506
- doc = Asciidoctor::Document.new input, :attributes => {'skip-front-matter' => ''}
507
- reader = doc.reader
508
- assert_equal '= Document Title', reader.peek_line
509
- assert_equal front_matter, doc.attributes['front-matter']
510
- end
511
- end
512
-
513
- context 'Include Stack' do
514
- test 'PreprocessorReader#push_include method should return reader' do
515
- reader = empty_document.reader
516
- append_lines = %w(one two three)
517
- result = reader.push_include append_lines, '<stdin>', '<stdin>'
518
- assert_equal reader, result
519
- end
520
-
521
- test 'PreprocessorReader#push_include method should put lines on top of stack' do
522
- lines = %w(a b c)
523
- doc = Asciidoctor::Document.new lines
524
- reader = doc.reader
525
- append_lines = %w(one two three)
526
- reader.push_include append_lines, '', '<stdin>'
527
- assert_equal 1, reader.include_stack.size
528
- assert_equal 'one', reader.read_line.rstrip
529
- end
530
-
531
- test 'PreprocessorReader#push_include method should gracefully handle file and path' do
532
- lines = %w(a b c)
533
- doc = Asciidoctor::Document.new lines
534
- reader = doc.reader
535
- append_lines = %w(one two three)
536
- reader.push_include append_lines
537
- assert_equal 1, reader.include_stack.size
538
- assert_equal 'one', reader.read_line.rstrip
539
- assert_nil reader.file
540
- assert_equal '<stdin>', reader.path
541
- end
542
-
543
- test 'PreprocessorReader#push_include method should set path from file automatically if not specified' do
544
- lines = %w(a b c)
545
- doc = Asciidoctor::Document.new lines
546
- reader = doc.reader
547
- append_lines = %w(one two three)
548
- reader.push_include append_lines, '/tmp/lines.adoc'
549
- assert_equal '/tmp/lines.adoc', reader.file
550
- assert_equal 'lines.adoc', reader.path
551
- end
552
-
553
- test 'PreprocessorReader#push_include method should accept file as a URI and compute dir and path' do
554
- file_uri = ::URI.parse 'http://example.com/docs/file.adoc'
555
- dir_uri = ::URI.parse 'http://example.com/docs'
556
- reader = empty_document.reader
557
- reader.push_include %w(one two three), file_uri
558
- assert_same file_uri, reader.file
559
- assert_equal dir_uri, reader.dir
560
- assert_equal 'file.adoc', reader.path
561
- end
562
-
563
- test 'PreprocessorReader#push_include method should accept file as a top-level URI and compute dir and path' do
564
- file_uri = ::URI.parse 'http://example.com/index.adoc'
565
- dir_uri = ::URI.parse 'http://example.com'
566
- reader = empty_document.reader
567
- reader.push_include %w(one two three), file_uri
568
- assert_same file_uri, reader.file
569
- assert_equal dir_uri, reader.dir
570
- assert_equal 'index.adoc', reader.path
571
- end
572
- end
573
-
574
- context 'Include Directive' do
575
- test 'include directive is disabled by default and becomes a link' do
576
- input = <<-EOS
577
- include::include-file.asciidoc[]
578
- EOS
579
- doc = Asciidoctor::Document.new input
580
- reader = doc.reader
581
- assert_equal 'link:include-file.asciidoc[]', reader.read_line
582
- end
583
-
584
- test 'include directive is enabled when safe mode is less than SECURE' do
585
- input = <<-EOS
586
- include::fixtures/include-file.asciidoc[]
587
- EOS
588
-
589
- doc = document_from_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
590
- output = doc.convert
591
- assert_match(/included content/, output)
592
- assert doc.catalog[:includes]['fixtures/include-file']
593
- end
594
-
595
- test 'should not track include in catalog for non-AsciiDoc include files' do
596
- input = <<-EOS
597
- ----
598
- include::fixtures/circle.svg[]
599
- ----
600
- EOS
601
-
602
- doc = document_from_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
603
- assert doc.catalog[:includes].empty?
604
- end
605
-
606
- test 'include directive should resolve file with spaces in name' do
607
- input = <<-EOS
608
- include::fixtures/include file.asciidoc[]
609
- EOS
610
-
611
- include_file = File.join DIRNAME, 'fixtures', 'include-file.asciidoc'
612
- include_file_with_sp = File.join DIRNAME, 'fixtures', 'include file.asciidoc'
613
- begin
614
- FileUtils.cp include_file, include_file_with_sp
615
- doc = document_from_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
616
- output = doc.convert
617
- assert_match(/included content/, output)
618
- ensure
619
- FileUtils.rm include_file_with_sp
620
- end
621
- end
622
-
623
- test 'include directive should resolve file with {sp} in name' do
624
- input = <<-EOS
625
- include::fixtures/include{sp}file.asciidoc[]
626
- EOS
627
-
628
- include_file = File.join DIRNAME, 'fixtures', 'include-file.asciidoc'
629
- include_file_with_sp = File.join DIRNAME, 'fixtures', 'include file.asciidoc'
630
- begin
631
- FileUtils.cp include_file, include_file_with_sp
632
- doc = document_from_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
633
- output = doc.convert
634
- assert_match(/included content/, output)
635
- ensure
636
- FileUtils.rm include_file_with_sp
637
- end
638
- end
639
-
640
- test 'include directive should resolve file relative to current include' do
641
- input = <<-EOS
642
- include::fixtures/parent-include.adoc[]
643
- EOS
644
-
645
- pseudo_docfile = File.join DIRNAME, 'include-master.adoc'
646
- fixtures_dir = File.join DIRNAME, 'fixtures'
647
- parent_include_docfile = File.join fixtures_dir, 'parent-include.adoc'
648
- child_include_docfile = File.join fixtures_dir, 'child-include.adoc'
649
- grandchild_include_docfile = File.join fixtures_dir, 'grandchild-include.adoc'
650
-
651
- doc = empty_safe_document :base_dir => DIRNAME
652
- reader = Asciidoctor::PreprocessorReader.new doc, input, pseudo_docfile, :normalize => true
653
-
654
- assert_equal pseudo_docfile, reader.file
655
- assert_equal DIRNAME, reader.dir
656
- assert_equal 'include-master.adoc', reader.path
657
-
658
- assert_equal 'first line of parent', reader.read_line
659
-
660
- assert_equal 'fixtures/parent-include.adoc: line 1', reader.cursor_at_prev_line.to_s
661
- assert_equal parent_include_docfile, reader.file
662
- assert_equal fixtures_dir, reader.dir
663
- assert_equal 'fixtures/parent-include.adoc', reader.path
664
-
665
- reader.skip_blank_lines
666
-
667
- assert_equal 'first line of child', reader.read_line
668
-
669
- assert_equal 'fixtures/child-include.adoc: line 1', reader.cursor_at_prev_line.to_s
670
- assert_equal child_include_docfile, reader.file
671
- assert_equal fixtures_dir, reader.dir
672
- assert_equal 'fixtures/child-include.adoc', reader.path
673
-
674
- reader.skip_blank_lines
675
-
676
- assert_equal 'first line of grandchild', reader.read_line
677
-
678
- assert_equal 'fixtures/grandchild-include.adoc: line 1', reader.cursor_at_prev_line.to_s
679
- assert_equal grandchild_include_docfile, reader.file
680
- assert_equal fixtures_dir, reader.dir
681
- assert_equal 'fixtures/grandchild-include.adoc', reader.path
682
-
683
- reader.skip_blank_lines
684
-
685
- assert_equal 'last line of grandchild', reader.read_line
686
-
687
- reader.skip_blank_lines
688
-
689
- assert_equal 'last line of child', reader.read_line
690
-
691
- reader.skip_blank_lines
692
-
693
- assert_equal 'last line of parent', reader.read_line
694
-
695
- assert_equal 'fixtures/parent-include.adoc: line 5', reader.cursor_at_prev_line.to_s
696
- assert_equal parent_include_docfile, reader.file
697
- assert_equal fixtures_dir, reader.dir
698
- assert_equal 'fixtures/parent-include.adoc', reader.path
699
- end
700
-
701
- test 'missing file referenced by include directive is skipped when optional option is set' do
702
- input = <<-EOS
703
- include::fixtures/no-such-file.adoc[opts=optional]
704
-
705
- trailing content
706
- EOS
707
-
708
- begin
709
- using_memory_logger do |logger|
710
- doc = document_from_string input, :safe => :safe, :base_dir => DIRNAME
711
- assert_equal 1, doc.blocks.size
712
- assert_equal ['trailing content'], doc.blocks[0].lines
713
- assert logger.empty?
714
- end
715
- rescue
716
- flunk 'include directive should not raise exception on missing file'
717
- end
718
- end
719
-
720
- test 'missing file referenced by include directive is replaced by warning' do
721
- input = <<-EOS
722
- include::fixtures/no-such-file.adoc[]
723
-
724
- trailing content
725
- EOS
726
-
727
- begin
728
- using_memory_logger do |logger|
729
- doc = document_from_string input, :safe => :safe, :base_dir => DIRNAME
730
- assert_equal 2, doc.blocks.size
731
- assert_equal ['Unresolved directive in <stdin> - include::fixtures/no-such-file.adoc[]'], doc.blocks[0].lines
732
- assert_equal ['trailing content'], doc.blocks[1].lines
733
- assert_message logger, :ERROR, '~<stdin>: line 1: include file not found', Hash
734
- end
735
- rescue
736
- flunk 'include directive should not raise exception on missing file'
737
- end
738
- end
739
-
740
- test 'unreadable file referenced by include directive is replaced by warning' do
741
- include_file = File.join DIRNAME, 'fixtures', 'chapter-a.adoc'
742
- FileUtils.chmod 0000, include_file
743
- input = <<-EOS
744
- include::fixtures/chapter-a.adoc[]
745
-
746
- trailing content
747
- EOS
748
-
749
- begin
750
- using_memory_logger do |logger|
751
- doc = document_from_string input, :safe => :safe, :base_dir => DIRNAME
752
- assert_equal 2, doc.blocks.size
753
- assert_equal ['Unresolved directive in <stdin> - include::fixtures/chapter-a.adoc[]'], doc.blocks[0].lines
754
- assert_equal ['trailing content'], doc.blocks[1].lines
755
- assert_message logger, :ERROR, '~<stdin>: line 1: include file not readable', Hash
756
- end
757
- rescue
758
- flunk 'include directive should not raise exception on missing file'
759
- ensure
760
- FileUtils.chmod 0644, include_file
761
- end
762
- end unless windows?
763
-
764
- # IMPORTANT this test needs to be run on Windows to verify proper behavior in Windows
765
- test 'can resolve include directive with absolute path' do
766
- include_path = ::File.join DIRNAME, 'fixtures', 'chapter-a.adoc'
767
- input = <<-EOS
768
- include::#{include_path}[]
769
- EOS
770
- result = document_from_string input, :safe => :safe
771
- assert_equal 'Chapter A', result.doctitle
772
-
773
- result = document_from_string input, :safe => :unsafe, :base_dir => ::Dir.tmpdir
774
- assert_equal 'Chapter A', result.doctitle
775
- end
776
-
777
- test 'include directive can retrieve data from uri' do
778
- url = %(http://#{resolve_localhost}:9876/name/asciidoctor)
779
- input = <<-EOS
780
- ....
781
- include::#{url}[]
782
- ....
783
- EOS
784
- expect = /\{"name": "asciidoctor"\}/
785
- output = using_test_webserver do
786
- convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
787
- end
788
-
789
- refute_nil output
790
- assert_match(expect, output)
791
- end
792
-
793
- test 'nested include directives are resolved relative to current file' do
794
- input = <<-EOS
795
- ....
796
- include::fixtures/outer-include.adoc[]
797
- ....
798
- EOS
799
-
800
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
801
- expected = 'first line of outer
802
-
803
- first line of middle
804
-
805
- first line of inner
806
-
807
- last line of inner
808
-
809
- last line of middle
810
-
811
- last line of outer'
812
- assert_includes output, expected
813
- end
814
-
815
- test 'nested remote include directive is resolved relative to uri of current file' do
816
- url = %(http://#{resolve_localhost}:9876/fixtures/outer-include.adoc)
817
- input = <<-EOS
818
- ....
819
- include::#{url}[]
820
- ....
821
- EOS
822
- output = using_test_webserver do
823
- convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
824
- end
825
-
826
- expected = 'first line of outer
827
-
828
- first line of middle
829
-
830
- first line of inner
831
-
832
- last line of inner
833
-
834
- last line of middle
835
-
836
- last line of outer'
837
- assert_includes output, expected
838
- end
839
-
840
- test 'nested remote include directive that cannot be resolved does not crash processor' do
841
- include_url = %(http://#{resolve_localhost}:9876/fixtures/file-with-missing-include.adoc)
842
- nested_include_url = 'no-such-file.adoc'
843
- input = <<-EOS
844
- ....
845
- include::#{include_url}[]
846
- ....
847
- EOS
848
- begin
849
- using_memory_logger do |logger|
850
- result = using_test_webserver do
851
- convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
852
- end
853
- assert_includes result, %(Unresolved directive in #{include_url} - include::#{nested_include_url}[])
854
- assert_message logger, :ERROR, %(#{include_url}: line 1: include uri not readable: http://#{resolve_localhost}:9876/fixtures/#{nested_include_url}), Hash
855
- end
856
- rescue
857
- flunk 'include directive should not raise exception on missing file'
858
- end
859
- end
860
-
861
- test 'tag filtering is supported for remote includes' do
862
- url = %(http://#{resolve_localhost}:9876/fixtures/tagged-class.rb)
863
- input = <<-EOS
864
- [source,ruby]
865
- ----
866
- include::#{url}[tag=init,indent=0]
867
- ----
868
- EOS
869
- output = using_test_webserver do
870
- convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
871
- end
872
-
873
- expected = '<code class="language-ruby" data-lang="ruby">def initialize breed
874
- @breed = breed
875
- end</code>'
876
- assert_includes output, expected
877
- end
878
-
879
- test 'inaccessible uri referenced by include directive does not crash processor' do
880
- url = %(http://#{resolve_localhost}:9876/no_such_file)
881
- input = <<-EOS
882
- ....
883
- include::#{url}[]
884
- ....
885
- EOS
886
-
887
- begin
888
- using_memory_logger do |logger|
889
- output = using_test_webserver do
890
- convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
891
- end
892
- refute_nil output
893
- assert_match(/Unresolved directive/, output)
894
- assert_message logger, :ERROR, %(<stdin>: line 2: include uri not readable: #{url}), Hash
895
- end
896
- rescue
897
- flunk 'include directive should not raise exception on inaccessible uri'
898
- end
899
- end
900
-
901
- test 'include directive supports selecting lines by line number' do
902
- input = <<-EOS
903
- include::fixtures/include-file.asciidoc[lines=1;3..4;6..-1]
904
- EOS
905
-
906
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
907
- assert_match(/first line/, output)
908
- refute_match(/second line/, output)
909
- assert_match(/third line/, output)
910
- assert_match(/fourth line/, output)
911
- refute_match(/fifth line/, output)
912
- assert_match(/sixth line/, output)
913
- assert_match(/seventh line/, output)
914
- assert_match(/eighth line/, output)
915
- assert_match(/last line of included content/, output)
916
- end
917
-
918
- test 'include directive supports line ranges specified in quoted attribute value' do
919
- input = <<-EOS
920
- include::fixtures/include-file.asciidoc[lines="1, 3..4 , 6 .. -1"]
921
- EOS
922
-
923
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
924
- assert_match(/first line/, output)
925
- refute_match(/second line/, output)
926
- assert_match(/third line/, output)
927
- assert_match(/fourth line/, output)
928
- refute_match(/fifth line/, output)
929
- assert_match(/sixth line/, output)
930
- assert_match(/seventh line/, output)
931
- assert_match(/eighth line/, output)
932
- assert_match(/last line of included content/, output)
933
- end
934
-
935
- test 'include directive supports implicit endless range' do
936
- input = <<-EOS
937
- include::fixtures/include-file.asciidoc[lines=6..]
938
- EOS
939
-
940
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
941
- refute_match(/first line/, output)
942
- refute_match(/second line/, output)
943
- refute_match(/third line/, output)
944
- refute_match(/fourth line/, output)
945
- refute_match(/fifth line/, output)
946
- assert_match(/sixth line/, output)
947
- assert_match(/seventh line/, output)
948
- assert_match(/eighth line/, output)
949
- assert_match(/last line of included content/, output)
950
- end
951
-
952
- test 'include directive ignores empty lines attribute' do
953
- input = <<-EOS
954
- ++++
955
- include::fixtures/include-file.asciidoc[lines=]
956
- ++++
957
- EOS
958
-
959
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
960
- assert_includes output, 'first line of included content'
961
- assert_includes output, 'last line of included content'
962
- end
963
-
964
- test 'include directive supports selecting lines by tag' do
965
- input = <<-EOS
966
- include::fixtures/include-file.asciidoc[tag=snippetA]
967
- EOS
968
-
969
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
970
- assert_match(/snippetA content/, output)
971
- refute_match(/snippetB content/, output)
972
- refute_match(/non-tagged content/, output)
973
- refute_match(/included content/, output)
974
- end
975
-
976
- test 'include directive supports selecting lines by tags' do
977
- input = <<-EOS
978
- include::fixtures/include-file.asciidoc[tags=snippetA;snippetB]
979
- EOS
980
-
981
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
982
- assert_match(/snippetA content/, output)
983
- assert_match(/snippetB content/, output)
984
- refute_match(/non-tagged content/, output)
985
- refute_match(/included content/, output)
986
- end
987
-
988
- test 'include directive supports selecting lines by tag in language that uses circumfix comments' do
989
- {
990
- 'include-file.xml' => '<snippet>content</snippet>',
991
- 'include-file.ml' => 'let s = SS.empty;;',
992
- 'include-file.jsx' => '<p>Welcome to the club.</p>'
993
- }.each do |filename, expect|
994
- input = <<-EOS
995
- [source,xml]
996
- ----
997
- include::fixtures/#{filename}[tag=snippet,indent=0]
998
- ----
999
- EOS
1000
-
1001
- doc = document_from_string input, :safe => :safe, :base_dir => DIRNAME
1002
- assert_equal expect, doc.blocks[0].source
1003
- end
1004
- end
1005
-
1006
- test 'include directive supports selecting tagged lines in file that has CRLF endlines' do
1007
- begin
1008
- tmp_include = Tempfile.new %w(include- .adoc)
1009
- tmp_include_dir, tmp_include_path = File.split tmp_include.path
1010
- tmp_include.write %(do not include\r\ntag::include-me[]\r\nincluded line\r\nend::include-me[]\r\ndo not include\r\n)
1011
- tmp_include.close
1012
- input = <<-EOS
1013
- include::#{tmp_include_path}[tag=include-me]
1014
- EOS
1015
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => tmp_include_dir
1016
- assert_includes output, 'included line'
1017
- refute_includes output, 'do not include'
1018
- ensure
1019
- tmp_include.close!
1020
- end
1021
- end
1022
-
1023
- test 'include directive finds closing tag on last line of file without a trailing newline' do
1024
- begin
1025
- tmp_include = Tempfile.new %w(include- .adoc)
1026
- tmp_include_dir, tmp_include_path = File.split tmp_include.path
1027
- tmp_include.write %(line not included\ntag::include-me[]\nline included\nend::include-me[])
1028
- tmp_include.close
1029
- input = <<-EOS
1030
- include::#{tmp_include_path}[tag=include-me]
1031
- EOS
1032
- using_memory_logger do |logger|
1033
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => tmp_include_dir
1034
- assert_empty logger.messages
1035
- assert_includes output, 'line included'
1036
- refute_includes output, 'line not included'
1037
- end
1038
- ensure
1039
- tmp_include.close!
1040
- end
1041
- end
1042
-
1043
- test 'include directive does not select lines with tag directives within selected tag region' do
1044
- input = <<-EOS
1045
- ++++
1046
- include::fixtures/include-file.asciidoc[tags=snippet]
1047
- ++++
1048
- EOS
1049
-
1050
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1051
- expect = %(snippetA content
1052
-
1053
- non-tagged content
1054
-
1055
- snippetB content)
1056
- assert_equal expect, output
1057
- end
1058
-
1059
- test 'include directive skips lines marked with negated tags' do
1060
- input = <<-EOS
1061
- ----
1062
- include::fixtures/tagged-class-enclosed.rb[tags=all;!bark]
1063
- ----
1064
- EOS
1065
-
1066
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1067
- expected = %(class Dog
1068
- def initialize breed
1069
- @breed = breed
1070
- end
1071
- end)
1072
- assert_includes output, expected
1073
- end
1074
-
1075
- test 'include directive takes all lines without tag directives when value is double asterisk' do
1076
- input = <<-EOS
1077
- ----
1078
- include::fixtures/tagged-class.rb[tags=**]
1079
- ----
1080
- EOS
1081
-
1082
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1083
- expected = %(class Dog
1084
- def initialize breed
1085
- @breed = breed
1086
- end
1087
-
1088
- def bark
1089
- if @breed == 'beagle'
1090
- 'woof woof woof woof woof'
1091
- else
1092
- 'woof woof'
1093
- end
1094
- end
1095
- end)
1096
- assert_includes output, expected
1097
- end
1098
-
1099
- test 'include directive takes all lines except negated tags when value contains double asterisk' do
1100
- input = <<-EOS
1101
- ----
1102
- include::fixtures/tagged-class.rb[tags=**;!bark]
1103
- ----
1104
- EOS
1105
-
1106
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1107
- expected = %(class Dog
1108
- def initialize breed
1109
- @breed = breed
1110
- end
1111
- end)
1112
- assert_includes output, expected
1113
- end
1114
-
1115
- test 'include directive selects lines for all tags when value of tags attribute is wildcard' do
1116
- input = <<-EOS
1117
- ----
1118
- include::fixtures/tagged-class-enclosed.rb[tags=*]
1119
- ----
1120
- EOS
1121
-
1122
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1123
- expected = %(class Dog
1124
- def initialize breed
1125
- @breed = breed
1126
- end
1127
-
1128
- def bark
1129
- if @breed == 'beagle'
1130
- 'woof woof woof woof woof'
1131
- else
1132
- 'woof woof'
1133
- end
1134
- end
1135
- end)
1136
- assert_includes output, expected
1137
- end
1138
-
1139
- test 'include directive selects lines for all tags except exclusions when value of tags attribute is wildcard' do
1140
- input = <<-EOS
1141
- ----
1142
- include::fixtures/tagged-class-enclosed.rb[tags=*;!init]
1143
- ----
1144
- EOS
1145
-
1146
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1147
- expected = %(class Dog
1148
-
1149
- def bark
1150
- if @breed == 'beagle'
1151
- 'woof woof woof woof woof'
1152
- else
1153
- 'woof woof'
1154
- end
1155
- end
1156
- end)
1157
- assert_includes output, expected
1158
- end
1159
-
1160
- test 'include directive skips lines all tagged lines when value of tags attribute is negated wildcard' do
1161
- input = <<-EOS
1162
- ----
1163
- include::fixtures/tagged-class.rb[tags=!*]
1164
- ----
1165
- EOS
1166
-
1167
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1168
- expected = %(class Dog
1169
- end)
1170
- assert_includes output, expected
1171
- end
1172
-
1173
- test 'include directive selects specified tagged lines and ignores the other tag directives' do
1174
- input = <<-EOS
1175
- [indent=0]
1176
- ----
1177
- include::fixtures/tagged-class.rb[tags=bark;!bark-other]
1178
- ----
1179
- EOS
1180
-
1181
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1182
- expected = %(def bark
1183
- if @breed == 'beagle'
1184
- 'woof woof woof woof woof'
1185
- end
1186
- end)
1187
- assert_includes output, expected
1188
- end
1189
-
1190
- test 'should warn if specified tag is not found in include file' do
1191
- input = <<-EOS
1192
- include::fixtures/include-file.asciidoc[tag=no-such-tag]
1193
- EOS
1194
-
1195
- using_memory_logger do |logger|
1196
- convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1197
- assert_message logger, :WARN, %(~<stdin>: line 1: tag 'no-such-tag' not found in include file), Hash
1198
- end
1199
- end
1200
-
1201
- test 'should warn if specified tags are not found in include file' do
1202
- input = <<-EOS
1203
- ++++
1204
- include::fixtures/include-file.asciidoc[tags=no-such-tag-b;no-such-tag-a]
1205
- ++++
1206
- EOS
1207
-
1208
- using_memory_logger do |logger|
1209
- convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1210
- # NOTE Ruby 1.8 swaps the order of the list for some silly reason
1211
- expected_tags = ::RUBY_MIN_VERSION_1_9 ? 'no-such-tag-b, no-such-tag-a' : 'no-such-tag-a, no-such-tag-b'
1212
- assert_message logger, :WARN, %(~<stdin>: line 2: tags '#{expected_tags}' not found in include file), Hash
1213
- end
1214
- end
1215
-
1216
- test 'should warn if specified tag in include file is not closed' do
1217
- input = <<-EOS
1218
- ++++
1219
- include::fixtures/unclosed-tag.adoc[tag=a]
1220
- ++++
1221
- EOS
1222
-
1223
- using_memory_logger do |logger|
1224
- result = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1225
- assert_equal 'a', result
1226
- assert_message logger, :WARN, %(~<stdin>: line 2: detected unclosed tag 'a' starting at line 2 of include file), Hash
1227
- refute_nil logger.messages[0][:message][:include_location]
1228
- end
1229
- end
1230
-
1231
- test 'should warn if end tag in included file is mismatched' do
1232
- input = <<-EOS
1233
- ++++
1234
- include::fixtures/mismatched-end-tag.adoc[tags=a;b]
1235
- ++++
1236
- EOS
1237
-
1238
- inc_path = File.join DIRNAME, 'fixtures/mismatched-end-tag.adoc'
1239
- using_memory_logger do |logger|
1240
- result = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1241
- assert_equal %(a\nb), result
1242
- assert_message logger, :WARN, %(<stdin>: line 2: mismatched end tag (expected 'b' but found 'a') at line 5 of include file: #{inc_path}), Hash
1243
- refute_nil logger.messages[0][:message][:include_location]
1244
- end
1245
- end
1246
-
1247
- test 'should warn if unexpected end tag is found in included file' do
1248
- input = <<-EOS
1249
- ++++
1250
- include::fixtures/unexpected-end-tag.adoc[tags=a]
1251
- ++++
1252
- EOS
1253
-
1254
- inc_path = File.join DIRNAME, 'fixtures/unexpected-end-tag.adoc'
1255
- using_memory_logger do |logger|
1256
- result = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1257
- assert_equal 'a', result
1258
- assert_message logger, :WARN, %(<stdin>: line 2: unexpected end tag 'a' at line 4 of include file: #{inc_path}), Hash
1259
- refute_nil logger.messages[0][:message][:include_location]
1260
- end
1261
- end
1262
-
1263
- test 'include directive ignores tags attribute when empty' do
1264
- ['tag', 'tags'].each do |attr_name|
1265
- input = <<-EOS
1266
- ++++
1267
- include::fixtures/include-file.xml[#{attr_name}=]
1268
- ++++
1269
- EOS
1270
-
1271
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1272
- assert_match(/(?:tag|end)::/, output, 2)
1273
- end
1274
- end
1275
-
1276
- test 'lines attribute takes precedence over tags attribute in include directive' do
1277
- input = <<-EOS
1278
- include::fixtures/include-file.asciidoc[lines=1, tags=snippetA;snippetB]
1279
- EOS
1280
-
1281
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1282
- assert_match(/first line of included content/, output)
1283
- refute_match(/snippetA content/, output)
1284
- refute_match(/snippetB content/, output)
1285
- end
1286
-
1287
- test 'indent of included file can be reset to size of indent attribute' do
1288
- input = <<-EOS
1289
- [source, xml]
1290
- ----
1291
- include::fixtures/basic-docinfo.xml[lines=2..3, indent=0]
1292
- ----
1293
- EOS
1294
-
1295
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1296
- result = xmlnodes_at_xpath('//pre', output, 1).text
1297
- assert_equal "<year>2013</year>\n<holder>Acme™, Inc.</holder>", result
1298
- end
1299
-
1300
- test 'should substitute attribute references in attrlist' do
1301
- input = <<-EOS
1302
- :name-of-tag: snippetA
1303
- include::fixtures/include-file.asciidoc[tag={name-of-tag}]
1304
- EOS
1305
-
1306
- output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1307
- assert_match(/snippetA content/, output)
1308
- refute_match(/snippetB content/, output)
1309
- refute_match(/non-tagged content/, output)
1310
- refute_match(/included content/, output)
1311
- end
1312
-
1313
- test 'should fall back to built-in include directive behavior when not handled by include processor' do
1314
- input = <<-EOS
1315
- include::fixtures/include-file.asciidoc[]
1316
- EOS
1317
-
1318
- include_processor = Class.new {
1319
- def initialize document
1320
- end
1321
-
1322
- def handles? target
1323
- false
1324
- end
1325
-
1326
- def process reader, target, attributes
1327
- raise 'TestIncludeHandler should not have been invoked'
1328
- end
1329
- }
1330
-
1331
- document = empty_safe_document :base_dir => DIRNAME
1332
- reader = Asciidoctor::PreprocessorReader.new document, input, nil, :normalize => true
1333
- reader.instance_variable_set '@include_processors', [include_processor.new(document)]
1334
- lines = reader.read_lines
1335
- source = lines * ::Asciidoctor::LF
1336
- assert_match(/included content/, source)
1337
- end
1338
-
1339
- test 'leveloffset attribute entries should be added to content if leveloffset attribute is specified' do
1340
- input = <<-EOS
1341
- include::fixtures/master.adoc[]
1342
- EOS
1343
-
1344
- expected = <<-EOS.chomp.split(::Asciidoctor::LF)
1345
- = Master Document
1346
-
1347
- preamble
1348
-
1349
- :leveloffset: +1
1350
-
1351
- = Chapter A
1352
-
1353
- content
1354
-
1355
- :leveloffset!:
1356
- EOS
1357
-
1358
- document = Asciidoctor.load input, :safe => :safe, :base_dir => DIRNAME, :parse => false
1359
- assert_equal expected, document.reader.read_lines
1360
- end
1361
-
1362
- test 'attributes are substituted in target of include directive' do
1363
- input = <<-EOS
1364
- :fixturesdir: fixtures
1365
- :ext: asciidoc
1366
-
1367
- include::{fixturesdir}/include-file.{ext}[]
1368
- EOS
1369
-
1370
- doc = document_from_string input, :safe => :safe, :base_dir => DIRNAME
1371
- output = doc.convert
1372
- assert_match(/included content/, output)
1373
- end
1374
-
1375
- test 'line is skipped by default if target of include directive resolves to empty' do
1376
- input = <<-EOS
1377
- include::{foodir}/include-file.asciidoc[]
1378
- EOS
1379
-
1380
- using_memory_logger do |logger|
1381
- doc = empty_safe_document :base_dir => DIRNAME
1382
- reader = Asciidoctor::PreprocessorReader.new doc, input, nil, :normalize => true
1383
- line = reader.read_line
1384
- assert_equal 'Unresolved directive in <stdin> - include::{foodir}/include-file.asciidoc[]', line
1385
- assert_message logger, :WARN, 'dropping line containing reference to missing attribute: foodir'
1386
- end
1387
- end
1388
-
1389
- test 'line is dropped if target of include directive resolves to empty and attribute-missing attribute is not skip' do
1390
- input = <<-EOS
1391
- include::{foodir}/include-file.asciidoc[]
1392
- EOS
1393
-
1394
- using_memory_logger do |logger|
1395
- doc = empty_safe_document :base_dir => DIRNAME, :attributes => {'attribute-missing' => 'drop'}
1396
- reader = Asciidoctor::PreprocessorReader.new doc, input, nil, :normalize => true
1397
- line = reader.read_line
1398
- assert_nil line
1399
- assert_message logger, :WARN, 'dropping line containing reference to missing attribute: foodir'
1400
- end
1401
- end
1402
-
1403
- test 'line following dropped include is not dropped' do
1404
- input = <<-EOS
1405
- include::{foodir}/include-file.asciidoc[]
1406
- yo
1407
- EOS
1408
-
1409
- using_memory_logger do |logger|
1410
- doc = empty_safe_document :base_dir => DIRNAME, :attributes => {'attribute-missing' => 'drop'}
1411
- reader = Asciidoctor::PreprocessorReader.new doc, input, nil, :normalize => true
1412
- line = reader.read_line
1413
- assert_equal 'yo', line
1414
- assert_message logger, :WARN, 'dropping line containing reference to missing attribute: foodir'
1415
- end
1416
- end
1417
-
1418
- test 'escaped include directive is left unprocessed' do
1419
- input = <<-EOS
1420
- \\include::fixtures/include-file.asciidoc[]
1421
- \\escape preserved here
1422
- EOS
1423
- doc = empty_safe_document :base_dir => DIRNAME
1424
- reader = Asciidoctor::PreprocessorReader.new doc, input, nil, :normalize => true
1425
- # we should be able to peek it multiple times and still have the backslash preserved
1426
- # this is the test for @unescape_next_line
1427
- assert_equal 'include::fixtures/include-file.asciidoc[]', reader.peek_line
1428
- assert_equal 'include::fixtures/include-file.asciidoc[]', reader.peek_line
1429
- assert_equal 'include::fixtures/include-file.asciidoc[]', reader.read_line
1430
- assert_equal '\\escape preserved here', reader.read_line
1431
- end
1432
-
1433
- test 'include directive not at start of line is ignored' do
1434
- input = <<-EOS
1435
- include::include-file.asciidoc[]
1436
- EOS
1437
- para = block_from_string input
1438
- assert_equal 1, para.lines.size
1439
- # NOTE the space gets stripped because the line is treated as an inline literal
1440
- assert_equal :literal, para.context
1441
- assert_equal 'include::include-file.asciidoc[]', para.source
1442
- end
1443
-
1444
- test 'include directive is disabled when max-include-depth attribute is 0' do
1445
- input = <<-EOS
1446
- include::include-file.asciidoc[]
1447
- EOS
1448
- para = block_from_string input, :safe => :safe, :attributes => { 'max-include-depth' => 0 }
1449
- assert_equal 1, para.lines.size
1450
- assert_equal 'include::include-file.asciidoc[]', para.source
1451
- end
1452
-
1453
- test 'max-include-depth cannot be set by document' do
1454
- input = <<-EOS
1455
- :max-include-depth: 1
1456
-
1457
- include::include-file.asciidoc[]
1458
- EOS
1459
- para = block_from_string input, :safe => :safe, :attributes => { 'max-include-depth' => 0 }
1460
- assert_equal 1, para.lines.size
1461
- assert_equal 'include::include-file.asciidoc[]', para.source
1462
- end
1463
-
1464
- test 'include directive should be disabled if max include depth has been exceeded' do
1465
- input = <<-EOS
1466
- include::fixtures/parent-include.adoc[depth=1]
1467
- EOS
1468
-
1469
- using_memory_logger do |logger|
1470
- pseudo_docfile = File.join DIRNAME, 'include-master.adoc'
1471
- doc = empty_safe_document :base_dir => DIRNAME
1472
- reader = Asciidoctor::PreprocessorReader.new doc, input, Asciidoctor::Reader::Cursor.new(pseudo_docfile), :normalize => true
1473
- lines = reader.readlines
1474
- assert_includes lines, 'include::child-include.adoc[]'
1475
- assert_message logger, :ERROR, 'fixtures/parent-include.adoc: line 3: maximum include depth of 1 exceeded', Hash
1476
- end
1477
- end
1478
-
1479
- test 'include directive should be disabled if max include depth set in nested context has been exceeded' do
1480
- input = <<-EOS
1481
- include::fixtures/parent-include-restricted.adoc[depth=3]
1482
- EOS
1483
-
1484
- using_memory_logger do |logger|
1485
- pseudo_docfile = File.join DIRNAME, 'include-master.adoc'
1486
- doc = empty_safe_document :base_dir => DIRNAME
1487
- reader = Asciidoctor::PreprocessorReader.new doc, input, Asciidoctor::Reader::Cursor.new(pseudo_docfile), :normalize => true
1488
- lines = reader.readlines
1489
- assert_includes lines, 'first line of child'
1490
- assert_includes lines, 'include::grandchild-include.adoc[]'
1491
- assert_message logger, :ERROR, 'fixtures/child-include.adoc: line 3: maximum include depth of 1 exceeded', Hash
1492
- end
1493
- end
1494
-
1495
- test 'read_lines_until should not process lines if process option is false' do
1496
- lines = <<-EOS.each_line.to_a
1497
- ////
1498
- include::fixtures/no-such-file.adoc[]
1499
- ////
1500
- EOS
1501
-
1502
- doc = empty_safe_document :base_dir => DIRNAME
1503
- reader = Asciidoctor::PreprocessorReader.new doc, lines, nil, :normalize => true
1504
- reader.read_line
1505
- result = reader.read_lines_until(:terminator => '////', :skip_processing => true)
1506
- assert_equal lines.map {|l| l.chomp}[1..1], result
1507
- end
1508
-
1509
- test 'skip_comment_lines should not process lines read' do
1510
- lines = <<-EOS.each_line.to_a
1511
- ////
1512
- include::fixtures/no-such-file.adoc[]
1513
- ////
1514
- EOS
1515
-
1516
- using_memory_logger do |logger|
1517
- doc = empty_safe_document :base_dir => DIRNAME
1518
- reader = Asciidoctor::PreprocessorReader.new doc, lines, nil, :normalize => true
1519
- reader.skip_comment_lines
1520
- assert reader.empty?
1521
- assert logger.empty?
1522
- end
1523
- end
1524
- end
1525
-
1526
- context 'Conditional Inclusions' do
1527
- test 'process_line returns nil if cursor advanced' do
1528
- input = <<-EOS
1529
- ifdef::asciidoctor[]
1530
- Asciidoctor!
1531
- endif::asciidoctor[]
1532
- EOS
1533
-
1534
- doc = Asciidoctor::Document.new input
1535
- reader = doc.reader
1536
- assert_nil reader.process_line(reader.lines.first)
1537
- end
1538
-
1539
- test 'peek_line advances cursor to next conditional line of content' do
1540
- input = <<-EOS
1541
- ifdef::asciidoctor[]
1542
- Asciidoctor!
1543
- endif::asciidoctor[]
1544
- EOS
1545
-
1546
- doc = Asciidoctor::Document.new input
1547
- reader = doc.reader
1548
- assert_equal 1, reader.lineno
1549
- assert_equal 'Asciidoctor!', reader.peek_line
1550
- assert_equal 2, reader.lineno
1551
- end
1552
-
1553
- test 'peek_lines should preprocess lines if direct is false' do
1554
- input = <<-EOS
1555
- The Asciidoctor
1556
- ifdef::asciidoctor[is in.]
1557
- EOS
1558
- doc = Asciidoctor::Document.new input
1559
- reader = doc.reader
1560
- result = reader.peek_lines 2, false
1561
- assert_equal ['The Asciidoctor', 'is in.'], result
1562
- end
1563
-
1564
- test 'peek_lines should not preprocess lines if direct is true' do
1565
- input = <<-EOS
1566
- The Asciidoctor
1567
- ifdef::asciidoctor[is in.]
1568
- EOS
1569
- doc = Asciidoctor::Document.new input
1570
- reader = doc.reader
1571
- result = reader.peek_lines 2, true
1572
- assert_equal ['The Asciidoctor', 'ifdef::asciidoctor[is in.]'], result
1573
- end
1574
-
1575
- test 'peek_lines should not prevent subsequent preprocessing of peeked lines' do
1576
- input = <<-EOS
1577
- The Asciidoctor
1578
- ifdef::asciidoctor[is in.]
1579
- EOS
1580
- doc = Asciidoctor::Document.new input
1581
- reader = doc.reader
1582
- result = reader.peek_lines 2, true
1583
- result = reader.peek_lines 2, false
1584
- assert_equal ['The Asciidoctor', 'is in.'], result
1585
- end
1586
-
1587
- test 'process_line returns line if cursor not advanced' do
1588
- input = <<-EOS
1589
- content
1590
- ifdef::asciidoctor[]
1591
- Asciidoctor!
1592
- endif::asciidoctor[]
1593
- EOS
1594
-
1595
- doc = Asciidoctor::Document.new input
1596
- reader = doc.reader
1597
- refute_nil reader.process_line(reader.lines.first)
1598
- end
1599
-
1600
- test 'peek_line does not advance cursor when on a regular content line' do
1601
- input = <<-EOS
1602
- content
1603
- ifdef::asciidoctor[]
1604
- Asciidoctor!
1605
- endif::asciidoctor[]
1606
- EOS
1607
-
1608
- doc = Asciidoctor::Document.new input
1609
- reader = doc.reader
1610
- assert_equal 1, reader.lineno
1611
- assert_equal 'content', reader.peek_line
1612
- assert_equal 1, reader.lineno
1613
- end
1614
-
1615
- test 'peek_line returns nil if cursor advances past end of source' do
1616
- input = <<-EOS
1617
- ifdef::foobar[]
1618
- swallowed content
1619
- endif::foobar[]
1620
- EOS
1621
-
1622
- doc = Asciidoctor::Document.new input
1623
- reader = doc.reader
1624
- assert_equal 1, reader.lineno
1625
- assert_nil reader.peek_line
1626
- assert_equal 4, reader.lineno
1627
- end
1628
-
1629
- test 'ifdef with defined attribute includes content' do
1630
- input = <<-EOS
1631
- ifdef::holygrail[]
1632
- There is a holy grail!
1633
- endif::holygrail[]
1634
- EOS
1635
-
1636
- doc = Asciidoctor::Document.new input, :attributes => { 'holygrail' => '' }
1637
- reader = doc.reader
1638
- lines = []
1639
- while reader.has_more_lines?
1640
- lines << reader.read_line
1641
- end
1642
- assert_equal 'There is a holy grail!', (lines * ::Asciidoctor::LF)
1643
- end
1644
-
1645
- test 'ifdef with defined attribute includes text in brackets' do
1646
- input = <<-EOS
1647
- On our quest we go...
1648
- ifdef::holygrail[There is a holy grail!]
1649
- There was much rejoicing.
1650
- EOS
1651
-
1652
- doc = Asciidoctor::Document.new input, :attributes => { 'holygrail' => '' }
1653
- reader = doc.reader
1654
- lines = []
1655
- while reader.has_more_lines?
1656
- lines << reader.read_line
1657
- end
1658
- assert_equal "On our quest we go...\nThere is a holy grail!\nThere was much rejoicing.", (lines * ::Asciidoctor::LF)
1659
- end
1660
-
1661
- test 'ifdef with defined attribute processes include directive in brackets' do
1662
- input = <<-EOS
1663
- ifdef::asciidoctor-version[include::fixtures/include-file.asciidoc[tag=snippetA]]
1664
- EOS
1665
-
1666
- doc = Asciidoctor::Document.new input, :safe => :safe, :base_dir => DIRNAME
1667
- reader = doc.reader
1668
- lines = []
1669
- while reader.has_more_lines?
1670
- lines << reader.read_line
1671
- end
1672
- assert_equal 'snippetA content', lines[0]
1673
- end
1674
-
1675
- test 'ifdef attribute name is not case sensitive' do
1676
- input = <<-EOS
1677
- ifdef::showScript[]
1678
- The script is shown!
1679
- endif::showScript[]
1680
- EOS
1681
-
1682
- doc = Asciidoctor::Document.new input, :attributes => { 'showscript' => '' }
1683
- result = doc.reader.read
1684
- assert_equal 'The script is shown!', result
1685
- end
1686
-
1687
- test 'ifndef with defined attribute does not include text in brackets' do
1688
- input = <<-EOS
1689
- On our quest we go...
1690
- ifndef::hardships[There is a holy grail!]
1691
- There was no rejoicing.
1692
- EOS
1693
-
1694
- doc = Asciidoctor::Document.new input, :attributes => { 'hardships' => '' }
1695
- reader = doc.reader
1696
- lines = []
1697
- while reader.has_more_lines?
1698
- lines << reader.read_line
1699
- end
1700
- assert_equal "On our quest we go...\nThere was no rejoicing.", (lines * ::Asciidoctor::LF)
1701
- end
1702
-
1703
- test 'include with non-matching nested exclude' do
1704
- input = <<-EOS
1705
- ifdef::grail[]
1706
- holy
1707
- ifdef::swallow[]
1708
- swallow
1709
- endif::swallow[]
1710
- grail
1711
- endif::grail[]
1712
- EOS
1713
-
1714
- doc = Asciidoctor::Document.new input, :attributes => { 'grail' => '' }
1715
- reader = doc.reader
1716
- lines = []
1717
- while reader.has_more_lines?
1718
- lines << reader.read_line
1719
- end
1720
- assert_equal "holy\ngrail", (lines * ::Asciidoctor::LF)
1721
- end
1722
-
1723
- test 'nested excludes with same condition' do
1724
- input = <<-EOS
1725
- ifndef::grail[]
1726
- ifndef::grail[]
1727
- not here
1728
- endif::grail[]
1729
- endif::grail[]
1730
- EOS
1731
-
1732
- doc = Asciidoctor::Document.new input, :attributes => { 'grail' => '' }
1733
- reader = doc.reader
1734
- lines = []
1735
- while reader.has_more_lines?
1736
- lines << reader.read_line
1737
- end
1738
- assert_equal '', (lines * ::Asciidoctor::LF)
1739
- end
1740
-
1741
- test 'include with nested exclude of inverted condition' do
1742
- input = <<-EOS
1743
- ifdef::grail[]
1744
- holy
1745
- ifndef::grail[]
1746
- not here
1747
- endif::grail[]
1748
- grail
1749
- endif::grail[]
1750
- EOS
1751
-
1752
- doc = Asciidoctor::Document.new input, :attributes => { 'grail' => '' }
1753
- reader = doc.reader
1754
- lines = []
1755
- while reader.has_more_lines?
1756
- lines << reader.read_line
1757
- end
1758
- assert_equal "holy\ngrail", (lines * ::Asciidoctor::LF)
1759
- end
1760
-
1761
- test 'exclude with matching nested exclude' do
1762
- input = <<-EOS
1763
- poof
1764
- ifdef::swallow[]
1765
- no
1766
- ifdef::swallow[]
1767
- swallow
1768
- endif::swallow[]
1769
- here
1770
- endif::swallow[]
1771
- gone
1772
- EOS
1773
-
1774
- doc = Asciidoctor::Document.new input, :attributes => { 'grail' => '' }
1775
- reader = doc.reader
1776
- lines = []
1777
- while reader.has_more_lines?
1778
- lines << reader.read_line
1779
- end
1780
- assert_equal "poof\ngone", (lines * ::Asciidoctor::LF)
1781
- end
1782
-
1783
- test 'exclude with nested include using shorthand end' do
1784
- input = <<-EOS
1785
- poof
1786
- ifndef::grail[]
1787
- no grail
1788
- ifndef::swallow[]
1789
- or swallow
1790
- endif::[]
1791
- in here
1792
- endif::[]
1793
- gone
1794
- EOS
1795
-
1796
- doc = Asciidoctor::Document.new input, :attributes => { 'grail' => '' }
1797
- reader = doc.reader
1798
- lines = []
1799
- while reader.has_more_lines?
1800
- lines << reader.read_line
1801
- end
1802
- assert_equal "poof\ngone", (lines * ::Asciidoctor::LF)
1803
- end
1804
-
1805
- test 'ifdef with one alternative attribute set includes content' do
1806
- input = <<-EOS
1807
- ifdef::holygrail,swallow[]
1808
- Our quest is complete!
1809
- endif::holygrail,swallow[]
1810
- EOS
1811
-
1812
- doc = Asciidoctor::Document.new input, :attributes => { 'swallow' => '' }
1813
- reader = doc.reader
1814
- lines = []
1815
- while reader.has_more_lines?
1816
- lines << reader.read_line
1817
- end
1818
- assert_equal 'Our quest is complete!', (lines * ::Asciidoctor::LF)
1819
- end
1820
-
1821
- test 'ifdef with no alternative attributes set does not include content' do
1822
- input = <<-EOS
1823
- ifdef::holygrail,swallow[]
1824
- Our quest is complete!
1825
- endif::holygrail,swallow[]
1826
- EOS
1827
-
1828
- doc = Asciidoctor::Document.new input
1829
- reader = doc.reader
1830
- lines = []
1831
- while reader.has_more_lines?
1832
- lines << reader.read_line
1833
- end
1834
- assert_equal '', (lines * ::Asciidoctor::LF)
1835
- end
1836
-
1837
- test 'ifdef with all required attributes set includes content' do
1838
- input = <<-EOS
1839
- ifdef::holygrail+swallow[]
1840
- Our quest is complete!
1841
- endif::holygrail+swallow[]
1842
- EOS
1843
-
1844
- doc = Asciidoctor::Document.new input, :attributes => { 'holygrail' => '', 'swallow' => '' }
1845
- reader = doc.reader
1846
- lines = []
1847
- while reader.has_more_lines?
1848
- lines << reader.read_line
1849
- end
1850
- assert_equal 'Our quest is complete!', (lines * ::Asciidoctor::LF)
1851
- end
1852
-
1853
- test 'ifdef with missing required attributes does not include content' do
1854
- input = <<-EOS
1855
- ifdef::holygrail+swallow[]
1856
- Our quest is complete!
1857
- endif::holygrail+swallow[]
1858
- EOS
1859
-
1860
- doc = Asciidoctor::Document.new input, :attributes => { 'holygrail' => '' }
1861
- reader = doc.reader
1862
- lines = []
1863
- while reader.has_more_lines?
1864
- lines << reader.read_line
1865
- end
1866
- assert_equal '', (lines * ::Asciidoctor::LF)
1867
- end
1868
-
1869
- test 'ifdef should permit leading, trailing, and repeat operators' do
1870
- {
1871
- 'asciidoctor,' => 'content',
1872
- ',asciidoctor' => 'content',
1873
- 'asciidoctor+' => '',
1874
- '+asciidoctor' => '',
1875
- 'asciidoctor,,asciidoctor-version' => 'content',
1876
- 'asciidoctor++asciidoctor-version' => ''
1877
- }.each do |condition, expected|
1878
- input = <<-EOS
1879
- ifdef::#{condition}[]
1880
- content
1881
- endif::[]
1882
- EOS
1883
- assert_equal expected, (document_from_string input, :parse => false).reader.read
1884
- end
1885
- end
1886
-
1887
- test 'ifndef with undefined attribute includes block' do
1888
- input = <<-EOS
1889
- ifndef::holygrail[]
1890
- Our quest continues to find the holy grail!
1891
- endif::holygrail[]
1892
- EOS
1893
-
1894
- doc = Asciidoctor::Document.new input
1895
- reader = doc.reader
1896
- lines = []
1897
- while reader.has_more_lines?
1898
- lines << reader.read_line
1899
- end
1900
- assert_equal 'Our quest continues to find the holy grail!', (lines * ::Asciidoctor::LF)
1901
- end
1902
-
1903
- test 'ifndef with one alternative attribute set does not include content' do
1904
- input = <<-EOS
1905
- ifndef::holygrail,swallow[]
1906
- Our quest is complete!
1907
- endif::holygrail,swallow[]
1908
- EOS
1909
-
1910
- result = (Asciidoctor::Document.new input, :attributes => { 'swallow' => '' }).reader.read
1911
- assert_empty result
1912
- end
1913
-
1914
- test 'ifndef with both alternative attributes set does not include content' do
1915
- input = <<-EOS
1916
- ifndef::holygrail,swallow[]
1917
- Our quest is complete!
1918
- endif::holygrail,swallow[]
1919
- EOS
1920
-
1921
- result = (Asciidoctor::Document.new input, :attributes => { 'swallow' => '', 'holygrail' => '' }).reader.read
1922
- assert_empty result
1923
- end
1924
-
1925
- test 'ifndef with no alternative attributes set includes content' do
1926
- input = <<-EOS
1927
- ifndef::holygrail,swallow[]
1928
- Our quest is complete!
1929
- endif::holygrail,swallow[]
1930
- EOS
1931
-
1932
- result = (Asciidoctor::Document.new input).reader.read
1933
- assert_equal 'Our quest is complete!', result
1934
- end
1935
-
1936
- test 'ifndef with no required attributes set includes content' do
1937
- input = <<-EOS
1938
- ifndef::holygrail+swallow[]
1939
- Our quest is complete!
1940
- endif::holygrail+swallow[]
1941
- EOS
1942
-
1943
- result = (Asciidoctor::Document.new input).reader.read
1944
- assert_equal 'Our quest is complete!', result
1945
- end
1946
-
1947
- test 'ifndef with all required attributes set does not include content' do
1948
- input = <<-EOS
1949
- ifndef::holygrail+swallow[]
1950
- Our quest is complete!
1951
- endif::holygrail+swallow[]
1952
- EOS
1953
-
1954
- result = (Asciidoctor::Document.new input, :attributes => { 'swallow' => '', 'holygrail' => '' }).reader.read
1955
- assert_empty result
1956
- end
1957
-
1958
- test 'ifndef with at least one required attributes set does not include content' do
1959
- input = <<-EOS
1960
- ifndef::holygrail+swallow[]
1961
- Our quest is complete!
1962
- endif::holygrail+swallow[]
1963
- EOS
1964
-
1965
- result = (Asciidoctor::Document.new input, :attributes => { 'swallow' => '' }).reader.read
1966
- assert_equal 'Our quest is complete!', result
1967
- end
1968
-
1969
- test 'escaped ifdef is unescaped and ignored' do
1970
- input = <<-EOS
1971
- \\ifdef::holygrail[]
1972
- content
1973
- \\endif::holygrail[]
1974
- EOS
1975
-
1976
- doc = Asciidoctor::Document.new input
1977
- reader = doc.reader
1978
- lines = []
1979
- while reader.has_more_lines?
1980
- lines << reader.read_line
1981
- end
1982
- assert_equal "ifdef::holygrail[]\ncontent\nendif::holygrail[]", (lines * ::Asciidoctor::LF)
1983
- end
1984
-
1985
- test 'ifeval comparing missing attribute to nil includes content' do
1986
- input = <<-EOS
1987
- ifeval::['{foo}' == '']
1988
- No foo for you!
1989
- endif::[]
1990
- EOS
1991
-
1992
- doc = Asciidoctor::Document.new input
1993
- reader = doc.reader
1994
- lines = []
1995
- while reader.has_more_lines?
1996
- lines << reader.read_line
1997
- end
1998
- assert_equal 'No foo for you!', (lines * ::Asciidoctor::LF)
1999
- end
2000
-
2001
- test 'ifeval comparing missing attribute to 0 drops content' do
2002
- input = <<-EOS
2003
- ifeval::[{leveloffset} == 0]
2004
- I didn't make the cut!
2005
- endif::[]
2006
- EOS
2007
-
2008
- doc = Asciidoctor::Document.new input
2009
- reader = doc.reader
2010
- lines = []
2011
- while reader.has_more_lines?
2012
- lines << reader.read_line
2013
- end
2014
- assert_equal '', (lines * ::Asciidoctor::LF)
2015
- end
2016
-
2017
- test 'ifeval comparing double-quoted attribute to matching string includes content' do
2018
- input = <<-EOS
2019
- ifeval::["{gem}" == "asciidoctor"]
2020
- Asciidoctor it is!
2021
- endif::[]
2022
- EOS
2023
-
2024
- doc = Asciidoctor::Document.new input, :attributes => { 'gem' => 'asciidoctor' }
2025
- reader = doc.reader
2026
- lines = []
2027
- while reader.has_more_lines?
2028
- lines << reader.read_line
2029
- end
2030
- assert_equal 'Asciidoctor it is!', (lines * ::Asciidoctor::LF)
2031
- end
2032
-
2033
- test 'ifeval comparing single-quoted attribute to matching string includes content' do
2034
- input = <<-EOS
2035
- ifeval::['{gem}' == 'asciidoctor']
2036
- Asciidoctor it is!
2037
- endif::[]
2038
- EOS
2039
-
2040
- doc = Asciidoctor::Document.new input, :attributes => { 'gem' => 'asciidoctor' }
2041
- reader = doc.reader
2042
- lines = []
2043
- while reader.has_more_lines?
2044
- lines << reader.read_line
2045
- end
2046
- assert_equal 'Asciidoctor it is!', (lines * ::Asciidoctor::LF)
2047
- end
2048
-
2049
- test 'ifeval comparing quoted attribute to non-matching string drops content' do
2050
- input = <<-EOS
2051
- ifeval::['{gem}' == 'asciidoctor']
2052
- Asciidoctor it is!
2053
- endif::[]
2054
- EOS
2055
-
2056
- doc = Asciidoctor::Document.new input, :attributes => { 'gem' => 'tilt' }
2057
- reader = doc.reader
2058
- lines = []
2059
- while reader.has_more_lines?
2060
- lines << reader.read_line
2061
- end
2062
- assert_equal '', (lines * ::Asciidoctor::LF)
2063
- end
2064
-
2065
- test 'ifeval comparing attribute to lower version number includes content' do
2066
- input = <<-EOS
2067
- ifeval::['{asciidoctor-version}' >= '0.1.0']
2068
- That version will do!
2069
- endif::[]
2070
- EOS
2071
-
2072
- doc = Asciidoctor::Document.new input
2073
- reader = doc.reader
2074
- lines = []
2075
- while reader.has_more_lines?
2076
- lines << reader.read_line
2077
- end
2078
- assert_equal 'That version will do!', (lines * ::Asciidoctor::LF)
2079
- end
2080
-
2081
- test 'ifeval comparing attribute to self includes content' do
2082
- input = <<-EOS
2083
- ifeval::['{asciidoctor-version}' == '{asciidoctor-version}']
2084
- Of course it's the same!
2085
- endif::[]
2086
- EOS
2087
-
2088
- doc = Asciidoctor::Document.new input
2089
- reader = doc.reader
2090
- lines = []
2091
- while reader.has_more_lines?
2092
- lines << reader.read_line
2093
- end
2094
- assert_equal 'Of course it\'s the same!', (lines * ::Asciidoctor::LF)
2095
- end
2096
-
2097
- test 'ifeval arguments can be transposed' do
2098
- input = <<-EOS
2099
- ifeval::['0.1.0' <= '{asciidoctor-version}']
2100
- That version will do!
2101
- endif::[]
2102
- EOS
2103
-
2104
- doc = Asciidoctor::Document.new input
2105
- reader = doc.reader
2106
- lines = []
2107
- while reader.has_more_lines?
2108
- lines << reader.read_line
2109
- end
2110
- assert_equal 'That version will do!', (lines * ::Asciidoctor::LF)
2111
- end
2112
-
2113
- test 'ifeval matching numeric equality includes content' do
2114
- input = <<-EOS
2115
- ifeval::[{rings} == 1]
2116
- One ring to rule them all!
2117
- endif::[]
2118
- EOS
2119
-
2120
- doc = Asciidoctor::Document.new input, :attributes => { 'rings' => '1' }
2121
- reader = doc.reader
2122
- lines = []
2123
- while reader.has_more_lines?
2124
- lines << reader.read_line
2125
- end
2126
- assert_equal 'One ring to rule them all!', (lines * ::Asciidoctor::LF)
2127
- end
2128
-
2129
- test 'ifeval matching numeric inequality includes content' do
2130
- input = <<-EOS
2131
- ifeval::[{rings} != 0]
2132
- One ring to rule them all!
2133
- endif::[]
2134
- EOS
2135
-
2136
- doc = Asciidoctor::Document.new input, :attributes => { 'rings' => '1' }
2137
- reader = doc.reader
2138
- lines = []
2139
- while reader.has_more_lines?
2140
- lines << reader.read_line
2141
- end
2142
- assert_equal 'One ring to rule them all!', (lines * ::Asciidoctor::LF)
2143
- end
2144
-
2145
- test 'ifdef with no target is ignored' do
2146
- input = <<-EOS
2147
- ifdef::[]
2148
- content
2149
- EOS
2150
-
2151
- doc = Asciidoctor::Document.new input
2152
- reader = doc.reader
2153
- lines = []
2154
- while reader.has_more_lines?
2155
- lines << reader.read_line
2156
- end
2157
- assert_equal "ifdef::[]\ncontent", (lines * ::Asciidoctor::LF)
2158
- end
2159
- end
2160
- end
2161
- end