asciidoctor 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of asciidoctor might be problematic. Click here for more details.

Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +387 -0
  3. data/README.adoc +358 -348
  4. data/asciidoctor.gemspec +30 -9
  5. data/bin/asciidoctor +3 -0
  6. data/bin/asciidoctor-safe +3 -0
  7. data/compat/asciidoc.conf +76 -4
  8. data/lib/asciidoctor.rb +174 -79
  9. data/lib/asciidoctor/abstract_block.rb +131 -101
  10. data/lib/asciidoctor/abstract_node.rb +108 -26
  11. data/lib/asciidoctor/attribute_list.rb +1 -1
  12. data/lib/asciidoctor/backends/_stylesheets.rb +204 -62
  13. data/lib/asciidoctor/backends/base_template.rb +11 -22
  14. data/lib/asciidoctor/backends/docbook45.rb +158 -163
  15. data/lib/asciidoctor/backends/docbook5.rb +103 -0
  16. data/lib/asciidoctor/backends/html5.rb +662 -445
  17. data/lib/asciidoctor/block.rb +54 -44
  18. data/lib/asciidoctor/cli/invoker.rb +41 -20
  19. data/lib/asciidoctor/cli/options.rb +66 -20
  20. data/lib/asciidoctor/debug.rb +1 -1
  21. data/lib/asciidoctor/document.rb +265 -100
  22. data/lib/asciidoctor/extensions.rb +443 -0
  23. data/lib/asciidoctor/helpers.rb +38 -6
  24. data/lib/asciidoctor/inline.rb +5 -5
  25. data/lib/asciidoctor/lexer.rb +532 -250
  26. data/lib/asciidoctor/{list_item.rb → list.rb} +33 -13
  27. data/lib/asciidoctor/path_resolver.rb +28 -2
  28. data/lib/asciidoctor/reader.rb +814 -455
  29. data/lib/asciidoctor/renderer.rb +128 -42
  30. data/lib/asciidoctor/section.rb +55 -41
  31. data/lib/asciidoctor/substituters.rb +380 -107
  32. data/lib/asciidoctor/table.rb +40 -30
  33. data/lib/asciidoctor/version.rb +1 -1
  34. data/man/asciidoctor.1 +32 -96
  35. data/man/{asciidoctor.ad → asciidoctor.adoc} +57 -48
  36. data/test/attributes_test.rb +200 -27
  37. data/test/blocks_test.rb +361 -22
  38. data/test/document_test.rb +496 -81
  39. data/test/extensions_test.rb +448 -0
  40. data/test/fixtures/basic-docinfo-footer.html +6 -0
  41. data/test/fixtures/basic-docinfo-footer.xml +8 -0
  42. data/test/fixtures/basic-docinfo.xml +3 -3
  43. data/test/fixtures/basic.asciidoc +1 -0
  44. data/test/fixtures/child-include.adoc +5 -0
  45. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
  46. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
  47. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
  48. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
  49. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
  50. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
  51. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
  52. data/test/fixtures/docinfo-footer.html +1 -0
  53. data/test/fixtures/docinfo-footer.xml +9 -0
  54. data/test/fixtures/docinfo.xml +1 -0
  55. data/test/fixtures/grandchild-include.adoc +3 -0
  56. data/test/fixtures/parent-include-restricted.adoc +5 -0
  57. data/test/fixtures/parent-include.adoc +5 -0
  58. data/test/invoker_test.rb +82 -8
  59. data/test/lexer_test.rb +21 -3
  60. data/test/links_test.rb +34 -2
  61. data/test/lists_test.rb +304 -7
  62. data/test/options_test.rb +19 -3
  63. data/test/paragraphs_test.rb +13 -0
  64. data/test/paths_test.rb +22 -0
  65. data/test/preamble_test.rb +20 -0
  66. data/test/reader_test.rb +1096 -644
  67. data/test/renderer_test.rb +152 -12
  68. data/test/sections_test.rb +417 -76
  69. data/test/substitutions_test.rb +339 -138
  70. data/test/tables_test.rb +109 -4
  71. data/test/test_helper.rb +79 -13
  72. data/test/text_test.rb +111 -11
  73. metadata +54 -18
@@ -36,9 +36,9 @@ context 'Options' do
36
36
 
37
37
  test 'should emit warning when unparsed options remain' do
38
38
  redirect_streams do |stdout, stderr|
39
- options = Asciidoctor::Cli::Options.parse!(%w(-b docbook extra junk test/fixtures/sample.asciidoc))
39
+ options = Asciidoctor::Cli::Options.parse!(%w(-b docbook - -))
40
40
  assert options.is_a? Hash
41
- assert_equal 'asciidoctor: WARNING: extra arguments detected (unparsed arguments: \'extra\', \'junk\')', stderr.string.chomp
41
+ assert_match(/asciidoctor: WARNING: extra arguments .*/, stderr.string.chomp)
42
42
  end
43
43
  end
44
44
 
@@ -48,7 +48,8 @@ context 'Options' do
48
48
  assert_equal true, options[:verbose]
49
49
  assert_equal false, options[:header_footer]
50
50
  assert_equal 'book', options[:attributes]['doctype']
51
- assert_equal 'test/fixtures/sample.asciidoc', options[:input_file]
51
+ assert_equal 1, options[:input_files].size
52
+ assert_equal 'test/fixtures/sample.asciidoc', options[:input_files][0]
52
53
  end
53
54
 
54
55
  test 'standard attribute assignment' do
@@ -92,4 +93,19 @@ context 'Options' do
92
93
  assert_equal 'inline', options[:attributes]['doctype']
93
94
  end
94
95
 
96
+ test 'template engine assignment' do
97
+ options = Asciidoctor::Cli::Options.parse!(%w(-E haml test/fixtures/sample.asciidoc))
98
+ assert_equal 'haml', options[:template_engine]
99
+ end
100
+
101
+ test 'template directory assignment' do
102
+ options = Asciidoctor::Cli::Options.parse!(%w(-T custom-backend test/fixtures/sample.asciidoc))
103
+ assert_equal ['custom-backend'], options[:template_dirs]
104
+ end
105
+
106
+ test 'multiple template directory assignments' do
107
+ options = Asciidoctor::Cli::Options.parse!(%w(-T custom-backend -T custom-backend-hacks test/fixtures/sample.asciidoc))
108
+ assert_equal ['custom-backend', 'custom-backend-hacks'], options[:template_dirs]
109
+ end
110
+
95
111
  end
@@ -83,6 +83,19 @@ Nothing special.
83
83
  assert_css 'p', output, 1
84
84
  end
85
85
 
