asciidoctor 1.5.7.1 → 1.5.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +95 -5
  3. data/Gemfile +23 -13
  4. data/README-de.adoc +482 -0
  5. data/README-fr.adoc +128 -119
  6. data/README-jp.adoc +2 -3
  7. data/README-zh_CN.adoc +2 -3
  8. data/README.adoc +131 -106
  9. data/asciidoctor.gemspec +9 -7
  10. data/data/locale/attributes-ar.adoc +1 -1
  11. data/data/locale/attributes-bg.adoc +1 -1
  12. data/data/locale/attributes-ca.adoc +1 -1
  13. data/data/locale/attributes-cs.adoc +1 -1
  14. data/data/locale/attributes-da.adoc +1 -1
  15. data/data/locale/attributes-de.adoc +1 -1
  16. data/data/locale/attributes-en.adoc +1 -1
  17. data/data/locale/attributes-es.adoc +1 -1
  18. data/data/locale/attributes-fa.adoc +1 -1
  19. data/data/locale/attributes-fi.adoc +1 -1
  20. data/data/locale/attributes-fr.adoc +1 -1
  21. data/data/locale/attributes-hu.adoc +1 -1
  22. data/data/locale/attributes-id.adoc +1 -1
  23. data/data/locale/attributes-it.adoc +1 -1
  24. data/data/locale/attributes-ja.adoc +1 -1
  25. data/data/locale/attributes-kr.adoc +1 -1
  26. data/data/locale/attributes-nb.adoc +1 -1
  27. data/data/locale/attributes-nl.adoc +1 -1
  28. data/data/locale/attributes-nn.adoc +1 -1
  29. data/data/locale/attributes-pl.adoc +1 -1
  30. data/data/locale/attributes-pt.adoc +1 -1
  31. data/data/locale/attributes-pt_BR.adoc +1 -1
  32. data/data/locale/attributes-ro.adoc +1 -1
  33. data/data/locale/attributes-ru.adoc +1 -1
  34. data/data/locale/attributes-sr.adoc +5 -4
  35. data/data/locale/attributes-sr_Latn.adoc +5 -4
  36. data/data/locale/attributes-sv.adoc +23 -0
  37. data/data/locale/attributes-tr.adoc +1 -1
  38. data/data/locale/attributes-uk.adoc +1 -1
  39. data/data/locale/attributes-zh_CN.adoc +1 -1
  40. data/data/locale/attributes-zh_TW.adoc +1 -1
  41. data/data/stylesheets/asciidoctor-default.css +23 -23
  42. data/lib/asciidoctor.rb +110 -104
  43. data/lib/asciidoctor/abstract_block.rb +55 -32
  44. data/lib/asciidoctor/abstract_node.rb +32 -17
  45. data/lib/asciidoctor/attribute_list.rb +8 -7
  46. data/lib/asciidoctor/block.rb +5 -7
  47. data/lib/asciidoctor/cli/options.rb +5 -9
  48. data/lib/asciidoctor/converter.rb +2 -2
  49. data/lib/asciidoctor/converter/docbook45.rb +7 -20
  50. data/lib/asciidoctor/converter/docbook5.rb +36 -37
  51. data/lib/asciidoctor/converter/factory.rb +10 -8
  52. data/lib/asciidoctor/converter/html5.rb +90 -65
  53. data/lib/asciidoctor/converter/manpage.rb +72 -62
  54. data/lib/asciidoctor/converter/template.rb +8 -6
  55. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +5 -0
  56. data/lib/asciidoctor/document.rb +62 -10
  57. data/lib/asciidoctor/extensions.rb +74 -16
  58. data/lib/asciidoctor/helpers.rb +11 -14
  59. data/lib/asciidoctor/list.rb +2 -2
  60. data/lib/asciidoctor/parser.rb +223 -195
  61. data/lib/asciidoctor/path_resolver.rb +15 -7
  62. data/lib/asciidoctor/reader.rb +65 -36
  63. data/lib/asciidoctor/section.rb +6 -4
  64. data/lib/asciidoctor/substitutors.rb +170 -149
  65. data/lib/asciidoctor/table.rb +16 -8
  66. data/lib/asciidoctor/version.rb +1 -1
  67. data/man/asciidoctor.1 +6 -5
  68. data/man/asciidoctor.adoc +3 -2
  69. data/test/api_test.rb +236 -0
  70. data/test/attribute_list_test.rb +242 -0
  71. data/test/attributes_test.rb +65 -52
  72. data/test/blocks_test.rb +408 -260
  73. data/test/converter_test.rb +7 -7
  74. data/test/document_test.rb +60 -54
  75. data/test/extensions_test.rb +218 -32
  76. data/test/fixtures/doctime-localtime.adoc +2 -0
  77. data/test/fixtures/section-a.adoc +4 -0
  78. data/test/fixtures/subs.adoc +0 -1
  79. data/test/invoker_test.rb +56 -18
  80. data/test/links_test.rb +105 -81
  81. data/test/lists_test.rb +636 -265
  82. data/test/logger_test.rb +1 -1
  83. data/test/manpage_test.rb +140 -3
  84. data/test/paragraphs_test.rb +42 -42
  85. data/test/parser_test.rb +63 -183
  86. data/test/paths_test.rb +21 -4
  87. data/test/preamble_test.rb +9 -9
  88. data/test/reader_test.rb +78 -28
  89. data/test/sections_test.rb +273 -151
  90. data/test/substitutions_test.rb +53 -19
  91. data/test/tables_test.rb +286 -163
  92. data/test/test_helper.rb +4 -3
  93. data/test/text_test.rb +65 -65
  94. metadata +16 -21
