asciidoctor 1.5.8 → 2.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +162 -17
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +12 -13
  5. data/README-fr.adoc +11 -12
  6. data/README-jp.adoc +11 -12
  7. data/README-zh_CN.adoc +12 -13
  8. data/README.adoc +6 -7
  9. data/asciidoctor.gemspec +19 -24
  10. data/bin/asciidoctor +5 -4
  11. data/data/reference/syntax.adoc +283 -0
  12. data/data/stylesheets/asciidoctor-default.css +56 -52
  13. data/data/stylesheets/coderay-asciidoctor.css +7 -9
  14. data/lib/asciidoctor.rb +171 -232
  15. data/lib/asciidoctor/abstract_block.rb +96 -105
  16. data/lib/asciidoctor/abstract_node.rb +118 -139
  17. data/lib/asciidoctor/attribute_list.rb +10 -14
  18. data/lib/asciidoctor/block.rb +20 -19
  19. data/lib/asciidoctor/callouts.rb +4 -2
  20. data/lib/asciidoctor/cli.rb +3 -2
  21. data/lib/asciidoctor/cli/invoker.rb +14 -21
  22. data/lib/asciidoctor/cli/options.rb +64 -54
  23. data/lib/asciidoctor/converter.rb +357 -185
  24. data/lib/asciidoctor/converter/composite.rb +40 -48
  25. data/lib/asciidoctor/converter/docbook5.rb +604 -640
  26. data/lib/asciidoctor/converter/html5.rb +949 -963
  27. data/lib/asciidoctor/converter/manpage.rb +569 -548
  28. data/lib/asciidoctor/converter/template.rb +231 -272
  29. data/lib/asciidoctor/core_ext.rb +5 -18
  30. data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
  31. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  32. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  33. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  34. data/lib/asciidoctor/document.rb +399 -377
  35. data/lib/asciidoctor/extensions.rb +72 -140
  36. data/lib/asciidoctor/helpers.rb +122 -83
  37. data/lib/asciidoctor/inline.rb +5 -1
  38. data/lib/asciidoctor/list.rb +13 -11
  39. data/lib/asciidoctor/logging.rb +17 -16
  40. data/lib/asciidoctor/parser.rb +390 -423
  41. data/lib/asciidoctor/path_resolver.rb +10 -5
  42. data/lib/asciidoctor/reader.rb +286 -263
  43. data/lib/asciidoctor/rouge_ext.rb +39 -0
  44. data/lib/asciidoctor/section.rb +9 -8
  45. data/lib/asciidoctor/stylesheets.rb +19 -37
  46. data/lib/asciidoctor/substitutors.rb +364 -509
  47. data/lib/asciidoctor/syntax_highlighter.rb +238 -0
  48. data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
  49. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
  50. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  51. data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
  52. data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
  53. data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
  54. data/lib/asciidoctor/table.rb +73 -66
  55. data/lib/asciidoctor/timings.rb +4 -2
  56. data/lib/asciidoctor/version.rb +2 -1
  57. data/lib/asciidoctor/writer.rb +30 -0
  58. data/man/asciidoctor.1 +19 -15
  59. data/man/asciidoctor.adoc +14 -12
  60. metadata +69 -216
  61. data/CONTRIBUTING.adoc +0 -185
  62. data/Gemfile +0 -60
  63. data/Rakefile +0 -129
  64. data/bin/asciidoctor-safe +0 -15
  65. data/features/open_block.feature +0 -92
  66. data/features/pass_block.feature +0 -66
  67. data/features/step_definitions.rb +0 -49
  68. data/features/text_formatting.feature +0 -57
  69. data/features/xref.feature +0 -1039
  70. data/lib/asciidoctor/converter/base.rb +0 -59
  71. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  72. data/lib/asciidoctor/converter/factory.rb +0 -226
  73. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  74. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  75. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  76. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  77. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  78. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  79. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  80. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  81. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  82. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  83. data/test/api_test.rb +0 -1240
  84. data/test/attribute_list_test.rb +0 -242
  85. data/test/attributes_test.rb +0 -1623
  86. data/test/blocks_test.rb +0 -3870
  87. data/test/converter_test.rb +0 -470
  88. data/test/document_test.rb +0 -1853
  89. data/test/extensions_test.rb +0 -1560
  90. data/test/fixtures/asciidoc_index.txt +0 -521
  91. data/test/fixtures/basic-docinfo-footer.html +0 -6
  92. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  93. data/test/fixtures/basic-docinfo.html +0 -1
  94. data/test/fixtures/basic-docinfo.xml +0 -4
  95. data/test/fixtures/basic.asciidoc +0 -5
  96. data/test/fixtures/chapter-a.adoc +0 -3
  97. data/test/fixtures/child-include.adoc +0 -5
  98. data/test/fixtures/circle.svg +0 -9
  99. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  100. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  101. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  102. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  103. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  104. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  105. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  106. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  107. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  108. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  109. data/test/fixtures/docinfo-footer.html +0 -1
  110. data/test/fixtures/docinfo-footer.xml +0 -9
  111. data/test/fixtures/docinfo.html +0 -1
  112. data/test/fixtures/docinfo.xml +0 -3
  113. data/test/fixtures/doctime-localtime.adoc +0 -2
  114. data/test/fixtures/dot.gif +0 -0
  115. data/test/fixtures/encoding.asciidoc +0 -13
  116. data/test/fixtures/file-with-missing-include.adoc +0 -1
  117. data/test/fixtures/grandchild-include.adoc +0 -3
  118. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  119. data/test/fixtures/include-file.asciidoc +0 -24
  120. data/test/fixtures/include-file.jsx +0 -8
  121. data/test/fixtures/include-file.ml +0 -3
  122. data/test/fixtures/include-file.xml +0 -5
  123. data/test/fixtures/lists.adoc +0 -96
  124. data/test/fixtures/master.adoc +0 -5
  125. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  126. data/test/fixtures/other-chapters.adoc +0 -11
  127. data/test/fixtures/outer-include.adoc +0 -5
  128. data/test/fixtures/parent-include-restricted.adoc +0 -5
  129. data/test/fixtures/parent-include.adoc +0 -5
  130. data/test/fixtures/sample.asciidoc +0 -30
  131. data/test/fixtures/section-a.adoc +0 -4
  132. data/test/fixtures/stylesheets/custom.css +0 -3
  133. data/test/fixtures/subdir/index.adoc +0 -3
  134. data/test/fixtures/subdir/inner-include.adoc +0 -3
  135. data/test/fixtures/subdir/middle-include.adoc +0 -5
  136. data/test/fixtures/subs-docinfo.html +0 -2
  137. data/test/fixtures/subs.adoc +0 -6
  138. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  139. data/test/fixtures/tagged-class.rb +0 -23
  140. data/test/fixtures/tip.gif +0 -0
  141. data/test/fixtures/unclosed-tag.adoc +0 -3
  142. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  143. data/test/invoker_test.rb +0 -745
  144. data/test/links_test.rb +0 -855
  145. data/test/lists_test.rb +0 -5151
  146. data/test/logger_test.rb +0 -211
  147. data/test/manpage_test.rb +0 -660
  148. data/test/options_test.rb +0 -262
  149. data/test/paragraphs_test.rb +0 -562
  150. data/test/parser_test.rb +0 -742
  151. data/test/paths_test.rb +0 -395
  152. data/test/preamble_test.rb +0 -173
  153. data/test/reader_test.rb +0 -2161
  154. data/test/sections_test.rb +0 -3575
  155. data/test/substitutions_test.rb +0 -2066
  156. data/test/tables_test.rb +0 -2036
  157. data/test/test_helper.rb +0 -447
  158. data/test/text_test.rb +0 -309
