asciidoctor 0.1.0 → 0.1.1

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 (40) hide show
  1. data/README.asciidoc +11 -2
  2. data/asciidoctor.gemspec +3 -2
  3. data/lib/asciidoctor.rb +95 -62
  4. data/lib/asciidoctor/abstract_block.rb +7 -5
  5. data/lib/asciidoctor/abstract_node.rb +63 -15
  6. data/lib/asciidoctor/attribute_list.rb +3 -1
  7. data/lib/asciidoctor/backends/base_template.rb +17 -7
  8. data/lib/asciidoctor/backends/docbook45.rb +182 -150
  9. data/lib/asciidoctor/backends/html5.rb +138 -110
  10. data/lib/asciidoctor/block.rb +21 -18
  11. data/lib/asciidoctor/callouts.rb +3 -1
  12. data/lib/asciidoctor/cli/invoker.rb +3 -3
  13. data/lib/asciidoctor/cli/options.rb +6 -6
  14. data/lib/asciidoctor/debug.rb +7 -6
  15. data/lib/asciidoctor/document.rb +197 -25
  16. data/lib/asciidoctor/errors.rb +1 -1
  17. data/lib/asciidoctor/helpers.rb +29 -0
  18. data/lib/asciidoctor/inline.rb +11 -4
  19. data/lib/asciidoctor/lexer.rb +338 -182
  20. data/lib/asciidoctor/list_item.rb +14 -12
  21. data/lib/asciidoctor/reader.rb +423 -206
  22. data/lib/asciidoctor/renderer.rb +59 -15
  23. data/lib/asciidoctor/section.rb +7 -4
  24. data/lib/asciidoctor/substituters.rb +536 -511
  25. data/lib/asciidoctor/table.rb +473 -472
  26. data/lib/asciidoctor/version.rb +1 -1
  27. data/man/asciidoctor.1 +23 -14
  28. data/man/asciidoctor.ad +13 -7
  29. data/test/attributes_test.rb +42 -8
  30. data/test/blocks_test.rb +161 -1
  31. data/test/document_test.rb +134 -16
  32. data/test/invoker_test.rb +14 -6
  33. data/test/lexer_test.rb +45 -18
  34. data/test/lists_test.rb +79 -0
  35. data/test/paragraphs_test.rb +9 -1
  36. data/test/reader_test.rb +456 -19
  37. data/test/sections_test.rb +19 -0
  38. data/test/substitutions_test.rb +14 -12
  39. data/test/tables_test.rb +10 -10
  40. metadata +3 -5
data/test/invoker_test.rb CHANGED
@@ -87,10 +87,10 @@ context 'Invoker' do
87
87
  end
88
88
  end
89
89
 
90
- test 'should fail with too many arguments if extra arguments are included' do
90
+ test 'should warn if extra arguments are detected' do
91
91
  redirect_streams do |stdout, stderr|
92
92
  invoker = invoke_cli %w(-o /dev/null extra arguments sample.asciidoc), nil
93
- assert_match(/too many arguments/, stderr.string)
93
+ assert_match(/extra arguments detected/, stderr.string)
94
94
  assert_equal 1, invoker.code
95
95
  end
96
96
  end
@@ -239,10 +239,18 @@ context 'Invoker' do
239
239
  assert_equal Asciidoctor::SafeMode::SAFE, doc.safe
240
240
  end
241
241
 