@@ -96,189 +96,6 @@ context "Parser" do
96
96
  end
97
97
  end
98
98
 
99
- test "collect unnamed attribute" do
100
- attributes = {}
101
- line = 'quote'
102
- expected = {1 => 'quote'}
103
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
104
- assert_equal expected, attributes
105
- end
106
-
107
- test "collect unnamed attribute double-quoted" do
108
- attributes = {}
109
- line = '"quote"'
110
- expected = {1 => 'quote'}
111
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
112
- assert_equal expected, attributes
113
- end
114
-
115
- test "collect empty unnamed attribute double-quoted" do
116
- attributes = {}
117
- line = '""'
118
- expected = {1 => ''}
119
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
120
- assert_equal expected, attributes
121
- end
122
-
123
- test "collect unnamed attribute double-quoted containing escaped quote" do
124
- attributes = {}
125
- line = '"ba\"zaar"'
126
- expected = {1 => 'ba"zaar'}
127
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
128
- assert_equal expected, attributes
129
- end
130
-
131
- test "collect unnamed attribute single-quoted" do
132
- attributes = {}
133
- line = '\'quote\''
134
- expected = {1 => 'quote'}
135
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
136
- assert_equal expected, attributes
137
- end
138
-
139
- test "collect empty unnamed attribute single-quoted" do
140
- attributes = {}
141
- line = '\'\''
142
- expected = {1 => ''}
143
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
144
- assert_equal expected, attributes
145
- end
146
-
147
- test "collect unnamed attribute single-quoted containing escaped quote" do
148
- attributes = {}
149
- line = '\'ba\\\'zaar\''
150
- expected = {1 => 'ba\'zaar'}
151
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
152
- assert_equal expected, attributes
153
- end
154
-
155
- test "collect unnamed attribute with dangling delimiter" do
156
- attributes = {}
157
- line = 'quote , '
158
- expected = {1 => 'quote'}
159
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
160
- assert_equal expected, attributes
161
- end
162
-
163
- test "collect unnamed attribute in second position after empty attribute" do
164
- attributes = {}
165
- line = ', John Smith'
166
- expected = {1 => nil, 2 => 'John Smith'}
167
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
168
- assert_equal expected, attributes
169
- end
170
-
171
- test "collect unnamed attributes" do
172
- attributes = {}
173
- line = "first, second one, third"
174
- expected = {1 => 'first', 2 => 'second one', 3 => 'third'}
175
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
176
- assert_equal expected, attributes
177
- end
178
-
179
- test "collect named attribute" do
180
- attributes = {}
181
- line = 'foo=bar'
182
- expected = {'foo' => 'bar'}
183
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
184
- assert_equal expected, attributes
185
- end
186
-
187
- test "collect named attribute double-quoted" do
188
- attributes = {}
189
- line = 'foo="bar"'
190
- expected = {'foo' => 'bar'}
191
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
192
- assert_equal expected, attributes
193
- end
194
-
195
- test 'collect named attribute with double-quoted empty value' do
196
- attributes = {}
197
- line = 'height=100,caption="",link="images/octocat.png"'
198
- expected = {'height' => '100', 'caption' => '', 'link' => 'images/octocat.png'}
199
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
200
- assert_equal expected, attributes
201
- end
202
-
203
- test "collect named attribute single-quoted" do
204
- attributes = {}
205
- line = 'foo=\'bar\''
206
- expected = {'foo' => 'bar'}
207
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
208
- assert_equal expected, attributes
209
- end
210
-
211
- test 'collect named attribute with single-quoted empty value' do
212
- attributes = {}
213
- line = "height=100,caption='',link='images/octocat.png'"
214
- expected = {'height' => '100', 'caption' => '', 'link' => 'images/octocat.png'}
215
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
216
- assert_equal expected, attributes
217
- end
218
-
219
- test "collect named attributes unquoted" do
220
- attributes = {}
221
- line = "first=value, second=two, third=3"
222
- expected = {'first' => 'value', 'second' => 'two', 'third' => '3'}
223
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
224
- assert_equal expected, attributes
225
- end
226
-
227
- test "collect named attributes quoted" do
228
- attributes = {}
229
- line = "first='value', second=\"value two\", third=three"
230
- expected = {'first' => 'value', 'second' => 'value two', 'third' => 'three'}
231
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
232
- assert_equal expected, attributes
233
- end
234
-
235
- test "collect named attributes quoted containing non-semantic spaces" do
236
- attributes = {}
237
- line = " first = 'value', second =\"value two\" , third= three "
238
- expected = {'first' => 'value', 'second' => 'value two', 'third' => 'three'}
239
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
240
- assert_equal expected, attributes
241
- end
242
-
243
- test "collect mixed named and unnamed attributes" do
244
- attributes = {}
245
- line = "first, second=\"value two\", third=three, Sherlock Holmes"
246
- expected = {1 => 'first', 'second' => 'value two', 'third' => 'three', 4 => 'Sherlock Holmes'}
247
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
248
- assert_equal expected, attributes
249
- end
250
-
251
- test "collect options attribute" do
252
- attributes = {}
253
- line = "quote, options='opt1,opt2 , opt3'"
254
- expected = {1 => 'quote', 'options' => 'opt1,opt2,opt3', 'opt1-option' => '', 'opt2-option' => '', 'opt3-option' => ''}
255
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
256
- assert_equal expected, attributes
257
- end
258
-
259
- test "collect opts attribute as options" do
260
- attributes = {}
261
- line = "quote, opts='opt1,opt2 , opt3'"
262
- expected = {1 => 'quote', 'options' => 'opt1,opt2,opt3', 'opt1-option' => '', 'opt2-option' => '', 'opt3-option' => ''}
263
- Asciidoctor::AttributeList.new(line).parse_into(attributes)
264
- assert_equal expected, attributes
265
- end
266
-
267
- test "collect and rekey unnamed attributes" do
268
- attributes = {}
269
- line = "first, second one, third, fourth"
270
- expected = {1 => 'first', 2 => 'second one', 3 => 'third', 4 => 'fourth', 'a' => 'first', 'b' => 'second one', 'c' => 'third'}
271
- Asciidoctor::AttributeList.new(line).parse_into(attributes, ['a', 'b', 'c'])
272
- assert_equal expected, attributes
273
- end
274
-
275
- test "rekey positional attributes" do
276
- attributes = {1 => 'source', 2 => 'java'}
277
- expected = {1 => 'source', 2 => 'java', 'style' => 'source', 'language' => 'java'}
278
- Asciidoctor::AttributeList.rekey(attributes, ['style', 'language', 'linenums'])
279
- assert_equal expected, attributes
280
- end
281
-
282
99
  test 'parse style attribute with id and role' do