86
+ test 'removes indentation from literal paragraph marked as normal' do
87
+ input = <<-EOS
88
+ [normal]
89
+ Normal paragraph.
90
+ Nothing special.
91
+ Last line.
92
+ EOS
93
+
94
+ output = render_embedded_string input
95
+ assert_css 'p', output, 1
96
+ assert_xpath %(//p[text()="Normal paragraph.\n Nothing special.\nLast line."]), output, 1
97
+ end
98
+
86
99
  test 'normal paragraph terminates at block attribute list' do
87
100
  input = <<-EOS
88
101
  normal text
@@ -42,6 +42,10 @@ context 'Path Resolver' do
42
42
  assert_equal './assets/images', @resolver.web_path('./images', './assets')
43
43
  end
44
44
 
45
+ test 'target with relative path appended to url start path' do
46
+ assert_equal 'http://www.example.com/assets/images', @resolver.web_path('images', 'http://www.example.com/assets')
47
+ end
48
+
45
49
  test 'normalize target' do
46
50
  assert_equal '../images', @resolver.web_path('../images/../images')
47
51
  end
@@ -170,5 +174,23 @@ context 'Path Resolver' do
170
174
  assert_equal 'C:/data/docs', @resolver.system_path('..\\..', "C:\\data\\docs\\assets", 'C:\\data\\docs')
171
175
  assert_equal 'C:/data/docs/css', @resolver.system_path('..\\..\\css', "C:\\data\\docs\\assets", 'C:\\data\\docs')
172
176
  end
177
+
178
+ test 'should calculate relative path' do
179
+ filename = @resolver.system_path('part1/chapter1/section1.adoc', nil, JAIL)
180
+ assert_equal "#{JAIL}/part1/chapter1/section1.adoc", filename
181
+ assert_equal 'part1/chapter1/section1.adoc', @resolver.relative_path(filename, JAIL)
182
+ end
183
+ end
184
+
185
+ context 'Helpers' do
186
+ test 'rootname should return file name without extension' do
187
+ assert_equal 'master', Asciidoctor::Helpers.rootname('master.adoc')
188
+ assert_equal 'docs/master', Asciidoctor::Helpers.rootname('docs/master.adoc')
189
+ end
190
+
191
+ test 'rootname should file name if it has no extension' do
192
+ assert_equal 'master', Asciidoctor::Helpers.rootname('master')
193
+ assert_equal 'docs/master', Asciidoctor::Helpers.rootname('docs/master')
194
+ end
173
195
  end
174
196
  end
@@ -109,4 +109,24 @@ They couldn't believe their eyes when...
109
109
  assert_xpath %{//*[@id="preamble"]//p[text() = "Back then#{[8230].pack('U*')}"]}, output, 1
110
110
  end
111
111
 
112
+ test 'should render table of contents in preamble if toc-placement attribute value is preamble' do
113
+ input = <<-EOS
114
+ = Article
115
+ :toc:
116
+ :toc-placement: preamble
117
+
118
+ Once upon a time...
119
+
120
+ == Section One
121
+
122
+ It was a dark and stormy night...
123
+
124
+ == Section Two
125
+
126
+ They couldn't believe their eyes when...
127
+ EOS
128
+
129
+ output = render_string input
130
+ assert_xpath '//*[@id="preamble"]/*[@id="toc"]', output, 1
131
+ end
112
132
  end
@@ -1,98 +1,257 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class ReaderTest < Test::Unit::TestCase
4
- # setup for test
5
- def setup
6
- @src_data = File.readlines(sample_doc_path(:asciidoc_index))
7
- @reader = Asciidoctor::Reader.new @src_data
8
- end
4
+ DIRNAME = File.expand_path(File.dirname(__FILE__))
9
5
 
10
- context "has_more_lines?" do
11
- test "returns false for empty document" do
12
- assert !Asciidoctor::Reader.new.has_more_lines?
13
- end
6
+ SAMPLE_DATA = <<-EOS.each_line.to_a
7
+ first line
8
+ second line
9
+ third line
10
+ EOS
11
+
12
+ context 'Reader' do
13
+ context 'Prepare lines' do
14
+ test 'should prepare lines from Array data' do
15
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
16
+ assert_equal SAMPLE_DATA, reader.lines
17
+ end
14
18
 
15
- test "returns true with lines remaining" do
16
- assert @reader.has_more_lines?, "Yo, didn't work"
19
+ test 'should prepare lines from String data' do
20
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
21
+ assert_equal SAMPLE_DATA, reader.lines
22
+ end
17
23
  end
18
- end
19
24
 
20
- context "with source data loaded" do
21
- test "get_line returns next line" do
22
- assert_equal @src_data[0], @reader.get_line
23
- end
25
+ context 'With empty data' do
26
+ test 'has_more_lines? should return false with empty data' do
27
+ assert !Asciidoctor::Reader.new.has_more_lines?
28
+ end
24
29
 
25
- test "get_line consumes the line it returns" do
26
- reader = Asciidoctor::Reader.new(["foo", "bar"])
27
- _ = reader.get_line
28
- second = reader.get_line
29
- assert_equal "bar", second
30
+ test 'empty? should return true with empty data' do
31
+ assert Asciidoctor::Reader.new.empty?
32
+ assert Asciidoctor::Reader.new.eof?
33
+ end
34
+
35
+ test 'next_line_empty? should return true with empty data' do
36
+ assert Asciidoctor::Reader.new.next_line_empty?
37
+ end
38
+
39
+ test 'peek_line should return nil with empty data' do
40
+ assert_nil Asciidoctor::Reader.new.peek_line
41
+ end
42
+
43
+ test 'peek_lines should return empty Array with empty data' do
44
+ assert_equal [], Asciidoctor::Reader.new.peek_lines
45
+ end
46
+
47
+ test 'read_line should return nil with empty data' do
48
+ assert_nil Asciidoctor::Reader.new.read_line
49
+ #assert_nil Asciidoctor::Reader.new.get_line
50
+ end
51
+
52
+ test 'read_lines should return empty Array with empty data' do
53
+ assert_equal [], Asciidoctor::Reader.new.read_lines
54
+ #assert_equal [], Asciidoctor::Reader.new.get_lines
55
+ end
30
56
  end
31
57
 
32
- test "peek_line does not consume the line it returns" do
33
- reader = Asciidoctor::Reader.new(["foo", "bar"])
34
- _ = reader.peek_line
35
- second = reader.peek_line
36
- assert_equal "foo", second
58
+ context 'With data' do
59
+ test 'has_more_lines? should return true if there are lines remaining' do
60
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
61
+ assert reader.has_more_lines?
62
+ end
63
+
64
+ test 'empty? should return false if there are lines remaining' do
65
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
66
+ assert !reader.empty?
67
+ assert !reader.eof?
68
+ end
69
+
70
+ test 'next_line_empty? should return false if next line is not blank' do
71
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
72
+ assert !reader.next_line_empty?
73
+ end
74
+
75
+ test 'next_line_empty? should return true if next line is blank' do
76
+ reader = Asciidoctor::Reader.new ["\n", "second line\n"]
77
+ assert reader.next_line_empty?
78
+ end
79
+
80
+ test 'peek_line should return next line if there are lines remaining' do
81
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
82
+ assert_equal SAMPLE_DATA.first, reader.peek_line
83
+ end
84
+
85
+ test 'peek_line should not consume line or increment line number' do
86
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
87
+ assert_equal SAMPLE_DATA.first, reader.peek_line
88
+ assert_equal SAMPLE_DATA.first, reader.peek_line
89
+ assert_equal 1, reader.lineno
90
+ end
91
+
92
+ test 'peek_line should return next lines if there are lines remaining' do
93
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
94
+ assert_equal SAMPLE_DATA[0..1], reader.peek_lines(2)
95
+ end
96
+
97
+ test 'peek_lines should not consume lines or increment line number' do
98
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
99
+ assert_equal SAMPLE_DATA[0..1], reader.peek_lines(2)
100
+ assert_equal SAMPLE_DATA[0..1], reader.peek_lines(2)
101
+ assert_equal 1, reader.lineno
102
+ end
103
+
104
+ test 'peek_lines should not invert order of lines' do
105
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
106
+ assert_equal SAMPLE_DATA, reader.lines
107
+ reader.peek_lines 3
108
+ assert_equal SAMPLE_DATA, reader.lines
109
+ end
110
+
111
+ test 'read_line should return next line if there are lines remaining' do
112
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
113
+ assert_equal SAMPLE_DATA.first, reader.read_line
114
+ end
115
+
116
+ test 'read_line should consume next line and increment line number' do
117
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
118
+ assert_equal SAMPLE_DATA[0], reader.read_line
119
+ assert_equal SAMPLE_DATA[1], reader.read_line
120
+ assert_equal 3, reader.lineno
121
+ end
122
+
123
+ test 'advance should consume next line and return a Boolean indicating if a line was consumed' do
124
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
125
+ assert reader.advance
126
+ assert reader.advance
127
+ assert reader.advance
128
+ assert !reader.advance
129
+ end
130
+
131
+ test 'read_lines should return all lines' do
132
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
133
+ assert_equal SAMPLE_DATA, reader.read_lines
134
+ end
135
+
136
+ test 'read should return all lines joined as String' do
137
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
138
+ assert_equal SAMPLE_DATA.join, reader.read
139
+ end
140
+
141
+ test 'has_more_lines? should return false after read_lines is invoked' do
142
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
143
+ reader.read_lines
144
+ assert !reader.has_more_lines?
145
+ end
146
+
147
+ test 'unshift puts line onto Reader as next line to read' do
148
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
149
+ reader.unshift "line zero\n"
150
+ assert_equal "line zero\n", reader.peek_line
151
+ assert_equal "line zero\n", reader.read_line
152
+ assert_equal 1, reader.lineno
153
+ end
154
+
155
+ test 'terminate should consume all lines and update line number' do
156
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
157
+ reader.terminate
158
+ assert reader.eof?
159
+ assert_equal 4, reader.lineno
160
+ end
161
+
162
+ test 'skip_blank_lines should skip blank lines' do
163
+ reader = Asciidoctor::Reader.new ["", "\n"].concat(SAMPLE_DATA)
164
+ reader.skip_blank_lines
165
+ assert_equal SAMPLE_DATA.first, reader.peek_line
166
+ end
167
+
168
+ test 'lines should return remaining lines' do
169
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
170
+ reader.read_line
171
+ assert_equal SAMPLE_DATA[1..-1], reader.lines
172
+ end
173
+
174
+ test 'source_lines should return copy of original data Array' do
175
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
176
+ reader.read_lines
177
+ assert_equal SAMPLE_DATA, reader.source_lines
178
+ end
179
+
180
+ test 'source should return original data Array joined as String' do
181
+ reader = Asciidoctor::Reader.new SAMPLE_DATA
182
+ reader.read_lines
183
+ assert_equal SAMPLE_DATA.join, reader.source
184
+ end
185
+
37
186
  end
38
187
 
39
- test "unshift puts line onto Reader instance for the next get_line" do
40
- reader = Asciidoctor::Reader.new(["foo"])
41
- reader.unshift("bar")
42
- assert_equal "bar", reader.get_line
43
- assert_equal "foo", reader.get_line
188
+ context 'Line context' do
189
+ test 'to_s should return file name and line number of current line' do
190
+ reader = Asciidoctor::Reader.new SAMPLE_DATA, 'sample.ad'
191
+ reader.read_line
192
+ assert_equal 'sample.ad: line 2', reader.to_s
193
+ end
194
+
195
+ test 'line_info should return file name and line number of current line' do
196
+ reader = Asciidoctor::Reader.new SAMPLE_DATA, 'sample.ad'
197
+ reader.read_line
198
+ assert_equal 'sample.ad: line 2', reader.line_info
199
+ assert_equal 'sample.ad: line 2', reader.next_line_info
200
+ end
201
+
202
+ test 'prev_line_info should return file name and line number of previous line read' do
203
+ reader = Asciidoctor::Reader.new SAMPLE_DATA, 'sample.ad'
204
+ reader.read_line
205
+ assert_equal 'sample.ad: line 1', reader.prev_line_info
206
+ end
44
207
  end
45
- end
46
208
 
47
- context "Grab lines" do
48
- test "Grab until end" do
49
- input = <<-EOS
209
+ context 'Read lines until' do
210
+ test 'Read lines until until end' do
211
+ lines = <<-EOS.each_line.to_a
50
212
  This is one paragraph.
51
213
 
52
214
  This is another paragraph.
53
- EOS
54
-
55
- lines = input.lines.entries
56
- reader = Asciidoctor::Reader.new(lines)
57
- result = reader.grab_lines_until
58
- assert_equal 3, result.size
59
- assert_equal lines, result
60
- assert !reader.has_more_lines?
61
- assert reader.empty?
62
- end
215
+ EOS
216
+
217
+ reader = Asciidoctor::Reader.new lines
218
+ result = reader.read_lines_until
219
+ assert_equal 3, result.size
220
+ assert_equal lines, result
221
+ assert !reader.has_more_lines?
222
+ assert reader.eof?
223
+ end
63
224
 
64
- test "Grab until blank line" do
65
- input = <<-EOS
225
+ test 'Read lines until until blank line' do
226
+ lines = <<-EOS.each_line.to_a
66
227
  This is one paragraph.
67
228
 
68
229
  This is another paragraph.
69
- EOS
230
+ EOS
70
231
 
71
- lines = input.lines.entries
72
- reader = Asciidoctor::Reader.new(lines)
73
- result = reader.grab_lines_until :break_on_blank_lines => true
74
- assert_equal 1, result.size
75
- assert_equal lines.first, result.first
76
- assert_equal lines.last, reader.peek_line
77
- end
232
+ reader = Asciidoctor::Reader.new lines
233
+ result = reader.read_lines_until :break_on_blank_lines => true
234
+ assert_equal 1, result.size
235
+ assert_equal lines.first.chomp, result.first
236
+ assert_equal lines.last, reader.peek_line
237
+ end
78
238
 
79
- test "Grab until blank line preserving last line" do
80
- input = <<-EOS
239
+ test 'Read lines until until blank line preserving last line' do
240
+ lines = <<-EOS.each_line.to_a
81
241
  This is one paragraph.
82
242
 
83
243
  This is another paragraph.
84
- EOS
244
+ EOS
85
245
 
86
- lines = input.lines.entries
87
- reader = Asciidoctor::Reader.new(lines)
88
- result = reader.grab_lines_until :break_on_blank_lines => true, :preserve_last_line => true
89
- assert_equal 1, result.size
90
- assert_equal lines.first, result.first
91
- assert_equal "\n", reader.peek_line
92
- end
246
+ reader = Asciidoctor::Reader.new lines
247
+ result = reader.read_lines_until :break_on_blank_lines => true, :preserve_last_line => true
248
+ assert_equal 1, result.size
249
+ assert_equal lines.first.chomp, result.first
250
+ assert reader.next_line_empty?
251
+ end
93
252
 
94
- test "Grab until condition" do
95
- input = <<-EOS
253
+ test 'Read lines until until condition is true' do
254
+ lines = <<-EOS.each_line.to_a
96
255
  --
97
256
  This is one paragraph inside the block.
98
257
 
@@ -100,19 +259,18 @@ This is another paragraph inside the block.
100
259
  --
101
260
 
102
261
  This is a paragraph outside the block.
103
- EOS
104
-
105
- lines = input.lines.entries
106
- reader = Asciidoctor::Reader.new(lines)
107
- reader.get_line
108
- result = reader.grab_lines_until {|line| line.chomp == '--' }
109
- assert_equal 3, result.size
110
- assert_equal lines[1, 3], result
111
- assert_equal "\n", reader.peek_line
112
- end
262
+ EOS
263
+
264
+ reader = Asciidoctor::Reader.new lines
265
+ reader.read_line
266
+ result = reader.read_lines_until {|line| line.chomp == '--' }
267
+ assert_equal 3, result.size
268
+ assert_equal lines[1, 3], result
269
+ assert reader.next_line_empty?
270
+ end
113
271
 
114
- test "Grab until condition with last line" do
115
- input = <<-EOS
272
+ test 'Read lines until until condition is true, taking last line' do
273
+ lines = <<-EOS.each_line.to_a
116
274
  --
117
275
  This is one paragraph inside the block.
118
276
 
@@ -120,19 +278,18 @@ This is another paragraph inside the block.
120
278
  --
121
279
 
122
280
  This is a paragraph outside the block.
123
- EOS
124
-
125
- lines = input.lines.entries
126
- reader = Asciidoctor::Reader.new(lines)
127
- reader.get_line
128
- result = reader.grab_lines_until(:grab_last_line => true) {|line| line.chomp == '--' }
129
- assert_equal 4, result.size
130
- assert_equal lines[1, 4], result
131
- assert_equal "\n", reader.peek_line
132
- end
281
+ EOS
282
+
283
+ reader = Asciidoctor::Reader.new lines
284
+ reader.read_line
285
+ result = reader.read_lines_until(:read_last_line => true) {|line| line.chomp == '--' }
286
+ assert_equal 4, result.size
287
+ assert_equal lines[1, 4], result
288
+ assert reader.next_line_empty?
289
+ end
133
290
 
134
- test "Grab until condition with last line and preserving last line" do
135
- input = <<-EOS
291
+ test 'Read lines until until condition is true, taking and preserving last line' do
292
+ lines = <<-EOS.each_line.to_a
136
293
  --
137
294
  This is one paragraph inside the block.
138
295
 
@@ -140,330 +297,646 @@ This is another paragraph inside the block.
140
297
  --
141
298
 
142
299
  This is a paragraph outside the block.
143
- EOS
144
-
145
- lines = input.lines.entries
146
- reader = Asciidoctor::Reader.new(lines)
147
- reader.get_line
148
- result = reader.grab_lines_until(:grab_last_line => true, :preserve_last_line => true) {|line| line.chomp == '--' }
149
- assert_equal 4, result.size
150
- assert_equal lines[1, 4], result
151
- assert_equal "--\n", reader.peek_line
300
+ EOS
301
+
302
+ reader = Asciidoctor::Reader.new lines
303
+ reader.read_line
304
+ result = reader.read_lines_until(:read_last_line => true, :preserve_last_line => true) {|line| line.chomp == '--' }
305
+ assert_equal 4, result.size
306
+ assert_equal lines[1, 4], result
307
+ assert_equal "--\n", reader.peek_line
308
+ end
152
309
  end
153
310
  end
154
311
 
155
- context 'Include Macro' do
156
- test 'include macro is disabled by default and becomes a link' do
157
- input = <<-EOS
158
- include::include-file.asciidoc[]
159
- EOS
160
- para = block_from_string input, :attributes => { 'include-depth' => 0 }
161
- assert_equal 1, para.buffer.size
162
- #assert_equal 'include::include-file.asciidoc[]', para.buffer.join
163
- assert_equal 'link:include-file.asciidoc[include-file.asciidoc]', para.buffer.join
312
+ context 'PreprocessorReader' do
313
+ context 'Type hierarchy' do
314
+ test 'PreprocessorReader should extend from Reader' do
315
+ doc = Asciidoctor::Document.new
316
+ reader = Asciidoctor::PreprocessorReader.new doc
317
+ assert reader.is_a?(Asciidoctor::Reader)
318
+ end
319
+
320
+ test 'PreprocessorReader should invoke or emulate Reader initializer' do
321
+ doc = Asciidoctor::Document.new
322
+ reader = Asciidoctor::PreprocessorReader.new doc, SAMPLE_DATA
323
+ assert_equal SAMPLE_DATA, reader.lines
324
+ assert_equal 1, reader.lineno
325
+ end
164
326
  end
165
327
 
166
- test 'include macro is enabled when safe mode is less than SECURE' do
167
- input = <<-EOS
168
- include::fixtures/include-file.asciidoc[]
169
- EOS
328
+ context 'Prepare lines' do
329
+ test 'should prepare and normalize lines from Array data' do
330
+ doc = Asciidoctor::Document.new
331
+ data = SAMPLE_DATA.map {|line| line.chomp}
332
+ data.unshift ''
333
+ data.push ''
334
+ reader = Asciidoctor::PreprocessorReader.new doc, data
335
+ assert_equal SAMPLE_DATA, reader.lines
336
+ end
170
337
 
171
- doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
172
- output = doc.render
173
- assert_match(/included content/, output)
174
- end
338
+ test 'should prepare and normalize lines from String data' do
339
+ doc = Asciidoctor::Document.new
340
+ data = SAMPLE_DATA.map {|line| line.chomp}
341
+ data.unshift ' '
342
+ data.push ' '
343
+ data_as_string = data * "\n"
344
+ reader = Asciidoctor::PreprocessorReader.new doc, data_as_string
345
+ assert_equal SAMPLE_DATA, reader.lines
346
+ end
175
347
 
176
- test 'missing file referenced by include macro does not crash processor' do
177
- input = <<-EOS
178
- include::fixtures/no-such-file.ad[]
348
+ test 'should clean CRLF from end of lines' do
349
+ input = <<-EOS
350
+ source\r
351
+ with\r
352
+ CRLF\r
353
+ endlines\r
179
354
  EOS
180
355
 
181
- begin
182
- doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
183
- assert_equal 0, doc.blocks.size
184
- rescue
185
- flunk('include macro should not raise exception on missing file')
356
+ doc = Asciidoctor::Document.new
357
+ [input, input.lines, input.split("\n"), input.split("\n").join].each do |lines|
358
+ reader = Asciidoctor::PreprocessorReader.new doc, lines
359
+ reader.lines.each do |line|
360
+ assert !line.end_with?("\r"), "CRLF not properly cleaned for source lines: #{lines.inspect}"
361
+ assert !line.end_with?("\r\n"), "CRLF not properly cleaned for source lines: #{lines.inspect}"
362
+ assert line.end_with?("\n"), "CRLF not properly cleaned for source lines: #{lines.inspect}"
363
+ end
364
+ end
186
365
  end
187
- end
188
366
 
189
- test 'include macro supports line selection' do
190
- input = <<-EOS
191
- include::fixtures/include-file.asciidoc[lines=1;3..4;6..-1]
192
- EOS
367
+ test 'should not skip front matter by default' do
368
+ input = <<-EOS
369
+ ---
370
+ layout: post
371
+ title: Document Title
372
+ author: username
373
+ tags: [ first, second ]
374
+ ---
375
+ = Document Title
376
+ Author Name
377
+
378
+ preamble
379
+ EOS
380
+
381
+ doc = Asciidoctor::Document.new
382
+ reader = Asciidoctor::PreprocessorReader.new doc, input
383
+ assert_equal '---', reader.peek_line.chomp
384
+ end
193
385
 
194
- output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :attributes => {'docdir' => File.dirname(__FILE__)}
195
- assert_match(/first line/, output)
196
- assert_no_match(/second line/, output)
197
- assert_match(/third line/, output)
198
- assert_match(/fourth line/, output)
199
- assert_no_match(/fifth line/, output)
200
- assert_match(/sixth line/, output)
201
- assert_match(/seventh line/, output)
202
- assert_match(/eighth line/, output)
203
- assert_match(/last line of included content/, output)
386
+ test 'should skip front matter if specified by skip-front-matter attribute' do
387
+ front_matter = %(layout: post
388
+ title: Document Title
389
+ author: username
390
+ tags: [ first, second ])
391
+ input = <<-EOS
392
+ ---
393
+ #{front_matter}
394
+ ---
395
+ = Document Title
396
+ Author Name
397
+
398
+ preamble
399
+ EOS
400
+
401
+ doc = Asciidoctor::Document.new [], :attributes => {'skip-front-matter' => ''}
402
+ reader = Asciidoctor::PreprocessorReader.new doc, input
403
+ assert_equal '= Document Title', reader.peek_line.chomp
404
+ assert_equal front_matter, doc.attributes['front-matter']
405
+ end
204
406
  end
205
407
 
206
- test 'include macro supports line selection using quoted attribute value' do
207
- input = <<-EOS
208
- include::fixtures/include-file.asciidoc[lines="1, 3..4 , 6 .. -1"]
209
- EOS
408
+ context 'Include Macro' do
409
+ test 'include macro is disabled by default and becomes a link' do
410
+ input = <<-EOS
411
+ include::include-file.asciidoc[]
412
+ EOS
413
+ doc = empty_document
414
+ reader = Asciidoctor::PreprocessorReader.new doc, input
415
+ assert_equal 'link:include-file.asciidoc[]', reader.read_line.chomp
416
+ end
417
+
418
+ test 'include macro is enabled when safe mode is less than SECURE' do
419
+ input = <<-EOS
420
+ include::fixtures/include-file.asciidoc[]
421
+ EOS
422
+
423
+ doc = document_from_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
424
+ output = doc.render
425
+ assert_match(/included content/, output)
426
+ end
210
427
 
211
- output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :attributes => {'docdir' => File.dirname(__FILE__)}
212
- assert_match(/first line/, output)
213
- assert_no_match(/second line/, output)
214
- assert_match(/third line/, output)
215
- assert_match(/fourth line/, output)
216
- assert_no_match(/fifth line/, output)
217
- assert_match(/sixth line/, output)
218
- assert_match(/seventh line/, output)
219
- assert_match(/eighth line/, output)
220
- assert_match(/last line of included content/, output)
221
- end
428
+ test 'include macro should resolve file relative to current include' do
429
+ input = <<-EOS
430
+ include::fixtures/parent-include.adoc[]
431
+ EOS
222
432
 
223
- test 'include macro supports tagged selection' do
224
- input = <<-EOS
225
- include::fixtures/include-file.asciidoc[tags=snippetA;snippetB]
226
- EOS
433
+ pseudo_docfile = File.join DIRNAME, 'include-master.adoc'
434
+ fixtures_dir = File.join DIRNAME, 'fixtures'
435
+ parent_include_docfile = File.join fixtures_dir, 'parent-include.adoc'
436
+ child_include_docfile = File.join fixtures_dir, 'child-include.adoc'
437
+ grandchild_include_docfile = File.join fixtures_dir, 'grandchild-include.adoc'
227
438
 
228
- output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :attributes => {'docdir' => File.dirname(__FILE__)}
229
- assert_match(/snippetA content/, output)
230
- assert_match(/snippetB content/, output)
231
- assert_no_match(/non-tagged content/, output)
232
- assert_no_match(/included content/, output)
233
- end
439
+ doc = empty_safe_document :base_dir => DIRNAME
440
+ reader = Asciidoctor::PreprocessorReader.new doc, input, pseudo_docfile
234
441
 
235
- test 'lines attribute takes precedence over tags attribute in include macro' do
236
- input = <<-EOS
237
- include::fixtures/include-file.asciidoc[lines=1, tags=snippetA;snippetB]
238
- EOS
442
+ assert_equal pseudo_docfile, reader.file
443
+ assert_equal DIRNAME, reader.dir
444
+ assert_equal 'include-master.adoc', reader.path
239
445
 
240
- output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :attributes => {'docdir' => File.dirname(__FILE__)}
241
- assert_match(/first line of included content/, output)
242
- assert_no_match(/snippetA content/, output)
243
- assert_no_match(/snippetB content/, output)
244
- end
446
+ assert_equal "first line of parent\n", reader.read_line
447
+
448
+ assert_equal 'fixtures/parent-include.adoc: line 1', reader.prev_line_info
449
+ assert_equal parent_include_docfile, reader.file
450
+ assert_equal fixtures_dir, reader.dir
451
+ assert_equal 'fixtures/parent-include.adoc', reader.path
452
+
453
+ reader.skip_blank_lines
454
+
455
+ assert_equal "first line of child\n", reader.read_line
456
+
457
+ assert_equal 'fixtures/child-include.adoc: line 1', reader.prev_line_info
458
+ assert_equal child_include_docfile, reader.file
459
+ assert_equal fixtures_dir, reader.dir
460
+ assert_equal 'fixtures/child-include.adoc', reader.path
461
+
462
+ reader.skip_blank_lines
245
463
 
246
- test 'indent of included file can be reset to size of indent attribute' do
247
- input = <<-EOS
464
+ assert_equal "first line of grandchild\n", reader.read_line
465
+
466
+ assert_equal 'fixtures/grandchild-include.adoc: line 1', reader.prev_line_info
467
+ assert_equal grandchild_include_docfile, reader.file
468
+ assert_equal fixtures_dir, reader.dir
469
+ assert_equal 'fixtures/grandchild-include.adoc', reader.path
470
+
471
+ reader.skip_blank_lines
472
+
473
+ assert_equal "last line of grandchild\n", reader.read_line
474
+
475
+ reader.skip_blank_lines
476
+
477
+ assert_equal "last line of child\n", reader.read_line
478
+
479
+ reader.skip_blank_lines
480
+
481
+ assert_equal "last line of parent\n", reader.read_line
482
+
483
+ assert_equal 'fixtures/parent-include.adoc: line 5', reader.prev_line_info
484
+ assert_equal parent_include_docfile, reader.file
485
+ assert_equal fixtures_dir, reader.dir
486
+ assert_equal 'fixtures/parent-include.adoc', reader.path
487
+ end
488
+
489
+ test 'missing file referenced by include macro does not crash processor' do
490
+ input = <<-EOS
491
+ include::fixtures/no-such-file.ad[]
492
+ EOS
493
+
494
+ begin
495
+ doc = document_from_string input, :safe => :safe, :base_dir => DIRNAME
496
+ assert_equal 0, doc.blocks.size
497
+ rescue
498
+ flunk 'include macro should not raise exception on missing file'
499
+ end
500
+ end
501
+
502
+ test 'include macro can retrieve data from uri' do
503
+ input = <<-EOS
504
+ ....
505
+ include::https://raw.github.com/asciidoctor/asciidoctor/master/LICENSE[]
506
+ ....
507
+ EOS
508
+
509
+ output = render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
510
+ assert_match(/MIT/, output)
511
+ end
512
+
513
+ test 'inaccessible uri referenced by include macro does not crash processor' do
514
+ input = <<-EOS
515
+ ....
516
+ include::http://127.0.0.1:0[]
517
+ ....
518
+ EOS
519
+
520
+ begin
521
+ output = render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
522
+ assert_css 'pre:empty', output, 1
523
+ rescue
524
+ flunk 'include macro should not raise exception on inaccessible uri'
525
+ end
526
+ end
527
+
528
+ test 'include macro supports line selection' do
529
+ input = <<-EOS
530
+ include::fixtures/include-file.asciidoc[lines=1;3..4;6..-1]
531
+ EOS
532
+
533
+ output = render_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
534
+ assert_match(/first line/, output)
535
+ assert_no_match(/second line/, output)
536
+ assert_match(/third line/, output)
537
+ assert_match(/fourth line/, output)
538
+ assert_no_match(/fifth line/, output)
539
+ assert_match(/sixth line/, output)
540
+ assert_match(/seventh line/, output)
541
+ assert_match(/eighth line/, output)
542
+ assert_match(/last line of included content/, output)
543
+ end
544
+
545
+ test 'include macro supports line selection using quoted attribute value' do
546
+ input = <<-EOS
547
+ include::fixtures/include-file.asciidoc[lines="1, 3..4 , 6 .. -1"]
548
+ EOS
549
+
550
+ output = render_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
551
+ assert_match(/first line/, output)
552
+ assert_no_match(/second line/, output)
553
+ assert_match(/third line/, output)
554
+ assert_match(/fourth line/, output)
555
+ assert_no_match(/fifth line/, output)
556
+ assert_match(/sixth line/, output)
557
+ assert_match(/seventh line/, output)
558
+ assert_match(/eighth line/, output)
559
+ assert_match(/last line of included content/, output)
560
+ end
561
+
562
+ test 'include macro supports tagged selection' do
563
+ input = <<-EOS
564
+ include::fixtures/include-file.asciidoc[tag=snippetA]
565
+ EOS
566
+
567
+ output = render_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
568
+ assert_match(/snippetA content/, output)
569
+ assert_no_match(/snippetB content/, output)
570
+ assert_no_match(/non-tagged content/, output)
571
+ assert_no_match(/included content/, output)
572
+ end
573
+
574
+ test 'include macro supports multiple tagged selection' do
575
+ input = <<-EOS
576
+ include::fixtures/include-file.asciidoc[tags=snippetA;snippetB]
577
+ EOS
578
+
579
+ output = render_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
580
+ assert_match(/snippetA content/, output)
581
+ assert_match(/snippetB content/, output)
582
+ assert_no_match(/non-tagged content/, output)
583
+ assert_no_match(/included content/, output)
584
+ end
585
+
586
+ test 'lines attribute takes precedence over tags attribute in include macro' do
587
+ input = <<-EOS
588
+ include::fixtures/include-file.asciidoc[lines=1, tags=snippetA;snippetB]
589
+ EOS
590
+
591
+ output = render_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
592
+ assert_match(/first line of included content/, output)
593
+ assert_no_match(/snippetA content/, output)
594
+ assert_no_match(/snippetB content/, output)
595
+ end
596
+
597
+ test 'indent of included file can be reset to size of indent attribute' do
598
+ input = <<-EOS
248
599
  [source, xml]
249
600
  ----
250
601
  include::fixtures/basic-docinfo.xml[lines=2..3, indent=0]
251
602
  ----
252
- EOS
253
-
254
- output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :attributes => {'docdir' => File.dirname(__FILE__)}
255
- result = xmlnodes_at_xpath('//pre', output, 1).text
256
- assert_equal "<year>2013</year>\n<holder>Acme, Inc.</holder>", result
257
- end
258
-
259
- test "block is called to handle an include macro" do
260
- input = <<-EOS
603
+ EOS
604
+
605
+ output = render_string input, :safe => :safe, :header_footer => false, :base_dir => DIRNAME
606
+ result = xmlnodes_at_xpath('//pre', output, 1).text
607
+ assert_equal "<year>2013</year>\n<holder>Acme, Inc.</holder>", result
608
+ end
609
+
610
+ test 'include processor is called to process include directive' do
611
+ input = <<-EOS
261
612
  first line
262
613
 
263
614
  include::include-file.asciidoc[]
264
615
 
265
616
  last line
266
- EOS
267
- doc = Asciidoctor::Document.new [], :safe => Asciidoctor::SafeMode::SAFE
268
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true) {|inc|
269
- ":includefile: #{inc}\n\nmiddle line".lines.entries
270
- }
271
- lines = []
272
- while reader.has_more_lines?
273
- lines << reader.get_line
274
- end
275
- assert_match(/^:includefile: include-file.asciidoc$/, lines.join)
276
- end
617
+ EOS
618
+
619
+ include_processor = Class.new {
620
+ def initialize document
621
+ end
622
+
623
+ def handles? target
624
+ true
625
+ end
626
+
627
+ def process reader, target, attributes
628
+ content = ["include target:: #{target}\n", "\n", "middle line\n"]
629
+ reader.push_include content, target, target, 1, attributes
630
+ end
631
+ }
632
+
633
+ # Safe Mode is not required
634
+ document = empty_document :base_dir => DIRNAME
635
+ reader = Asciidoctor::PreprocessorReader.new document, input
636
+ reader.instance_variable_set '@include_processors', [include_processor.new(document)]
637
+ lines = []
638
+ lines << reader.read_line
639
+ lines << reader.read_line
640
+ lines << reader.read_line
641
+ assert_equal "include target:: include-file.asciidoc\n", lines.last
642
+ assert_equal 'include-file.asciidoc: line 2', reader.line_info
643
+ while reader.has_more_lines?
644
+ lines << reader.read_line
645
+ end
646
+ source = lines.join
647
+ assert_match(/^include target:: include-file.asciidoc$/, source)
648
+ assert_match(/^middle line$/, source)
649
+ end
277
650
 
278
- test 'attributes are substituted in target of include macro' do
279
- input = <<-EOS
651
+ test 'should fall back to built-in include macro behavior when not handled by include processor' do
652
+ input = <<-EOS
653
+ include::fixtures/include-file.asciidoc[]
654
+ EOS
655
+
656
+ include_processor = Class.new {
657
+ def initialize document
658
+ end
659
+
660
+ def handles? target
661
+ false
662
+ end
663
+
664
+ def process reader, target, attributes
665
+ raise 'TestIncludeHandler should not have been invoked'
666
+ end
667
+ }
668
+
669
+ document = empty_safe_document :base_dir => DIRNAME
670
+ reader = Asciidoctor::PreprocessorReader.new document, input
671
+ reader.instance_variable_set '@include_processors', [include_processor.new(document)]
672
+ lines = reader.read_lines
673
+ source = lines.join
674
+ assert_match(/included content/, source)
675
+ end
676
+
677
+ test 'attributes are substituted in target of include macro' do
678
+ input = <<-EOS
280
679
  :fixturesdir: fixtures
281
680
  :ext: asciidoc
282
681
 
283
682
  include::{fixturesdir}/include-file.{ext}[]
284
- EOS
285
-
286
- doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
287
- output = doc.render
288
- assert_match(/included content/, output)
289
- end
290
-
291
- test 'line is dropped if target of include macro resolves to empty' do
292
- input = <<-EOS
683
+ EOS
684
+
685
+ doc = document_from_string input, :safe => :safe, :base_dir => DIRNAME
686
+ output = doc.render
687
+ assert_match(/included content/, output)
688
+ end
689
+
690
+ test 'line is skipped by default if target of include macro resolves to empty' do
691
+ input = <<-EOS
293
692
  include::{foodir}/include-file.asciidoc[]
294
- EOS
295
-
296
- output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
297
- assert output.strip.empty?
298
- end
693
+ EOS
694
+
695
+ doc = empty_safe_document :base_dir => DIRNAME
696
+ reader = Asciidoctor::PreprocessorReader.new doc, input
697
+ assert_equal "include::{foodir}/include-file.asciidoc[]\n", reader.read_line
698
+ end
299
699
 
300
- test 'line is dropped but not following line if target of include macro resolves to empty' do
301
- input = <<-EOS
700
+ test 'line is dropped if target of include macro resolves to empty and attribute-missing attribute is not skip' do
701
+ input = <<-EOS
702
+ include::{foodir}/include-file.asciidoc[]
703
+ EOS
704
+
705
+ doc = empty_safe_document :base_dir => DIRNAME, :attributes => {'attribute-missing' => 'drop'}
706
+ reader = Asciidoctor::PreprocessorReader.new doc, input
707
+ assert_nil reader.read_line
708
+ end
709
+
710
+ test 'line following dropped include is not dropped' do
711
+ input = <<-EOS
302
712
  include::{foodir}/include-file.asciidoc[]
303
713
  yo
304
- EOS
714
+ EOS
715
+
716
+ doc = empty_safe_document :base_dir => DIRNAME, :attributes => {'attribute-missing' => 'drop'}
717
+ reader = Asciidoctor::PreprocessorReader.new doc, input
718
+ assert_equal "yo\n", reader.read_line
719
+ end
720
+
721
+ test 'escaped include macro is left unprocessed' do
722
+ input = <<-EOS
723
+ \\include::fixtures/include-file.asciidoc[]
724
+ \\escape preserved here
725
+ EOS
726
+ doc = empty_safe_document :base_dir => DIRNAME
727
+ reader = Asciidoctor::PreprocessorReader.new doc, input
728
+ # we should be able to peek it multiple times and still have the backslash preserved
729
+ # this is the test for @unescape_next_line
730
+ assert_equal 'include::fixtures/include-file.asciidoc[]', reader.peek_line.chomp
731
+ assert_equal 'include::fixtures/include-file.asciidoc[]', reader.peek_line.chomp
732
+ assert_equal 'include::fixtures/include-file.asciidoc[]', reader.read_line.chomp
733
+ assert_equal '\\escape preserved here', reader.read_line.chomp
734
+ end
735
+
736
+ test 'include macro not at start of line is ignored' do
737
+ input = <<-EOS
738
+ include::include-file.asciidoc[]
739
+ EOS
740
+ para = block_from_string input
741
+ assert_equal 1, para.lines.size
742
+ # NOTE the space gets stripped because the line is treated as an inline literal
743
+ assert_equal :literal, para.context
744
+ assert_equal 'include::include-file.asciidoc[]', para.source
745
+ end
746
+
747
+ test 'include macro is disabled when max-include-depth attribute is 0' do
748
+ input = <<-EOS
749
+ include::include-file.asciidoc[]
750
+ EOS
751
+ para = block_from_string input, :safe => :safe, :attributes => { 'max-include-depth' => 0 }
752
+ assert_equal 1, para.lines.size
753
+ assert_equal 'include::include-file.asciidoc[]', para.source
754
+ end
755
+
756
+ test 'max-include-depth cannot be set by document' do
757
+ input = <<-EOS
758
+ :max-include-depth: 1
759
+
760
+ include::include-file.asciidoc[]
761
+ EOS
762
+ para = block_from_string input, :safe => :safe, :attributes => { 'max-include-depth' => 0 }
763
+ assert_equal 1, para.lines.size
764
+ assert_equal 'include::include-file.asciidoc[]', para.source
765
+ end
305
766
 
306
- output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
307
- assert_xpath '//p', output, 1
308
- assert_xpath '//p[text()="yo"]', output, 1
309
- end
767
+ test 'include macro should be disabled if max include depth has been exceeded' do
768
+ input = <<-EOS
769
+ include::fixtures/parent-include.adoc[depth=1]
770
+ EOS
310
771
 
311
- test 'escaped include macro is left unprocessed' do
312
- input = <<-EOS
313
- \\include::include-file.asciidoc[]
314
- EOS
315
- para = block_from_string input
316
- assert_equal 1, para.buffer.size
317
- assert_equal 'include::include-file.asciidoc[]', para.buffer.join
318
- end
772
+ pseudo_docfile = File.join DIRNAME, 'include-master.adoc'
319
773
 
320
- test 'include macro not at start of line is ignored' do
321
- input = <<-EOS
322
- include::include-file.asciidoc[]
323
- EOS
324
- para = block_from_string input
325
- assert_equal 1, para.buffer.size
326
- # NOTE the space gets stripped because the line is treated as an inline literal
327
- assert_equal :literal, para.context
328
- assert_equal 'include::include-file.asciidoc[]', para.buffer.join
329
- end
774
+ doc = empty_safe_document :base_dir => DIRNAME
775
+ reader = Asciidoctor::PreprocessorReader.new doc, input, Asciidoctor::Reader::Cursor.new(pseudo_docfile)
330
776
 
331
- test 'include macro is disabled when include-depth attribute is 0' do
332
- input = <<-EOS
333
- include::include-file.asciidoc[]
334
- EOS
335
- para = block_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'include-depth' => 0 }
336
- assert_equal 1, para.buffer.size
337
- assert_equal 'include::include-file.asciidoc[]', para.buffer.join
338
- end
777
+ lines = reader.readlines
778
+ assert lines.include?("include::child-include.adoc[]\n")
779
+ end
339
780
 