@@ -1,6 +0,0 @@
1
- # Educate Ruby 1.8.7 about the Symbol#empty? method.
2
- class Symbol
3
- def empty?
4
- to_s.empty?
5
- end unless method_defined? :empty?
6
- end
@@ -1,6 +0,0 @@
1
- # Educate Ruby 1.8.7 about the Symbol#empty? and Symbol#length methods.
2
- class Symbol
3
- def length
4
- to_s.length
5
- end unless method_defined? :length
6
- end
@@ -1,10 +0,0 @@
1
- class String
2
- # Safely truncate the string to the specified number of bytes.
3
- # If a multibyte char gets split, the dangling fragment is removed.
4
- def limit_bytesize size
5
- return self unless size < bytesize
6
- # NOTE JRuby 1.7 & Rubinius fail to detect invalid encoding unless encoding is forced; impact is marginal.
7
- size -= 1 until ((result = byteslice 0, size).force_encoding ::Encoding::UTF_8).valid_encoding?
8
- result
9
- end unless method_defined? :limit_bytesize
10
- end
@@ -1,1240 +0,0 @@
1
- # encoding: UTF-8
2
- unless defined? ASCIIDOCTOR_PROJECT_DIR
3
- $: << File.dirname(__FILE__); $:.uniq!
4
- require 'test_helper'
5
- end
6
-
7
- context 'API' do
8
- context 'Load' do
9
- test 'should load input file' do
10
- sample_input_path = fixture_path('sample.asciidoc')
11
- doc = File.open(sample_input_path) {|file| Asciidoctor.load file, :safe => Asciidoctor::SafeMode::SAFE }
12
- assert_equal 'Document Title', doc.doctitle
13
- assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
14
- assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
15
- assert_equal '.asciidoc', doc.attr('docfilesuffix')
16
- end
17
-
18
- test 'should load input file from filename' do
19
- sample_input_path = fixture_path('sample.asciidoc')
20
- doc = Asciidoctor.load_file(sample_input_path, :safe => Asciidoctor::SafeMode::SAFE)
21
- assert_equal 'Document Title', doc.doctitle
22
- assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
23
- assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
24
- assert_equal '.asciidoc', doc.attr('docfilesuffix')
25
- end
26
-
27
- test 'should not load invalid file' do
28
- sample_input_path = fixture_path('hello-asciidoctor.pdf')
29
- exception = assert_raises ArgumentError do
30
- Asciidoctor.load_file(sample_input_path, :safe => Asciidoctor::SafeMode::SAFE)
31
- end
32
- assert_match(/Failed to load AsciiDoc document/, exception.message)
33
- # verify we have the correct backtrace (should be in at least first 5 lines)
34
- assert_match((RUBY_ENGINE == 'rbx' ? /parser\.rb/ : /helpers\.rb/), exception.backtrace[0..4].join("\n"))
35
- end if RUBY_MIN_VERSION_1_9
36
-
37
- test 'should load input IO' do
38
- input = StringIO.new(<<-EOS)
39
- Document Title
40
- ==============
41
-
42
- preamble
43
- EOS
44
- doc = Asciidoctor.load(input, :safe => Asciidoctor::SafeMode::SAFE)
45
- assert_equal 'Document Title', doc.doctitle
46
- refute doc.attr?('docfile')
47
- assert_equal doc.base_dir, doc.attr('docdir')
48
- end
49
-
50
- test 'should load input string' do
51
- input = <<-EOS
52
- Document Title
53
- ==============
54
-
55
- preamble
56
- EOS
57
- doc = Asciidoctor.load(input, :safe => Asciidoctor::SafeMode::SAFE)
58
- assert_equal 'Document Title', doc.doctitle
59
- refute doc.attr?('docfile')
60
- assert_equal doc.base_dir, doc.attr('docdir')
61
- end
62
-
63
- test 'should load input string array' do
64
- input = <<-EOS
65
- Document Title
66
- ==============
67
-
68
- preamble
69
- EOS
70
- doc = Asciidoctor.load(input.lines.entries, :safe => Asciidoctor::SafeMode::SAFE)
71
- assert_equal 'Document Title', doc.doctitle
72
- refute doc.attr?('docfile')
73
- assert_equal doc.base_dir, doc.attr('docdir')
74
- end
75
-
76
- test 'should accept attributes as array' do
77
- # NOTE there's a tab character before idseparator
78
- doc = Asciidoctor.load('text', :attributes => %w(toc sectnums source-highlighter=coderay idprefix idseparator=-))
79
- assert_kind_of Hash, doc.attributes
80
- assert doc.attr?('toc')
81
- assert_equal '', doc.attr('toc')
82
- assert doc.attr?('sectnums')
83
- assert_equal '', doc.attr('sectnums')
84
- assert doc.attr?('source-highlighter')
85
- assert_equal 'coderay', doc.attr('source-highlighter')
86
- assert doc.attr?('idprefix')
87
- assert_equal '', doc.attr('idprefix')
88
- assert doc.attr?('idseparator')
89
- assert_equal '-', doc.attr('idseparator')
90
- end
91
-
92
- test 'should accept attributes as empty array' do
93
- doc = Asciidoctor.load('text', :attributes => [])
94
- assert_kind_of Hash, doc.attributes
95
- end
96
-
97
- test 'should accept attributes as string' do
98
- doc = Asciidoctor.load('text', :attributes => 'toc sectnums
99
- source-highlighter=coderay
100
- idprefix
101
- idseparator=-')
102
- assert_kind_of Hash, doc.attributes
103
- assert doc.attr?('toc')
104
- assert_equal '', doc.attr('toc')
105
- assert doc.attr?('sectnums')
106
- assert_equal '', doc.attr('sectnums')
107
- assert doc.attr?('source-highlighter')
108
- assert_equal 'coderay', doc.attr('source-highlighter')
109
- assert doc.attr?('idprefix')
110
- assert_equal '', doc.attr('idprefix')
111
- assert doc.attr?('idseparator')
112
- assert_equal '-', doc.attr('idseparator')
113
- end
114
-
115
- test 'should accept values containing spaces in attributes string' do
116
- doc = Asciidoctor.load('text', :attributes => %(idprefix idseparator=- note-caption=Note\\ to\\\tself toc))
117
- assert_kind_of Hash, doc.attributes
118
- assert doc.attr?('idprefix')
119
- assert_equal '', doc.attr('idprefix')
120
- assert doc.attr?('idseparator')
121
- assert_equal '-', doc.attr('idseparator')
122
- assert doc.attr?('note-caption')
123
- assert_equal "Note to\tself", doc.attr('note-caption')
124
- end
125
-
126
- test 'should accept attributes as empty string' do
127
- doc = Asciidoctor.load('text', :attributes => '')
128
- assert_kind_of Hash, doc.attributes
129
- end
130
-
131
- test 'should accept attributes as nil' do
132
- doc = Asciidoctor.load('text', :attributes => nil)
133
- assert_kind_of Hash, doc.attributes
134
- end
135
-
136
- test 'should accept attributes if hash like' do
137
- class Hashish
138
- def initialize
139
- @table = {'toc' => ''}
140
- end
141
-
142
- def keys
143
- @table.keys
144
- end
145
-
146
- def [](key)
147
- @table[key]
148
- end
149
- end
150
-
151
- doc = Asciidoctor.load('text', :attributes => Hashish.new)
152
- assert_kind_of Hash, doc.attributes
153
- assert doc.attributes.has_key?('toc')
154
- end
155
-
156
- test 'should not expand value of docdir attribute if specified via API' do
157
- docdir = 'virtual/directory'
158
- doc = document_from_string '', :safe => :safe, :attributes => { 'docdir' => docdir }
159
- assert_equal docdir, (doc.attr 'docdir')
160
- assert_equal docdir, doc.base_dir
161
- end
162
-
163
- test 'converts block to output format when convert is called' do
164
- doc = Asciidoctor.load 'paragraph text'
165
- expected = <<-EOS
166
- <div class="paragraph">
167
- <p>paragraph text</p>
168
- </div>
169
- EOS
170
- assert_equal 1, doc.blocks.length
171
- assert_equal :paragraph, doc.blocks[0].context
172
- assert_equal expected.chomp, doc.blocks[0].convert
173
- end
174
-
175
- test 'render method on node is aliased to convert method' do
176
- input = <<-EOS
177
- paragraph text
178
-
179
- * list item
180
- EOS
181
- doc = Asciidoctor.load input
182
- assert_equal 2, doc.blocks.length
183
- ([doc] + doc.blocks).each do |block|
184
- assert_equal block.method(:convert), block.method(:render)
185
- end
186
- inline = Asciidoctor::Inline.new doc.blocks[0], :image, nil, :type => 'image', :target => 'tiger.png'
187
- assert_equal inline.method(:convert), inline.method(:render)
188
- end
189
-
190
- test 'should output timestamps by default' do
191
- doc = document_from_string 'text', :backend => :html5, :attributes => nil
192
- result = doc.convert
193
- assert doc.attr?('docdate')
194
- refute doc.attr? 'reproducible'
195
- assert_xpath '//div[@id="footer-text" and contains(string(.//text()), "Last updated")]', result, 1
196
- end
197
-
198
- test 'should not output timestamps if reproducible attribute is set in HTML 5' do
199
- doc = document_from_string 'text', :backend => :html5, :attributes => { 'reproducible' => '' }
200
- result = doc.convert
201
- assert doc.attr?('docdate')
202
- assert doc.attr?('reproducible')
203
- assert_xpath '//div[@id="footer-text" and contains(string(.//text()), "Last updated")]', result, 0
204
- end
205
-
206
- test 'should not output timestamps if reproducible attribute is set in DocBook' do
207
- doc = document_from_string 'text', :backend => :docbook, :attributes => { 'reproducible' => '' }
208
- result = doc.convert
209
- assert doc.attr?('docdate')
210
- assert doc.attr?('reproducible')
211
- assert_xpath '/article/info/date', result, 0
212
- end
213
-
214
- test 'should not modify options argument' do
215
- options = {
216
- :safe => Asciidoctor::SafeMode::SAFE
217
- }
218
- options.freeze
219
- sample_input_path = fixture_path('sample.asciidoc')
220
- begin
221
- Asciidoctor.load_file sample_input_path, options
222
- rescue
223
- flunk %(options argument should not be modified)
224
- end
225
- end
226
-
227
- test 'should not modify attributes Hash argument' do
228
- attributes = {}
229
- attributes.freeze
230
- options = {
231
- :safe => Asciidoctor::SafeMode::SAFE,
232
- :attributes => attributes
233
- }
234
- sample_input_path = fixture_path('sample.asciidoc')
235
- begin
236
- Asciidoctor.load_file sample_input_path, options
237
- rescue
238
- flunk %(attributes argument should not be modified)
239
- end
240
- end
241
-
242
- test 'should be able to restore header attributes after call to convert' do
243
- input = <<-EOS
244
- = Document Title
245
- :foo: bar
246
-
247
- content
248
-
249
- :foo: baz
250
-
251
- content
252
- EOS
253
- doc = Asciidoctor.load input
254
- assert_equal 'bar', (doc.attr 'foo')
255
- doc.convert
256
- assert_equal 'baz', (doc.attr 'foo')
257
- doc.restore_attributes
258
- assert_equal 'bar', (doc.attr 'foo')
259
- end
260
-
261
- test 'should track file and line information with blocks if sourcemap option is set' do
262
- doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :sourcemap => true
263
-
264
- refute_nil doc.source_location
265
- assert_equal 'sample.asciidoc', doc.file
266
- assert_equal 1, doc.lineno
267
-
268
- section_1 = doc.sections[0]
269
- assert_equal 'Section A', section_1.title
270
- refute_nil section_1.source_location
271
- assert_equal 'sample.asciidoc', section_1.file
272
- assert_equal 10, section_1.lineno
273
-
274
- section_2 = doc.sections[1]
275
- assert_equal 'Section B', section_2.title
276
- refute_nil section_2.source_location
277
- assert_equal 'sample.asciidoc', section_2.file
278
- assert_equal 18, section_2.lineno
279
-
280
- table_block = section_2.blocks[1]
281
- assert_equal :table, table_block.context
282
- refute_nil table_block.source_location
283
- assert_equal 'sample.asciidoc', table_block.file
284
- assert_equal 22, table_block.lineno
285
- first_cell = table_block.rows.body[0][0]
286
- refute_nil first_cell.source_location
287
- assert_equal 'sample.asciidoc', first_cell.file
288
- assert_equal 23, first_cell.lineno
289
- second_cell = table_block.rows.body[0][1]
290
- refute_nil second_cell.source_location
291
- assert_equal 'sample.asciidoc', second_cell.file
292
- assert_equal 23, second_cell.lineno
293
- last_cell = table_block.rows.body[-1][-1]
294
- refute_nil last_cell.source_location
295
- assert_equal 'sample.asciidoc', last_cell.file
296
- assert_equal 24, last_cell.lineno
297
-
298
- last_block = section_2.blocks[-1]
299
- assert_equal :ulist, last_block.context
300
- refute_nil last_block.source_location
301
- assert_equal 'sample.asciidoc', last_block.file
302
- assert_equal 28, last_block.lineno
303
-
304
- list_items = last_block.blocks
305
- refute_nil list_items[0].source_location
306
- assert_equal 'sample.asciidoc', list_items[0].file
307
- assert_equal 28, list_items[0].lineno
308
-
309
- refute_nil list_items[1].source_location
310
- assert_equal 'sample.asciidoc', list_items[1].file
311
- assert_equal 29, list_items[1].lineno
312
-
313
- refute_nil list_items[2].source_location
314
- assert_equal 'sample.asciidoc', list_items[2].file
315
- assert_equal 30, list_items[2].lineno
316
-
317
- doc = Asciidoctor.load_file fixture_path('master.adoc'), :sourcemap => true, :safe => :safe
318
-
319
- section_1 = doc.sections[0]
320
- assert_equal 'Chapter A', section_1.title
321
- refute_nil section_1.source_location
322
- assert_equal fixture_path('chapter-a.adoc'), section_1.file
323
- assert_equal 1, section_1.lineno
324
- end
325
-
326
- test 'should track file and line information on list items if sourcemap option is set' do
327
- doc = Asciidoctor.load_file fixture_path('lists.adoc'), :sourcemap => true
328
-
329
- first_section = doc.blocks[1]
330
-
331
- unordered_basic_list = first_section.blocks[0]
332
- assert_equal 11, unordered_basic_list.lineno
333
-
334
- unordered_basic_list_items = unordered_basic_list.find_by :context => :list_item
335
- assert_equal 11, unordered_basic_list_items[0].lineno
336
- assert_equal 12, unordered_basic_list_items[1].lineno
337
- assert_equal 13, unordered_basic_list_items[2].lineno
338
-
339
- unordered_max_nesting = first_section.blocks[1]
340
- assert_equal 16, unordered_max_nesting.lineno
341
- unordered_max_nesting_items = unordered_max_nesting.find_by :context => :list_item
342
- assert_equal 16, unordered_max_nesting_items[0].lineno
343
- assert_equal 17, unordered_max_nesting_items[1].lineno
344
- assert_equal 18, unordered_max_nesting_items[2].lineno
345
- assert_equal 19, unordered_max_nesting_items[3].lineno
346
- assert_equal 20, unordered_max_nesting_items[4].lineno
347
- assert_equal 21, unordered_max_nesting_items[5].lineno
348
-
349
- checklist = first_section.blocks[2]
350
- assert_equal 24, checklist.lineno
351
- checklist_list_items = checklist.find_by :context => :list_item
352
- assert_equal 24, checklist_list_items[0].lineno
353
- assert_equal 25, checklist_list_items[1].lineno
354
- assert_equal 26, checklist_list_items[2].lineno
355
- assert_equal 27, checklist_list_items[3].lineno
356
-
357
- ordered_basic = first_section.blocks[3]
358
- assert_equal 30, ordered_basic.lineno
359
- ordered_basic_list_items = ordered_basic.find_by :context => :list_item
360
- assert_equal 30, ordered_basic_list_items[0].lineno
361
- assert_equal 31, ordered_basic_list_items[1].lineno
362
- assert_equal 32, ordered_basic_list_items[2].lineno
363
-
364
- ordered_nested = first_section.blocks[4]
365
- assert_equal 35, ordered_nested.lineno
366
- ordered_nested_list_items = ordered_nested.find_by :context => :list_item
367
- assert_equal 35, ordered_nested_list_items[0].lineno
368
- assert_equal 36, ordered_nested_list_items[1].lineno
369
- assert_equal 37, ordered_nested_list_items[2].lineno
370
- assert_equal 38, ordered_nested_list_items[3].lineno
371
- assert_equal 39, ordered_nested_list_items[4].lineno
372
-
373
- ordered_max_nesting = first_section.blocks[5]
374
- assert_equal 42, ordered_max_nesting.lineno
375
- ordered_max_nesting_items = ordered_max_nesting.find_by :context => :list_item
376
- assert_equal 42, ordered_max_nesting_items[0].lineno
377
- assert_equal 43, ordered_max_nesting_items[1].lineno
378
- assert_equal 44, ordered_max_nesting_items[2].lineno
379
- assert_equal 45, ordered_max_nesting_items[3].lineno
380
- assert_equal 46, ordered_max_nesting_items[4].lineno
381
- assert_equal 47, ordered_max_nesting_items[5].lineno
382
-
383
- labeled_singleline = first_section.blocks[6]
384
- assert_equal 50, labeled_singleline.lineno
385
- labeled_singleline_items = labeled_singleline.find_by :context => :list_item
386
- assert_equal 50, labeled_singleline_items[0].lineno
387
- assert_equal 50, labeled_singleline_items[1].lineno
388
- assert_equal 51, labeled_singleline_items[2].lineno
389
- assert_equal 51, labeled_singleline_items[3].lineno
390
-
391
- labeled_multiline = first_section.blocks[7]
392
- assert_equal 54, labeled_multiline.lineno
393
- labeled_multiline_items = labeled_multiline.find_by :context => :list_item
394
- assert_equal 54, labeled_multiline_items[0].lineno
395
- assert_equal 55, labeled_multiline_items[1].lineno
396
- assert_equal 56, labeled_multiline_items[2].lineno
397
- assert_equal 57, labeled_multiline_items[3].lineno
398
-
399
- qanda = first_section.blocks[8]
400
- assert_equal 61, qanda.lineno
401
- qanda_items = qanda.find_by :context => :list_item
402
- assert_equal 61, qanda_items[0].lineno
403
- assert_equal 62, qanda_items[1].lineno
404
- assert_equal 63, qanda_items[2].lineno
405
- assert_equal 63, qanda_items[3].lineno
406
-
407
- mixed = first_section.blocks[9]
408
- assert_equal 66, mixed.lineno
409
- mixed_items = mixed.find_by(:context => :list_item) {|block| block.text? }
410
- assert_equal 66, mixed_items[0].lineno
411
- assert_equal 67, mixed_items[1].lineno
412
- assert_equal 68, mixed_items[2].lineno
413
- assert_equal 69, mixed_items[3].lineno
414
- assert_equal 70, mixed_items[4].lineno
415
- assert_equal 71, mixed_items[5].lineno
416
- assert_equal 72, mixed_items[6].lineno
417
- assert_equal 73, mixed_items[7].lineno
418
- assert_equal 74, mixed_items[8].lineno
419
- assert_equal 75, mixed_items[9].lineno
420
- assert_equal 77, mixed_items[10].lineno
421
- assert_equal 78, mixed_items[11].lineno
422
- assert_equal 79, mixed_items[12].lineno
423
- assert_equal 80, mixed_items[13].lineno
424
- assert_equal 81, mixed_items[14].lineno
425
- assert_equal 82, mixed_items[15].lineno
426
- assert_equal 83, mixed_items[16].lineno
427
-
428
- unordered_complex_list = first_section.blocks[10]
429
- assert_equal 86, unordered_complex_list.lineno
430
- unordered_complex_items = unordered_complex_list.find_by :context => :list_item
431
- assert_equal 86, unordered_complex_items[0].lineno
432
- assert_equal 87, unordered_complex_items[1].lineno
433
- assert_equal 88, unordered_complex_items[2].lineno
434
- assert_equal 92, unordered_complex_items[3].lineno
435
- assert_equal 96, unordered_complex_items[4].lineno
436
- end
437
-
438
- test 'should assign correct source location if section occurs on last line of input' do
439
- input = <<-EOS
440
- = Document Title
441
-
442
- == Section A
443
-
444
- content
445
-
446
- == Section B
447
- EOS
448
-
449
- doc = document_from_string input, :sourcemap => true
450
- assert_equal [1, 3, 7], (doc.find_by :context => :section).map(&:lineno)
451
- end
452
-
453
- test 'should allow sourcemap option on document to be modified' do
454
- doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :parse => false
455
- doc.sourcemap = true
456
- doc = doc.parse
457
-
458
- section_1 = doc.sections[0]
459
- assert_equal 'Section A', section_1.title
460
- refute_nil section_1.source_location
461
- assert_equal 'sample.asciidoc', section_1.file
462
- assert_equal 10, section_1.lineno
463
- end
464
-
465
- test 'find_by should return Array of blocks anywhere in document tree that match criteria' do
466
- input = <<-EOS
467
- = Document Title
468
-
469
- preamble
470
-
471
- == Section A
472
-
473
- paragraph
474
-
475
- --
476
- Exhibit A::
477
- +
478
- [#tiger.animal]
479
- image::tiger.png[Tiger]
480
- --
481
-
482
- image::shoe.png[Shoe]
483
-
484
- == Section B
485
-
486
- paragraph
487
- EOS
488
-
489
- doc = Asciidoctor.load input
490
- result = doc.find_by :context => :image
491
- assert_equal 2, result.size
492
- assert_equal :image, result[0].context
493
- assert_equal 'tiger.png', result[0].attr('target')
494
- assert_equal :image, result[1].context
495
- assert_equal 'shoe.png', result[1].attr('target')
496
- end
497
-
498
- test 'find_by should return an empty Array if no matches are found' do
499
- input = <<-EOS
500
- paragraph
501
- EOS
502
- doc = Asciidoctor.load input
503
- result = doc.find_by :context => :section
504
- refute_nil result
505
- assert_equal 0, result.size
506
- end
507
-
508
- test 'find_by should return Array of blocks that match style criteria' do
509
- input = <<-EOS
510
- [square]
511
- * one
512
- * two
513
- * three
514
-
515
- ---
516
-
517
- * apples
518
- * bananas
519
- * pears
520
- EOS
521
-
522
- doc = Asciidoctor.load input
523
- result = doc.find_by :context => :ulist, :style => 'square'
524
- assert_equal 1, result.size
525
- assert_equal :ulist, result[0].context
526
- end
527
-
528
- test 'find_by should return Array of blocks that match role criteria' do
529
- input = <<-EOS
530
- [#tiger.animal]
531
- image::tiger.png[Tiger]
532
-
533
- image::shoe.png[Shoe]
534
- EOS
535
-
536
- doc = Asciidoctor.load input
537
- result = doc.find_by :context => :image, :role => 'animal'
538
- assert_equal 1, result.size
539
- assert_equal :image, result[0].context
540
- assert_equal 'tiger.png', result[0].attr('target')
541
- end
542
-
543
- test 'find_by should return the document title section if context selector is :section' do
544
- input = <<-EOS
545
- = Document Title
546
-
547
- preamble
548
-
549
- == Section One
550
-
551
- content
552
- EOS
553
- doc = Asciidoctor.load input
554
- result = doc.find_by :context => :section
555
- refute_nil result
556
- assert_equal 2, result.size
557
- assert_equal :section, result[0].context
558
- assert_equal 'Document Title', result[0].title
559
- end
560
-
561
- test 'find_by should only return results for which the block argument yields true' do
562
- input = <<-EOS
563
- == Section
564
-
565
- content
566
-
567
- === Subsection
568
-
569
- content
570
- EOS
571
- doc = Asciidoctor.load input
572
- result = doc.find_by(:context => :section) {|sect| sect.level == 1 }
573
- refute_nil result
574
- assert_equal 1, result.size
575
- assert_equal :section, result[0].context
576
- assert_equal 'Section', result[0].title
577
- end
578
-
579
- test 'find_by should skip node and its children if block returns :skip' do
580
- input = <<-EOS
581
- paragraph 1
582
-
583
- ====
584
- paragraph 2
585
-
586
- term::
587
- +
588
- paragraph 3
589
- ====
590
-
591
- paragraph 4
592
- EOS
593
- doc = Asciidoctor.load input
594
- result = doc.find_by do |candidate|
595
- ctx = candidate.context
596
- if ctx == :example
597
- :skip
598
- elsif ctx == :paragraph
599
- true
600
- end
601
- end
602
- refute_nil result
603
- assert_equal 2, result.size
604
- assert_equal :paragraph, result[0].context
605
- assert_equal :paragraph, result[1].context
606
- end
607
-
608
- test 'find_by should accept node but skip its children if block returns :skip_children' do
609
- input = <<-EOS
610
- ====
611
- paragraph 2
612
-
613
- term::
614
- +
615
- paragraph 3
616
- ====
617
- EOS
618
- doc = Asciidoctor.load input
619
- result = doc.find_by do |candidate|
620
- if candidate.context == :example
621
- :skip_children
622
- end
623
- end
624
- refute_nil result
625
- assert_equal 1, result.size
626
- assert_equal :example, result[0].context
627
- end
628
-
629
- test 'find_by should stop looking for blocks when StopIteration is raised' do
630
- input = <<-EOS
631
- paragraph 1
632
-
633
- ====
634
- paragraph 2
635
-
636
- ****
637
- paragraph 3
638
- ****
639
- ====
640
-
641
- paragraph 4
642
-
643
- * item
644
- +
645
- paragraph 5
646
- EOS
647
- doc = Asciidoctor.load input
648
-
649
- stop_at_next = false
650
- result = doc.find_by do |candidate|
651
- raise StopIteration if stop_at_next
652
- if candidate.context == :paragraph
653
- candidate.parent.context == :sidebar ? (stop_at_next = true) : true
654
- end
655
- end
656
- refute_nil result
657
- assert_equal 3, result.size
658
- assert_equal 'paragraph 1', result[0].content
659
- assert_equal 'paragraph 2', result[1].content
660
- assert_equal 'paragraph 3', result[2].content
661
- end
662
-
663
- test 'find_by should only return one result when matching by id' do
664
- input = <<-EOS
665
- == Section
666
-
667
- content
668
-
669
- [#subsection]
670
- === Subsection
671
-
672
- content
673
- EOS
674
- doc = Asciidoctor.load input
675
- result = doc.find_by(:context => :section, :id => 'subsection')
676
- refute_nil result
677
- assert_equal 1, result.size
678
- assert_equal :section, result[0].context
679
- assert_equal 'Subsection', result[0].title
680
- end
681
-
682
- test 'find_by should stop seeking once match is found' do
683
- input = <<-EOS
684
- == Section
685
-
686
- content
687
-
688
- [#subsection]
689
- === Subsection
690
-
691
- [#last]
692
- content
693
- EOS
694
- doc = Asciidoctor.load input
695
- visited_last = false
696
- result = doc.find_by(:id => 'subsection') do |candidate|
697
- visited_last = true if candidate.id == 'last'
698
- true
699
- end
700
- refute_nil result
701
- assert_equal 1, result.size
702
- refute visited_last
703
- end
704
-
705
- test 'find_by should return an empty Array if the id criteria matches but the block argument yields false' do
706
- input = <<-EOS
707
- == Section
708
-
709
- content
710
-
711
- [#subsection]
712
- === Subsection
713
-
714
- content
715
- EOS
716
- doc = Asciidoctor.load input
717
- result = doc.find_by(:context => :section, :id => 'subsection') {|sect| false }
718
- refute_nil result
719
- assert_equal 0, result.size
720
- end
721
-
722
- test 'find_by should not crash if dlist entry does not have description' do
723
- input = <<-EOS
724
- term without description::
725
- EOS
726
- doc = Asciidoctor.load input
727
- result = doc.find_by
728
- refute_nil result
729
- assert_equal 3, result.size
730
- assert_kind_of Asciidoctor::Document, result[0]
731
- assert_kind_of Asciidoctor::List, result[1]
732
- assert_kind_of Asciidoctor::ListItem, result[2]
733
- end
734
-
735
- test 'timings are recorded for each step when load and convert are called separately' do
736
- sample_input_path = fixture_path 'asciidoc_index.txt'
737
- (Asciidoctor.load_file sample_input_path, :timings => (timings = Asciidoctor::Timings.new)).convert
738
- refute_equal '0.00000', '%05.5f' % timings.read_parse.to_f
739
- refute_equal '0.00000', '%05.5f' % timings.convert.to_f
740
- refute_equal timings.read_parse, timings.total
741
- end
742
- end
743
-
744
- context 'Convert' do
745
- test 'render_file is aliased to convert_file' do
746
- assert_equal Asciidoctor.method(:convert_file), Asciidoctor.method(:render_file)
747
- end
748
-
749
- test 'render is aliased to convert' do
750
- assert_equal Asciidoctor.method(:convert), Asciidoctor.method(:render)
751
- end
752
-
753
- test 'should convert source document to string when to_file is false' do
754
- sample_input_path = fixture_path('sample.asciidoc')
755
-
756
- output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
757
- refute_empty output
758
- assert_xpath '/html', output, 1
759
- assert_xpath '/html/head', output, 1
760
- assert_xpath '/html/body', output, 1
761
- assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
762
- assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
763
- end
764
-
765
- test 'lines in output should be separated by line feed' do
766
- sample_input_path = fixture_path('sample.asciidoc')
767
-
768
- output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
769
- refute_empty output
770
- lines = output.split("\n")
771
- assert_equal lines.size, output.split(/\r\n|\r|\n/).size
772
- raw_lengths = lines.map(&:length)
773
- trimmed_lengths = lines.map {|line| line.rstrip.length }
774
- assert_equal raw_lengths, trimmed_lengths
775
- end
776
-
777
- test 'should accept attributes as array' do
778
- sample_input_path = fixture_path('sample.asciidoc')
779
- output = Asciidoctor.convert_file sample_input_path, :attributes => %w(sectnums idprefix idseparator=-), :to_file => false
780
- assert_css '#section-a', output, 1
781
- end
782
-
783
- test 'should accept attributes as string' do
784
- sample_input_path = fixture_path('sample.asciidoc')
785
- output = Asciidoctor.convert_file sample_input_path, :attributes => 'sectnums idprefix idseparator=-', :to_file => false
786
- assert_css '#section-a', output, 1
787
- end
788
-
789
- test 'should link to default stylesheet by default when safe mode is SECURE or greater' do
790
- sample_input_path = fixture_path('basic.asciidoc')
791
- output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
792
- assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
793
- assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
794
- end
795
-
796
- test 'should embed default stylesheet by default if SafeMode is less than SECURE' do
797
- input = <<-EOS
798
- = Document Title
799
-
800
- text
801
- EOS
802
-
803
- output = Asciidoctor.convert input, :safe => Asciidoctor::SafeMode::SERVER, :header_footer => true
804
- assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
805
- assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
806
- stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
807
- styles = stylenode.content
808
- refute_nil styles
809
- refute_empty styles.strip
810
- end
811
-
812
- test 'should not allow linkcss be unset from document if SafeMode is SECURE or greater' do
813
- input = <<-EOS
814
- = Document Title
815
- :linkcss!:
816
-
817
- text
818
- EOS
819
-
820
- output = Asciidoctor.convert input, :header_footer => true
821
- assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
822
- assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
823
- end
824
-
825
- test 'should embed default stylesheet if linkcss is unset from API and SafeMode is SECURE or greater' do
826
- input = <<-EOS
827
- = Document Title
828
-
829
- text
830
- EOS
831
-
832
- #[{ 'linkcss!' => '' }, { 'linkcss' => nil }, { 'linkcss' => false }].each do |attrs|
833
- [{ 'linkcss!' => '' }, { 'linkcss' => nil }].each do |attrs|
834
- output = Asciidoctor.convert input, :header_footer => true, :attributes => attrs
835
- assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
836
- assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
837
- stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
838
- styles = stylenode.content
839
- refute_nil styles
840
- refute_empty styles.strip
841
- end
842
- end
843
-
844
- test 'should embed default stylesheet if safe mode is less than SECURE and linkcss is unset from API' do
845
- sample_input_path = fixture_path('basic.asciidoc')
846
- output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false,
847
- :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss!' => ''}
848
- assert_css 'html:root > head > style', output, 1
849
- stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
850
- styles = stylenode.content
851
- refute_nil styles
852
- refute_empty styles.strip
853
- end
854
-
855
- test 'should not link to stylesheet if stylesheet is unset' do
856
- input = <<-EOS
857
- = Document Title
858
-
859
- text
860
- EOS
861
-
862
- output = Asciidoctor.convert input, :header_footer => true, :attributes => {'stylesheet!' => ''}
863
- assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 0
864
- assert_css 'html:root > head > link[rel="stylesheet"]', output, 0
865
- end
866
-
867
- test 'should link to custom stylesheet if specified in stylesheet attribute' do
868
- input = <<-EOS
869
- = Document Title
870
-
871
- text
872
- EOS
873
-
874
- output = Asciidoctor.convert input, :header_footer => true, :attributes => {'stylesheet' => './custom.css'}
875
- assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 0
876
- assert_css 'html:root > head > link[rel="stylesheet"][href="./custom.css"]', output, 1
877
-
878
- output = Asciidoctor.convert input, :header_footer => true, :attributes => {'stylesheet' => 'file:///home/username/custom.css'}
879
- assert_css 'html:root > head > link[rel="stylesheet"][href="file:///home/username/custom.css"]', output, 1
880
- end
881
-
882
- test 'should resolve custom stylesheet relative to stylesdir' do
883
- input = <<-EOS
884
- = Document Title
885
-
886
- text
887
- EOS
888
-
889
- output = Asciidoctor.convert input, :header_footer => true, :attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets'}
890
- assert_css 'html:root > head > link[rel="stylesheet"][href="./stylesheets/custom.css"]', output, 1
891
- end
892
-
893
- test 'should resolve custom stylesheet to embed relative to stylesdir' do
894
- sample_input_path = fixture_path('basic.asciidoc')
895
- output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :safe => Asciidoctor::SafeMode::SAFE, :to_file => false,
896
- :attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets', 'linkcss!' => ''}
897
- stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
898
- styles = stylenode.content
899
- refute_nil styles
900
- refute_empty styles.strip
901
- end
902
-
903
- test 'should convert source file and write result to adjacent file by default' do
904
- sample_input_path = fixture_path('sample.asciidoc')
905
- sample_output_path = fixture_path('sample.html')
906
- begin
907
- Asciidoctor.convert_file sample_input_path
908
- assert File.exist?(sample_output_path)
909
- output = IO.read(sample_output_path)
910
- refute_empty output
911
- assert_xpath '/html', output, 1
912
- assert_xpath '/html/head', output, 1
913
- assert_xpath '/html/body', output, 1
914
- assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
915
- assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
916
- ensure
917
- FileUtils.rm(sample_output_path)
918
- end
919
- end
920
-
921
- test 'should convert source file and write to specified file' do
922
- sample_input_path = fixture_path('sample.asciidoc')
923
- sample_output_path = fixture_path('result.html')
924
- begin
925
- Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path
926
- assert File.exist?(sample_output_path)
927
- output = IO.read(sample_output_path)
928
- refute_empty output
929
- assert_xpath '/html', output, 1
930
- assert_xpath '/html/head', output, 1
931
- assert_xpath '/html/body', output, 1
932
- assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
933
- assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
934
- ensure
935
- FileUtils.rm(sample_output_path)
936
- end
937
- end
938
-
939
- test 'should convert source file and write to specified file in base_dir' do
940
- sample_input_path = fixture_path('sample.asciidoc')
941
- sample_output_path = fixture_path('result.html')
942
- fixture_dir = fixture_path('')
943
- begin
944
- Asciidoctor.convert_file sample_input_path, :to_file => 'result.html', :base_dir => fixture_dir
945
- assert File.exist?(sample_output_path)
946
- output = IO.read(sample_output_path)
947
- refute_empty output
948
- assert_xpath '/html', output, 1
949
- assert_xpath '/html/head', output, 1
950
- assert_xpath '/html/body', output, 1
951
- assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
952
- assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
953
- rescue => e
954
- flunk e.message
955
- ensure
956
- FileUtils.rm(sample_output_path, :force => true)
957
- end
958
- end
959
-
960
- test 'in_place option is ignored when to_file is specified' do
961
- sample_input_path = fixture_path('sample.asciidoc')
962
- sample_output_path = fixture_path('result.html')
963
- begin
964
- Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path, :in_place => true
965
- assert File.exist?(sample_output_path)
966
- ensure
967
- FileUtils.rm(sample_output_path) if File.exist? sample_output_path
968
- end
969
- end
970
-
971
- test 'in_place option is ignored when to_dir is specified' do
972
- sample_input_path = fixture_path('sample.asciidoc')
973
- sample_output_path = fixture_path('sample.html')
974
- begin
975
- Asciidoctor.convert_file sample_input_path, :to_dir => File.dirname(sample_output_path), :in_place => true
976
- assert File.exist?(sample_output_path)
977
- ensure
978
- FileUtils.rm(sample_output_path) if File.exist? sample_output_path
979
- end
980
- end
981
-
982
- test 'should set outfilesuffix to match file extension of target file' do
983
- sample_input = '{outfilesuffix}'
984
- sample_output_path = fixture_path('result.htm')
985
- begin
986
- Asciidoctor.convert sample_input, :to_file => sample_output_path, :header_footer => false
987
- assert File.exist?(sample_output_path)
988
- output = IO.read(sample_output_path)
989
- refute_empty output
990
- assert_includes output, '<p>.htm</p>'
991
- ensure
992
- FileUtils.rm(sample_output_path)
993
- end
994
- end
995
-
996
- test 'output should be relative to to_dir option' do
997
- sample_input_path = fixture_path('sample.asciidoc')
998
- output_dir = File.join(File.dirname(sample_input_path), 'test_output')
999
- Dir.mkdir output_dir if !File.exist? output_dir
1000
- sample_output_path = File.join(output_dir, 'sample.html')
1001
- begin
1002
- Asciidoctor.convert_file sample_input_path, :to_dir => output_dir
1003
- assert File.exist? sample_output_path
1004
- ensure
1005
- FileUtils.rm(sample_output_path) if File.exist? sample_output_path
1006
- FileUtils.rmdir output_dir
1007
- end
1008
- end
1009
-
1010
- test 'missing directories should be created if mkdirs is enabled' do
1011
- sample_input_path = fixture_path('sample.asciidoc')
1012
- output_dir = File.join(File.join(File.dirname(sample_input_path), 'test_output'), 'subdir')
1013
- sample_output_path = File.join(output_dir, 'sample.html')
1014
- begin
1015
- Asciidoctor.convert_file sample_input_path, :to_dir => output_dir, :mkdirs => true
1016
- assert File.exist? sample_output_path
1017
- ensure
1018
- FileUtils.rm(sample_output_path) if File.exist? sample_output_path
1019
- FileUtils.rmdir output_dir
1020
- FileUtils.rmdir File.dirname(output_dir)
1021
- end
1022
- end
1023
-
1024
- # TODO need similar test for when to_dir is specified
1025
- test 'should raise exception if an attempt is made to overwrite input file' do
1026
- sample_input_path = fixture_path('sample.asciidoc')
1027
-
1028
- assert_raises IOError do
1029
- Asciidoctor.convert_file sample_input_path, :attributes => { 'outfilesuffix' => '.asciidoc' }
1030
- end
1031
- end
1032
-
1033
- test 'to_file should be relative to to_dir when both given' do
1034
- sample_input_path = fixture_path('sample.asciidoc')
1035
- base_dir = File.dirname(sample_input_path)
1036
- sample_rel_output_path = File.join('test_output', 'result.html')
1037
- output_dir = File.dirname(File.join(base_dir, sample_rel_output_path))
1038
- Dir.mkdir output_dir if !File.exist? output_dir
1039
- sample_output_path = File.join(base_dir, sample_rel_output_path)
1040
- begin
1041
- Asciidoctor.convert_file sample_input_path, :to_dir => base_dir, :to_file => sample_rel_output_path
1042
- assert File.exist? sample_output_path
1043
- ensure
1044
- FileUtils.rm(sample_output_path) if File.exist? sample_output_path
1045
- FileUtils.rmdir output_dir
1046
- end
1047
- end
1048
-
1049
- test 'should not modify options argument' do
1050
- options = {
1051
- :safe => Asciidoctor::SafeMode::SAFE,
1052
- :to_file => false
1053
- }
1054
- options.freeze
1055
- sample_input_path = fixture_path('sample.asciidoc')
1056
- begin
1057
- Asciidoctor.convert_file sample_input_path, options
1058
- rescue
1059
- flunk %(options argument should not be modified)
1060
- end
1061
- end
1062
-
1063
- test 'should set to_dir option to parent directory of specified output file' do
1064
- sample_input_path = fixture_path 'basic.asciidoc'
1065
- sample_output_path = fixture_path 'basic.html'
1066
- begin
1067
- doc = Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path
1068
- assert_equal File.dirname(sample_output_path), doc.options[:to_dir]
1069
- ensure
1070
- FileUtils.rm(sample_output_path)
1071
- end
1072
- end
1073
-
1074
- test 'should set to_dir option to parent directory of specified output directory and file' do
1075
- sample_input_path = fixture_path 'basic.asciidoc'
1076
- sample_output_path = fixture_path 'basic.html'
1077
- fixture_base_path = File.dirname sample_output_path
1078
- fixture_parent_path = File.dirname fixture_base_path
1079
- sample_output_relpath = File.join 'fixtures', 'basic.html'
1080
- begin
1081
- doc = Asciidoctor.convert_file sample_input_path, :to_dir => fixture_parent_path, :to_file => sample_output_relpath
1082
- assert_equal fixture_base_path, doc.options[:to_dir]
1083
- ensure
1084
- FileUtils.rm(sample_output_path)
1085
- end
1086
- end
1087
-
1088
- test 'timings are recorded for each step' do
1089
- sample_input_path = fixture_path 'asciidoc_index.txt'
1090
- Asciidoctor.convert_file sample_input_path, :timings => (timings = Asciidoctor::Timings.new), :to_file => false
1091
- refute_equal '0.00000', '%05.5f' % timings.read_parse.to_f
1092
- refute_equal '0.00000', '%05.5f' % timings.convert.to_f
1093
- refute_equal timings.read_parse, timings.total
1094
- end
1095
- end
1096
-
1097
- context 'AST' do
1098
- test 'with no author' do
1099
- input = <<-EOS
1100
- = Getting Real: The Smarter, Faster, Easier Way to Build a Successful Web Application
1101
-
1102
- Getting Real details the business, design, programming, and marketing principles of 37signals.
1103
- EOS
1104
-
1105
- doc = document_from_string input
1106
- assert_equal 0, doc.authors.size
1107
- end
1108
-
1109
- test 'with one author' do
1110
- input = <<-EOS
1111
- = Getting Real: The Smarter, Faster, Easier Way to Build a Successful Web Application
1112
- David Heinemeier Hansson <david@37signals.com>
1113
-
1114
- Getting Real details the business, design, programming, and marketing principles of 37signals.
1115
- EOS
1116
-
1117
- doc = document_from_string input
1118
- authors = doc.authors
1119
- assert_equal 1, authors.size
1120
- author_1 = authors[0]
1121
- assert_equal 'david@37signals.com', author_1.email
1122
- assert_equal 'David Heinemeier Hansson', author_1.name
1123
- assert_equal 'David', author_1.firstname
1124
- assert_equal 'Heinemeier', author_1.middlename
1125
- assert_equal 'Hansson', author_1.lastname
1126
- assert_equal 'DHH', author_1.initials
1127
- end
1128
-
1129
- test 'with two authors' do
1130
- input = <<-EOS
1131
- = Getting Real: The Smarter, Faster, Easier Way to Build a Successful Web Application
1132
- David Heinemeier Hansson <david@37signals.com>; Jason Fried <jason@37signals.com>
1133
-
1134
- Getting Real details the business, design, programming, and marketing principles of 37signals.
1135
- EOS
1136
-
1137
- doc = document_from_string input
1138
- authors = doc.authors
1139
- assert_equal 2, authors.size
1140
- author_1 = authors[0]
1141
- assert_equal 'david@37signals.com', author_1.email
1142
- assert_equal 'David Heinemeier Hansson', author_1.name
1143
- assert_equal 'David', author_1.firstname
1144
- assert_equal 'Heinemeier', author_1.middlename
1145
- assert_equal 'Hansson', author_1.lastname
1146
- assert_equal 'DHH', author_1.initials
1147
- author_2 = authors[1]
1148
- assert_equal 'jason@37signals.com', author_2.email
1149
- assert_equal 'Jason Fried', author_2.name
1150
- assert_equal 'Jason', author_2.firstname
1151
- assert_nil author_2.middlename
1152
- assert_equal 'Fried', author_2.lastname
1153
- assert_equal 'JF', author_2.initials
1154
- end
1155
-
1156
- test 'with authors as attributes' do
1157
- input = <<-EOS
1158
- = Getting Real: The Smarter, Faster, Easier Way to Build a Successful Web Application
1159
- :author_1: David Heinemeier Hansson
1160
- :email_1: david@37signals.com
1161
- :author_2: Jason Fried
1162
- :email_2: jason@37signals.com
1163
-
1164
- Getting Real details the business, design, programming, and marketing principles of 37signals.
1165
- EOS
1166
-
1167
- doc = document_from_string input
1168
- authors = doc.authors
1169
- assert_equal 2, authors.size
1170
- author_1 = authors[0]
1171
- assert_equal 'david@37signals.com', author_1.email
1172
- assert_equal 'David Heinemeier Hansson', author_1.name
1173
- assert_equal 'David', author_1.firstname
1174
- assert_equal 'Heinemeier', author_1.middlename
1175
- assert_equal 'Hansson', author_1.lastname
1176
- assert_equal 'DHH', author_1.initials
1177
- author_2 = authors[1]
1178
- assert_equal 'jason@37signals.com', author_2.email
1179
- assert_equal 'Jason Fried', author_2.name
1180
- assert_equal 'Jason', author_2.firstname
1181
- assert_nil author_2.middlename
1182
- assert_equal 'Fried', author_2.lastname
1183
- assert_equal 'JF', author_2.initials
1184
- end
1185
-
1186
- test 'should not crash if nil cell text is passed to Cell constructor' do
1187
- input = <<-EOS
1188
- |===
1189
- |a
1190
- |===
1191
- EOS
1192
- table = (document_from_string input).blocks[0]
1193
- cell = Asciidoctor::Table::Cell.new table.rows.body[0][0].column, nil, {}
1194
- refute cell.style
1195
- assert_same Asciidoctor::AbstractNode::NORMAL_SUBS, cell.subs
1196
- assert_equal '', cell.text
1197
- end
1198
-
1199
- test 'should set option on node when set_option is called' do
1200
- input = <<-EOS
1201
- . three
1202
- . two
1203
- . one
1204
- EOS
1205
-
1206
- block = (document_from_string input).blocks[0]
1207
- assert block.set_option('reversed')
1208
- refute block.set_option('reversed')
1209
- assert block.option?('reversed')
1210
- assert_equal '', block.attributes['reversed-option']
1211
- assert_equal 'reversed', block.attributes['options']
1212
- end
1213
-
1214
- test 'should append option to existing options' do
1215
- input = <<-EOS
1216
- [%fancy]
1217
- . three
1218
- . two
1219
- . one
1220
- EOS
1221
-
1222
- block = (document_from_string input).blocks[0]
1223
- assert block.set_option('reversed')
1224
- assert_equal 'fancy,reversed', block.attributes['options']
1225
- end
1226
-
1227
- test 'should not append option if option is already set' do
1228
- input = <<-EOS
1229
- [%reversed]
1230
- . three
1231
- . two
1232
- . one
1233
- EOS
1234
-
1235
- block = (document_from_string input).blocks[0]
1236
- refute block.set_option('reversed')
1237
- assert_equal 'reversed', block.attributes['options']
1238
- end
1239
- end
1240
- end