283
100
  attributes = {1 => 'style#id.role'}
284
101
  style = Asciidoctor::Parser.parse_style_attribute(attributes)
@@ -542,6 +359,26 @@ context "Parser" do
542
359
  assert_equal 'Scherer, Jr.', doc.attributes['lastname']
543
360
  end
544
361
 
362
+ test 'use explicit authorinitials if set after implicit author line' do
363
+ input = <<-EOS.chomp
364
+ Jean-Claude Van Damme
365
+ :authorinitials: JCVD
366
+ EOS
367
+ doc = empty_document
368
+ parse_header_metadata input, doc
369
+ assert_equal 'JCVD', doc.attributes['authorinitials']
370
+ end
371
+
372
+ test 'use explicit authorinitials if set after author attribute' do
373
+ input = <<-EOS.chomp
374
+ :author: Jean-Claude Van Damme
375
+ :authorinitials: JCVD
376
+ EOS
377
+ doc = empty_document
378
+ parse_header_metadata input, doc
379
+ assert_equal 'JCVD', doc.attributes['authorinitials']
380
+ end
381
+
545
382
  test 'sets authorcount to 0 if document has no authors' do
546
383
  input = ''
547
384
  doc = empty_document
@@ -603,6 +440,34 @@ v0.0.7, 2013-12-18: The first release you can stand on
603
440
  assert_equal 'The first release you can stand on', metadata['revremark']