340
- test 'include-depth cannot be set by document' do
341
- input = <<-EOS
342
- :include-depth: 1
781
+ test 'include macro should be disabled if max include depth set in nested context has been exceeded' do
782
+ input = <<-EOS
783
+ include::fixtures/parent-include-restricted.adoc[depth=3]
784
+ EOS
343
785
 
344
- include::include-file.asciidoc[]
345
- EOS
346
- para = block_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => { 'include-depth' => 0 }
347
- assert_equal 1, para.buffer.size
348
- assert_equal 'include::include-file.asciidoc[]', para.buffer.join
349
- end
350
- end
786
+ pseudo_docfile = File.join DIRNAME, 'include-master.adoc'
351
787
 
352
- context 'build secure asset path' do
353
- test 'allows us to specify a path relative to the current dir' do
354
- doc = Asciidoctor::Document.new
355
- Asciidoctor::Reader.new([], doc, true)
356
- legit_path = Dir.pwd + "/foo"
357
- assert_equal legit_path, doc.normalize_asset_path(legit_path)
358
- end
788
+ doc = empty_safe_document :base_dir => DIRNAME
789
+ reader = Asciidoctor::PreprocessorReader.new doc, input, Asciidoctor::Reader::Cursor.new(pseudo_docfile)
359
790
 
