asciidoctor 1.5.8 → 2.0.0.rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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