604
441
  end
605
442
 
443
+ test 'parse rev number, data, and remark as attribute references' do
444
+ input = <<-EOS
445
+ Author Name
446
+ v{project-version}, {release-date}: {release-summary}
447
+ EOS
448
+ metadata, _ = parse_header_metadata input
449
+ assert_equal 9, metadata.size
450
+ assert_equal '{project-version}', metadata['revnumber']
451
+ assert_equal '{release-date}', metadata['revdate']
452
+ assert_equal '{release-summary}', metadata['revremark']
453
+ end
454
+
455
+ test 'should resolve attribute references in rev number, data, and remark' do
456
+ input = <<-EOS
457
+ = Document Title
458
+ Author Name
459
+ {project-version}, {release-date}: {release-summary}
460
+ EOS
461
+ doc = document_from_string input, :attributes => {
462
+ 'project-version' => '1.0.1',
463
+ 'release-date' => '2018-05-15',
464
+ 'release-summary' => 'The one you can count on!'
465
+ }
466
+ assert_equal '1.0.1', (doc.attr 'revnumber')
467
+ assert_equal '2018-05-15', (doc.attr 'revdate')
468
+ assert_equal 'The one you can count on!', (doc.attr 'revremark')
469
+ end
470
+
606
471
  test "parse rev date" do
607
472
  input = <<-EOS
608
473
  Ryan Waldron
@@ -859,4 +724,19 @@ devtmpfs 3.9G 0 3.9G 0% /dev
859
724
  assert_equal expected, lines
860
725
  end
861
726
 