360
- test "keeps naughty absolute paths from getting outside" do
361
- naughty_path = "#{disk_root}etc/passwd"
362
- doc = Asciidoctor::Document.new
363
- Asciidoctor::Reader.new([], doc, true)
364
- secure_path = doc.normalize_asset_path(naughty_path)
365
- assert naughty_path != secure_path
366
- assert_match(/^#{doc.base_dir}/, secure_path)
367
- end
791
+ lines = reader.readlines
792
+ assert lines.include?("first line of child\n")
793
+ assert lines.include?("include::grandchild-include.adoc[]\n")
794
+ end
368
795
 
369
- test "keeps naughty relative paths from getting outside" do
370
- naughty_path = "safe/ok/../../../../../etc/passwd"
371
- doc = Asciidoctor::Document.new
372
- Asciidoctor::Reader.new([], doc, true)
373
- secure_path = doc.normalize_asset_path(naughty_path)
374
- assert naughty_path != secure_path
375
- assert_match(/^#{doc.base_dir}/, secure_path)
796
+ test 'read_lines_until should not process lines if process option is false' do
797
+ lines = <<-EOS.each_line.to_a
798
+ ////
799
+ include::fixtures/no-such-file.asciidoc[]
800
+ ////
801
+ EOS
802
+
803
+ doc = empty_safe_document :base_dir => DIRNAME
804
+ reader = Asciidoctor::PreprocessorReader.new doc, lines
805
+ reader.read_line
806
+ result = reader.read_lines_until(:terminator => '////', :skip_processing => true)
807
+ assert_equal lines[1..1], result
808
+ end
809
+
810
+ test 'skip_comment_lines should not process lines read' do
811
+ lines = <<-EOS.each_line.to_a
812
+ ////
813
+ include::fixtures/no-such-file.asciidoc[]
814
+ ////
815
+ EOS
816
+
817
+ doc = empty_safe_document :base_dir => DIRNAME
818
+ reader = Asciidoctor::PreprocessorReader.new doc, lines
819
+ result = reader.skip_comment_lines
820
+ assert_equal lines, result
821
+ end
376
822
  end
377
- end
378
823
 
379
- context 'Conditional Inclusions' do
380
- test 'preprocess_next_line returns true if cursor advanced' do
381
- input = <<-EOS
824
+ context 'Conditional Inclusions' do
825
+ #test 'process_line returns next line of content' do
826
+ test 'process_line returns nil if cursor advanced' do
827
+ input = <<-EOS
382
828
  ifdef::asciidoctor[]
383
829
  Asciidoctor!
384
830
  endif::asciidoctor[]
385
- EOS
386
-
387
- doc = Asciidoctor::Document.new
388
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
389
- assert reader.preprocess_next_line == true
390
- end
831
+ EOS
832
+
833
+ reader = Asciidoctor::PreprocessorReader.new empty_document, input
834
+ #assert_equal "Asciidoctor!\n", reader.process_line(reader.lines.first)
835
+ assert_nil reader.process_line(reader.lines.first)
836
+ end
391
837
 
392
- test 'preprocess_next_line returns false if cursor not advanced' do
393
- input = <<-EOS
838
+ test 'peek_line advances cursor to next conditional line of content' do
839
+ input = <<-EOS
840
+ ifdef::asciidoctor[]
841
+ Asciidoctor!
842
+ endif::asciidoctor[]
843
+ EOS
844
+
845
+ reader = Asciidoctor::PreprocessorReader.new empty_document, input
846
+ assert_equal 1, reader.lineno
847
+ assert_equal "Asciidoctor!\n", reader.peek_line
848
+ assert_equal 2, reader.lineno
849
+ end
850
+
851
+ test 'process_line returns line if cursor not advanced' do
852
+ input = <<-EOS
394
853
  content
395
854
  ifdef::asciidoctor[]
396
855
  Asciidoctor!
397
856
  endif::asciidoctor[]
398
- EOS
399
-
400
- doc = Asciidoctor::Document.new
401
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
402
- assert reader.preprocess_next_line == false
403
- end
857
+ EOS
858
+
859
+ reader = Asciidoctor::PreprocessorReader.new empty_document, input
860
+ assert_not_nil reader.process_line(reader.lines.first)
861
+ end
404
862
 
405
- test 'preprocess_next_line returns nil if cursor advanced past end of source' do
406
- input = <<-EOS
863
+ test 'peek_line does not advance cursor when on a regular content line' do
864
+ input = <<-EOS
865
+ content
866
+ ifdef::asciidoctor[]
867
+ Asciidoctor!
868
+ endif::asciidoctor[]
869
+ EOS
870
+
871
+ reader = Asciidoctor::PreprocessorReader.new empty_document, input
872
+ assert_equal 1, reader.lineno
873
+ assert_equal "content\n", reader.peek_line
874
+ assert_equal 1, reader.lineno
875
+ end
876
+
877
+ test 'peek_line returns nil if cursor advances past end of source' do
878
+ input = <<-EOS
407
879
  ifdef::foobar[]
408
880
  swallowed content
409
881
  endif::foobar[]
410
- EOS
411
-
412
- doc = Asciidoctor::Document.new
413
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
414
- assert reader.preprocess_next_line.nil?
415
- end
416
-
417
- test 'ifdef with defined attribute includes block' do
418
- input = <<-EOS
882
+ EOS
883
+
884
+ reader = Asciidoctor::PreprocessorReader.new empty_document, input
885
+ assert_equal 1, reader.lineno
886
+ assert_nil reader.peek_line
887
+ assert_equal 4, reader.lineno
888
+ end
889
+
890
+ test 'ifdef with defined attribute includes content' do
891
+ input = <<-EOS
419
892
  ifdef::holygrail[]
420
893
  There is a holy grail!
421
894
  endif::holygrail[]
422
- EOS
423
-
424
- doc = Asciidoctor::Document.new [], :attributes => {'holygrail' => ''}
425
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
426
- lines = []
427
- while reader.has_more_lines?
428
- lines << reader.get_line
429
- end
430
- assert_equal 'There is a holy grail!', lines.join.strip
431
- end
432
-
433
- test 'ifdef with defined attribute includes text in brackets' do
434
- input = <<-EOS
895
+ EOS
896
+
897
+ doc = empty_document :attributes => {'holygrail' => ''}
898
+ reader = Asciidoctor::PreprocessorReader.new doc, input
899
+ lines = []
900
+ while reader.has_more_lines?
901
+ lines << reader.read_line
902
+ end
903
+ assert_equal 'There is a holy grail!', lines.join.chomp
904
+ end
905
+
906
+ test 'ifdef with defined attribute includes text in brackets' do
907
+ input = <<-EOS
435
908
  On our quest we go...
436
909
  ifdef::holygrail[There is a holy grail!]
437
910
  There was much rejoicing.
438
- EOS
439
-
440
- doc = Asciidoctor::Document.new [], :attributes => {'holygrail' => ''}
441
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
442
- lines = []
443
- while reader.has_more_lines?
444
- lines << reader.get_line
445
- end
446
- assert_equal "On our quest we go...\nThere is a holy grail!\nThere was much rejoicing.", lines.join.strip
447
- end
448
-
449
- test 'ifndef with defined attribute does not include text in brackets' do
450
- input = <<-EOS
911
+ EOS
912
+
913
+ doc = empty_document :attributes => {'holygrail' => ''}
914
+ reader = Asciidoctor::PreprocessorReader.new doc, input
915
+ lines = []
916
+ while reader.has_more_lines?
917
+ lines << reader.read_line
918
+ end
919
+ assert_equal "On our quest we go...\nThere is a holy grail!\nThere was much rejoicing.", lines.join.chomp
920
+ end
921
+
922
+ test 'ifndef with defined attribute does not include text in brackets' do
923
+ input = <<-EOS
451
924
  On our quest we go...
452
925
  ifndef::hardships[There is a holy grail!]
453
926
  There was no rejoicing.
454
- EOS
455
-
456
- doc = Asciidoctor::Document.new [], :attributes => {'hardships' => ''}
457
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
458
- lines = []
459
- while reader.has_more_lines?
460
- lines << reader.get_line
461
- end
462
- assert_equal "On our quest we go...\nThere was no rejoicing.", lines.join.strip
463
- end
464
-
465
- test 'include with non-matching nested exclude' do
466
- input = <<-EOS
927
+ EOS
928
+
929
+ doc = empty_document :attributes => {'hardships' => ''}
930
+ reader = Asciidoctor::PreprocessorReader.new doc, input
931
+ lines = []
932
+ while reader.has_more_lines?
933
+ lines << reader.read_line
934
+ end
935
+ assert_equal "On our quest we go...\nThere was no rejoicing.", lines.join.chomp
936
+ end
937
+
938
+ test 'include with non-matching nested exclude' do
939
+ input = <<-EOS
467
940
  ifdef::grail[]
468
941
  holy
469
942
  ifdef::swallow[]
@@ -471,37 +944,37 @@ swallow
471
944
  endif::swallow[]
472
945
  grail
473
946
  endif::grail[]
474
- EOS
475
-
476
- doc = Asciidoctor::Document.new [], :attributes => {'grail' => ''}
477
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
478
- lines = []
479
- while reader.has_more_lines?
480
- lines << reader.get_line
481
- end
482
- assert_equal "holy\ngrail", lines.join.strip
483
- end
484
-
485
- test 'nested excludes with same condition' do
486
- input = <<-EOS
947
+ EOS
948
+
949
+ doc = empty_document :attributes => {'grail' => ''}
950
+ reader = Asciidoctor::PreprocessorReader.new doc, input
951
+ lines = []
952
+ while reader.has_more_lines?
953
+ lines << reader.read_line
954
+ end
955
+ assert_equal "holy\ngrail", lines.join.chomp
956
+ end
957
+
958
+ test 'nested excludes with same condition' do
959
+ input = <<-EOS
487
960
  ifndef::grail[]
488
961
  ifndef::grail[]
489
962
  not here
490
963
  endif::grail[]
491
964
  endif::grail[]
492
- EOS
493
-
494
- doc = Asciidoctor::Document.new [], :attributes => {'grail' => ''}
495
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
496
- lines = []
497
- while reader.has_more_lines?
498
- lines << reader.get_line
499
- end
500
- assert_equal '', lines.join.strip
501
- end
502
-
503
- test 'include with nested exclude of inverted condition' do
504
- input = <<-EOS
965
+ EOS
966
+
967
+ doc = empty_document :attributes => {'grail' => ''}
968
+ reader = Asciidoctor::PreprocessorReader.new doc, input
969
+ lines = []
970
+ while reader.has_more_lines?
971
+ lines << reader.read_line
972
+ end
973
+ assert_equal '', lines.join.chomp
974
+ end
975
+
976
+ test 'include with nested exclude of inverted condition' do
977
+ input = <<-EOS
505
978
  ifdef::grail[]
506
979
  holy
507
980
  ifndef::grail[]
@@ -509,19 +982,19 @@ not here
509
982
  endif::grail[]
510
983
  grail
511
984
  endif::grail[]
512
- EOS
513
-
514
- doc = Asciidoctor::Document.new [], :attributes => {'grail' => ''}
515
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
516
- lines = []
517
- while reader.has_more_lines?
518
- lines << reader.get_line
519
- end
520
- assert_equal "holy\ngrail", lines.join.strip
521
- end
522
-
523
- test 'exclude with matching nested exclude' do
524
- input = <<-EOS
985
+ EOS
986
+
987
+ doc = empty_document :attributes => {'grail' => ''}
988
+ reader = Asciidoctor::PreprocessorReader.new doc, input
989
+ lines = []
990
+ while reader.has_more_lines?
991
+ lines << reader.read_line
992
+ end
993
+ assert_equal "holy\ngrail", lines.join.chomp
994
+ end
995
+
996
+ test 'exclude with matching nested exclude' do
997
+ input = <<-EOS
525
998
  poof
526
999
  ifdef::swallow[]
527
1000
  no
@@ -531,19 +1004,19 @@ endif::swallow[]
531
1004
  here
532
1005
  endif::swallow[]
533
1006
  gone
534
- EOS
535
-
536
- doc = Asciidoctor::Document.new [], :attributes => {'grail' => ''}
537
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
538
- lines = []
539
- while reader.has_more_lines?
540
- lines << reader.get_line
541
- end
542
- assert_equal "poof\ngone", lines.join.strip
543
- end
544
-
545
- test 'exclude with nested include using shorthand end' do
546
- input = <<-EOS
1007
+ EOS
1008
+
1009
+ doc = empty_document :attributes => {'grail' => ''}
1010
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1011
+ lines = []
1012
+ while reader.has_more_lines?
1013
+ lines << reader.read_line
1014
+ end
1015
+ assert_equal "poof\ngone", lines.join.chomp
1016
+ end
1017
+
1018
+ test 'exclude with nested include using shorthand end' do
1019
+ input = <<-EOS
547
1020
  poof
548
1021
  ifndef::grail[]
549
1022
  no grail
@@ -553,324 +1026,303 @@ endif::[]
553
1026
  in here
554
1027
  endif::[]
555
1028
  gone
556
- EOS
557
-
558
- doc = Asciidoctor::Document.new [], :attributes => {'grail' => ''}
559
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
560
- lines = []
561
- while reader.has_more_lines?
562
- lines << reader.get_line
563
- end
564
- assert_equal "poof\ngone", lines.join.strip
565
- end
566
-
567
- test 'ifdef with one alternative attribute set includes content' do
568
- input = <<-EOS
1029
+ EOS
1030
+
1031
+ doc = empty_document :attributes => {'grail' => ''}
1032
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1033
+ lines = []
1034
+ while reader.has_more_lines?
1035
+ lines << reader.read_line
1036
+ end
1037
+ assert_equal "poof\ngone", lines.join.chomp
1038
+ end
1039
+
1040
+ test 'ifdef with one alternative attribute set includes content' do
1041
+ input = <<-EOS
569
1042
  ifdef::holygrail,swallow[]
570
1043
  Our quest is complete!
571
1044
  endif::holygrail,swallow[]
572
- EOS
573
-
574
- doc = Asciidoctor::Document.new [], :attributes => {'swallow' => ''}
575
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
576
- lines = []
577
- while reader.has_more_lines?
578
- lines << reader.get_line
1045
+ EOS
1046
+
1047
+ doc = empty_document :attributes => {'swallow' => ''}
1048
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1049
+ lines = []
1050
+ while reader.has_more_lines?
1051
+ lines << reader.read_line
1052
+ end
1053
+ assert_equal 'Our quest is complete!', lines.join.chomp
579
1054
  end
580
- assert_equal 'Our quest is complete!', lines.join.strip
581
- end
582
-
583
- test 'ifdef with no alternative attributes set does not include content' do
584
- input = <<-EOS
1055
+
1056
+ test 'ifdef with no alternative attributes set does not include content' do
1057
+ input = <<-EOS
585
1058
  ifdef::holygrail,swallow[]
586
1059
  Our quest is complete!
587
1060
  endif::holygrail,swallow[]
588
- EOS
589
-
590
- doc = Asciidoctor::Document.new
591
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
592
- lines = []
593
- while reader.has_more_lines?
594
- lines << reader.get_line
1061
+ EOS
1062
+
1063
+ doc = empty_document
1064
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1065
+ lines = []
1066
+ while reader.has_more_lines?
1067
+ lines << reader.read_line
1068
+ end
1069
+ assert_equal '', lines.join.chomp
595
1070
  end
596
- assert_equal '', lines.join.strip
597
- end
598
-
599
- test 'ifdef with all required attributes set includes content' do
600
- input = <<-EOS
1071
+
1072
+ test 'ifdef with all required attributes set includes content' do
1073
+ input = <<-EOS
601
1074
  ifdef::holygrail+swallow[]
602
1075
  Our quest is complete!
603
1076
  endif::holygrail+swallow[]
604
- EOS
605
-
606
- doc = Asciidoctor::Document.new [], :attributes => {'holygrail' => '', 'swallow' => ''}
607
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
608
- lines = []
609
- while reader.has_more_lines?
610
- lines << reader.get_line
1077
+ EOS
1078
+
1079
+ doc = empty_document :attributes => {'holygrail' => '', 'swallow' => ''}
1080
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1081
+ lines = []
1082
+ while reader.has_more_lines?
1083
+ lines << reader.read_line
1084
+ end
1085
+ assert_equal 'Our quest is complete!', lines.join.chomp
611
1086
  end
612
- assert_equal 'Our quest is complete!', lines.join.strip
613
- end
614
-
615
- test 'ifdef with missing required attributes does not include content' do
616
- input = <<-EOS
1087
+
1088
+ test 'ifdef with missing required attributes does not include content' do
1089
+ input = <<-EOS
617
1090
  ifdef::holygrail+swallow[]
618
1091
  Our quest is complete!
619
1092
  endif::holygrail+swallow[]
620
- EOS
621
-
622
- doc = Asciidoctor::Document.new [], :attributes => {'holygrail' => ''}
623
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
624
- lines = []
625
- while reader.has_more_lines?
626
- lines << reader.get_line
1093
+ EOS
1094
+
1095
+ doc = empty_document :attributes => {'holygrail' => ''}
1096
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1097
+ lines = []
1098
+ while reader.has_more_lines?
1099
+ lines << reader.read_line
1100
+ end
1101
+ assert_equal '', lines.join.chomp
627
1102
  end
628
- assert_equal '', lines.join.strip
629
- end
630
-
631
- test 'ifndef with undefined attribute includes block' do
632
- input = <<-EOS
1103
+
1104
+ test 'ifndef with undefined attribute includes block' do
1105
+ input = <<-EOS
633
1106
  ifndef::holygrail[]
634
1107
  Our quest continues to find the holy grail!
635
1108
  endif::holygrail[]
636
- EOS
637
-
638
- doc = Asciidoctor::Document.new
639
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
640
- lines = []
641
- while reader.has_more_lines?
642
- lines << reader.get_line
1109
+ EOS
1110
+
1111
+ doc = empty_document
1112
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1113
+ lines = []
1114
+ while reader.has_more_lines?
1115
+ lines << reader.read_line
1116
+ end
1117
+ assert_equal 'Our quest continues to find the holy grail!', lines.join.chomp
643
1118
  end
644
- assert_equal 'Our quest continues to find the holy grail!', lines.join.strip
645
- end
646
-
647
- test 'ifndef with one alternative attribute set includes content' do
648
- input = <<-EOS
1119
+
1120
+ test 'ifndef with one alternative attribute set includes content' do
1121
+ input = <<-EOS
649
1122
  ifndef::holygrail,swallow[]
650
1123
  Our quest is complete!
651
1124
  endif::holygrail,swallow[]
652
- EOS
653
-
654
- doc = Asciidoctor::Document.new [], :attributes => {'swallow' => ''}
655
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
656
- lines = []
657
- while reader.has_more_lines?
658
- lines << reader.get_line
1125
+ EOS
1126
+
1127
+ doc = empty_document :attributes => {'swallow' => ''}
1128
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1129
+ lines = []
1130
+ while reader.has_more_lines?
1131
+ lines << reader.read_line
1132
+ end
1133
+ assert_equal 'Our quest is complete!', lines.join.chomp
659
1134
  end
660
- assert_equal 'Our quest is complete!', lines.join.strip
661
- end
662
-
663
- test 'ifndef with no alternative attributes set includes content' do
664
- input = <<-EOS
1135
+
1136
+ test 'ifndef with no alternative attributes set includes content' do
1137
+ input = <<-EOS
665
1138
  ifndef::holygrail,swallow[]
666
1139
  Our quest is complete!
667
1140
  endif::holygrail,swallow[]
668
- EOS
669
-
670
- doc = Asciidoctor::Document.new
671
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
672
- lines = []
673
- while reader.has_more_lines?
674
- lines << reader.get_line
1141
+ EOS
1142
+
1143
+ doc = empty_document
1144
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1145
+ lines = []
1146
+ while reader.has_more_lines?
1147
+ lines << reader.read_line
1148
+ end
1149
+ assert_equal 'Our quest is complete!', lines.join.chomp
675
1150
  end
676
- assert_equal 'Our quest is complete!', lines.join.strip
677
- end
678
-
679
- test 'ifndef with any required attributes set does not include content' do
680
- input = <<-EOS
1151
+
1152
+ test 'ifndef with any required attributes set does not include content' do
1153
+ input = <<-EOS
681
1154
  ifndef::holygrail+swallow[]
682
1155
  Our quest is complete!
683
1156
  endif::holygrail+swallow[]
684
- EOS
685
-
686
- doc = Asciidoctor::Document.new [], :attributes => {'swallow' => ''}
687
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
688
- lines = []
689
- while reader.has_more_lines?
690
- lines << reader.get_line
1157
+ EOS
1158
+
1159
+ doc = empty_document :attributes => {'swallow' => ''}
1160
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1161
+ lines = []
1162
+ while reader.has_more_lines?
1163
+ lines << reader.read_line
1164
+ end
1165
+ assert_equal '', lines.join.chomp
691
1166
  end
692
- assert_equal '', lines.join.strip
693
- end
694
-
695
- test 'ifndef with no required attributes set includes content' do
696
- input = <<-EOS
1167
+
1168
+ test 'ifndef with no required attributes set includes content' do
1169
+ input = <<-EOS
697
1170
  ifndef::holygrail+swallow[]
698
1171
  Our quest is complete!
699
1172
  endif::holygrail+swallow[]
700
- EOS
701
-
702
- doc = Asciidoctor::Document.new
703
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
704
- lines = []
705
- while reader.has_more_lines?
706
- lines << reader.get_line
1173
+ EOS
1174
+
1175
+ doc = empty_document
1176
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1177
+ lines = []
1178
+ while reader.has_more_lines?
1179
+ lines << reader.read_line
1180
+ end
1181
+ assert_equal 'Our quest is complete!', lines.join.chomp
707
1182
  end
708
- assert_equal 'Our quest is complete!', lines.join.strip
709
- end
710
-
711
- test 'escaped ifdef is unescaped and ignored' do
712
- input = <<-EOS
1183
+
1184
+ test 'escaped ifdef is unescaped and ignored' do
1185
+ input = <<-EOS
713
1186
  \\ifdef::holygrail[]
714
1187
  content
715
1188
  \\endif::holygrail[]
716
- EOS
717
-
718
- doc = Asciidoctor::Document.new
719
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
720
- lines = []
721
- while reader.has_more_lines?
722
- lines << reader.get_line
1189
+ EOS
1190
+
1191
+ doc = empty_document
1192
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1193
+ lines = []
1194
+ while reader.has_more_lines?
1195
+ lines << reader.read_line
1196
+ end
1197
+ assert_equal "ifdef::holygrail[]\ncontent\nendif::holygrail[]", lines.join.chomp
723
1198
  end
724
- assert_equal "ifdef::holygrail[]\ncontent\nendif::holygrail[]", lines.join.strip
725
- end
726
-
727
- test 'ifeval comparing double-quoted attribute to matching string is included' do
728
- input = <<-EOS
1199
+
1200
+ test 'ifeval comparing double-quoted attribute to matching string is included' do
1201
+ input = <<-EOS
729
1202
  ifeval::["{gem}" == "asciidoctor"]
730
1203
  Asciidoctor it is!
731
1204
  endif::[]
732
- EOS
733
-
734
- doc = Asciidoctor::Document.new [], :attributes => {'gem' => 'asciidoctor'}
735
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
736
- lines = []
737
- while reader.has_more_lines?
738
- lines << reader.get_line
1205
+ EOS
1206
+
1207
+ doc = empty_document :attributes => {'gem' => 'asciidoctor'}
1208
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1209
+ lines = []
1210
+ while reader.has_more_lines?
1211
+ lines << reader.read_line
1212
+ end
1213
+ assert_equal 'Asciidoctor it is!', lines.join.chomp
739
1214
  end
740
- assert_equal 'Asciidoctor it is!', lines.join.strip
741
- end
742
-
743
- test 'ifeval comparing single-quoted attribute to matching string is included' do
744
- input = <<-EOS
1215
+
1216
+ test 'ifeval comparing single-quoted attribute to matching string is included' do
1217
+ input = <<-EOS
745
1218
  ifeval::['{gem}' == 'asciidoctor']
746
1219
  Asciidoctor it is!
747
1220
  endif::[]
748
- EOS
749
-
750
- doc = Asciidoctor::Document.new [], :attributes => {'gem' => 'asciidoctor'}
751
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
752
- lines = []
753
- while reader.has_more_lines?
754
- lines << reader.get_line
1221
+ EOS
1222
+
1223
+ doc = empty_document :attributes => {'gem' => 'asciidoctor'}
1224
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1225
+ lines = []
1226
+ while reader.has_more_lines?
1227
+ lines << reader.read_line
1228
+ end
1229
+ assert_equal 'Asciidoctor it is!', lines.join.chomp
755
1230
  end
756
- assert_equal 'Asciidoctor it is!', lines.join.strip
757
- end
758
-
759
- test 'ifeval comparing quoted attribute to non-matching string is ignored' do
760
- input = <<-EOS
1231
+
1232
+ test 'ifeval comparing quoted attribute to non-matching string is ignored' do
1233
+ input = <<-EOS
761
1234
  ifeval::['{gem}' == 'asciidoctor']
762
1235
  Asciidoctor it is!
763
1236
  endif::[]
764
- EOS
765
-
766
- doc = Asciidoctor::Document.new [], :attributes => {'gem' => 'tilt'}
767
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
768
- lines = []
769
- while reader.has_more_lines?
770
- lines << reader.get_line
1237
+ EOS
1238
+
1239
+ doc = empty_document :attributes => {'gem' => 'tilt'}
1240
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1241
+ lines = []
1242
+ while reader.has_more_lines?
1243
+ lines << reader.read_line
1244
+ end
1245
+ assert_equal '', lines.join.chomp
771
1246
  end
772
- assert_equal '', lines.join.strip
773
- end
774
-
775
- test 'ifeval comparing attribute to lower version number is included' do
776
- input = <<-EOS
1247
+
1248
+ test 'ifeval comparing attribute to lower version number is included' do
1249
+ input = <<-EOS
777
1250
  ifeval::['{asciidoctor-version}' >= '0.1.0']
778
1251
  That version will do!
779
1252
  endif::[]
780
- EOS
781
-
782
- doc = Asciidoctor::Document.new
783
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
784
- lines = []
785
- while reader.has_more_lines?
786
- lines << reader.get_line
1253
+ EOS
1254
+
1255
+ doc = empty_document
1256
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1257
+ lines = []
1258
+ while reader.has_more_lines?
1259
+ lines << reader.read_line
1260
+ end
1261
+ assert_equal 'That version will do!', lines.join.chomp
787
1262
  end
788
- assert_equal 'That version will do!', lines.join.strip
789
- end
790
-
791
- test 'ifeval comparing attribute to self is included' do
792
- input = <<-EOS
1263
+
1264
+ test 'ifeval comparing attribute to self is included' do
1265
+ input = <<-EOS
793
1266
  ifeval::['{asciidoctor-version}' == '{asciidoctor-version}']
794
1267
  Of course it's the same!
795
1268
  endif::[]
796
- EOS
797
-
798
- doc = Asciidoctor::Document.new
799
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
800
- lines = []
801
- while reader.has_more_lines?
802
- lines << reader.get_line
1269
+ EOS
1270
+
1271
+ doc = empty_document
1272
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1273
+ lines = []
1274
+ while reader.has_more_lines?
1275
+ lines << reader.read_line
1276
+ end
1277
+ assert_equal 'Of course it\'s the same!', lines.join.chomp
803
1278
  end
804
- assert_equal 'Of course it\'s the same!', lines.join.strip
805
- end
806
-
807
- test 'ifeval arguments can be mirrored' do
808
- input = <<-EOS
1279
+
1280
+ test 'ifeval arguments can be transposed' do
1281
+ input = <<-EOS
809
1282
  ifeval::["0.1.0" <= "{asciidoctor-version}"]
810
1283
  That version will do!
811
1284
  endif::[]
812
- EOS
813
-
814
- doc = Asciidoctor::Document.new
815
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
816
- lines = []
817
- while reader.has_more_lines?
818
- lines << reader.get_line
1285
+ EOS
1286
+
1287
+ doc = empty_document
1288
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1289
+ lines = []
1290
+ while reader.has_more_lines?
1291
+ lines << reader.read_line
1292
+ end
1293
+ assert_equal 'That version will do!', lines.join.chomp
819
1294
  end
820
- assert_equal 'That version will do!', lines.join.strip
821
- end
822
-
823
- test 'ifeval matching numeric comparison is included' do
824
- input = <<-EOS
1295
+
1296
+ test 'ifeval matching numeric comparison is included' do
1297
+ input = <<-EOS
825
1298
  ifeval::[{rings} == 1]
826
1299
  One ring to rule them all!
827
1300
  endif::[]
828
- EOS
829
-
830
- doc = Asciidoctor::Document.new [], :attributes => {'rings' => 1}
831
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
832
- lines = []
833
- while reader.has_more_lines?
834
- lines << reader.get_line
1301
+ EOS
1302
+
1303
+ doc = empty_document :attributes => {'rings' => 1}
1304
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1305
+ lines = []
1306
+ while reader.has_more_lines?
1307
+ lines << reader.read_line
1308
+ end
1309
+ assert_equal 'One ring to rule them all!', lines.join.chomp
835
1310
  end
836
- assert_equal 'One ring to rule them all!', lines.join.strip
837
- end
838
-
839
- test 'ifdef with no target is ignored' do
840
- input = <<-EOS
1311
+
1312
+ test 'ifdef with no target is ignored' do
1313
+ input = <<-EOS
841
1314
  ifdef::[]
842
1315
  content
843
- EOS
844
-
845
- doc = Asciidoctor::Document.new
846
- reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
847
- lines = []
848
- while reader.has_more_lines?
849
- lines << reader.get_line
850
- end
851
- assert_equal "ifdef::[]\ncontent", lines.join.strip
852
- end
853
- end
854
-
855
- context 'Text processing' do
856
- test 'should clean CRLF from end of lines' do
857
- input = <<-EOS
858
- source\r
859
- with\r
860
- CRLF\r
861
- endlines\r
862
- EOS
863
-
864
- reader = Asciidoctor::Reader.new(input.lines.entries, Asciidoctor::Document.new, true)
865
- reader.lines.each do |line|
866
- assert !line.end_with?("\r\n")
1316
+ EOS
1317
+
1318
+ doc = empty_document
1319
+ reader = Asciidoctor::PreprocessorReader.new doc, input
1320
+ lines = []
1321
+ while reader.has_more_lines?
1322
+ lines << reader.read_line
1323
+ end
1324
+ assert_equal "ifdef::[]\ncontent", lines.join.chomp
867
1325
  end
868
1326
  end
869
-
870
- test 'sanitize attribute name' do
871
- assert_equal 'foobar', @reader.sanitize_attribute_name("Foo Bar")
872
- assert_equal 'foo', @reader.sanitize_attribute_name("foo")
873
- assert_equal 'foo3-bar', @reader.sanitize_attribute_name("Foo 3^ # - Bar[")
874
- end
875
1327
  end
876
1328
  end