242
- test 'should set safe mode to specified level if specified' do
243
- invoker = invoke_cli_to_buffer %w(-S safe -o /dev/null)
244
- doc = invoker.document
245
- assert_equal Asciidoctor::SafeMode::SAFE, doc.safe
242
+ test 'should set safe mode to specified level' do
243
+ levels = {
244
+ 'unsafe' => Asciidoctor::SafeMode::UNSAFE,
245
+ 'safe' => Asciidoctor::SafeMode::SAFE,
246
+ 'server' => Asciidoctor::SafeMode::SERVER,
247
+ 'secure' => Asciidoctor::SafeMode::SECURE,
248
+ }
249
+ levels.each do |name, const|
250
+ invoker = invoke_cli_to_buffer %W(-S #{name} -o /dev/null)
251
+ doc = invoker.document
252
+ assert_equal const, doc.safe
253
+ end
246
254
  end
247
255
 
248
256
  test 'should set eRuby impl if specified' do
data/test/lexer_test.rb CHANGED
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  context "Lexer" do
4
4
 
5
- test "test_is_section_title" do
5
+ test "is_section_title?" do
6
6
  assert Asciidoctor::Lexer.is_section_title?('AsciiDoc Home Page', '==================')
7
7
  assert Asciidoctor::Lexer.is_section_title?('=== AsciiDoc Home Page')
8
8
  end
@@ -174,7 +174,7 @@ context "Lexer" do
174
174
  assert_equal expected, attributes
175
175
  end
176
176
 
177
- test "test_parse_author_first" do
177
+ test "parse author first" do
178
178
  metadata, = parse_header_metadata 'Stuart'
179
179
  assert_equal 3, metadata.size
180
180
  assert_equal 'Stuart', metadata['author']
@@ -182,7 +182,7 @@ context "Lexer" do
182
182
  assert_equal 'S', metadata['authorinitials']
183
183
  end
184
184
 
185
- test "test_parse_author_first_last" do
185
+ test "parse author first last" do
186
186
  metadata, = parse_header_metadata 'Yukihiro Matsumoto'
187
187
  assert_equal 4, metadata.size
188
188
  assert_equal 'Yukihiro Matsumoto', metadata['author']
@@ -191,7 +191,7 @@ context "Lexer" do
191
191
  assert_equal 'YM', metadata['authorinitials']
192
192
  end
193
193
 
194
- test "test_parse_author_first_middle_last" do
194
+ test "parse author first middle last" do
195
195
  metadata, = parse_header_metadata 'David Heinemeier Hansson'
196
196
  assert_equal 5, metadata.size
197
197
  assert_equal 'David Heinemeier Hansson', metadata['author']
@@ -201,7 +201,7 @@ context "Lexer" do
201
201
  assert_equal 'DHH', metadata['authorinitials']
202
202
  end
203
203
 
204
- test "test_parse_author_first_middle_last_email" do
204
+ test "parse author first middle last email" do
205
205
  metadata, = parse_header_metadata 'David Heinemeier Hansson <rails@ruby-lang.org>'
206
206
  assert_equal 6, metadata.size
207
207
  assert_equal 'David Heinemeier Hansson', metadata['author']
@@ -212,7 +212,7 @@ context "Lexer" do
212
212
  assert_equal 'DHH', metadata['authorinitials']
213
213
  end
214
214
 
215
- test "test_parse_author_first_email" do
215
+ test "parse author first email" do
216
216
  metadata, = parse_header_metadata 'Stuart <founder@asciidoc.org>'
217
217
  assert_equal 4, metadata.size
218
218
  assert_equal 'Stuart', metadata['author']
@@ -221,7 +221,7 @@ context "Lexer" do
221
221
  assert_equal 'S', metadata['authorinitials']
222
222
  end
223
223
 
224
- test "test_parse_author_first_last_email" do
224
+ test "parse author first last email" do
225
225
  metadata, = parse_header_metadata 'Stuart Rackham <founder@asciidoc.org>'
226
226
  assert_equal 5, metadata.size
227
227
  assert_equal 'Stuart Rackham', metadata['author']
@@ -231,7 +231,7 @@ context "Lexer" do
231
231
  assert_equal 'SR', metadata['authorinitials']
232
232
  end
233
233
 
234
- test "test_parse_author_with_hyphen" do
234
+ test "parse author with hyphen" do
235
235
  metadata, = parse_header_metadata 'Tim Berners-Lee <founder@www.org>'
236
236
  assert_equal 5, metadata.size
237
237
  assert_equal 'Tim Berners-Lee', metadata['author']
@@ -241,7 +241,7 @@ context "Lexer" do
241
241
  assert_equal 'TB', metadata['authorinitials']
242
242
  end
243
243
 
244
- test "test_parse_author_with_single_quote" do
244
+ test "parse author with single quote" do
245
245
  metadata, = parse_header_metadata 'Stephen O\'Grady <founder@redmonk.com>'
246
246
  assert_equal 5, metadata.size
247
247
  assert_equal 'Stephen O\'Grady', metadata['author']
@@ -262,7 +262,7 @@ context "Lexer" do
262
262
  assert_equal 'HWR', metadata['authorinitials']
263
263
  end
264
264
 
265
- test "test_parse_author_with_underscore" do
265
+ test "parse author with underscore" do
266
266
  metadata, = parse_header_metadata 'Tim_E Fella'
267
267
  assert_equal 4, metadata.size
268
268
  assert_equal 'Tim E Fella', metadata['author']
@@ -271,7 +271,7 @@ context "Lexer" do
271
271
  assert_equal 'TF', metadata['authorinitials']
272
272
  end
273
273
 
274
- test "test_parse_author_condenses_whitespace" do
274
+ test "parse author condenses whitespace" do
275
275
  metadata, = parse_header_metadata ' Stuart Rackham <founder@asciidoc.org>'
276
276
  assert_equal 5, metadata.size
277
277
  assert_equal 'Stuart Rackham', metadata['author']
@@ -281,7 +281,7 @@ context "Lexer" do
281
281
  assert_equal 'SR', metadata['authorinitials']
282
282
  end
283
283
 
284
- test "test_parse_invalid_author_line_becomes_author" do
284
+ test "parse invalid author line becomes author" do
285
285
  metadata, = parse_header_metadata ' Stuart Rackham, founder of AsciiDoc <founder@asciidoc.org>'
286
286
  assert_equal 3, metadata.size
287
287
  assert_equal 'Stuart Rackham, founder of AsciiDoc <founder@asciidoc.org>', metadata['author']
@@ -289,7 +289,7 @@ context "Lexer" do
289
289
  assert_equal 'S', metadata['authorinitials']
290
290
  end
291
291
 
292
- test "test_parse_rev_number_date_remark" do
292
+ test "parse rev number date remark" do
293
293
  metadata, = parse_header_metadata "Ryan Waldron\nv0.0.7, 2013-12-18: The first release you can stand on"
294
294
  assert_equal 7, metadata.size
295
295
  assert_equal '0.0.7', metadata['revnumber']
@@ -297,20 +297,39 @@ context "Lexer" do
297
297
  assert_equal 'The first release you can stand on', metadata['revremark']
298
298
  end
299
299
 
300
- test "test_parse_rev_date" do
300
+ test "parse rev date" do
301
301
  metadata, = parse_header_metadata "Ryan Waldron\n2013-12-18"
302
302
  assert_equal 5, metadata.size
303
303
  assert_equal '2013-12-18', metadata['revdate']
304
304
  end
305
305
 
306
- test "test_parse_rev_date_remark" do
306
+ # while compliant w/ AsciiDoc, this is just sloppy parsing
307
+ test "treats arbitrary text on rev line as revdate" do
308
+ metadata, = parse_header_metadata "Ryan Waldron\nfoobar\n"
309
+ assert_equal 5, metadata.size
310
+ assert_equal 'foobar', metadata['revdate']
311
+ end
312
+
313
+ test "parse rev date remark" do
307
314
  metadata, = parse_header_metadata "Ryan Waldron\n2013-12-18: The first release you can stand on"
308
315
  assert_equal 6, metadata.size
309
316
  assert_equal '2013-12-18', metadata['revdate']
310
317
  assert_equal 'The first release you can stand on', metadata['revremark']
311
318
  end
312
319
 
313
- test "test_skip_line_comments_before_author" do
320
+ test "should not mistake attribute entry as rev remark" do
321
+ metadata, = parse_header_metadata "Joe Cool\n:layout: post\n"
322
+ assert_not_equal 'layout: post', metadata['revremark']
323
+ assert !metadata.has_key?('revdate')
324
+ end
325
+
326
+ test "parse rev remark only" do
327
+ metadata, = parse_header_metadata "Joe Cool\n :Must start line with space\n"
328
+ assert_equal 'Must start line with space', metadata['revremark']
329
+ assert_equal '', metadata['revdate']
330
+ end
331
+
332
+ test "skip line comments before author" do
314
333
  metadata, = parse_header_metadata "// Asciidoctor\n// release artist\nRyan Waldron"
315
334
  assert_equal 4, metadata.size
316
335
  assert_equal 'Ryan Waldron', metadata['author']
@@ -319,7 +338,7 @@ context "Lexer" do
319
338
  assert_equal 'RW', metadata['authorinitials']
320
339
  end
321
340
 
322
- test "test_skip_block_comment_before_author" do
341
+ test "skip block comment before author" do
323
342
  metadata, = parse_header_metadata "////\nAsciidoctor\nrelease artist\n////\nRyan Waldron"
324
343
  assert_equal 4, metadata.size
325
344
  assert_equal 'Ryan Waldron', metadata['author']
@@ -328,7 +347,7 @@ context "Lexer" do
328
347
  assert_equal 'RW', metadata['authorinitials']
329
348
  end
330
349
 
331
- test "test_skip_block_comment_before_rev" do
350
+ test "skip block comment before rev" do
332
351
  metadata, = parse_header_metadata "Ryan Waldron\n////\nAsciidoctor\nrelease info\n////\nv0.0.7, 2013-12-18"
333
352
  assert_equal 6, metadata.size
334
353
  assert_equal 'Ryan Waldron', metadata['author']
@@ -336,4 +355,12 @@ context "Lexer" do
336
355
  assert_equal '2013-12-18', metadata['revdate']
337
356
  end
338
357
 
358
+ test "attribute entry overrides generated author initials" do
359
+ blankdoc = Asciidoctor::Document.new
360
+ reader = Asciidoctor::Reader.new "Stuart Rackham <founder@asciidoc.org>\n:Author Initials: SJR".lines.entries
361
+ metadata = Asciidoctor::Lexer.parse_header_metadata(reader, blankdoc)
362
+ assert_equal 'SR', metadata['authorinitials']
363
+ assert_equal 'SJR', blankdoc.attributes['authorinitials']
364
+ end
365
+
339
366
  end
data/test/lists_test.rb CHANGED
@@ -88,6 +88,22 @@ List
88
88
  assert_xpath '(//ul)[2]/preceding-sibling::*[@class = "title"][text() = "Also"]', output, 1
89
89
  end
90
90
 
91
+ test "dash elements separated by an attribute entry offset by a blank line should not merge lists" do
92
+ input = <<-EOS
93
+ == List
94
+
95
+ - Foo
96
+ - Boo
97
+
98
+ :foo: bar
99
+ - Blech
100
+ EOS
101
+ output = render_embedded_string input
102
+ assert_xpath '//ul', output, 2
103
+ assert_xpath '(//ul)[1]/li', output, 2
104
+ assert_xpath '(//ul)[2]/li', output, 1
105
+ end
106
+
91
107
  test 'a non-indented wrapped line is folded into text of list item' do
92
108
  input = <<-EOS
93
109
  List
@@ -104,6 +120,36 @@ wrapped content
104
120
  assert_xpath "//ul/li[1]/p[text() = 'Foo\nwrapped content']", output, 1
105
121
  end
106
122
 
123
+ test 'a non-indented wrapped line that resembles a block title is folded into text of list item' do
124
+ input = <<-EOS
125
+ == List
126
+
127
+ - Foo
128
+ .wrapped content
129
+ - Boo
130
+ - Blech
131
+ EOS
132
+ output = render_embedded_string input
133
+ assert_xpath '//ul', output, 1
134
+ assert_xpath '//ul/li[1]/*', output, 1
135
+ assert_xpath "//ul/li[1]/p[text() = 'Foo\n.wrapped content']", output, 1
136
+ end
137
+
138
+ test 'a non-indented wrapped line that resembles an attribute entry is folded into text of list item' do
139
+ input = <<-EOS
140
+ == List
141
+
142
+ - Foo
143
+ :foo: bar
144
+ - Boo
145
+ - Blech
146
+ EOS
147
+ output = render_embedded_string input
148
+ assert_xpath '//ul', output, 1
149
+ assert_xpath '//ul/li[1]/*', output, 1
150
+ assert_xpath "//ul/li[1]/p[text() = 'Foo\n:foo: bar']", output, 1
151
+ end
152
+
107
153
  test 'an indented wrapped line is unindented and folded into text of list item' do
108
154
  input = <<-EOS
109
155
  List
@@ -357,6 +403,22 @@ List
357
403
  assert_xpath '(//ul)[2]/preceding-sibling::*[@class = "title"][text() = "Also"]', output, 1
358
404
  end
359
405
 
406
+ test "asterisk elements separated by an attribute entry offset by a blank line should not merge lists" do
407
+ input = <<-EOS
408
+ == List
409
+
410
+ * Foo
411
+ * Boo
412
+
413
+ :foo: bar
414
+ * Blech
415
+ EOS
416
+ output = render_embedded_string input
417
+ assert_xpath '//ul', output, 2
418
+ assert_xpath '(//ul)[1]/li', output, 2
419
+ assert_xpath '(//ul)[2]/li', output, 1
420
+ end
421
+
360
422
  test "list should terminate before next lower section heading" do
361
423
  input = <<-EOS
362
424
  List
@@ -815,6 +877,7 @@ Lists
815
877
 
816
878
  * Item one, paragraph one
817
879
  +
880
+ :foo: bar
818
881
  [[beck]]
819
882
  .Read the following aloud to yourself
820
883
  [source, ruby]
@@ -1295,6 +1358,22 @@ List
1295
1358
  assert_xpath '(//ol)[2]/li', output, 1
1296
1359
  assert_xpath '(//ol)[2]/preceding-sibling::*[@class = "title"][text() = "Also"]', output, 1
1297
1360
  end
1361
+
1362
+ test "dot elements separated by an attribute entry offset by a blank line should not merge lists" do
1363
+ input = <<-EOS
1364
+ == List
1365
+
1366
+ . Foo
1367
+ . Boo
1368
+
1369
+ :foo: bar
1370
+ . Blech
1371
+ EOS
1372
+ output = render_embedded_string input
1373
+ assert_xpath '//ol', output, 2
1374
+ assert_xpath '(//ol)[1]/li', output, 2
1375
+ assert_xpath '(//ol)[2]/li', output, 1
1376
+ end
1298
1377
  end
1299
1378
  end
1300
1379
 
@@ -102,11 +102,19 @@ You're good to go!
102
102
  assert_match(/^gem install asciidoctor/, output, "Indentation should be trimmed from literal block")
103
103
  end
104
104
 
105
+ test "literal paragraph" do
106
+ assert_xpath "//*[@class='literalblock']//pre[text()='blah blah blah']", render_string("[literal]\nblah blah blah")
107
+ end
108
+
105
109
  test "listing paragraph" do
106
- assert_xpath "//pre[@class='highlight']/code", render_string("[source]\n----\nblah blah blah\n----")
110
+ assert_xpath "//*[@class='listingblock']//pre[text()='blah blah blah']", render_string("[listing]\nblah blah blah")
107
111
  end
108
112
 
109
113
  test "source code paragraph" do
114
+ assert_xpath "//pre[@class='highlight']/code", render_string("[source]\nblah blah blah")
115
+ end
116
+
117
+ test "source code paragraph with language" do
110
118
  assert_xpath "//pre[@class='highlight']/code[@class='perl']", render_string("[source, perl]\ndie 'zomg perl sucks';")
111
119
  end
112
120
  end
data/test/reader_test.rb CHANGED
@@ -7,13 +7,13 @@ class ReaderTest < Test::Unit::TestCase
7
7
  @reader = Asciidoctor::Reader.new @src_data
8
8
  end
9
9
 
10
- context "has_lines?" do
10
+ context "has_more_lines?" do
11
11
  test "returns false for empty document" do
12
- assert !Asciidoctor::Reader.new.has_lines?
12
+ assert !Asciidoctor::Reader.new.has_more_lines?
13
13
  end
14
14
 
15
15
  test "returns true with lines remaining" do
16
- assert @reader.has_lines?, "Yo, didn't work"
16
+ assert @reader.has_more_lines?, "Yo, didn't work"
17
17
  end
18
18
  end
19
19
 
@@ -57,7 +57,7 @@ This is another paragraph.
57
57
  result = reader.grab_lines_until
58
58
  assert_equal 3, result.size
59
59
  assert_equal lines, result
60
- assert !reader.has_lines?
60
+ assert !reader.has_more_lines?
61
61
  assert reader.empty?
62
62
  end
63
63
 
@@ -181,10 +181,14 @@ include::include-file.asciidoc[]
181
181
  last line
182
182
  EOS
183
183
  doc = Asciidoctor::Document.new [], :safe => Asciidoctor::SafeMode::SAFE
184
- Asciidoctor::Reader.new(input.lines.entries, doc) {|inc|
185
- ":file: #{inc}\n\nmiddle line".lines.entries
184
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true) {|inc|
185
+ ":includefile: #{inc}\n\nmiddle line".lines.entries
186
186
  }
187
- assert_equal 'include-file.asciidoc', doc.attributes['file']
187
+ lines = []
188
+ while reader.has_more_lines?
189
+ lines << reader.get_line
190
+ end
191
+ assert_match(/^:includefile: include-file.asciidoc$/, lines.join)
188
192
  end
189
193
 
190
194
  test 'escaped include macro is left unprocessed' do
@@ -231,7 +235,7 @@ include::include-file.asciidoc[]
231
235
  context 'build secure asset path' do
232
236
  test 'allows us to specify a path relative to the current dir' do
233
237
  doc = Asciidoctor::Document.new
234
- Asciidoctor::Reader.new(["foo"], doc)
238
+ Asciidoctor::Reader.new([], doc, true)
235
239
  legit_path = Dir.pwd + "/foo"
236
240
  assert_equal legit_path, doc.normalize_asset_path(legit_path)
237
241
  end
@@ -239,7 +243,7 @@ include::include-file.asciidoc[]
239
243
  test "keeps naughty absolute paths from getting outside" do
240
244
  naughty_path = "#{disk_root}etc/passwd"
241
245
  doc = Asciidoctor::Document.new
242
- Asciidoctor::Reader.new(["foo"], doc)
246
+ Asciidoctor::Reader.new([], doc, true)
243
247
  secure_path = doc.normalize_asset_path(naughty_path)
244
248
  assert naughty_path != secure_path
245
249
  assert_match(/^#{doc.base_dir}/, secure_path)
@@ -248,26 +252,247 @@ include::include-file.asciidoc[]
248
252
  test "keeps naughty relative paths from getting outside" do
249
253
  naughty_path = "safe/ok/../../../../../etc/passwd"
250
254
  doc = Asciidoctor::Document.new
251
- Asciidoctor::Reader.new(["foo"], doc)
255
+ Asciidoctor::Reader.new([], doc, true)
252
256
  secure_path = doc.normalize_asset_path(naughty_path)
253
257
  assert naughty_path != secure_path
254
258
  assert_match(/^#{doc.base_dir}/, secure_path)
255
259
  end
256
260
  end
257
261
 
258
- # TODO these tests could be expanded
259
- context 'Conditional blocks' do
260
- test 'ifdef with defined attribute includes block' do
262
+ context 'Conditional Inclusions' do
263
+ test 'preprocess_next_line returns true if cursor advanced' do
264
+ input = <<-EOS
265
+ ifdef::asciidoctor[]
266
+ Asciidoctor!
267
+ endif::asciidoctor[]
268
+ EOS
269
+
270
+ doc = Asciidoctor::Document.new
271
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
272
+ assert reader.preprocess_next_line == true
273
+ end
274
+
275
+ test 'preprocess_next_line returns false if cursor not advanced' do
276
+ input = <<-EOS
277
+ content
278
+ ifdef::asciidoctor[]
279
+ Asciidoctor!
280
+ endif::asciidoctor[]
281
+ EOS
282
+
283
+ doc = Asciidoctor::Document.new
284
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
285
+ assert reader.preprocess_next_line == false
286
+ end
287
+
288
+ test 'preprocess_next_line returns nil if cursor advanced past end of source' do
261
289
  input = <<-EOS
262
- :holygrail:
290
+ ifdef::foobar[]
291
+ swallowed content
292
+ endif::foobar[]
293
+ EOS
263
294
 
295
+ doc = Asciidoctor::Document.new
296
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
297
+ assert reader.preprocess_next_line.nil?
298
+ end
299
+
300
+ test 'ifdef with defined attribute includes block' do
301
+ input = <<-EOS
264
302
  ifdef::holygrail[]
265
303
  There is a holy grail!
266
304
  endif::holygrail[]
267
305
  EOS
268
306
 
269
- reader = Asciidoctor::Reader.new(input.lines.entries, Asciidoctor::Document.new)
270
- assert_match(/There is a holy grail!/, reader.lines.join)
307
+ doc = Asciidoctor::Document.new [], :attributes => {'holygrail' => ''}
308
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
309
+ lines = []
310
+ while reader.has_more_lines?
311
+ lines << reader.get_line
312
+ end
313
+ assert_equal 'There is a holy grail!', lines.join.strip
314
+ end
315
+
316
+ test 'ifdef with defined attribute includes text in brackets' do
317
+ input = <<-EOS
318
+ On our quest we go...
319
+ ifdef::holygrail[There is a holy grail!]
320
+ There was much rejoicing.
321
+ EOS
322
+
323
+ doc = Asciidoctor::Document.new [], :attributes => {'holygrail' => ''}
324
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
325
+ lines = []
326
+ while reader.has_more_lines?
327
+ lines << reader.get_line
328
+ end
329
+ assert_equal "On our quest we go...\nThere is a holy grail!\nThere was much rejoicing.", lines.join.strip
330
+ end
331
+
332
+ test 'include with non-matching nested exclude' do
333
+ input = <<-EOS
334
+ ifdef::grail[]
335
+ holy
336
+ ifdef::swallow[]
337
+ swallow
338
+ endif::swallow[]
339
+ grail
340
+ endif::grail[]
341
+ EOS
342
+
343
+ doc = Asciidoctor::Document.new [], :attributes => {'grail' => ''}
344
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
345
+ lines = []
346
+ while reader.has_more_lines?
347
+ lines << reader.get_line
348
+ end
349
+ assert_equal "holy\ngrail", lines.join.strip
350
+ end
351
+
352
+ test 'nested excludes with same condition' do
353
+ input = <<-EOS
354
+ ifndef::grail[]
355
+ ifndef::grail[]
356
+ not here
357
+ endif::grail[]
358
+ endif::grail[]
359
+ EOS
360
+
361
+ doc = Asciidoctor::Document.new [], :attributes => {'grail' => ''}
362
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
363
+ lines = []
364
+ while reader.has_more_lines?
365
+ lines << reader.get_line
366
+ end
367
+ assert_equal '', lines.join.strip
368
+ end
369
+
370
+ test 'include with nested exclude of inverted condition' do
371
+ input = <<-EOS
372
+ ifdef::grail[]
373
+ holy
374
+ ifndef::grail[]
375
+ not here
376
+ endif::grail[]
377
+ grail
378
+ endif::grail[]
379
+ EOS
380
+
381
+ doc = Asciidoctor::Document.new [], :attributes => {'grail' => ''}
382
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
383
+ lines = []
384
+ while reader.has_more_lines?
385
+ lines << reader.get_line
386
+ end
387
+ assert_equal "holy\ngrail", lines.join.strip
388
+ end
389
+
390
+ test 'exclude with matching nested exclude' do
391
+ input = <<-EOS
392
+ poof
393
+ ifdef::swallow[]
394
+ no
395
+ ifdef::swallow[]
396
+ swallow
397
+ endif::swallow[]
398
+ here
399
+ endif::swallow[]
400
+ gone
401
+ EOS
402
+
403
+ doc = Asciidoctor::Document.new [], :attributes => {'grail' => ''}
404
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
405
+ lines = []
406
+ while reader.has_more_lines?
407
+ lines << reader.get_line
408
+ end
409
+ assert_equal "poof\ngone", lines.join.strip
410
+ end
411
+
412
+ test 'exclude with nested include using shorthand end' do
413
+ input = <<-EOS
414
+ poof
415
+ ifndef::grail[]
416
+ no grail
417
+ ifndef::swallow[]
418
+ or swallow
419
+ endif::[]
420
+ in here
421
+ endif::[]
422
+ gone
423
+ EOS
424
+
425
+ doc = Asciidoctor::Document.new [], :attributes => {'grail' => ''}
426
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
427
+ lines = []
428
+ while reader.has_more_lines?
429
+ lines << reader.get_line
430
+ end
431
+ assert_equal "poof\ngone", lines.join.strip
432
+ end
433
+
434
+ test 'ifdef with one alternative attribute set includes content' do
435
+ input = <<-EOS
436
+ ifdef::holygrail,swallow[]
437
+ Our quest is complete!
438
+ endif::holygrail,swallow[]
439
+ EOS
440
+
441
+ doc = Asciidoctor::Document.new [], :attributes => {'swallow' => ''}
442
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
443
+ lines = []
444
+ while reader.has_more_lines?
445
+ lines << reader.get_line
446
+ end
447
+ assert_equal 'Our quest is complete!', lines.join.strip
448
+ end
449
+
450
+ test 'ifdef with no alternative attributes set does not include content' do
451
+ input = <<-EOS
452
+ ifdef::holygrail,swallow[]
453
+ Our quest is complete!
454
+ endif::holygrail,swallow[]
455
+ EOS
456
+
457
+ doc = Asciidoctor::Document.new
458
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
459
+ lines = []
460
+ while reader.has_more_lines?
461
+ lines << reader.get_line
462
+ end
463
+ assert_equal '', lines.join.strip
464
+ end
465
+
466
+ test 'ifdef with all required attributes set includes content' do
467
+ input = <<-EOS
468
+ ifdef::holygrail+swallow[]
469
+ Our quest is complete!
470
+ endif::holygrail+swallow[]
471
+ EOS
472
+
473
+ doc = Asciidoctor::Document.new [], :attributes => {'holygrail' => '', 'swallow' => ''}
474
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
475
+ lines = []
476
+ while reader.has_more_lines?
477
+ lines << reader.get_line
478
+ end
479
+ assert_equal 'Our quest is complete!', lines.join.strip
480
+ end
481
+
482
+ test 'ifdef with missing required attributes does not include content' do
483
+ input = <<-EOS
484
+ ifdef::holygrail+swallow[]
485
+ Our quest is complete!
486
+ endif::holygrail+swallow[]
487
+ EOS
488
+
489
+ doc = Asciidoctor::Document.new [], :attributes => {'holygrail' => ''}
490
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
491
+ lines = []
492
+ while reader.has_more_lines?
493
+ lines << reader.get_line
494
+ end
495
+ assert_equal '', lines.join.strip
271
496
  end
272
497
 
273
498
  test 'ifndef with undefined attribute includes block' do
@@ -277,8 +502,220 @@ Our quest continues to find the holy grail!
277
502
  endif::holygrail[]
278
503
  EOS
279
504
 
280
- reader = Asciidoctor::Reader.new(input.lines.entries, Asciidoctor::Document.new)
281
- assert_match(/Our quest continues to find the holy grail!/, reader.lines.join)
505
+ doc = Asciidoctor::Document.new
506
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
507
+ lines = []
508
+ while reader.has_more_lines?
509
+ lines << reader.get_line
510
+ end
511
+ assert_equal 'Our quest continues to find the holy grail!', lines.join.strip
512
+ end
513
+
514
+ test 'ifndef with one alternative attribute set includes content' do
515
+ input = <<-EOS
516
+ ifndef::holygrail,swallow[]
517
+ Our quest is complete!
518
+ endif::holygrail,swallow[]
519
+ EOS
520
+
521
+ doc = Asciidoctor::Document.new [], :attributes => {'swallow' => ''}
522
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
523
+ lines = []
524
+ while reader.has_more_lines?
525
+ lines << reader.get_line
526
+ end
527
+ assert_equal 'Our quest is complete!', lines.join.strip
528
+ end
529
+
530
+ test 'ifndef with no alternative attributes set includes content' do
531
+ input = <<-EOS
532
+ ifndef::holygrail,swallow[]
533
+ Our quest is complete!
534
+ endif::holygrail,swallow[]
535
+ EOS
536
+
537
+ doc = Asciidoctor::Document.new
538
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
539
+ lines = []
540
+ while reader.has_more_lines?
541
+ lines << reader.get_line
542
+ end
543
+ assert_equal 'Our quest is complete!', lines.join.strip
544
+ end
545
+
546
+ test 'ifndef with any required attributes set does not include content' do
547
+ input = <<-EOS
548
+ ifndef::holygrail+swallow[]
549
+ Our quest is complete!
550
+ endif::holygrail+swallow[]
551
+ EOS
552
+
553
+ doc = Asciidoctor::Document.new [], :attributes => {'swallow' => ''}
554
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
555
+ lines = []
556
+ while reader.has_more_lines?
557
+ lines << reader.get_line
558
+ end
559
+ assert_equal '', lines.join.strip
560
+ end
561
+
562
+ test 'ifndef with no required attributes set includes content' do
563
+ input = <<-EOS
564
+ ifndef::holygrail+swallow[]
565
+ Our quest is complete!
566
+ endif::holygrail+swallow[]
567
+ EOS
568
+
569
+ doc = Asciidoctor::Document.new
570
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
571
+ lines = []
572
+ while reader.has_more_lines?
573
+ lines << reader.get_line
574
+ end
575
+ assert_equal 'Our quest is complete!', lines.join.strip
576
+ end
577
+
578
+ test 'escaped ifdef is unescaped and ignored' do
579
+ input = <<-EOS
580
+ \\ifdef::holygrail[]
581
+ content
582
+ \\endif::holygrail[]
583
+ EOS
584
+
585
+ doc = Asciidoctor::Document.new
586
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
587
+ lines = []
588
+ while reader.has_more_lines?
589
+ lines << reader.get_line
590
+ end
591
+ assert_equal "ifdef::holygrail[]\ncontent\nendif::holygrail[]", lines.join.strip
592
+ end
593
+
594
+ test 'ifeval comparing double-quoted attribute to matching string is included' do
595
+ input = <<-EOS
596
+ ifeval::["{gem}" == "asciidoctor"]
597
+ Asciidoctor it is!
598
+ endif::[]
599
+ EOS
600
+
601
+ doc = Asciidoctor::Document.new [], :attributes => {'gem' => 'asciidoctor'}
602
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
603
+ lines = []
604
+ while reader.has_more_lines?
605
+ lines << reader.get_line
606
+ end
607
+ assert_equal 'Asciidoctor it is!', lines.join.strip
608
+ end
609
+
610
+ test 'ifeval comparing single-quoted attribute to matching string is included' do
611
+ input = <<-EOS
612
+ ifeval::['{gem}' == 'asciidoctor']
613
+ Asciidoctor it is!
614
+ endif::[]
615
+ EOS
616
+
617
+ doc = Asciidoctor::Document.new [], :attributes => {'gem' => 'asciidoctor'}
618
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
619
+ lines = []
620
+ while reader.has_more_lines?
621
+ lines << reader.get_line
622
+ end
623
+ assert_equal 'Asciidoctor it is!', lines.join.strip
624
+ end
625
+
626
+ test 'ifeval comparing quoted attribute to non-matching string is ignored' do
627
+ input = <<-EOS
628
+ ifeval::['{gem}' == 'asciidoctor']
629
+ Asciidoctor it is!
630
+ endif::[]
631
+ EOS
632
+
633
+ doc = Asciidoctor::Document.new [], :attributes => {'gem' => 'tilt'}
634
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
635
+ lines = []
636
+ while reader.has_more_lines?
637
+ lines << reader.get_line
638
+ end
639
+ assert_equal '', lines.join.strip
640
+ end
641
+
642
+ test 'ifeval comparing attribute to lower version number is included' do
643
+ input = <<-EOS
644
+ ifeval::['{asciidoctor-version}' >= '0.1.0']
645
+ That version will do!
646
+ endif::[]
647
+ EOS
648
+
649
+ doc = Asciidoctor::Document.new
650
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
651
+ lines = []
652
+ while reader.has_more_lines?
653
+ lines << reader.get_line
654
+ end
655
+ assert_equal 'That version will do!', lines.join.strip
656
+ end
657
+
658
+ test 'ifeval comparing attribute to self is included' do
659
+ input = <<-EOS
660
+ ifeval::['{asciidoctor-version}' == '{asciidoctor-version}']
661
+ Of course it's the same!
662
+ endif::[]
663
+ EOS
664
+
665
+ doc = Asciidoctor::Document.new
666
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
667
+ lines = []
668
+ while reader.has_more_lines?
669
+ lines << reader.get_line
670
+ end
671
+ assert_equal 'Of course it\'s the same!', lines.join.strip
672
+ end
673
+
674
+ test 'ifeval arguments can be mirrored' do
675
+ input = <<-EOS
676
+ ifeval::["0.1.0" <= "{asciidoctor-version}"]
677
+ That version will do!
678
+ endif::[]
679
+ EOS
680
+
681
+ doc = Asciidoctor::Document.new
682
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
683
+ lines = []
684
+ while reader.has_more_lines?
685
+ lines << reader.get_line
686
+ end
687
+ assert_equal 'That version will do!', lines.join.strip
688
+ end
689
+
690
+ test 'ifeval matching numeric comparison is included' do
691
+ input = <<-EOS
692
+ ifeval::[{rings} == 1]
693
+ One ring to rule them all!
694
+ endif::[]
695
+ EOS
696
+
697
+ doc = Asciidoctor::Document.new [], :attributes => {'rings' => 1}
698
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
699
+ lines = []
700
+ while reader.has_more_lines?
701
+ lines << reader.get_line
702
+ end
703
+ assert_equal 'One ring to rule them all!', lines.join.strip
704
+ end
705
+
706
+ test 'ifdef with no target is ignored' do
707
+ input = <<-EOS
708
+ ifdef::[]
709
+ content
710
+ EOS
711
+
712
+ doc = Asciidoctor::Document.new
713
+ reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
714
+ lines = []
715
+ while reader.has_more_lines?
716
+ lines << reader.get_line
717
+ end
718
+ assert_equal "ifdef::[]\ncontent", lines.join.strip
282
719
  end
283
720
  end
284
721
 
@@ -291,7 +728,7 @@ CRLF\r
291
728
  endlines\r
292
729
  EOS
293
730
 
294
- reader = Asciidoctor::Reader.new(input.lines.entries, Asciidoctor::Document.new)
731
+ reader = Asciidoctor::Reader.new(input.lines.entries, Asciidoctor::Document.new, true)
295
732
  reader.lines.each do |line|
296
733
  assert !line.end_with?("\r\n")
297
734
  end