727
+ test 'should warn if inline anchor is already in use' do
728
+ input = <<-EOS
729
+ [#in-use]
730
+ A paragraph with an id.
731
+
732
+ Another paragraph
733
+ [[in-use]]that uses an id
734
+ which is already in use.
735
+ EOS
736
+
737
+ using_memory_logger do |logger|
738
+ document_from_string input
739
+ assert_message logger, :WARN, '<stdin>: line 5: id assigned to anchor already in use: in-use', Hash
740
+ end
741
+ end
862
742
  end
@@ -276,10 +276,27 @@ context 'Path Resolver' do
276
276
  assert_equal '/usr/share/assets/stylesheet.css', @resolver.system_path('assets/stylesheet.css', '/usr/share')
277
277
  end
278
278
 
279
- test 'resolves absolute UNC path if start is absolute and target is relative' do
279
+ test 'File.dirname preserves UNC path root on Windows' do
280
+ assert_equal File.dirname('\\\\server\\docs\\file.html'), '\\\\server\\docs'
281
+ end if windows?
282
+
283
+ test 'File.dirname preserves posix-style UNC path root on Windows' do
284
+ assert_equal File.dirname('//server/docs/file.html'), '//server/docs'
285
+ end if windows?
286
+
287
+ test 'resolves UNC path if start is absolute and target is relative' do
280
288
  assert_equal '//QA/c$/users/asciidoctor/assets/stylesheet.css', @resolver.system_path('assets/stylesheet.css', '//QA/c$/users/asciidoctor')
281
289
  end
282
290
 
291
+ test 'resolves UNC path if target is UNC path' do
292
+ @resolver.file_separator = '\\'
293
+ assert_equal '//server/docs/output.html', @resolver.system_path('\\\\server\\docs\\output.html')
294
+ end
295
+
296
+ test 'resolves UNC path if target is posix-style UNC path' do
297
+ assert_equal '//server/docs/output.html', @resolver.system_path('//server/docs/output.html')
298
+ end
299
+
283
300
  test 'resolves relative target relative to current directory if start is empty' do
284
301
  pwd = File.expand_path(Dir.pwd)
285
302
  assert_equal "#{pwd}/images/tiger.png", @resolver.system_path('images/tiger.png', '')
@@ -330,11 +347,11 @@ context 'Path Resolver' do
330
347
  assert_equal 'part1/chapter1/section1.adoc', @resolver.relative_path(filename, JAIL)
331
348
  end
332
349
 
333
- test 'should resolve relative path to filename if does not share common root with base directory' do
334
- filename = '/docs/partials'
350
+ test 'should resolve relative path to filename outside of base directory' do
351
+ filename = '/home/shared/partials'
335
352
  base_dir = '/home/user/docs'
336
353
  result = @resolver.relative_path filename, base_dir
337
- assert_equal filename, result
354
+ assert_equal '../../shared/partials', result
338
355
  end
339
356
 
340
357
  test 'should resolve relative path relative to base dir in unsafe mode' do
@@ -16,7 +16,7 @@ Preamble paragraph 1.
16
16
 
17
17
  Section paragraph 1.
18
18
  EOS
19
- result = render_string(input)
19
+ result = convert_string(input)
20
20
  assert_xpath '//p', result, 2
21
21
  assert_xpath '//*[@id="preamble"]', result, 1
22
22
  assert_xpath '//*[@id="preamble"]//p', result, 1
@@ -35,7 +35,7 @@ Preface content.
35
35
 
36
36
  Section content.
37
37
  EOS
38
- result = render_string input, :backend => :docbook
38
+ result = convert_string input, :backend => :docbook
39
39
  assert_xpath '//preface/title', result, 1
40
40
  title_node = xmlnodes_at_xpath '//preface/title', result, 1
41
41
  assert_equal '', title_node.text
@@ -53,7 +53,7 @@ Preface content.
53
53
 
54
54
  Section content.
55
55
  EOS
56
- result = render_string input, :backend => :docbook
56
+ result = convert_string input, :backend => :docbook
57
57
  assert_xpath '//preface/title[text()="Preface"]', result, 1
58
58
  end
59
59
 
@@ -69,7 +69,7 @@ Preamble paragraph 2.
69
69
 
70
70
  Section paragraph 1.
71
71
  EOS
72
- result = render_string(input)
72
+ result = convert_string(input)
73
73
  assert_xpath '//p', result, 3
74
74
  assert_xpath '//*[@id="preamble"]', result, 1
75
75
  assert_xpath '//*[@id="preamble"]//p', result, 2
@@ -83,7 +83,7 @@ Section paragraph 1.
83
83
 
84
84
  paragraph
85
85
  EOS
86
- result = render_string(input)
86
+ result = convert_string(input)
87
87
  assert_xpath '//p', result, 1
88
88
  assert_xpath '//*[@id="content"]/*[@class="paragraph"]/p', result, 1
89
89
  assert_xpath '//*[@id="content"]/*[@class="paragraph"]/following-sibling::*', result, 0
@@ -97,7 +97,7 @@ paragraph
97
97
 
98
98
  Section paragraph 1.
99
99
  EOS
100
- result = render_string(input)
100
+ result = convert_string(input)
101
101
  assert_xpath '//p', result, 1
102
102
  assert_xpath '//*[@id="preamble"]', result, 0
103
103
  assert_xpath '//h2[@id="_first_section"]', result, 1
@@ -111,7 +111,7 @@ Preamble paragraph 1.
111
111
 
112
112
  Section paragraph 1.
113
113
  EOS
114
- result = render_string(input)
114
+ result = convert_string(input)
115
115
  assert_xpath '//p', result, 2
116
116
  assert_xpath '//*[@id="preamble"]', result, 0
117
117
  assert_xpath '//h2[@id="_first_section"]/preceding::p', result, 1
@@ -150,7 +150,7 @@ The axe came swinging.
150
150
  assert_xpath %{//*[@id="preamble"]//p[text() = "Back then#{decode_char 8230}#{decode_char 8203}"]}, output, 1
151
151
  end
152
152
 
153
- test 'should render table of contents in preamble if toc-placement attribute value is preamble' do
153
+ test 'should output table of contents in preamble if toc-placement attribute value is preamble' do
154
154
  input = <<-EOS
155
155
  = Article
156
156
  :toc:
@@ -167,7 +167,7 @@ It was a dark and stormy night...
167
167
  They couldn't believe their eyes when...
168
168
  EOS
169
169
 
170
- output = render_string input
170
+ output = convert_string input
171
171
  assert_xpath '//*[@id="preamble"]/*[@id="toc"]', output, 1
172
172
  end
173
173
  end
@@ -783,7 +783,7 @@ include::#{url}[]
783
783
  EOS
784
784
  expect = /\{"name": "asciidoctor"\}/
785
785
  output = using_test_webserver do
786
- render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
786
+ convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
787
787
  end
788
788
 
789
789
  refute_nil output
@@ -797,7 +797,7 @@ include::fixtures/outer-include.adoc[]
797
797
  ....
798
798
  EOS
799
799
 
800
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
800
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
801
801
  expected = 'first line of outer
802
802
 
803
803
  first line of middle
@@ -820,7 +820,7 @@ include::#{url}[]
820
820
  ....
821
821
  EOS
822
822
  output = using_test_webserver do
823
- render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
823
+ convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
824
824
  end
825
825
 
826
826
  expected = 'first line of outer
@@ -848,7 +848,7 @@ include::#{include_url}[]
848
848
  begin
849
849
  using_memory_logger do |logger|
850
850
  result = using_test_webserver do
851
- render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
851
+ convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
852
852
  end
853
853
  assert_includes result, %(Unresolved directive in #{include_url} - include::#{nested_include_url}[])
854
854
  assert_message logger, :ERROR, %(#{include_url}: line 1: include uri not readable: http://#{resolve_localhost}:9876/fixtures/#{nested_include_url}), Hash
@@ -867,7 +867,7 @@ include::#{url}[tag=init,indent=0]
867
867
  ----
868
868
  EOS
869
869
  output = using_test_webserver do
870
- render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
870
+ convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
871
871
  end
872
872
 
873
873
  expected = '<code class="language-ruby" data-lang="ruby">def initialize breed
@@ -887,7 +887,7 @@ include::#{url}[]
887
887
  begin
888
888
  using_memory_logger do |logger|
889
889
  output = using_test_webserver do
890
- render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
890
+ convert_string_to_embedded input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
891
891
  end
892
892
  refute_nil output
893
893
  assert_match(/Unresolved directive/, output)
@@ -903,7 +903,7 @@ include::#{url}[]
903
903
  include::fixtures/include-file.asciidoc[lines=1;3..4;6..-1]
904
904
  EOS
905
905
 
906
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
906
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
907
907
  assert_match(/first line/, output)
908
908
  refute_match(/second line/, output)
909
909
  assert_match(/third line/, output)
@@ -920,7 +920,7 @@ include::fixtures/include-file.asciidoc[lines=1;3..4;6..-1]
920
920
  include::fixtures/include-file.asciidoc[lines="1, 3..4 , 6 .. -1"]
921
921
  EOS
922
922
 
923
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
923
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
924
924
  assert_match(/first line/, output)
925
925
  refute_match(/second line/, output)
926
926
  assert_match(/third line/, output)
@@ -932,6 +932,23 @@ include::fixtures/include-file.asciidoc[lines="1, 3..4 , 6 .. -1"]
932
932
  assert_match(/last line of included content/, output)
933
933
  end
934
934
 
935
+ test 'include directive supports implicit endless range' do
936
+ input = <<-EOS
937
+ include::fixtures/include-file.asciidoc[lines=6..]
938
+ EOS
939
+
940
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
941
+ refute_match(/first line/, output)
942
+ refute_match(/second line/, output)
943
+ refute_match(/third line/, output)
944
+ refute_match(/fourth line/, output)
945
+ refute_match(/fifth line/, output)
946
+ assert_match(/sixth line/, output)
947
+ assert_match(/seventh line/, output)
948
+ assert_match(/eighth line/, output)
949
+ assert_match(/last line of included content/, output)
950
+ end
951
+
935
952
  test 'include directive ignores empty lines attribute' do
936
953
  input = <<-EOS
937
954
  ++++
@@ -939,7 +956,7 @@ include::fixtures/include-file.asciidoc[lines=]
939
956
  ++++
940
957
  EOS
941
958
 
942
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
959
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
943
960
  assert_includes output, 'first line of included content'
944
961
  assert_includes output, 'last line of included content'
945
962
  end
@@ -949,7 +966,7 @@ include::fixtures/include-file.asciidoc[lines=]
949
966
  include::fixtures/include-file.asciidoc[tag=snippetA]
950
967
  EOS
951
968
 
952
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
969
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
953
970
  assert_match(/snippetA content/, output)
954
971
  refute_match(/snippetB content/, output)
955
972
  refute_match(/non-tagged content/, output)
@@ -961,7 +978,7 @@ include::fixtures/include-file.asciidoc[tag=snippetA]
961
978
  include::fixtures/include-file.asciidoc[tags=snippetA;snippetB]
962
979
  EOS
963
980
 
964
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
981
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
965
982
  assert_match(/snippetA content/, output)
966
983
  assert_match(/snippetB content/, output)
967
984
  refute_match(/non-tagged content/, output)
@@ -995,7 +1012,7 @@ include::fixtures/#{filename}[tag=snippet,indent=0]
995
1012
  input = <<-EOS
996
1013
  include::#{tmp_include_path}[tag=include-me]
997
1014
  EOS
998
- output = render_embedded_string input, :safe => :safe, :base_dir => tmp_include_dir
1015
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => tmp_include_dir
999
1016
  assert_includes output, 'included line'
1000
1017
  refute_includes output, 'do not include'
1001
1018
  ensure
@@ -1003,6 +1020,26 @@ include::#{tmp_include_path}[tag=include-me]
1003
1020
  end
1004
1021
  end
1005
1022
 
1023
+ test 'include directive finds closing tag on last line of file without a trailing newline' do
1024
+ begin
1025
+ tmp_include = Tempfile.new %w(include- .adoc)
1026
+ tmp_include_dir, tmp_include_path = File.split tmp_include.path
1027
+ tmp_include.write %(line not included\ntag::include-me[]\nline included\nend::include-me[])
1028
+ tmp_include.close
1029
+ input = <<-EOS
1030
+ include::#{tmp_include_path}[tag=include-me]
1031
+ EOS
1032
+ using_memory_logger do |logger|
1033
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => tmp_include_dir
1034
+ assert_empty logger.messages
1035
+ assert_includes output, 'line included'
1036
+ refute_includes output, 'line not included'
1037
+ end
1038
+ ensure
1039
+ tmp_include.close!
1040
+ end
1041
+ end
1042
+
1006
1043
  test 'include directive does not select lines with tag directives within selected tag region' do
1007
1044
  input = <<-EOS
1008
1045
  ++++
@@ -1010,7 +1047,7 @@ include::fixtures/include-file.asciidoc[tags=snippet]
1010
1047
  ++++
1011
1048
  EOS
1012
1049
 
1013
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1050
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1014
1051
  expect = %(snippetA content
1015
1052
 
1016
1053
  non-tagged content
@@ -1026,7 +1063,7 @@ include::fixtures/tagged-class-enclosed.rb[tags=all;!bark]
1026
1063
  ----
1027
1064
  EOS
1028
1065
 
1029
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1066
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1030
1067
  expected = %(class Dog
1031
1068
  def initialize breed
1032
1069
  @breed = breed
@@ -1042,7 +1079,7 @@ include::fixtures/tagged-class.rb[tags=**]
1042
1079
  ----
1043
1080
  EOS
1044
1081
 
1045
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1082
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1046
1083
  expected = %(class Dog
1047
1084
  def initialize breed
1048
1085
  @breed = breed
@@ -1066,7 +1103,7 @@ include::fixtures/tagged-class.rb[tags=**;!bark]
1066
1103
  ----
1067
1104
  EOS
1068
1105
 
1069
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1106
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1070
1107
  expected = %(class Dog
1071
1108
  def initialize breed
1072
1109
  @breed = breed
@@ -1082,7 +1119,7 @@ include::fixtures/tagged-class-enclosed.rb[tags=*]
1082
1119
  ----
1083
1120
  EOS
1084
1121
 
1085
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1122
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1086
1123
  expected = %(class Dog
1087
1124
  def initialize breed
1088
1125
  @breed = breed
@@ -1106,7 +1143,7 @@ include::fixtures/tagged-class-enclosed.rb[tags=*;!init]
1106
1143
  ----
1107
1144
  EOS
1108
1145
 
1109
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1146
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1110
1147
  expected = %(class Dog
1111
1148
 
1112
1149
  def bark
@@ -1127,7 +1164,7 @@ include::fixtures/tagged-class.rb[tags=!*]
1127
1164
  ----
1128
1165
  EOS
1129
1166
 
1130
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1167
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1131
1168
  expected = %(class Dog
1132
1169
  end)
1133
1170
  assert_includes output, expected
@@ -1141,7 +1178,7 @@ include::fixtures/tagged-class.rb[tags=bark;!bark-other]
1141
1178
  ----
1142
1179
  EOS
1143
1180
 
1144
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1181
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1145
1182
  expected = %(def bark
1146
1183
  if @breed == 'beagle'
1147
1184
  'woof woof woof woof woof'
@@ -1156,7 +1193,7 @@ include::fixtures/include-file.asciidoc[tag=no-such-tag]
1156
1193
  EOS
1157
1194
 
1158
1195
  using_memory_logger do |logger|
1159
- render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1196
+ convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1160
1197
  assert_message logger, :WARN, %(~<stdin>: line 1: tag 'no-such-tag' not found in include file), Hash
1161
1198
  end
1162
1199
  end
@@ -1169,7 +1206,7 @@ include::fixtures/include-file.asciidoc[tags=no-such-tag-b;no-such-tag-a]
1169
1206
  EOS
1170
1207
 
1171
1208
  using_memory_logger do |logger|
1172
- render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1209
+ convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1173
1210
  # NOTE Ruby 1.8 swaps the order of the list for some silly reason
1174
1211
  expected_tags = ::RUBY_MIN_VERSION_1_9 ? 'no-such-tag-b, no-such-tag-a' : 'no-such-tag-a, no-such-tag-b'
1175
1212
  assert_message logger, :WARN, %(~<stdin>: line 2: tags '#{expected_tags}' not found in include file), Hash
@@ -1184,7 +1221,7 @@ include::fixtures/unclosed-tag.adoc[tag=a]
1184
1221
  EOS
1185
1222
 
1186
1223
  using_memory_logger do |logger|
1187
- result = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1224
+ result = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1188
1225
  assert_equal 'a', result
1189
1226
  assert_message logger, :WARN, %(~<stdin>: line 2: detected unclosed tag 'a' starting at line 2 of include file), Hash
1190
1227
  refute_nil logger.messages[0][:message][:include_location]
@@ -1200,7 +1237,7 @@ include::fixtures/mismatched-end-tag.adoc[tags=a;b]
1200
1237
 
1201
1238
  inc_path = File.join DIRNAME, 'fixtures/mismatched-end-tag.adoc'
1202
1239
  using_memory_logger do |logger|
1203
- result = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1240
+ result = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1204
1241
  assert_equal %(a\nb), result
1205
1242
  assert_message logger, :WARN, %(<stdin>: line 2: mismatched end tag (expected 'b' but found 'a') at line 5 of include file: #{inc_path}), Hash
1206
1243
  refute_nil logger.messages[0][:message][:include_location]
@@ -1216,7 +1253,7 @@ include::fixtures/unexpected-end-tag.adoc[tags=a]
1216
1253
 
1217
1254
  inc_path = File.join DIRNAME, 'fixtures/unexpected-end-tag.adoc'
1218
1255
  using_memory_logger do |logger|
1219
- result = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1256
+ result = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1220
1257
  assert_equal 'a', result
1221
1258
  assert_message logger, :WARN, %(<stdin>: line 2: unexpected end tag 'a' at line 4 of include file: #{inc_path}), Hash
1222
1259
  refute_nil logger.messages[0][:message][:include_location]
@@ -1231,7 +1268,7 @@ include::fixtures/include-file.xml[#{attr_name}=]
1231
1268
  ++++
1232
1269
  EOS
1233
1270
 
1234
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1271
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1235
1272
  assert_match(/(?:tag|end)::/, output, 2)
1236
1273
  end
1237
1274
  end
@@ -1241,7 +1278,7 @@ include::fixtures/include-file.xml[#{attr_name}=]
1241
1278
  include::fixtures/include-file.asciidoc[lines=1, tags=snippetA;snippetB]
1242
1279
  EOS
1243
1280
 
1244
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1281
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1245
1282
  assert_match(/first line of included content/, output)
1246
1283
  refute_match(/snippetA content/, output)
1247
1284
  refute_match(/snippetB content/, output)
@@ -1255,11 +1292,24 @@ include::fixtures/basic-docinfo.xml[lines=2..3, indent=0]
1255
1292
  ----
1256
1293
  EOS
1257
1294
 
1258
- output = render_embedded_string input, :safe => :safe, :base_dir => DIRNAME
1295
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1259
1296
  result = xmlnodes_at_xpath('//pre', output, 1).text
1260
1297
  assert_equal "<year>2013</year>\n<holder>Acme™, Inc.</holder>", result
1261
1298
  end
1262
1299
 
1300
+ test 'should substitute attribute references in attrlist' do
1301
+ input = <<-EOS
1302
+ :name-of-tag: snippetA
1303
+ include::fixtures/include-file.asciidoc[tag={name-of-tag}]
1304
+ EOS
1305
+
1306
+ output = convert_string_to_embedded input, :safe => :safe, :base_dir => DIRNAME
1307
+ assert_match(/snippetA content/, output)
1308
+ refute_match(/snippetB content/, output)
1309
+ refute_match(/non-tagged content/, output)
1310
+ refute_match(/included content/, output)
1311
+ end
1312
+
1263
1313
  test 'should fall back to built-in include directive behavior when not handled by include processor' do
1264
1314
  input = <<-EOS
1265
1315
  include::fixtures/include-file.asciidoc[]