asciidoctor 1.5.8 → 2.0.0.rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +162 -17
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +12 -13
  5. data/README-fr.adoc +11 -12
  6. data/README-jp.adoc +11 -12
  7. data/README-zh_CN.adoc +12 -13
  8. data/README.adoc +6 -7
  9. data/asciidoctor.gemspec +19 -24
  10. data/bin/asciidoctor +5 -4
  11. data/data/reference/syntax.adoc +283 -0
  12. data/data/stylesheets/asciidoctor-default.css +56 -52
  13. data/data/stylesheets/coderay-asciidoctor.css +7 -9
  14. data/lib/asciidoctor.rb +171 -232
  15. data/lib/asciidoctor/abstract_block.rb +96 -105
  16. data/lib/asciidoctor/abstract_node.rb +118 -139
  17. data/lib/asciidoctor/attribute_list.rb +10 -14
  18. data/lib/asciidoctor/block.rb +20 -19
  19. data/lib/asciidoctor/callouts.rb +4 -2
  20. data/lib/asciidoctor/cli.rb +3 -2
  21. data/lib/asciidoctor/cli/invoker.rb +14 -21
  22. data/lib/asciidoctor/cli/options.rb +64 -54
  23. data/lib/asciidoctor/converter.rb +357 -185
  24. data/lib/asciidoctor/converter/composite.rb +40 -48
  25. data/lib/asciidoctor/converter/docbook5.rb +604 -640
  26. data/lib/asciidoctor/converter/html5.rb +949 -963
  27. data/lib/asciidoctor/converter/manpage.rb +569 -548
  28. data/lib/asciidoctor/converter/template.rb +231 -272
  29. data/lib/asciidoctor/core_ext.rb +5 -18
  30. data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
  31. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  32. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  33. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  34. data/lib/asciidoctor/document.rb +399 -377
  35. data/lib/asciidoctor/extensions.rb +72 -140
  36. data/lib/asciidoctor/helpers.rb +122 -83
  37. data/lib/asciidoctor/inline.rb +5 -1
  38. data/lib/asciidoctor/list.rb +13 -11
  39. data/lib/asciidoctor/logging.rb +17 -16
  40. data/lib/asciidoctor/parser.rb +390 -423
  41. data/lib/asciidoctor/path_resolver.rb +10 -5
  42. data/lib/asciidoctor/reader.rb +286 -263
  43. data/lib/asciidoctor/rouge_ext.rb +39 -0
  44. data/lib/asciidoctor/section.rb +9 -8
  45. data/lib/asciidoctor/stylesheets.rb +19 -37
  46. data/lib/asciidoctor/substitutors.rb +364 -509
  47. data/lib/asciidoctor/syntax_highlighter.rb +238 -0
  48. data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
  49. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
  50. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  51. data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
  52. data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
  53. data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
  54. data/lib/asciidoctor/table.rb +73 -66
  55. data/lib/asciidoctor/timings.rb +4 -2
  56. data/lib/asciidoctor/version.rb +2 -1
  57. data/lib/asciidoctor/writer.rb +30 -0
  58. data/man/asciidoctor.1 +19 -15
  59. data/man/asciidoctor.adoc +14 -12
  60. metadata +69 -216
  61. data/CONTRIBUTING.adoc +0 -185
  62. data/Gemfile +0 -60
  63. data/Rakefile +0 -129
  64. data/bin/asciidoctor-safe +0 -15
  65. data/features/open_block.feature +0 -92
  66. data/features/pass_block.feature +0 -66
  67. data/features/step_definitions.rb +0 -49
  68. data/features/text_formatting.feature +0 -57
  69. data/features/xref.feature +0 -1039
  70. data/lib/asciidoctor/converter/base.rb +0 -59
  71. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  72. data/lib/asciidoctor/converter/factory.rb +0 -226
  73. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  74. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  75. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  76. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  77. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  78. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  79. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  80. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  81. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  82. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  83. data/test/api_test.rb +0 -1240
  84. data/test/attribute_list_test.rb +0 -242
  85. data/test/attributes_test.rb +0 -1623
  86. data/test/blocks_test.rb +0 -3870
  87. data/test/converter_test.rb +0 -470
  88. data/test/document_test.rb +0 -1853
  89. data/test/extensions_test.rb +0 -1560
  90. data/test/fixtures/asciidoc_index.txt +0 -521
  91. data/test/fixtures/basic-docinfo-footer.html +0 -6
  92. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  93. data/test/fixtures/basic-docinfo.html +0 -1
  94. data/test/fixtures/basic-docinfo.xml +0 -4
  95. data/test/fixtures/basic.asciidoc +0 -5
  96. data/test/fixtures/chapter-a.adoc +0 -3
  97. data/test/fixtures/child-include.adoc +0 -5
  98. data/test/fixtures/circle.svg +0 -9
  99. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  100. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  101. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  102. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  103. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  104. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  105. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  106. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  107. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  108. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  109. data/test/fixtures/docinfo-footer.html +0 -1
  110. data/test/fixtures/docinfo-footer.xml +0 -9
  111. data/test/fixtures/docinfo.html +0 -1
  112. data/test/fixtures/docinfo.xml +0 -3
  113. data/test/fixtures/doctime-localtime.adoc +0 -2
  114. data/test/fixtures/dot.gif +0 -0
  115. data/test/fixtures/encoding.asciidoc +0 -13
  116. data/test/fixtures/file-with-missing-include.adoc +0 -1
  117. data/test/fixtures/grandchild-include.adoc +0 -3
  118. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  119. data/test/fixtures/include-file.asciidoc +0 -24
  120. data/test/fixtures/include-file.jsx +0 -8
  121. data/test/fixtures/include-file.ml +0 -3
  122. data/test/fixtures/include-file.xml +0 -5
  123. data/test/fixtures/lists.adoc +0 -96
  124. data/test/fixtures/master.adoc +0 -5
  125. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  126. data/test/fixtures/other-chapters.adoc +0 -11
  127. data/test/fixtures/outer-include.adoc +0 -5
  128. data/test/fixtures/parent-include-restricted.adoc +0 -5
  129. data/test/fixtures/parent-include.adoc +0 -5
  130. data/test/fixtures/sample.asciidoc +0 -30
  131. data/test/fixtures/section-a.adoc +0 -4
  132. data/test/fixtures/stylesheets/custom.css +0 -3
  133. data/test/fixtures/subdir/index.adoc +0 -3
  134. data/test/fixtures/subdir/inner-include.adoc +0 -3
  135. data/test/fixtures/subdir/middle-include.adoc +0 -5
  136. data/test/fixtures/subs-docinfo.html +0 -2
  137. data/test/fixtures/subs.adoc +0 -6
  138. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  139. data/test/fixtures/tagged-class.rb +0 -23
  140. data/test/fixtures/tip.gif +0 -0
  141. data/test/fixtures/unclosed-tag.adoc +0 -3
  142. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  143. data/test/invoker_test.rb +0 -745
  144. data/test/links_test.rb +0 -855
  145. data/test/lists_test.rb +0 -5151
  146. data/test/logger_test.rb +0 -211
  147. data/test/manpage_test.rb +0 -660
  148. data/test/options_test.rb +0 -262
  149. data/test/paragraphs_test.rb +0 -562
  150. data/test/parser_test.rb +0 -742
  151. data/test/paths_test.rb +0 -395
  152. data/test/preamble_test.rb +0 -173
  153. data/test/reader_test.rb +0 -2161
  154. data/test/sections_test.rb +0 -3575
  155. data/test/substitutions_test.rb +0 -2066
  156. data/test/tables_test.rb +0 -2036
  157. data/test/test_helper.rb +0 -447
  158. data/test/text_test.rb +0 -309
@@ -1,3575 +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 'Sections' do
8
- context 'Ids' do
9
- test 'synthetic id is generated by default' do
10
- sec = block_from_string('== Section One')
11
- assert_equal '_section_one', sec.id
12
- end
13
-
14
- test 'duplicate synthetic id is automatically enumerated' do
15
- doc = document_from_string <<-EOS
16
- == Section One
17
-
18
- == Section One
19
- EOS
20
- assert_equal 2, doc.blocks.size
21
- assert_equal '_section_one', doc.blocks[0].id
22
- assert_equal '_section_one_2', doc.blocks[1].id
23
- end
24
-
25
- test 'synthetic id removes non-word characters' do
26
- sec = block_from_string("== We’re back!")
27
- assert_equal '_were_back', sec.id
28
- end
29
-
30
- test 'synthetic id removes repeating separators' do
31
- sec = block_from_string('== Section $ One')
32
- assert_equal '_section_one', sec.id
33
- end
34
-
35
- test 'synthetic id removes entities' do
36
- sec = block_from_string('== Ben & Jerry &amp; Company&sup1; &#34;Ice Cream Brothers&#34; &#12354;')
37
- assert_equal '_ben_jerry_company_ice_cream_brothers', sec.id
38
- end
39
-
40
- test 'synthetic id removes adjacent entities with mixed case' do
41
- sec = block_from_string('== a &#xae;&AMP;&#xA9; b')
42
- assert_equal '_a_b', sec.id
43
- end
44
-
45
- test 'synthetic id removes XML tags' do
46
- sec = block_from_string('== Use the `run` command to make it icon:gear[]')
47
- assert_equal '_use_the_run_command_to_make_it_gear', sec.id
48
- end
49
-
50
- test 'synthetic id collapses repeating spaces' do
51
- sec = block_from_string('== Go Far')
52
- assert_equal '_go_far', sec.id
53
- end
54
-
55
- test 'synthetic id replaces hyphens with separator' do
56
- sec = block_from_string('== State-of-the-art design')
57
- assert_equal '_state_of_the_art_design', sec.id
58
- end
59
-
60
- test 'synthetic id replaces dots with separator' do
61
- sec = block_from_string("== Section 1.1.1")
62
- assert_equal '_section_1_1_1', sec.id
63
- end
64
-
65
- test 'synthetic id prefix can be customized' do
66
- sec = block_from_string(":idprefix: id_\n\n== Section One")
67
- assert_equal 'id_section_one', sec.id
68
- end
69
-
70
- test 'synthetic id prefix can be set to blank' do
71
- sec = block_from_string(":idprefix:\n\n== Section One")
72
- assert_equal 'section_one', sec.id
73
- end
74
-
75
- test 'synthetic id prefix is stripped from beginning of id if set to blank' do
76
- sec = block_from_string(":idprefix:\n\n== & ! More")
77
- assert_equal 'more', sec.id
78
- end
79
-
80
- test 'synthetic id separator can be customized' do
81
- sec = block_from_string(":idseparator: -\n\n== Section One")
82
- assert_equal '_section-one', sec.id
83
- end
84
-
85
- test 'synthetic id separator can be hyphen and hyphens are preserved' do
86
- sec = block_from_string(":idseparator: -\n\n== State-of-the-art design")
87
- assert_equal '_state-of-the-art-design', sec.id
88
- end
89
-
90
- test 'synthetic id separator can be dot and dots are preserved' do
91
- sec = block_from_string(":idseparator: .\n\n== Version 5.0.1")
92
- assert_equal '_version.5.0.1', sec.id
93
- end
94
-
95
- test 'synthetic id separator can only be one character' do
96
- input = <<-EOS
97
- :idseparator: -=-
98
-
99
- == This Section Is All You Need
100
- EOS
101
- sec = block_from_string input
102
- assert_equal '_this-section-is-all-you-need', sec.id
103
- end
104
-
105
- test 'synthetic id separator can be set to blank' do
106
- sec = block_from_string(":idseparator:\n\n== Section One")
107
- assert_equal '_sectionone', sec.id
108
- end
109
-
110
- test 'synthetic id separator can be set to blank when idprefix is blank' do
111
- sec = block_from_string(":idprefix:\n:idseparator:\n\n== Section One")
112
- assert_equal 'sectionone', sec.id
113
- end
114
-
115
- test 'synthetic id separator is removed from beginning of id when idprefix is blank' do
116
- sec = block_from_string(":idprefix:\n:idseparator: _\n\n== +Section One")
117
- assert_equal 'section_one', sec.id
118
- end
119
-
120
- test 'synthetic ids can be disabled' do
121
- sec = block_from_string(":sectids!:\n\n== Section One\n")
122
- assert_nil sec.id
123
- end
124
-
125
- test 'explicit id in anchor above section title overrides synthetic id' do
126
- sec = block_from_string("[[one]]\n== Section One")
127
- assert_equal 'one', sec.id
128
- end
129
-
130
- test 'explicit id in block attributes above section title overrides synthetic id' do
131
- sec = block_from_string("[id=one]\n== Section One")
132
- assert_equal 'one', sec.id
133
- end
134
-
135
- test 'explicit id set using shorthand in style above section title overrides synthetic id' do
136
- sec = block_from_string("[#one]\n== Section One")
137
- assert_equal 'one', sec.id
138
- end
139
-
140
- test 'should use explicit id from last block attribute line above section title that defines an explicit id' do
141
- input = <<-EOS
142
- [#un]
143
- [#one]
144
- == Section One
145
- EOS
146
- sec = block_from_string input
147
- assert_equal 'one', sec.id
148
- end
149
-
150
- test 'explicit id can be defined using an embedded anchor' do
151
- sec = block_from_string("== Section One [[one]] ==")
152
- assert_equal 'one', sec.id
153
- assert_equal 'Section One', sec.title
154
- end
155
-
156
- test 'explicit id can be defined using an embedded anchor when using setext section titles' do
157
- input = <<-EOS
158
- Section Title [[refid,reftext]]
159
- -------------------------------
160
- EOS
161
- sec = block_from_string input
162
- assert_equal 'Section Title', sec.title
163
- assert_equal 'refid', sec.id
164
- assert_equal 'reftext', (sec.attr 'reftext')
165
- end
166
-
167
- test 'explicit id can be defined using an embedded anchor with reftext' do
168
- sec = block_from_string("== Section One [[one,Section Uno]] ==")
169
- assert_equal 'one', sec.id
170
- assert_equal 'Section One', sec.title
171
- assert_equal 'Section Uno', (sec.attr 'reftext')
172
- end
173
-
174
- test 'id and reftext in embedded anchor cannot be quoted' do
175
- sec = block_from_string(%(== Section One [["one","Section Uno"]] ==))
176
- refute_equal 'one', sec.id
177
- assert_equal 'Section One [["one","Section Uno"]]', sec.title
178
- assert_nil(sec.attr 'reftext')
179
- end
180
-
181
- test 'reftext in embedded anchor may contain comma' do
182
- sec = block_from_string(%(== Section One [[one, Section,Uno]] ==))
183
- assert_equal 'one', sec.id
184
- assert_equal 'Section One', sec.title
185
- assert_equal 'Section,Uno', (sec.attr 'reftext')
186
- end
187
-
188
- test 'should unescape but not process inline anchor' do
189
- sec = block_from_string(%(== Section One \\[[one]] ==))
190
- refute_equal 'one', sec.id
191
- assert_equal 'Section One [[one]]', sec.title
192
- end
193
-
194
- test 'should not process inline anchor in section title if section has explicit ID' do
195
- sec = block_from_string(%([#sect-one]\n== Section One [[one]]))
196
- assert_equal 'sect-one', sec.id
197
- assert_equal 'Section One <a id="one"></a>', sec.title
198
- end
199
-
200
- test 'title substitutions are applied before generating id' do
201
- sec = block_from_string("== Section{sp}One\n")
202
- assert_equal '_section_one', sec.id
203
- end
204
-
205
- test 'synthetic ids are unique' do
206
- input = <<-EOS
207
- == Some section
208
-
209
- text
210
-
211
- == Some section
212
-
213
- text
214
- EOS
215
- doc = document_from_string input
216
- assert_equal '_some_section', doc.blocks[0].id
217
- assert_equal '_some_section_2', doc.blocks[1].id
218
- end
219
-
220
- # NOTE test cannot be run in parallel with other tests
221
- test 'can set start index of synthetic ids' do
222
- old_unique_id_start_index = Asciidoctor::Compliance.unique_id_start_index
223
- begin
224
- input = <<-EOS
225
- == Some section
226
-
227
- text
228
-
229
- == Some section
230
-
231
- text
232
- EOS
233
- Asciidoctor::Compliance.unique_id_start_index = 1
234
- doc = document_from_string input
235
- assert_equal '_some_section', doc.blocks[0].id
236
- assert_equal '_some_section_1', doc.blocks[1].id
237
- ensure
238
- Asciidoctor::Compliance.unique_id_start_index = old_unique_id_start_index
239
- end
240
- end
241
-
242
- test 'should use specified id and reftext when registering section reference' do
243
- input = <<-EOS
244
- [[install,Install Procedure]]
245
- == Install
246
-
247
- content
248
- EOS
249
-
250
- doc = document_from_string input
251
- reftext = doc.catalog[:ids]['install']
252
- refute_nil reftext
253
- assert_equal 'Install Procedure', reftext
254
- end
255
-
256
- test 'should use specified reftext when registering section reference' do
257
- input = <<-EOS
258
- [reftext="Install Procedure"]
259
- == Install
260
-
261
- content
262
- EOS
263
-
264
- doc = document_from_string input
265
- reftext = doc.catalog[:ids]['_install']
266
- refute_nil reftext
267
- assert_equal 'Install Procedure', reftext
268
- end
269
-
270
- test 'should substitute attributes when registering reftext for section' do
271
- input = <<-EOS
272
- :platform-name: Linux
273
-
274
- [[install,install on {platform-name}]]
275
- == Install
276
-
277
- content
278
- EOS
279
-
280
- doc = document_from_string input
281
- reftext = doc.catalog[:ids]['install']
282
- refute_nil reftext
283
- assert_equal 'install on Linux', reftext
284
- end
285
-
286
- test 'duplicate section id should not overwrite existing section id entry in references table' do
287
- input = <<-EOS
288
- [#install]
289
- == First Install
290
-
291
- content
292
-
293
- [#install]
294
- == Second Install
295
-
296
- content
297
- EOS
298
-
299
- using_memory_logger do |logger|
300
- doc = document_from_string input
301
- reftext = doc.catalog[:ids]['install']
302
- refute_nil reftext
303
- assert_equal 'First Install', reftext
304
- assert_message logger, :WARN, '<stdin>: line 7: id assigned to section already in use: install', Hash
305
- end
306
- end
307
-
308
- test 'should warn if explicit section ID matches auto-generated section ID' do
309
- input = <<-EOS
310
- == Do Not Repeat Yourself
311
-
312
- content
313
-
314
- [#_do_not_repeat_yourself]
315
- == Do Not Repeat Yourself
316
-
317
- content
318
- EOS
319
-
320
- using_memory_logger do |logger|
321
- doc = document_from_string input
322
- reftext = doc.catalog[:ids]['_do_not_repeat_yourself']
323
- refute_nil reftext
324
- assert_equal 'Do Not Repeat Yourself', reftext
325
- assert_message logger, :WARN, '<stdin>: line 6: id assigned to section already in use: _do_not_repeat_yourself', Hash
326
- assert_equal 2, (doc.convert.scan 'id="_do_not_repeat_yourself"').size
327
- end
328
- end
329
-
330
- test 'duplicate block id should not overwrite existing section id entry in references table' do
331
- input = <<-EOS
332
- [#install]
333
- == First Install
334
-
335
- content
336
-
337
- [#install]
338
- content
339
- EOS
340
-
341
- using_memory_logger do |logger|
342
- doc = document_from_string input
343
- reftext = doc.catalog[:ids]['install']
344
- refute_nil reftext
345
- assert_equal 'First Install', reftext
346
- assert_message logger, :WARN, '<stdin>: line 7: id assigned to block already in use: install', Hash
347
- end
348
- end
349
- end
350
-
351
- context "document title (level 0)" do
352
- test "document title with multiline syntax" do
353
- title = "My Title"
354
- chars = "=" * title.length
355
- assert_xpath "//h1[not(@id)][text() = 'My Title']", convert_string(title + "\n" + chars)
356
- assert_xpath "//h1[not(@id)][text() = 'My Title']", convert_string(title + "\n" + chars + "\n")
357
- end
358
-
359
- test "document title with multiline syntax, give a char" do
360
- title = "My Title"
361
- chars = "=" * (title.length + 1)
362
- assert_xpath "//h1[not(@id)][text() = 'My Title']", convert_string(title + "\n" + chars)
363
- assert_xpath "//h1[not(@id)][text() = 'My Title']", convert_string(title + "\n" + chars + "\n")
364
- end
365
-
366
- test "document title with multiline syntax, take a char" do
367
- title = "My Title"
368
- chars = "=" * (title.length - 1)
369
- assert_xpath "//h1[not(@id)][text() = 'My Title']", convert_string(title + "\n" + chars)
370
- assert_xpath "//h1[not(@id)][text() = 'My Title']", convert_string(title + "\n" + chars + "\n")
371
- end
372
-
373
- test 'document title with multiline syntax and unicode characters' do
374
- input = <<-EOS
375
- AsciiDoc Writer’s Guide
376
- =======================
377
- Author Name
378
-
379
- preamble
380
- EOS
381
-
382
- result = convert_string input
383
- assert_xpath '//h1', result, 1
384
- assert_xpath '//h1[text()="AsciiDoc Writer’s Guide"]', result, 1
385
- end
386
-
387
- test "not enough chars for a multiline document title" do
388
- title = "My Title"
389
- chars = "=" * (title.length - 2)
390
- using_memory_logger do |logger|
391
- output = convert_string(title + "\n" + chars)
392
- assert_xpath '//h1', output, 0
393
- refute logger.empty?
394
- logger.clear
395
- output = convert_string(title + "\n" + chars + "\n")
396
- assert_xpath '//h1', output, 0
397
- refute logger.empty?
398
- end
399
- end
400
-
401
- test "too many chars for a multiline document title" do
402
- title = "My Title"
403
- chars = "=" * (title.length + 2)
404
- using_memory_logger do |logger|
405
- output = convert_string(title + "\n" + chars)
406
- assert_xpath '//h1', output, 0
407
- refute logger.empty?
408
- logger.clear
409
- output = convert_string(title + "\n" + chars + "\n")
410
- assert_xpath '//h1', output, 0
411
- refute logger.empty?
412
- end
413
- end
414
-
415
- test "document title with multiline syntax cannot begin with a dot" do
416
- title = ".My Title"
417
- chars = "=" * title.length
418
- using_memory_logger do |logger|
419
- output = convert_string(title + "\n" + chars)
420
- assert_xpath '//h1', output, 0
421
- refute logger.empty?
422
- end
423
- end
424
-
425
- test "document title with atx syntax" do
426
- assert_xpath "//h1[not(@id)][text() = 'My Title']", convert_string("= My Title")
427
- end
428
-
429
- test "document title with symmetric syntax" do
430
- assert_xpath "//h1[not(@id)][text() = 'My Title']", convert_string("= My Title =")
431
- end
432
-
433
- test 'document title created from leveloffset shift defined in document' do
434
- assert_xpath "//h1[not(@id)][text() = 'Document Title']", convert_string(%(:leveloffset: -1\n== Document Title))
435
- end
436
-
437
- test 'document title created from leveloffset shift defined in API' do
438
- assert_xpath "//h1[not(@id)][text() = 'Document Title']", convert_string('== Document Title', :attributes => { 'leveloffset' => '-1@' })
439
- end
440
-
441
- test 'should assign id on document title to body' do
442
- input = <<-EOS
443
- [[idname]]
444
- = Document Title
445
-
446
- content
447
- EOS
448
- output = convert_string input
449
- assert_css 'body#idname', output, 1
450
- end
451
-
452
- test 'should assign id defined using shorthand syntax on document title to body' do
453
- input = <<-EOS
454
- [#idname]
455
- = Document Title
456
-
457
- content
458
- EOS
459
- output = convert_string input
460
- assert_css 'body#idname', output, 1
461
- end
462
-
463
- test 'should use ID defined in block attributes instead of ID defined inline' do
464
- input = <<-EOS
465
- [#idname-block]
466
- = Document Title [[idname-inline]]
467
-
468
- content
469
- EOS
470
- output = convert_string input
471
- assert_css 'body#idname-block', output, 1
472
- end
473
-
474
- test 'block id above document title sets id on document' do
475
- input = <<-EOS
476
- [[reference]]
477
- = Reference Manual
478
- :css-signature: refguide
479
-
480
- preamble
481
- EOS
482
- doc = document_from_string input
483
- assert_equal 'reference', doc.id
484
- assert_equal 'refguide', doc.attr('css-signature')
485
- output = doc.convert
486
- assert_css 'body#reference', output, 1
487
- end
488
-
489
- test 'should register document in catalog if id is set' do
490
- input = <<-EOS
491
- [[manual,Manual]]
492
- = Reference Manual
493
-
494
- preamble
495
- EOS
496
- doc = document_from_string input
497
- assert_equal 'manual', doc.id
498
- assert_equal 'Manual', doc.attributes['reftext']
499
- assert_equal doc, doc.catalog[:refs]['manual']
500
- end
501
-
502
- test 'should discard style, role and options shorthand attributes defined on document title' do
503
- input = <<-EOS
504
- [style#idname.rolename%optionname]
505
- = Document Title
506
-
507
- content
508
- EOS
509
- doc = document_from_string input
510
- assert_empty doc.blocks[0].attributes
511
- output = doc.convert
512
- assert_css '#idname', output, 1
513
- assert_css 'body#idname', output, 1
514
- assert_css '.rolename', output, 1
515
- assert_css 'body.rolename', output, 1
516
- end
517
- end
518
-
519
- context "level 1" do
520
- test "with multiline syntax" do
521
- assert_xpath "//h2[@id='_my_section'][text() = 'My Section']", convert_string("My Section\n-----------")
522
- end
523
-
524
- test 'should not recognize underline containing a mix of characters as setext section title' do
525
- input = <<-EOS
526
- My Section
527
- ----^^----
528
- EOS
529
-
530
- result = convert_string_to_embedded input
531
- assert_xpath '//h2[@id="_my_section"][text() = "My Section"]', result, 0
532
- assert_includes result, '----^^----'
533
- end
534
-
535
- test 'should preprocess second line of setext section title' do
536
- input = <<-EOS
537
- Section Title
538
- ifdef::asciidoctor[]
539
- -------------
540
- endif::[]
541
- EOS
542
- result = convert_string_to_embedded input
543
- assert_xpath '//h2', result, 1
544
- end
545
-
546
- test "heading title with multiline syntax cannot begin with a dot" do
547
- title = ".My Title"
548
- chars = "-" * title.length
549
- using_memory_logger do |logger|
550
- output = convert_string(title + "\n" + chars)
551
- assert_xpath '//h2', output, 0
552
- refute logger.empty?
553
- end
554
- end
555
-
556
- test "with atx syntax" do
557
- assert_xpath "//h2[@id='_my_title'][text() = 'My Title']", convert_string("== My Title")
558
- end
559
-
560
- test "with atx symmetric syntax" do
561
- assert_xpath "//h2[@id='_my_title'][text() = 'My Title']", convert_string("== My Title ==")
562
- end
563
-
564
- test "with atx non-matching symmetric syntax" do
565
- assert_xpath "//h2[@id='_my_title'][text() = 'My Title ===']", convert_string("== My Title ===")
566
- end
567
-
568
- test "with XML entity" do
569
- assert_xpath "//h2[@id='_whats_new'][text() = \"What#{decode_char 8217}s new?\"]", convert_string("== What's new?")
570
- end
571
-
572
- test "with non-word character" do
573
- assert_xpath "//h2[@id='_whats_new'][text() = \"What’s new?\"]", convert_string("== What’s new?")
574
- end
575
-
576
- test "with sequential non-word characters" do
577
- assert_xpath "//h2[@id='_what_the_is_this'][text() = 'What the \#@$ is this?']", convert_string('== What the #@$ is this?')
578
- end
579
-
580
- test "with trailing whitespace" do
581
- assert_xpath "//h2[@id='_my_title'][text() = 'My Title']", convert_string("== My Title ")
582
- end
583
-
584
- test "with custom blank idprefix" do
585
- assert_xpath "//h2[@id='my_title'][text() = 'My Title']", convert_string(":idprefix:\n\n== My Title ")
586
- end
587
-
588
- test "with custom non-blank idprefix" do
589
- assert_xpath "//h2[@id='ref_my_title'][text() = 'My Title']", convert_string(":idprefix: ref_\n\n== My Title ")
590
- end
591
-
592
- test 'with multibyte characters' do
593
- input = <<-EOS
594
- == Asciidoctor in 中文
595
- EOS
596
- output = convert_string input
597
- if ::RUBY_MIN_VERSION_1_9
598
- assert_xpath '//h2[@id="_asciidoctor_in_中文"][text()="Asciidoctor in 中文"]', output
599
- else
600
- assert_xpath '//h2[@id="_asciidoctor_in"][text()="Asciidoctor in 中文"]', output
601
- end
602
- end
603
-
604
- test 'with only multibyte characters' do
605
- input = <<-EOS
606
- == 视图
607
- EOS
608
- output = convert_string_to_embedded input
609
- assert_xpath '//h2[@id="_视图"][text()="视图"]', output
610
- end if ::RUBY_MIN_VERSION_1_9
611
-
612
- test 'multiline syntax with only multibyte characters' do
613
- input = <<-EOS
614
- 视图
615
- --
616
-
617
- content
618
-
619
- 连接器
620
- ---
621
-
622
- content
623
- EOS
624
- output = convert_string_to_embedded input
625
- assert_xpath '//h2[@id="_视图"][text()="视图"]', output
626
- assert_xpath '//h2[@id="_连接器"][text()="连接器"]', output
627
- end if ::RUBY_MIN_VERSION_1_9
628
- end
629
-
630
- context "level 2" do
631
- test "with multiline syntax" do
632
- assert_xpath "//h3[@id='_my_section'][text() = 'My Section']", convert_string(":fragment:\nMy Section\n~~~~~~~~~~~")
633
- end
634
-
635
- test "with atx line syntax" do
636
- assert_xpath "//h3[@id='_my_title'][text() = 'My Title']", convert_string(":fragment:\n=== My Title")
637
- end
638
- end
639
-
640
- context "level 3" do
641
- test "with multiline syntax" do
642
- assert_xpath "//h4[@id='_my_section'][text() = 'My Section']", convert_string(":fragment:\nMy Section\n^^^^^^^^^^")
643
- end
644
-
645
- test "with atx line syntax" do
646
- assert_xpath "//h4[@id='_my_title'][text() = 'My Title']", convert_string(":fragment:\n==== My Title")
647
- end
648
- end
649
-
650
- context "level 4" do
651
- test "with multiline syntax" do
652
- assert_xpath "//h5[@id='_my_section'][text() = 'My Section']", convert_string(":fragment:\nMy Section\n++++++++++")
653
- end
654
-
655
- test "with atx line syntax" do
656
- assert_xpath "//h5[@id='_my_title'][text() = 'My Title']", convert_string(":fragment:\n===== My Title")
657
- end
658
- end
659
-
660
- context "level 5" do
661
- test "with atx line syntax" do
662
- assert_xpath "//h6[@id='_my_title'][text() = 'My Title']", convert_string(":fragment:\n====== My Title")
663
- end
664
- end
665
-
666
- context 'Nesting' do
667
- test 'should warn if section title is out of sequence' do
668
- input = <<-EOS
669
- = Document Title
670
-
671
- == Section A
672
-
673
- ==== Nested Section
674
-
675
- content
676
-
677
- == Section B
678
-
679
- content
680
- EOS
681
-
682
- using_memory_logger do |logger|
683
- result = convert_string_to_embedded input
684
- assert_xpath '//h4[text()="Nested Section"]', result, 1
685
- assert_message logger, :WARN, '<stdin>: line 5: section title out of sequence: expected level 2, got level 3', Hash
686
- end
687
- end
688
-
689
- test 'should warn if chapter title is out of sequence' do
690
- input = <<-EOS
691
- = Document Title
692
- :doctype: book
693
-
694
- === Not a Chapter
695
-
696
- content
697
- EOS
698
-
699
- using_memory_logger do |logger|
700
- result = convert_string_to_embedded input
701
- assert_xpath '//h3[text()="Not a Chapter"]', result, 1
702
- assert_message logger, :WARN, '<stdin>: line 4: section title out of sequence: expected levels 0 or 1, got level 2', Hash
703
- end
704
- end
705
-
706
- test 'should not warn if top-level section title is out of sequence when fragment attribute is set on document' do
707
- input = <<-EOS
708
- = Document Title
709
-
710
- === First Section
711
-
712
- content
713
- EOS
714
-
715
- using_memory_logger do |logger|
716
- convert_string_to_embedded input, :attributes => { 'fragment' => '' }
717
- assert logger.empty?
718
- end
719
- end
720
-
721
- test 'should warn if nested section title is out of sequence when fragment attribute is set on document' do
722
- input = <<-EOS
723
- = Document Title
724
-
725
- === First Section
726
-
727
- ===== Nested Section
728
- EOS
729
-
730
- using_memory_logger do |logger|
731
- convert_string_to_embedded input, :attributes => { 'fragment' => '' }
732
- assert_message logger, :WARN, '<stdin>: line 5: section title out of sequence: expected level 3, got level 4', Hash
733
- end
734
- end
735
- test 'should log error if subsections are found in special sections in article that do not support subsections' do
736
- input = <<-EOS
737
- = Document Title
738
-
739
- == Section
740
-
741
- === Subsection of Section
742
-
743
- allowed
744
-
745
- [appendix]
746
- == Appendix
747
-
748
- === Subsection of Appendix
749
-
750
- allowed
751
-
752
- [glossary]
753
- == Glossary
754
-
755
- === Subsection of Glossary
756
-
757
- not allowed
758
-
759
- [bibliography]
760
- == Bibliography
761
-
762
- === Subsection of Bibliography
763
-
764
- not allowed
765
- EOS
766
-
767
- using_memory_logger do |logger|
768
- convert_string_to_embedded input
769
- assert_messages logger, [
770
- [:ERROR, '<stdin>: line 19: glossary sections do not support nested sections', Hash],
771
- [:ERROR, '<stdin>: line 26: bibliography sections do not support nested sections', Hash],
772
- ]
773
- end
774
- end
775
-
776
- test 'should log error if subsections are found in special sections in book that do not support subsections' do
777
- input = <<-EOS
778
- = Document Title
779
- :doctype: book
780
-
781
- [preface]
782
- = Preface
783
-
784
- === Subsection of Preface
785
-
786
- allowed
787
-
788
- [colophon]
789
- = Colophon
790
-
791
- === Subsection of Colophon
792
-
793
- not allowed
794
-
795
- [dedication]
796
- = Dedication
797
-
798
- === Subsection of Dedication
799
-
800
- not allowed
801
-
802
- = Part 1
803
-
804
- [abstract]
805
- == Abstract
806
-
807
- === Subsection of Abstract
808
-
809
- allowed
810
-
811
- == Chapter 1
812
-
813
- === Subsection of Chapter
814
-
815
- allowed
816
-
817
- [appendix]
818
- = Appendix
819
-
820
- === Subsection of Appendix
821
-
822
- allowed
823
-
824
- [glossary]
825
- = Glossary
826
-
827
- === Subsection of Glossary
828
-
829
- not allowed
830
-
831
- [bibliography]
832
- = Bibliography
833
-
834
- === Subsection of Bibliography
835
-
836
- not allowed
837
- EOS
838
-
839
- using_memory_logger do |logger|
840
- convert_string_to_embedded input
841
- assert_messages logger, [
842
- [:ERROR, '<stdin>: line 14: colophon sections do not support nested sections', Hash],
843
- [:ERROR, '<stdin>: line 21: dedication sections do not support nested sections', Hash],
844
- [:ERROR, '<stdin>: line 50: glossary sections do not support nested sections', Hash],
845
- [:ERROR, '<stdin>: line 57: bibliography sections do not support nested sections', Hash]
846
- ]
847
- end
848
- end
849
- end
850
-
851
- context 'Markdown-style headings' do
852
- test 'atx document title with leading marker' do
853
- input = <<-EOS
854
- # Document Title
855
- EOS
856
- output = convert_string input
857
- assert_xpath "//h1[not(@id)][text() = 'Document Title']", output, 1
858
- end
859
-
860
- test 'atx document title with symmetric markers' do
861
- input = <<-EOS
862
- # Document Title #
863
- EOS
864
- output = convert_string input
865
- assert_xpath "//h1[not(@id)][text() = 'Document Title']", output, 1
866
- end
867
-
868
- test 'atx section title with leading marker' do
869
- input = <<-EOS
870
- ## Section One
871
-
872
- blah blah
873
- EOS
874
- output = convert_string input
875
- assert_xpath "//h2[@id='_section_one'][text() = 'Section One']", output, 1
876
- end
877
-
878
- test 'atx section title with symmetric markers' do
879
- input = <<-EOS
880
- ## Section One ##
881
-
882
- blah blah
883
- EOS
884
- output = convert_string input
885
- assert_xpath "//h2[@id='_section_one'][text() = 'Section One']", output, 1
886
- end
887
-
888
- test 'should not match atx syntax with mixed markers' do
889
- input = <<-EOS
890
- =#= My Title
891
- EOS
892
- output = convert_string_to_embedded input
893
- assert_xpath "//h3[@id='_my_title'][text() = 'My Title']", output, 0
894
- assert_includes output, '<p>=#= My Title</p>'
895
- end
896
- end
897
-
898
- context 'Discrete Heading' do
899
- test 'should create discrete heading instead of section if style is float' do
900
- input = <<-EOS
901
- [float]
902
- = Independent Heading!
903
-
904
- not in section
905
- EOS
906
-
907
- output = convert_string_to_embedded input
908
- assert_xpath '/h1[@id="_independent_heading"]', output, 1
909
- assert_xpath '/h1[@class="float"]', output, 1
910
- assert_xpath %(/h1[@class="float"][text()="Independent Heading!"]), output, 1
911
- assert_xpath '/h1/following-sibling::*[@class="paragraph"]', output, 1
912
- assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p', output, 1
913
- assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p[text()="not in section"]', output, 1
914
- end
915
-
916
- test 'should create discrete heading instead of section if style is discrete' do
917
- input = <<-EOS
918
- [discrete]
919
- === Independent Heading!
920
-
921
- not in section
922
- EOS
923
-
924
- output = convert_string_to_embedded input
925
- assert_xpath '/h3', output, 1
926
- assert_xpath '/h3[@id="_independent_heading"]', output, 1
927
- assert_xpath '/h3[@class="discrete"]', output, 1
928
- assert_xpath %(/h3[@class="discrete"][text()="Independent Heading!"]), output, 1
929
- assert_xpath '/h3/following-sibling::*[@class="paragraph"]', output, 1
930
- assert_xpath '/h3/following-sibling::*[@class="paragraph"]/p', output, 1
931
- assert_xpath '/h3/following-sibling::*[@class="paragraph"]/p[text()="not in section"]', output, 1
932
- end
933
-
934
- test 'should generate id for discrete heading from converted title' do
935
- input = <<-EOS
936
- [discrete]
937
- === {sp}Heading{sp}
938
-
939
- not in section
940
- EOS
941
-
942
- output = convert_string_to_embedded input
943
- assert_xpath '/h3', output, 1
944
- assert_xpath '/h3[@class="discrete"][@id="_heading"]', output, 1
945
- assert_xpath '/h3[@class="discrete"][@id="_heading"][text()=" Heading "]', output, 1
946
- end
947
-
948
- test 'should create discrete heading if style is float with shorthand role and id' do
949
- input = <<-EOS
950
- [float.independent#first]
951
- = Independent Heading!
952
-
953
- not in section
954
- EOS
955
-
956
- output = convert_string_to_embedded input
957
- assert_xpath '/h1[@id="first"]', output, 1
958
- assert_xpath '/h1[@class="float independent"]', output, 1
959
- assert_xpath %(/h1[@class="float independent"][text()="Independent Heading!"]), output, 1
960
- assert_xpath '/h1/following-sibling::*[@class="paragraph"]', output, 1
961
- assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p', output, 1
962
- assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p[text()="not in section"]', output, 1
963
- end
964
-
965
- test 'should create discrete heading if style is discrete with shorthand role and id' do
966
- input = <<-EOS
967
- [discrete.independent#first]
968
- = Independent Heading!
969
-
970
- not in section
971
- EOS
972
-
973
- output = convert_string_to_embedded input
974
- assert_xpath '/h1[@id="first"]', output, 1
975
- assert_xpath '/h1[@class="discrete independent"]', output, 1
976
- assert_xpath %(/h1[@class="discrete independent"][text()="Independent Heading!"]), output, 1
977
- assert_xpath '/h1/following-sibling::*[@class="paragraph"]', output, 1
978
- assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p', output, 1
979
- assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p[text()="not in section"]', output, 1
980
- end
981
-
982
- test 'discrete heading should be a block with context floating_title' do
983
- input = <<-EOS
984
- [float]
985
- === Independent Heading!
986
-
987
- not in section
988
- EOS
989
-
990
- doc = document_from_string input
991
- heading = doc.blocks.first
992
- assert_kind_of Asciidoctor::Block, heading
993
- assert_equal :floating_title, heading.context
994
- assert_equal '_independent_heading', heading.id
995
- assert doc.catalog[:ids].has_key?('_independent_heading')
996
- end
997
-
998
- test 'should preprocess second line of setext discrete heading' do
999
- input = <<-EOS
1000
- [discrete]
1001
- Heading Title
1002
- ifdef::asciidoctor[]
1003
- -------------
1004
- endif::[]
1005
- EOS
1006
- result = convert_string_to_embedded input
1007
- assert_xpath '//h2', result, 1
1008
- end
1009
-
1010
- test 'can assign explicit id to discrete heading' do
1011
- input = <<-EOS
1012
- [[unchained]]
1013
- [float]
1014
- === Independent Heading!
1015
-
1016
- not in section
1017
- EOS
1018
-
1019
- doc = document_from_string input
1020
- heading = doc.blocks.first
1021
- assert_equal 'unchained', heading.id
1022
- assert doc.catalog[:ids].has_key?('unchained')
1023
- end
1024
-
1025
- test 'should not include discrete heading in toc' do
1026
- input = <<-EOS
1027
- :toc:
1028
-
1029
- == Section One
1030
-
1031
- [float]
1032
- === Miss Independent
1033
-
1034
- == Section Two
1035
- EOS
1036
-
1037
- output = convert_string input
1038
- assert_xpath '//*[@id="toc"]', output, 1
1039
- assert_xpath %(//*[@id="toc"]//a[contains(text(), "Section ")]), output, 2
1040
- assert_xpath %(//*[@id="toc"]//a[text()="Miss Independent"]), output, 0
1041
- end
1042
-
1043
- test 'should not set id on discrete heading if sectids attribute is unset' do
1044
- input = <<-EOS
1045
- [float]
1046
- === Independent Heading!
1047
-
1048
- not in section
1049
- EOS
1050
-
1051
- output = convert_string_to_embedded input, :attributes => {'sectids' => nil}
1052
- assert_xpath '/h3', output, 1
1053
- assert_xpath '/h3[@id="_independent_heading"]', output, 0
1054
- assert_xpath '/h3[@class="float"]', output, 1
1055
- end
1056
-
1057
- test 'should use explicit id for discrete heading if specified' do
1058
- input = <<-EOS
1059
- [[free]]
1060
- [float]
1061
- == Independent Heading!
1062
-
1063
- not in section
1064
- EOS
1065
-
1066
- output = convert_string_to_embedded input
1067
- assert_xpath '/h2', output, 1
1068
- assert_xpath '/h2[@id="free"]', output, 1
1069
- assert_xpath '/h2[@class="float"]', output, 1
1070
- end
1071
-
1072
- test 'should add role to class attribute on discrete heading' do
1073
- input = <<-EOS
1074
- [float, role="isolated"]
1075
- == Independent Heading!
1076
-
1077
- not in section
1078
- EOS
1079
-
1080
- output = convert_string_to_embedded input
1081
- assert_xpath '/h2', output, 1
1082
- assert_xpath '/h2[@id="_independent_heading"]', output, 1
1083
- assert_xpath '/h2[@class="float isolated"]', output, 1
1084
- end
1085
-
1086
- test 'should ignore title attribute on discrete heading' do
1087
- input = <<-EOS
1088
- [discrete,title="Captured!"]
1089
- == Independent Heading!
1090
-
1091
- not in section
1092
- EOS
1093
-
1094
- doc = document_from_string input
1095
- heading = doc.blocks[0]
1096
- assert_equal 'Independent Heading!', heading.title
1097
- refute heading.attributes.key? 'title'
1098
- end
1099
-
1100
- test 'should use specified id and reftext when registering discrete section reference' do
1101
- input = <<-EOS
1102
- [[install,Install Procedure]]
1103
- [discrete]
1104
- == Install
1105
-
1106
- content
1107
- EOS
1108
-
1109
- doc = document_from_string input
1110
- reftext = doc.catalog[:ids]['install']
1111
- refute_nil reftext
1112
- assert_equal 'Install Procedure', reftext
1113
- end
1114
-
1115
- test 'should use specified reftext when registering discrete section reference' do
1116
- input = <<-EOS
1117
- [reftext="Install Procedure"]
1118
- [discrete]
1119
- == Install
1120
-
1121
- content
1122
- EOS
1123
-
1124
- doc = document_from_string input
1125
- reftext = doc.catalog[:ids]['_install']
1126
- refute_nil reftext
1127
- assert_equal 'Install Procedure', reftext
1128
- end
1129
-
1130
- test 'should not process inline anchor in discrete heading if explicit ID is assigned' do
1131
- input = <<-EOS
1132
- [discrete#install]
1133
- == Install [[installation]]
1134
-
1135
- content
1136
- EOS
1137
-
1138
- block = block_from_string input
1139
- assert_equal block.id, 'install'
1140
- assert_equal 'Install <a id="installation"></a>', block.title
1141
- end
1142
- end
1143
-
1144
- context 'Level offset' do
1145
- test 'should print error if standalone document is included without level offset' do
1146
- input = <<-EOS
1147
- = Master Document
1148
- Doc Writer
1149
-
1150
- text in master
1151
-
1152
- // begin simulated include::[]
1153
- = Standalone Document
1154
- :author: Junior Writer
1155
-
1156
- text in standalone
1157
-
1158
- // end simulated include::[]
1159
- EOS
1160
-
1161
- using_memory_logger do |logger|
1162
- convert_string input
1163
- assert_message logger, :ERROR, '<stdin>: line 7: level 0 sections can only be used when doctype is book', Hash
1164
- end
1165
- end
1166
-
1167
- test 'should add level offset to section level' do
1168
- input = <<-EOS
1169
- = Master Document
1170
- Doc Writer
1171
-
1172
- Master document written by {author}.
1173
-
1174
- :leveloffset: 1
1175
-
1176
- // begin simulated include::[]
1177
- = Standalone Document
1178
- :author: Junior Writer
1179
-
1180
- Standalone document written by {author}.
1181
-
1182
- == Section in Standalone
1183
-
1184
- Standalone section text.
1185
- // end simulated include::[]
1186
-
1187
- :leveloffset!:
1188
-
1189
- == Section in Master
1190
-
1191
- Master section text.
1192
- EOS
1193
-
1194
- output = nil
1195
- using_memory_logger do |logger|
1196
- output = convert_string input
1197
- assert logger.empty?
1198
- end
1199
-
1200
- assert_match(/Master document written by Doc Writer/, output)
1201
- assert_match(/Standalone document written by Junior Writer/, output)
1202
- assert_xpath '//*[@class="sect1"]/h2[text() = "Standalone Document"]', output, 1
1203
- assert_xpath '//*[@class="sect2"]/h3[text() = "Section in Standalone"]', output, 1
1204
- assert_xpath '//*[@class="sect1"]/h2[text() = "Section in Master"]', output, 1
1205
- end
1206
-
1207
- test 'level offset should be added to discrete heading' do
1208
- input = <<-EOS
1209
- = Master Document
1210
- Doc Writer
1211
-
1212
- :leveloffset: 1
1213
-
1214
- [float]
1215
- = Discrete Heading
1216
- EOS
1217
-
1218
- output = convert_string input
1219
- assert_xpath '//h2[@class="float"][text() = "Discrete Heading"]', output, 1
1220
- end
1221
-
1222
- test 'should be able to reset level offset' do
1223
- input = <<-EOS
1224
- = Master Document
1225
- Doc Writer
1226
-
1227
- Master preamble.
1228
-
1229
- :leveloffset: 1
1230
-
1231
- = Standalone Document
1232
-
1233
- Standalone preamble.
1234
-
1235
- :leveloffset!:
1236
-
1237
- == Level 1 Section
1238
- EOS
1239
-
1240
- output = convert_string input
1241
- assert_xpath '//*[@class = "sect1"]/h2[text() = "Standalone Document"]', output, 1
1242
- assert_xpath '//*[@class = "sect1"]/h2[text() = "Level 1 Section"]', output, 1
1243
- end
1244
-
1245
- test 'should add relative offset value to current leveloffset' do
1246
- input = <<-EOS
1247
- = Master Document
1248
- Doc Writer
1249
-
1250
- Master preamble.
1251
-
1252
- :leveloffset: 1
1253
-
1254
- = Chapter 1
1255
-
1256
- content
1257
-
1258
- :leveloffset: +1
1259
-
1260
- = Standalone Section
1261
-
1262
- content
1263
- EOS
1264
-
1265
- output = convert_string input
1266
- assert_xpath '//*[@class = "sect1"]/h2[text() = "Chapter 1"]', output, 1
1267
- assert_xpath '//*[@class = "sect2"]/h3[text() = "Standalone Section"]', output, 1
1268
- end
1269
- end
1270
-
1271
- context 'Section Numbering' do
1272
- test 'should create section number with one entry for level 1' do
1273
- doc = empty_document
1274
- sect1 = Asciidoctor::Section.new nil, nil, true
1275
- doc << sect1
1276
- assert_equal '1.', sect1.sectnum
1277
- end
1278
-
1279
- test 'should create section number with two entries for level 2' do
1280
- doc = empty_document
1281
- sect1 = Asciidoctor::Section.new nil, nil, true
1282
- doc << sect1
1283
- sect1_1 = Asciidoctor::Section.new sect1, nil, true
1284
- sect1 << sect1_1
1285
- assert_equal '1.1.', sect1_1.sectnum
1286
- end
1287
-
1288
- test 'should create section number with three entries for level 3' do
1289
- doc = empty_document
1290
- sect1 = Asciidoctor::Section.new nil, nil, true
1291
- doc << sect1
1292
- sect1_1 = Asciidoctor::Section.new sect1, nil, true
1293
- sect1 << sect1_1
1294
- sect1_1_1 = Asciidoctor::Section.new sect1_1, nil, true
1295
- sect1_1 << sect1_1_1
1296
- assert_equal '1.1.1.', sect1_1_1.sectnum
1297
- end
1298
-
1299
- test 'should create section number for second section in level' do
1300
- doc = empty_document
1301
- sect1 = Asciidoctor::Section.new nil, nil, true
1302
- doc << sect1
1303
- sect1_1 = Asciidoctor::Section.new sect1, nil, true
1304
- sect1 << sect1_1
1305
- sect1_2 = Asciidoctor::Section.new sect1, nil, true
1306
- sect1 << sect1_2
1307
- assert_equal '1.2.', sect1_2.sectnum
1308
- end
1309
-
1310
- test 'sectnum should use specified delimiter and append string' do
1311
- doc = empty_document
1312
- sect1 = Asciidoctor::Section.new nil, nil, true
1313
- doc << sect1
1314
- sect1_1 = Asciidoctor::Section.new sect1, nil, true
1315
- sect1 << sect1_1
1316
- sect1_1_1 = Asciidoctor::Section.new sect1_1, nil, true
1317
- sect1_1 << sect1_1_1
1318
- assert_equal '1,1,1,', sect1_1_1.sectnum(',')
1319
- assert_equal '1:1:1', sect1_1_1.sectnum(':', false)
1320
- end
1321
-
1322
- test 'should output section numbers when sectnums attribute is set' do
1323
- input = <<-EOS
1324
- = Title
1325
- :sectnums:
1326
-
1327
- == Section_1
1328
-
1329
- text
1330
-
1331
- === Section_1_1
1332
-
1333
- text
1334
-
1335
- ==== Section_1_1_1
1336
-
1337
- text
1338
-
1339
- == Section_2
1340
-
1341
- text
1342
-
1343
- === Section_2_1
1344
-
1345
- text
1346
-
1347
- === Section_2_2
1348
-
1349
- text
1350
- EOS
1351
-
1352
- output = convert_string input
1353
- assert_xpath '//h2[@id="_section_1"][starts-with(text(), "1. ")]', output, 1
1354
- assert_xpath '//h3[@id="_section_1_1"][starts-with(text(), "1.1. ")]', output, 1
1355
- assert_xpath '//h4[@id="_section_1_1_1"][starts-with(text(), "1.1.1. ")]', output, 1
1356
- assert_xpath '//h2[@id="_section_2"][starts-with(text(), "2. ")]', output, 1
1357
- assert_xpath '//h3[@id="_section_2_1"][starts-with(text(), "2.1. ")]', output, 1
1358
- assert_xpath '//h3[@id="_section_2_2"][starts-with(text(), "2.2. ")]', output, 1
1359
- end
1360
-
1361
- test 'should output section numbers when numbered attribute is set' do
1362
- input = <<-EOS
1363
- = Title
1364
- :numbered:
1365
-
1366
- == Section_1
1367
-
1368
- text
1369
-
1370
- === Section_1_1
1371
-
1372
- text
1373
-
1374
- ==== Section_1_1_1
1375
-
1376
- text
1377
-
1378
- == Section_2
1379
-
1380
- text
1381
-
1382
- === Section_2_1
1383
-
1384
- text
1385
-
1386
- === Section_2_2
1387
-
1388
- text
1389
- EOS
1390
-
1391
- output = convert_string input
1392
- assert_xpath '//h2[@id="_section_1"][starts-with(text(), "1. ")]', output, 1
1393
- assert_xpath '//h3[@id="_section_1_1"][starts-with(text(), "1.1. ")]', output, 1
1394
- assert_xpath '//h4[@id="_section_1_1_1"][starts-with(text(), "1.1.1. ")]', output, 1
1395
- assert_xpath '//h2[@id="_section_2"][starts-with(text(), "2. ")]', output, 1
1396
- assert_xpath '//h3[@id="_section_2_1"][starts-with(text(), "2.1. ")]', output, 1
1397
- assert_xpath '//h3[@id="_section_2_2"][starts-with(text(), "2.2. ")]', output, 1
1398
- end
1399
-
1400
- test 'should not crash if child section of part is out of sequence and part numbering is disabled' do
1401
- input = <<-EOS
1402
- = Document Title
1403
- :doctype: book
1404
- :sectnums:
1405
-
1406
- = Part
1407
-
1408
- === Out of Sequence Section
1409
- EOS
1410
-
1411
- using_memory_logger do |logger|
1412
- output = convert_string input
1413
- assert_xpath '//h1[text()="Part"]', output, 1
1414
- assert_xpath '//h3[text()=".1. Out of Sequence Section"]', output, 1
1415
- end
1416
- end
1417
-
1418
- test 'should number parts when doctype is book and partnums attributes is set' do
1419
- input = <<-EOS
1420
- = Book Title
1421
- :doctype: book
1422
- :sectnums:
1423
- :partnums:
1424
-
1425
- = Language
1426
-
1427
- == Syntax
1428
-
1429
- content
1430
-
1431
- = Processor
1432
-
1433
- == CLI
1434
-
1435
- content
1436
- EOS
1437
-
1438
- output = convert_string input
1439
- assert_xpath '//h1[@id="_language"][text() = "I: Language"]', output, 1
1440
- assert_xpath '//h1[@id="_processor"][text() = "II: Processor"]', output, 1
1441
- end
1442
-
1443
- test 'should prepend value of part-signifier attribute to title of numbered part' do
1444
- input = <<-EOS
1445
- = Book Title
1446
- :doctype: book
1447
- :sectnums:
1448
- :partnums:
1449
- :part-signifier: Part
1450
-
1451
- = Language
1452
-
1453
- == Syntax
1454
-
1455
- content
1456
-
1457
- = Processor
1458
-
1459
- == CLI
1460
-
1461
- content
1462
- EOS
1463
-
1464
- output = convert_string input
1465
- assert_xpath '//h1[@id="_language"][text() = "Part I: Language"]', output, 1
1466
- assert_xpath '//h1[@id="_processor"][text() = "Part II: Processor"]', output, 1
1467
- end
1468
-
1469
- test 'should prepend value of chapter-signifier attribute to title of numbered chapter' do
1470
- input = <<-EOS
1471
- = Book Title
1472
- :doctype: book
1473
- :sectnums:
1474
- :partnums:
1475
- :chapter-signifier: Chapter
1476
-
1477
- = Language
1478
-
1479
- == Syntax
1480
-
1481
- content
1482
-
1483
- = Processor
1484
-
1485
- == CLI
1486
-
1487
- content
1488
- EOS
1489
-
1490
- output = convert_string input
1491
- assert_xpath '//h2[@id="_syntax"][text() = "Chapter 1. Syntax"]', output, 1
1492
- assert_xpath '//h2[@id="_cli"][text() = "Chapter 2. CLI"]', output, 1
1493
- end
1494
-
1495
- test 'blocks should have level' do
1496
- input = <<-EOS
1497
- = Title
1498
-
1499
- preamble
1500
-
1501
- == Section 1
1502
-
1503
- paragraph
1504
-
1505
- === Section 1.1
1506
-
1507
- paragraph
1508
- EOS
1509
- doc = document_from_string input
1510
- assert_equal 0, doc.blocks[0].level
1511
- assert_equal 1, doc.blocks[1].level
1512
- assert_equal 1, doc.blocks[1].blocks[0].level
1513
- assert_equal 2, doc.blocks[1].blocks[1].level
1514
- assert_equal 2, doc.blocks[1].blocks[1].blocks[0].level
1515
- end
1516
-
1517
- test 'section numbers should not increment when numbered attribute is turned off within document' do
1518
- input = <<-EOS
1519
- = Document Title
1520
- :numbered:
1521
-
1522
- :numbered!:
1523
-
1524
- == Colophon Section
1525
-
1526
- == Another Colophon Section
1527
-
1528
- == Final Colophon Section
1529
-
1530
- :numbered:
1531
-
1532
- == Section One
1533
-
1534
- === Section One Subsection
1535
-
1536
- == Section Two
1537
-
1538
- == Section Three
1539
- EOS
1540
-
1541
- output = convert_string input
1542
- assert_xpath '//h1[text()="Document Title"]', output, 1
1543
- assert_xpath '//h2[@id="_colophon_section"][text()="Colophon Section"]', output, 1
1544
- assert_xpath '//h2[@id="_another_colophon_section"][text()="Another Colophon Section"]', output, 1
1545
- assert_xpath '//h2[@id="_final_colophon_section"][text()="Final Colophon Section"]', output, 1
1546
- assert_xpath '//h2[@id="_section_one"][text()="1. Section One"]', output, 1
1547
- assert_xpath '//h3[@id="_section_one_subsection"][text()="1.1. Section One Subsection"]', output, 1
1548
- assert_xpath '//h2[@id="_section_two"][text()="2. Section Two"]', output, 1
1549
- assert_xpath '//h2[@id="_section_three"][text()="3. Section Three"]', output, 1
1550
- end
1551
-
1552
- test 'section numbers can be toggled even if numbered attribute is enable via the API' do
1553
- input = <<-EOS
1554
- = Document Title
1555
-
1556
- :numbered!:
1557
-
1558
- == Colophon Section
1559
-
1560
- == Another Colophon Section
1561
-
1562
- == Final Colophon Section
1563
-
1564
- :numbered:
1565
-
1566
- == Section One
1567
-
1568
- === Section One Subsection
1569
-
1570
- == Section Two
1571
-
1572
- == Section Three
1573
- EOS
1574
-
1575
- output = convert_string input, :attributes => {'numbered' => ''}
1576
- assert_xpath '//h1[text()="Document Title"]', output, 1
1577
- assert_xpath '//h2[@id="_colophon_section"][text()="Colophon Section"]', output, 1
1578
- assert_xpath '//h2[@id="_another_colophon_section"][text()="Another Colophon Section"]', output, 1
1579
- assert_xpath '//h2[@id="_final_colophon_section"][text()="Final Colophon Section"]', output, 1
1580
- assert_xpath '//h2[@id="_section_one"][text()="1. Section One"]', output, 1
1581
- assert_xpath '//h3[@id="_section_one_subsection"][text()="1.1. Section One Subsection"]', output, 1
1582
- assert_xpath '//h2[@id="_section_two"][text()="2. Section Two"]', output, 1
1583
- assert_xpath '//h2[@id="_section_three"][text()="3. Section Three"]', output, 1
1584
- end
1585
-
1586
- test 'section numbers cannot be toggled even if numbered attribute is disabled via the API' do
1587
- input = <<-EOS
1588
- = Document Title
1589
-
1590
- :numbered!:
1591
-
1592
- == Colophon Section
1593
-
1594
- == Another Colophon Section
1595
-
1596
- == Final Colophon Section
1597
-
1598
- :numbered:
1599
-
1600
- == Section One
1601
-
1602
- === Section One Subsection
1603
-
1604
- == Section Two
1605
-
1606
- == Section Three
1607
- EOS
1608
-
1609
- output = convert_string input, :attributes => {'numbered!' => ''}
1610
- assert_xpath '//h1[text()="Document Title"]', output, 1
1611
- assert_xpath '//h2[@id="_colophon_section"][text()="Colophon Section"]', output, 1
1612
- assert_xpath '//h2[@id="_another_colophon_section"][text()="Another Colophon Section"]', output, 1
1613
- assert_xpath '//h2[@id="_final_colophon_section"][text()="Final Colophon Section"]', output, 1
1614
- assert_xpath '//h2[@id="_section_one"][text()="Section One"]', output, 1
1615
- assert_xpath '//h3[@id="_section_one_subsection"][text()="Section One Subsection"]', output, 1
1616
- assert_xpath '//h2[@id="_section_two"][text()="Section Two"]', output, 1
1617
- assert_xpath '//h2[@id="_section_three"][text()="Section Three"]', output, 1
1618
- end
1619
-
1620
- # NOTE AsciiDoc fails this test because it does not properly check for a None value when looking up the numbered attribute
1621
- test 'section numbers should not increment until numbered attribute is turned back on' do
1622
- input = <<-EOS
1623
- = Document Title
1624
- :numbered!:
1625
-
1626
- == Colophon Section
1627
-
1628
- == Another Colophon Section
1629
-
1630
- == Final Colophon Section
1631
-
1632
- :numbered:
1633
-
1634
- == Section One
1635
-
1636
- === Section One Subsection
1637
-
1638
- == Section Two
1639
-
1640
- == Section Three
1641
- EOS
1642
-
1643
- output = convert_string input
1644
- assert_xpath '//h1[text()="Document Title"]', output, 1
1645
- assert_xpath '//h2[@id="_colophon_section"][text()="Colophon Section"]', output, 1
1646
- assert_xpath '//h2[@id="_another_colophon_section"][text()="Another Colophon Section"]', output, 1
1647
- assert_xpath '//h2[@id="_final_colophon_section"][text()="Final Colophon Section"]', output, 1
1648
- assert_xpath '//h2[@id="_section_one"][text()="1. Section One"]', output, 1
1649
- assert_xpath '//h3[@id="_section_one_subsection"][text()="1.1. Section One Subsection"]', output, 1
1650
- assert_xpath '//h2[@id="_section_two"][text()="2. Section Two"]', output, 1
1651
- assert_xpath '//h2[@id="_section_three"][text()="3. Section Three"]', output, 1
1652
- end
1653
-
1654
- test 'table with asciidoc content should not disable numbering of subsequent sections' do
1655
- input = <<-EOS
1656
- = Document Title
1657
- :numbered:
1658
-
1659
- preamble
1660
-
1661
- == Section One
1662
-
1663
- |===
1664
- a|content
1665
- |===
1666
-
1667
- == Section Two
1668
-
1669
- content
1670
- EOS
1671
-
1672
- output = convert_string input
1673
- assert_xpath '//h2[@id="_section_one"]', output, 1
1674
- assert_xpath '//h2[@id="_section_one"][text()="1. Section One"]', output, 1
1675
- assert_xpath '//h2[@id="_section_two"]', output, 1
1676
- assert_xpath '//h2[@id="_section_two"][text()="2. Section Two"]', output, 1
1677
- end
1678
-
1679
- test 'should not number parts when doctype is book' do
1680
- input = <<-EOS
1681
- = Document Title
1682
- :doctype: book
1683
- :numbered:
1684
-
1685
- = Part 1
1686
-
1687
- == Chapter 1
1688
-
1689
- content
1690
-
1691
- = Part 2
1692
-
1693
- == Chapter 2
1694
-
1695
- content
1696
- EOS
1697
-
1698
- output = convert_string input
1699
- assert_xpath '(//h1)[1][text()="Document Title"]', output, 1
1700
- assert_xpath '(//h1)[2][text()="Part 1"]', output, 1
1701
- assert_xpath '(//h1)[3][text()="Part 2"]', output, 1
1702
- assert_xpath '(//h2)[1][text()="1. Chapter 1"]', output, 1
1703
- assert_xpath '(//h2)[2][text()="2. Chapter 2"]', output, 1
1704
- end
1705
-
1706
- test 'should number chapters sequentially even when divided into parts' do
1707
- input = <<-EOS
1708
- = Document Title
1709
- :doctype: book
1710
- :numbered:
1711
-
1712
- == Chapter 1
1713
-
1714
- content
1715
-
1716
- = Part 1
1717
-
1718
- == Chapter 2
1719
-
1720
- content
1721
-
1722
- = Part 2
1723
-
1724
- == Chapter 3
1725
-
1726
- content
1727
-
1728
- == Chapter 4
1729
-
1730
- content
1731
- EOS
1732
-
1733
- result = convert_string input
1734
- (1..4).each do |num|
1735
- assert_xpath %(//h2[@id="_chapter_#{num}"]), result, 1
1736
- assert_xpath %(//h2[@id="_chapter_#{num}"][text()="#{num}. Chapter #{num}"]), result, 1
1737
- end
1738
- end
1739
-
1740
- test 'reindex_sections should correct section enumeration after sections are modified' do
1741
- input = <<-EOS
1742
- :sectnums:
1743
-
1744
- == First Section
1745
-
1746
- content
1747
-
1748
- == Last Section
1749
-
1750
- content
1751
- EOS
1752
-
1753
- doc = document_from_string input
1754
- second_section = Asciidoctor::Section.new doc, nil, true
1755
- doc.blocks.insert 1, second_section
1756
- doc.reindex_sections
1757
- sections = doc.sections
1758
- [0, 1, 2].each do |index|
1759
- assert_equal index, sections[index].index
1760
- assert_equal index + 1, sections[index].numeral
1761
- assert_equal index + 1, sections[index].number
1762
- end
1763
- end
1764
-
1765
- test 'should allow sections to be renumbered using deprecated number property' do
1766
- input = <<-EOS
1767
- == Somewhere in the Middle
1768
-
1769
- == The End
1770
- EOS
1771
-
1772
- doc = document_from_string input, :attributes => { 'sectnums' => '' }
1773
- doc.sections.each do |sect|
1774
- sect.number += 1
1775
- end
1776
-
1777
- output = doc.convert :header_footer => false
1778
- assert_xpath '//h2[text()="2. Somewhere in the Middle"]', output, 1
1779
- assert_xpath '//h2[text()="3. The End"]', output, 1
1780
- end
1781
- end
1782
-
1783
- context 'Links and anchors' do
1784
- test 'should include anchor if sectanchors document attribute is set' do
1785
- input = <<-EOS
1786
- == Installation
1787
-
1788
- Installation section.
1789
-
1790
- === Linux
1791
-
1792
- Linux installation instructions.
1793
- EOS
1794
-
1795
- output = convert_string_to_embedded input, :attributes => {'sectanchors' => ''}
1796
- assert_xpath '/*[@class="sect1"]/h2[@id="_installation"]/a', output, 1
1797
- assert_xpath '/*[@class="sect1"]/h2[@id="_installation"]/a[@class="anchor"][@href="#_installation"]', output, 1
1798
- assert_xpath '/*[@class="sect1"]/h2[@id="_installation"]/a/following-sibling::text()="Installation"', output, true
1799
- assert_xpath '//*[@class="sect2"]/h3[@id="_linux"]/a', output, 1
1800
- assert_xpath '//*[@class="sect2"]/h3[@id="_linux"]/a[@class="anchor"][@href="#_linux"]', output, 1
1801
- assert_xpath '//*[@class="sect2"]/h3[@id="_linux"]/a/following-sibling::text()="Linux"', output, true
1802
- end
1803
-
1804
- test 'should position after title text if sectanchors is set to after' do
1805
- input = <<-EOS
1806
- == Installation
1807
-
1808
- Installation section.
1809
-
1810
- === Linux
1811
-
1812
- Linux installation instructions.
1813
- EOS
1814
-
1815
- output = convert_string_to_embedded input, :attributes => {'sectanchors' => 'after'}
1816
- assert_xpath '/*[@class="sect1"]/h2[@id="_installation"]/a', output, 1
1817
- assert_xpath '/*[@class="sect1"]/h2[@id="_installation"]/a[@class="anchor"][@href="#_installation"]', output, 1
1818
- assert_xpath '/*[@class="sect1"]/h2[@id="_installation"]/a/preceding-sibling::text()="Installation"', output, true
1819
- assert_xpath '//*[@class="sect2"]/h3[@id="_linux"]/a', output, 1
1820
- assert_xpath '//*[@class="sect2"]/h3[@id="_linux"]/a[@class="anchor"][@href="#_linux"]', output, 1
1821
- assert_xpath '//*[@class="sect2"]/h3[@id="_linux"]/a/preceding-sibling::text()="Linux"', output, true
1822
- end
1823
-
1824
- test 'should link section if sectlinks document attribute is set' do
1825
- input = <<-EOS
1826
- == Installation
1827
-
1828
- Installation section.
1829
-
1830
- === Linux
1831
-
1832
- Linux installation instructions.
1833
- EOS
1834
-
1835
- output = convert_string_to_embedded input, :attributes => {'sectlinks' => ''}
1836
- assert_xpath '/*[@class="sect1"]/h2[@id="_installation"]/a', output, 1
1837
- assert_xpath '/*[@class="sect1"]/h2[@id="_installation"]/a[@class="link"][@href="#_installation"]', output, 1
1838
- assert_xpath '/*[@class="sect1"]/h2[@id="_installation"]/a[text()="Installation"]', output, 1
1839
- assert_xpath '//*[@class="sect2"]/h3[@id="_linux"]/a', output, 1
1840
- assert_xpath '//*[@class="sect2"]/h3[@id="_linux"]/a[@class="link"][@href="#_linux"]', output, 1
1841
- assert_xpath '//*[@class="sect2"]/h3[@id="_linux"]/a[text()="Linux"]', output, 1
1842
- end
1843
- end
1844
-
1845
- context 'Special sections' do
1846
- test 'should assign sectname, caption, and numeral to appendix section by default' do
1847
- input = <<-EOS
1848
- [appendix]
1849
- == Attribute Options
1850
-
1851
- Details
1852
- EOS
1853
-
1854
- appendix = block_from_string input
1855
- assert_equal 'appendix', appendix.sectname
1856
- assert_equal 'Appendix A: ', appendix.caption
1857
- assert_equal 'A', appendix.numeral
1858
- assert_equal 'A', appendix.number
1859
- assert_equal true, appendix.numbered
1860
- end
1861
-
1862
- test 'should prefix appendix title by numbered label even when section numbering is disabled' do
1863
- input = <<-EOS
1864
- [appendix]
1865
- == Attribute Options
1866
-
1867
- Details
1868
- EOS
1869
-
1870
- output = convert_string_to_embedded input
1871
- assert_xpath '//h2[text()="Appendix A: Attribute Options"]', output, 1
1872
- end
1873
-
1874
- test 'should use style from last block attribute line above section that defines a style' do
1875
- input = <<-EOS
1876
- [glossary]
1877
- [appendix]
1878
- == Attribute Options
1879
-
1880
- Details
1881
- EOS
1882
-
1883
- output = convert_string_to_embedded input
1884
- assert_xpath '//h2[text()="Appendix A: Attribute Options"]', output, 1
1885
- end
1886
-
1887
- test 'setting ID using style shorthand should not clear section style' do
1888
- input = <<-EOS
1889
- [appendix]
1890
- [#attribute-options]
1891
- == Attribute Options
1892
-
1893
- Details
1894
- EOS
1895
-
1896
- output = convert_string_to_embedded input
1897
- assert_xpath '//h2[@id="attribute-options"][text()="Appendix A: Attribute Options"]', output, 1
1898
- end
1899
-
1900
- test 'should use custom appendix caption if specified' do
1901
- input = <<-EOS
1902
- :appendix-caption: App
1903
-
1904
- [appendix]
1905
- == Attribute Options
1906
-
1907
- Details
1908
- EOS
1909
-
1910
- output = convert_string_to_embedded input
1911
- assert_xpath '//h2[text()="App A: Attribute Options"]', output, 1
1912
- end
1913
-
1914
- test 'should only assign letter to appendix when numbered is enabled and appendix caption is not set' do
1915
- input = <<-EOS
1916
- :numbered:
1917
- :!appendix-caption:
1918
-
1919
- [appendix]
1920
- == Attribute Options
1921
-
1922
- Details
1923
- EOS
1924
-
1925
- output = convert_string_to_embedded input
1926
- assert_xpath '//h2[text()="A. Attribute Options"]', output, 1
1927
- end
1928
-
1929
- test 'should increment appendix number for each appendix section' do
1930
- input = <<-EOS
1931
- [appendix]
1932
- == Attribute Options
1933
-
1934
- Details
1935
-
1936
- [appendix]
1937
- == Migration
1938
-
1939
- Details
1940
- EOS
1941
-
1942
- output = convert_string_to_embedded input
1943
- assert_xpath '(//h2)[1][text()="Appendix A: Attribute Options"]', output, 1
1944
- assert_xpath '(//h2)[2][text()="Appendix B: Migration"]', output, 1
1945
- end
1946
-
1947
- test 'should continue numbering after appendix' do
1948
- input = <<-EOS
1949
- :numbered:
1950
-
1951
- == First Section
1952
-
1953
- content
1954
-
1955
- [appendix]
1956
- == Attribute Options
1957
-
1958
- content
1959
-
1960
- == Migration
1961
-
1962
- content
1963
- EOS
1964
-
1965
- output = convert_string_to_embedded input
1966
- assert_xpath '(//h2)[1][text()="1. First Section"]', output, 1
1967
- assert_xpath '(//h2)[2][text()="Appendix A: Attribute Options"]', output, 1
1968
- assert_xpath '(//h2)[3][text()="2. Migration"]', output, 1
1969
- end
1970
-
1971
- test 'should number appendix subsections using appendix letter' do
1972
- input = <<-EOS
1973
- :numbered:
1974
-
1975
- [appendix]
1976
- == Attribute Options
1977
-
1978
- Details
1979
-
1980
- === Optional Attributes
1981
-
1982
- Details
1983
- EOS
1984
-
1985
- output = convert_string_to_embedded input
1986
- assert_xpath '(//h2)[1][text()="Appendix A: Attribute Options"]', output, 1
1987
- assert_xpath '(//h3)[1][text()="A.1. Optional Attributes"]', output, 1
1988
- end
1989
-
1990
- test 'should not number level 4 section by default' do
1991
- input = <<-EOS
1992
- :numbered:
1993
-
1994
- == Level_1
1995
-
1996
- === Level_2
1997
-
1998
- ==== Level_3
1999
-
2000
- ===== Level_4
2001
-
2002
- text
2003
- EOS
2004
- output = convert_string_to_embedded input
2005
- assert_xpath '//h5', output, 1
2006
- assert_xpath '//h5[text()="Level_4"]', output, 1
2007
- end
2008
-
2009
- test 'should only number levels up to value defined by sectnumlevels attribute' do
2010
- input = <<-EOS
2011
- :numbered:
2012
- :sectnumlevels: 2
2013
-
2014
- == Level_1
2015
-
2016
- === Level_2
2017
-
2018
- ==== Level_3
2019
-
2020
- ===== Level_4
2021
-
2022
- text
2023
- EOS
2024
- output = convert_string_to_embedded input
2025
- assert_xpath '//h2', output, 1
2026
- assert_xpath '//h2[text()="1. Level_1"]', output, 1
2027
- assert_xpath '//h3', output, 1
2028
- assert_xpath '//h3[text()="1.1. Level_2"]', output, 1
2029
- assert_xpath '//h4', output, 1
2030
- assert_xpath '//h4[text()="Level_3"]', output, 1
2031
- assert_xpath '//h5', output, 1
2032
- assert_xpath '//h5[text()="Level_4"]', output, 1
2033
- end
2034
-
2035
- test 'should not number sections or subsections in regions where numbered is off' do
2036
- input = <<-EOS
2037
- :numbered:
2038
-
2039
- == Section One
2040
-
2041
- :numbered!:
2042
-
2043
- [appendix]
2044
- == Attribute Options
2045
-
2046
- Details
2047
-
2048
- [appendix]
2049
- == Migration
2050
-
2051
- Details
2052
-
2053
- === Gotchas
2054
-
2055
- Details
2056
-
2057
- [glossary]
2058
- == Glossary
2059
-
2060
- Terms
2061
- EOS
2062
-
2063
- output = convert_string_to_embedded input
2064
- assert_xpath '(//h2)[1][text()="1. Section One"]', output, 1
2065
- assert_xpath '(//h2)[2][text()="Appendix A: Attribute Options"]', output, 1
2066
- assert_xpath '(//h2)[3][text()="Appendix B: Migration"]', output, 1
2067
- assert_xpath '(//h3)[1][text()="Gotchas"]', output, 1
2068
- assert_xpath '(//h2)[4][text()="Glossary"]', output, 1
2069
- end
2070
-
2071
- test 'should not number sections or subsections in toc in regions where numbered is off' do
2072
- input = <<-EOS
2073
- :numbered:
2074
- :toc:
2075
-
2076
- == Section One
2077
-
2078
- :numbered!:
2079
-
2080
- [appendix]
2081
- == Attribute Options
2082
-
2083
- Details
2084
-
2085
- [appendix]
2086
- == Migration
2087
-
2088
- Details
2089
-
2090
- === Gotchas
2091
-
2092
- Details
2093
-
2094
- [glossary]
2095
- == Glossary
2096
-
2097
- Terms
2098
- EOS
2099
-
2100
- output = convert_string input
2101
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="1. Section One"]', output, 1
2102
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Appendix A: Attribute Options"]', output, 1
2103
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Appendix B: Migration"]', output, 1
2104
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Gotchas"]', output, 1
2105
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Glossary"]', output, 1
2106
- end
2107
-
2108
- test 'should only number sections in toc up to value defined by sectnumlevels attribute' do
2109
- input = <<-EOS
2110
- :numbered:
2111
- :toc:
2112
- :sectnumlevels: 2
2113
- :toclevels: 3
2114
-
2115
- == Level 1
2116
-
2117
- === Level 2
2118
-
2119
- ==== Level 3
2120
- EOS
2121
-
2122
- output = convert_string input
2123
- assert_xpath '//*[@id="toc"]//a[@href="#_level_1"][text()="1. Level 1"]', output, 1
2124
- assert_xpath '//*[@id="toc"]//a[@href="#_level_2"][text()="1.1. Level 2"]', output, 1
2125
- assert_xpath '//*[@id="toc"]//a[@href="#_level_3"][text()="Level 3"]', output, 1
2126
- end
2127
-
2128
- test 'should not number special sections or their subsections by default except for appendices' do
2129
- input = <<-EOS
2130
- :doctype: book
2131
- :sectnums:
2132
-
2133
- [preface]
2134
- == Preface
2135
-
2136
- === Preface Subsection
2137
-
2138
- content
2139
-
2140
- == Section One
2141
-
2142
- content
2143
-
2144
- [appendix]
2145
- == Attribute Options
2146
-
2147
- Details
2148
-
2149
- [appendix]
2150
- == Migration
2151
-
2152
- Details
2153
-
2154
- === Gotchas
2155
-
2156
- Details
2157
-
2158
- [glossary]
2159
- == Glossary
2160
-
2161
- Terms
2162
- EOS
2163
-
2164
- output = convert_string_to_embedded input
2165
- assert_xpath '(//h2)[1][text()="Preface"]', output, 1
2166
- assert_xpath '(//h3)[1][text()="Preface Subsection"]', output, 1
2167
- assert_xpath '(//h2)[2][text()="1. Section One"]', output, 1
2168
- assert_xpath '(//h2)[3][text()="Appendix A: Attribute Options"]', output, 1
2169
- assert_xpath '(//h2)[4][text()="Appendix B: Migration"]', output, 1
2170
- assert_xpath '(//h3)[2][text()="B.1. Gotchas"]', output, 1
2171
- assert_xpath '(//h2)[5][text()="Glossary"]', output, 1
2172
- end
2173
-
2174
- test 'should not number special sections or their subsections in toc by default except for appendices' do
2175
- input = <<-EOS
2176
- :doctype: book
2177
- :sectnums:
2178
- :toc:
2179
-
2180
- [preface]
2181
- == Preface
2182
-
2183
- === Preface Subsection
2184
-
2185
- content
2186
-
2187
- == Section One
2188
-
2189
- content
2190
-
2191
- [appendix]
2192
- == Attribute Options
2193
-
2194
- Details
2195
-
2196
- [appendix]
2197
- == Migration
2198
-
2199
- Details
2200
-
2201
- === Gotchas
2202
-
2203
- Details
2204
-
2205
- [glossary]
2206
- == Glossary
2207
-
2208
- Terms
2209
- EOS
2210
-
2211
- output = convert_string input
2212
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Preface"]', output, 1
2213
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Preface Subsection"]', output, 1
2214
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="1. Section One"]', output, 1
2215
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Appendix A: Attribute Options"]', output, 1
2216
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Appendix B: Migration"]', output, 1
2217
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="B.1. Gotchas"]', output, 1
2218
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Glossary"]', output, 1
2219
- end
2220
-
2221
- test 'should number special sections and their subsections when sectnums is all' do
2222
- input = <<-EOS
2223
- :doctype: book
2224
- :sectnums: all
2225
-
2226
- [preface]
2227
- == Preface
2228
-
2229
- === Preface Subsection
2230
-
2231
- content
2232
-
2233
- == Section One
2234
-
2235
- content
2236
-
2237
- [appendix]
2238
- == Attribute Options
2239
-
2240
- Details
2241
-
2242
- [appendix]
2243
- == Migration
2244
-
2245
- Details
2246
-
2247
- === Gotchas
2248
-
2249
- Details
2250
-
2251
- [glossary]
2252
- == Glossary
2253
-
2254
- Terms
2255
- EOS
2256
-
2257
- output = convert_string_to_embedded input
2258
- assert_xpath '(//h2)[1][text()="1. Preface"]', output, 1
2259
- assert_xpath '(//h3)[1][text()="1.1. Preface Subsection"]', output, 1
2260
- assert_xpath '(//h2)[2][text()="2. Section One"]', output, 1
2261
- assert_xpath '(//h2)[3][text()="Appendix A: Attribute Options"]', output, 1
2262
- assert_xpath '(//h2)[4][text()="Appendix B: Migration"]', output, 1
2263
- assert_xpath '(//h3)[2][text()="B.1. Gotchas"]', output, 1
2264
- assert_xpath '(//h2)[5][text()="3. Glossary"]', output, 1
2265
- end
2266
-
2267
- test 'should number special sections and their subsections in toc when sectnums is all' do
2268
- input = <<-EOS
2269
- :doctype: book
2270
- :sectnums: all
2271
- :toc:
2272
-
2273
- [preface]
2274
- == Preface
2275
-
2276
- === Preface Subsection
2277
-
2278
- content
2279
-
2280
- == Section One
2281
-
2282
- content
2283
-
2284
- [appendix]
2285
- == Attribute Options
2286
-
2287
- Details
2288
-
2289
- [appendix]
2290
- == Migration
2291
-
2292
- Details
2293
-
2294
- === Gotchas
2295
-
2296
- Details
2297
-
2298
- [glossary]
2299
- == Glossary
2300
-
2301
- Terms
2302
- EOS
2303
-
2304
- output = convert_string input
2305
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="1. Preface"]', output, 1
2306
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="1.1. Preface Subsection"]', output, 1
2307
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="2. Section One"]', output, 1
2308
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Appendix A: Attribute Options"]', output, 1
2309
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="Appendix B: Migration"]', output, 1
2310
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="B.1. Gotchas"]', output, 1
2311
- assert_xpath '//*[@id="toc"]/ul//li/a[text()="3. Glossary"]', output, 1
2312
- end
2313
-
2314
- test 'level 0 special sections in multipart book should be coerced to level 1' do
2315
- input = <<-EOS
2316
- = Multipart Book
2317
- Doc Writer
2318
- :doctype: book
2319
-
2320
- [preface]
2321
- = Preface
2322
-
2323
- Preface text
2324
-
2325
- [appendix]
2326
- = Appendix
2327
-
2328
- Appendix text
2329
- EOS
2330
-
2331
- output = convert_string input
2332
- assert_xpath '//h2[@id = "_preface"]', output, 1
2333
- assert_xpath '//h2[@id = "_appendix"]', output, 1
2334
- end
2335
-
2336
- test 'should output docbook elements that correspond to special sections in book doctype' do
2337
- input = <<-EOS
2338
- = Multipart Book
2339
- :doctype: book
2340
- :idprefix:
2341
-
2342
- [abstract]
2343
- = Abstract Title
2344
-
2345
- Normal chapter (no abstract in book)
2346
-
2347
- [dedication]
2348
- = Dedication Title
2349
-
2350
- Dedication content
2351
-
2352
- [preface]
2353
- = Preface Title
2354
-
2355
- Preface content
2356
-
2357
- === Preface sub-section
2358
-
2359
- Preface subsection content
2360
-
2361
- = Part 1
2362
-
2363
- [partintro]
2364
- .Part intro title
2365
- Part intro content
2366
-
2367
- == Chapter 1
2368
-
2369
- blah blah
2370
-
2371
- == Chapter 2
2372
-
2373
- blah blah
2374
-
2375
- = Part 2
2376
-
2377
- [partintro]
2378
- blah blah
2379
-
2380
- == Chapter 3
2381
-
2382
- blah blah
2383
-
2384
- == Chapter 4
2385
-
2386
- blah blah
2387
-
2388
- [appendix]
2389
- = Appendix Title
2390
-
2391
- Appendix content
2392
-
2393
- === Appendix sub-section
2394
-
2395
- Appendix sub-section content
2396
-
2397
- [bibliography]
2398
- = Bibliography Title
2399
-
2400
- Bibliography content
2401
-
2402
- [glossary]
2403
- = Glossary Title
2404
-
2405
- Glossary content
2406
-
2407
- [colophon]
2408
- = Colophon Title
2409
-
2410
- Colophon content
2411
-
2412
- [index]
2413
- = Index Title
2414
- EOS
2415
-
2416
- output = convert_string_to_embedded input, :backend => 'docbook45'
2417
- assert_xpath '/chapter[@id="abstract_title"]', output, 1
2418
- assert_xpath '/chapter[@id="abstract_title"]/title[text()="Abstract Title"]', output, 1
2419
- assert_xpath '/chapter/following-sibling::dedication[@id="dedication_title"]', output, 1
2420
- assert_xpath '/chapter/following-sibling::dedication[@id="dedication_title"]/title[text()="Dedication Title"]', output, 1
2421
- assert_xpath '/dedication/following-sibling::preface[@id="preface_title"]', output, 1
2422
- assert_xpath '/dedication/following-sibling::preface[@id="preface_title"]/title[text()="Preface Title"]', output, 1
2423
- assert_xpath '/preface/section[@id="preface_sub_section"]', output, 1
2424
- assert_xpath '/preface/section[@id="preface_sub_section"]/title[text()="Preface sub-section"]', output, 1
2425
- assert_xpath '/preface/following-sibling::part[@id="part_1"]', output, 1
2426
- assert_xpath '/preface/following-sibling::part[@id="part_1"]/title[text()="Part 1"]', output, 1
2427
- assert_xpath '/part[@id="part_1"]/partintro', output, 1
2428
- assert_xpath '/part[@id="part_1"]/partintro/title[text()="Part intro title"]', output, 1
2429
- assert_xpath '/part[@id="part_1"]/partintro/following-sibling::chapter[@id="chapter_1"]', output, 1
2430
- assert_xpath '/part[@id="part_1"]/partintro/following-sibling::chapter[@id="chapter_1"]/title[text()="Chapter 1"]', output, 1
2431
- assert_xpath '(/part)[2]/following-sibling::appendix[@id="appendix_title"]', output, 1
2432
- assert_xpath '(/part)[2]/following-sibling::appendix[@id="appendix_title"]/title[text()="Appendix Title"]', output, 1
2433
- assert_xpath '/appendix/section[@id="appendix_sub_section"]', output, 1
2434
- assert_xpath '/appendix/section[@id="appendix_sub_section"]/title[text()="Appendix sub-section"]', output, 1
2435
- assert_xpath '/appendix/following-sibling::bibliography[@id="bibliography_title"]', output, 1
2436
- assert_xpath '/appendix/following-sibling::bibliography[@id="bibliography_title"]/title[text()="Bibliography Title"]', output, 1
2437
- assert_xpath '/bibliography/following-sibling::glossary[@id="glossary_title"]', output, 1
2438
- assert_xpath '/bibliography/following-sibling::glossary[@id="glossary_title"]/title[text()="Glossary Title"]', output, 1
2439
- assert_xpath '/glossary/following-sibling::colophon[@id="colophon_title"]', output, 1
2440
- assert_xpath '/glossary/following-sibling::colophon[@id="colophon_title"]/title[text()="Colophon Title"]', output, 1
2441
- assert_xpath '/colophon/following-sibling::index[@id="index_title"]', output, 1
2442
- assert_xpath '/colophon/following-sibling::index[@id="index_title"]/title[text()="Index Title"]', output, 1
2443
- end
2444
-
2445
- test 'abstract section maps to abstract element in docbook for article doctype' do
2446
- input = <<-EOS
2447
- = Article
2448
- :idprefix:
2449
-
2450
- [abstract]
2451
- == Abstract Title
2452
-
2453
- Abstract content
2454
- EOS
2455
-
2456
- output = convert_string_to_embedded input, :backend => 'docbook45'
2457
- assert_xpath '/abstract[@id="abstract_title"]', output, 1
2458
- assert_xpath '/abstract[@id="abstract_title"]/title[text()="Abstract Title"]', output, 1
2459
- end
2460
-
2461
- test 'should allow a special section to be nested at arbitrary depth in DocBook output' do
2462
- input = <<-EOS
2463
- = Document Title
2464
- :doctype: book
2465
-
2466
- == Glossaries
2467
-
2468
- [glossary]
2469
- === Glossary A
2470
-
2471
- Glossaries are optional.
2472
- Glossaries entries are an example of a style of AsciiDoc description lists.
2473
-
2474
- [glossary]
2475
- A glossary term::
2476
- The corresponding definition.
2477
-
2478
- A second glossary term::
2479
- The corresponding definition.
2480
- EOS
2481
-
2482
- output = convert_string input, :backend => :docbook
2483
- assert_xpath '//glossary', output, 1
2484
- assert_xpath '//chapter/glossary', output, 1
2485
- assert_xpath '//glossary/title[text()="Glossary A"]', output, 1
2486
- assert_xpath '//glossary/glossentry', output, 2
2487
- end
2488
-
2489
- test 'should drop title on special section in DocBook output if untitled option is set' do
2490
- input = <<-EOS
2491
- [dedication%untitled]
2492
- == Dedication
2493
-
2494
- content
2495
- EOS
2496
-
2497
- output = convert_string_to_embedded input, :backend => :docbook
2498
- assert_xpath '/dedication', output, 1
2499
- assert_xpath '/dedication/title', output, 0
2500
- end
2501
- end
2502
-
2503
- context "heading patterns in blocks" do
2504
- test "should not interpret a listing block as a heading" do
2505
- input = <<-EOS
2506
- Section
2507
- -------
2508
-
2509
- ----
2510
- code
2511
- ----
2512
-
2513
- fin.
2514
- EOS
2515
- output = convert_string input
2516
- assert_xpath "//h2", output, 1
2517
- end
2518
-
2519
- test "should not interpret an open block as a heading" do
2520
- input = <<-EOS
2521
- Section
2522
- -------
2523
-
2524
- --
2525
- ha
2526
- --
2527
-
2528
- fin.
2529
- EOS
2530
- output = convert_string input
2531
- assert_xpath "//h2", output, 1
2532
- end
2533
-
2534
- test "should not interpret an attribute list as a heading" do
2535
- input = <<-EOS
2536
- Section
2537
- =======
2538
-
2539
- preamble
2540
-
2541
- [TIP]
2542
- ====
2543
- This should be a tip, not a heading.
2544
- ====
2545
- EOS
2546
- output = convert_string input
2547
- assert_xpath "//*[@class='admonitionblock tip']//p[text() = 'This should be a tip, not a heading.']", output, 1
2548
- end
2549
-
2550
- test "should not match a heading in a description list" do
2551
- input = <<-EOS
2552
- Section
2553
- -------
2554
-
2555
- term1::
2556
- +
2557
- ----
2558
- list = [1, 2, 3];
2559
- ----
2560
- term2::
2561
- == not a heading
2562
- term3:: def
2563
-
2564
- //
2565
-
2566
- fin.
2567
- EOS
2568
- output = convert_string input
2569
- assert_xpath "//h2", output, 1
2570
- assert_xpath "//dl", output, 1
2571
- end
2572
-
2573
- test "should not match a heading in a bulleted list" do
2574
- input = <<-EOS
2575
- Section
2576
- -------
2577
-
2578
- * first
2579
- +
2580
- ----
2581
- list = [1, 2, 3];
2582
- ----
2583
- +
2584
- * second
2585
- == not a heading
2586
- * third
2587
-
2588
- fin.
2589
- EOS
2590
- output = convert_string input
2591
- assert_xpath "//h2", output, 1
2592
- assert_xpath "//ul", output, 1
2593
- end
2594
-
2595
- test "should not match a heading in a block" do
2596
- input = <<-EOS
2597
- ====
2598
-
2599
- == not a heading
2600
-
2601
- ====
2602
- EOS
2603
- output = convert_string input
2604
- assert_xpath "//h2", output, 0
2605
- assert_xpath "//*[@class='exampleblock']//p[text() = '== not a heading']", output, 1
2606
- end
2607
- end
2608
-
2609
- context 'Table of Contents' do
2610
- test 'should output unnumbered table of contents in header if toc attribute is set' do
2611
- input = <<-EOS
2612
- = Article
2613
- :toc:
2614
-
2615
- == Section One
2616
-
2617
- It was a dark and stormy night...
2618
-
2619
- == Section Two
2620
-
2621
- They couldn't believe their eyes when...
2622
-
2623
- === Interlude
2624
-
2625
- While they were waiting...
2626
-
2627
- == Section Three
2628
-
2629
- That's all she wrote!
2630
- EOS
2631
- output = convert_string input
2632
- assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc"]', output, 1
2633
- assert_xpath '//*[@id="header"]//*[@id="toc"]/*[@id="toctitle"][text()="Table of Contents"]', output, 1
2634
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul', output, 1
2635
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul[@class="sectlevel1"]', output, 1
2636
- assert_xpath '//*[@id="header"]//*[@id="toc"]//ul', output, 2
2637
- assert_xpath '//*[@id="header"]//*[@id="toc"]//li', output, 4
2638
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="Section One"]', output, 1
2639
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul', output, 1
2640
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul[@class="sectlevel2"]', output, 1
2641
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li', output, 1
2642
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li/a[@href="#_interlude"][text()="Interlude"]', output, 1
2643
- assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[3]/a[@href="#_section_three"][text()="Section Three"]', output, 1
2644
- end
2645
-
2646
- test 'should output numbered table of contents in header if toc and numbered attributes are set' do
2647
- input = <<-EOS
2648
- = Article
2649
- :toc:
2650
- :numbered:
2651
-
2652
- == Section One
2653
-
2654
- It was a dark and stormy night...
2655
-
2656
- == Section Two
2657
-
2658
- They couldn't believe their eyes when...
2659
-
2660
- === Interlude
2661
-
2662
- While they were waiting...
2663
-
2664
- == Section Three
2665
-
2666
- That's all she wrote!
2667
- EOS
2668
- output = convert_string input
2669
- assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc"]', output, 1
2670
- assert_xpath '//*[@id="header"]//*[@id="toc"]/*[@id="toctitle"][text()="Table of Contents"]', output, 1
2671
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul', output, 1
2672
- assert_xpath '//*[@id="header"]//*[@id="toc"]//ul', output, 2
2673
- assert_xpath '//*[@id="header"]//*[@id="toc"]//li', output, 4
2674
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
2675
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li', output, 1
2676
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li/a[@href="#_interlude"][text()="2.1. Interlude"]', output, 1
2677
- assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[3]/a[@href="#_section_three"][text()="3. Section Three"]', output, 1
2678
- end
2679
-
2680
- test 'should output a table of contents that honors numbered setting at position of section in document' do
2681
- input = <<-EOS
2682
- = Article
2683
- :toc:
2684
- :numbered:
2685
-
2686
- == Section One
2687
-
2688
- It was a dark and stormy night...
2689
-
2690
- == Section Two
2691
-
2692
- They couldn't believe their eyes when...
2693
-
2694
- === Interlude
2695
-
2696
- While they were waiting...
2697
-
2698
- :numbered!:
2699
-
2700
- == Section Three
2701
-
2702
- That's all she wrote!
2703
- EOS
2704
- output = convert_string input
2705
- assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc"]', output, 1
2706
- assert_xpath '//*[@id="header"]//*[@id="toc"]/*[@id="toctitle"][text()="Table of Contents"]', output, 1
2707
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul', output, 1
2708
- assert_xpath '//*[@id="header"]//*[@id="toc"]//ul', output, 2
2709
- assert_xpath '//*[@id="header"]//*[@id="toc"]//li', output, 4
2710
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
2711
- assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[3]/a[@href="#_section_three"][text()="Section Three"]', output, 1
2712
- end
2713
-
2714
- test 'should not number parts in table of contents for book doctype when numbered attribute is set' do
2715
- input = <<-EOS
2716
- = Book
2717
- :doctype: book
2718
- :toc:
2719
- :numbered:
2720
-
2721
- = Part 1
2722
-
2723
- == First Section of Part 1
2724
-
2725
- blah
2726
-
2727
- == Second Section of Part 1
2728
-
2729
- blah
2730
-
2731
- = Part 2
2732
-
2733
- == First Section of Part 2
2734
-
2735
- blah
2736
- EOS
2737
-
2738
- output = convert_string input
2739
- assert_xpath '//*[@id="toc"]', output, 1
2740
- assert_xpath '//*[@id="toc"]/ul', output, 1
2741
- assert_xpath '//*[@id="toc"]/ul[@class="sectlevel0"]', output, 1
2742
- assert_xpath '//*[@id="toc"]/ul[@class="sectlevel0"]/li', output, 2
2743
- assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[1]/a[text()="Part 1"]', output, 1
2744
- assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[2]/a[text()="Part 2"]', output, 1
2745
- assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[1]/ul', output, 1
2746
- assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[1]/ul[@class="sectlevel1"]', output, 1
2747
- assert_xpath '(//*[@id="toc"]/ul[@class="sectlevel0"]/li)[1]/ul/li', output, 2
2748
- assert_xpath '((//*[@id="toc"]/ul[@class="sectlevel0"]/li)[1]/ul/li)[1]/a[text()="1. First Section of Part 1"]', output, 1
2749
- end
2750
-
2751
- test 'should output table of contents in header if toc2 attribute is set' do
2752
- input = <<-EOS
2753
- = Article
2754
- :toc2:
2755
- :numbered:
2756
-
2757
- == Section One
2758
-
2759
- It was a dark and stormy night...
2760
-
2761
- == Section Two
2762
-
2763
- They couldn't believe their eyes when...
2764
- EOS
2765
-
2766
- output = convert_string input
2767
- assert_xpath '//body[@class="article toc2 toc-left"]', output, 1
2768
- assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc2"]', output, 1
2769
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
2770
- end
2771
-
2772
- test 'should set toc position if toc attribute is set to position' do
2773
- input = <<-EOS
2774
- = Article
2775
- :toc: >
2776
- :numbered:
2777
-
2778
- == Section One
2779
-
2780
- It was a dark and stormy night...
2781
-
2782
- == Section Two
2783
-
2784
- They couldn't believe their eyes when...
2785
- EOS
2786
-
2787
- output = convert_string input
2788
- assert_xpath '//body[@class="article toc2 toc-right"]', output, 1
2789
- assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc2"]', output, 1
2790
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
2791
- end
2792
-
2793
- test 'should set toc position if toc and toc-position attributes are set' do
2794
- input = <<-EOS
2795
- = Article
2796
- :toc:
2797
- :toc-position: right
2798
- :numbered:
2799
-
2800
- == Section One
2801
-
2802
- It was a dark and stormy night...
2803
-
2804
- == Section Two
2805
-
2806
- They couldn't believe their eyes when...
2807
- EOS
2808
-
2809
- output = convert_string input
2810
- assert_xpath '//body[@class="article toc2 toc-right"]', output, 1
2811
- assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc2"]', output, 1
2812
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
2813
- end
2814
-
2815
- test 'should set toc position if toc2 and toc-position attribute are set' do
2816
- input = <<-EOS
2817
- = Article
2818
- :toc2:
2819
- :toc-position: right
2820
- :numbered:
2821
-
2822
- == Section One
2823
-
2824
- It was a dark and stormy night...
2825
-
2826
- == Section Two
2827
-
2828
- They couldn't believe their eyes when...
2829
- EOS
2830
-
2831
- output = convert_string input
2832
- assert_xpath '//body[@class="article toc2 toc-right"]', output, 1
2833
- assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc2"]', output, 1
2834
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
2835
- end
2836
-
2837
- test 'should set toc position if toc attribute is set to direction' do
2838
- input = <<-EOS
2839
- = Article
2840
- :toc: right
2841
- :numbered:
2842
-
2843
- == Section One
2844
-
2845
- It was a dark and stormy night...
2846
-
2847
- == Section Two
2848
-
2849
- They couldn't believe their eyes when...
2850
- EOS
2851
-
2852
- output = convert_string input
2853
- assert_xpath '//body[@class="article toc2 toc-right"]', output, 1
2854
- assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc2"]', output, 1
2855
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
2856
- end
2857
-
2858
- test 'should set toc placement to preamble if toc attribute is set to preamble' do
2859
- input = <<-EOS
2860
- = Article
2861
- :toc: preamble
2862
-
2863
- Yada yada
2864
-
2865
- == Section One
2866
-
2867
- It was a dark and stormy night...
2868
-
2869
- == Section Two
2870
-
2871
- They couldn't believe their eyes when...
2872
- EOS
2873
-
2874
- output = convert_string input
2875
- assert_css '#preamble #toc', output, 1
2876
- assert_css '#preamble .sectionbody + #toc', output, 1
2877
- end
2878
-
2879
- test 'should use document attributes toc-class, toc-title and toclevels to create toc' do
2880
- input = <<-EOS
2881
- = Article
2882
- :toc:
2883
- :toc-title: Contents
2884
- :toc-class: toc2
2885
- :toclevels: 1
2886
-
2887
- == Section 1
2888
-
2889
- === Section 1.1
2890
-
2891
- ==== Section 1.1.1
2892
-
2893
- ==== Section 1.1.2
2894
-
2895
- === Section 1.2
2896
-
2897
- == Section 2
2898
-
2899
- Fin.
2900
- EOS
2901
- output = convert_string input
2902
- assert_css '#header #toc', output, 1
2903
- assert_css '#header #toc.toc2', output, 1
2904
- assert_css '#header #toc li', output, 2
2905
- assert_css '#header #toc #toctitle', output, 1
2906
- assert_xpath '//*[@id="header"]//*[@id="toc"]/*[@id="toctitle"][text()="Contents"]', output, 1
2907
- end
2908
-
2909
- test 'should not output table of contents if toc-placement attribute is unset' do
2910
- input = <<-EOS
2911
- = Article
2912
- :toc:
2913
- :toc-placement!:
2914
-
2915
- == Section One
2916
-
2917
- It was a dark and stormy night...
2918
-
2919
- == Section Two
2920
-
2921
- They couldn't believe their eyes when...
2922
- EOS
2923
-
2924
- output = convert_string input
2925
- assert_xpath '//*[@id="toc"]', output, 0
2926
- end
2927
-
2928
- test 'should output table of contents at location of toc macro' do
2929
- input = <<-EOS
2930
- = Article
2931
- :toc:
2932
- :toc-placement: macro
2933
-
2934
- Once upon a time...
2935
-
2936
- toc::[]
2937
-
2938
- == Section One
2939
-
2940
- It was a dark and stormy night...
2941
-
2942
- == Section Two
2943
-
2944
- They couldn't believe their eyes when...
2945
- EOS
2946
-
2947
- output = convert_string input
2948
- assert_css '#preamble #toc', output, 1
2949
- assert_css '#preamble .paragraph + #toc', output, 1
2950
- end
2951
-
2952
- test 'should output table of contents at location of toc macro in embedded document' do
2953
- input = <<-EOS
2954
- = Article
2955
- :toc:
2956
- :toc-placement: macro
2957
-
2958
- Once upon a time...
2959
-
2960
- toc::[]
2961
-
2962
- == Section One
2963
-
2964
- It was a dark and stormy night...
2965
-
2966
- == Section Two
2967
-
2968
- They couldn't believe their eyes when...
2969
- EOS
2970
-
2971
- output = convert_string_to_embedded input
2972
- assert_css '#preamble:root #toc', output, 1
2973
- assert_css '#preamble:root .paragraph + #toc', output, 1
2974
- end
2975
-
2976
- test 'should output table of contents at default location in embedded document if toc attribute is set' do
2977
- input = <<-EOS
2978
- = Article
2979
- :showtitle:
2980
- :toc:
2981
-
2982
- Once upon a time...
2983
-
2984
- == Section One
2985
-
2986
- It was a dark and stormy night...
2987
-
2988
- == Section Two
2989
-
2990
- They couldn't believe their eyes when...
2991
- EOS
2992
-
2993
- output = convert_string_to_embedded input
2994
- assert_css 'h1:root', output, 1
2995
- assert_css 'h1:root + #toc:root', output, 1
2996
- assert_css 'h1:root + #toc:root + #preamble:root', output, 1
2997
- end
2998
-
2999
- test 'should not activate toc macro if toc-placement is not set' do
3000
- input = <<-EOS
3001
- = Article
3002
- :toc:
3003
-
3004
- Once upon a time...
3005
-
3006
- toc::[]
3007
-
3008
- == Section One
3009
-
3010
- It was a dark and stormy night...
3011
-
3012
- == Section Two
3013
-
3014
- They couldn't believe their eyes when...
3015
- EOS
3016
-
3017
- output = convert_string input
3018
-
3019
- assert_css '#toc', output, 1
3020
- assert_css '#toctitle', output, 1
3021
- assert_css '.toc', output, 1
3022
- assert_css '#content .toc', output, 0
3023
- end
3024
-
3025
- test 'should only output toc at toc macro if toc is macro' do
3026
- input = <<-EOS
3027
- = Article
3028
- :toc: macro
3029
-
3030
- Once upon a time...
3031
-
3032
- toc::[]
3033
-
3034
- == Section One
3035
-
3036
- It was a dark and stormy night...
3037
-
3038
- == Section Two
3039
-
3040
- They couldn't believe their eyes when...
3041
- EOS
3042
-
3043
- output = convert_string input
3044
-
3045
- assert_css '#toc', output, 1
3046
- assert_css '#toctitle', output, 1
3047
- assert_css '.toc', output, 1
3048
- assert_css '#content .toc', output, 1
3049
- end
3050
-
3051
- test 'should use global attributes for toc-title, toc-class and toclevels for toc macro' do
3052
- input = <<-EOS
3053
- = Article
3054
- :toc:
3055
- :toc-placement: macro
3056
- :toc-title: Contents
3057
- :toc-class: contents
3058
- :toclevels: 1
3059
-
3060
- Preamble.
3061
-
3062
- toc::[]
3063
-
3064
- == Section 1
3065
-
3066
- === Section 1.1
3067
-
3068
- ==== Section 1.1.1
3069
-
3070
- ==== Section 1.1.2
3071
-
3072
- === Section 1.2
3073
-
3074
- == Section 2
3075
-
3076
- Fin.
3077
- EOS
3078
-
3079
- output = convert_string input
3080
- assert_css '#toc', output, 1
3081
- assert_css '#toctitle', output, 1
3082
- assert_css '#preamble #toc', output, 1
3083
- assert_css '#preamble #toc.contents', output, 1
3084
- assert_xpath '//*[@id="toc"]/*[@class="title"][text() = "Contents"]', output, 1
3085
- assert_css '#toc li', output, 2
3086
- assert_xpath '(//*[@id="toc"]//li)[1]/a[text() = "Section 1"]', output, 1
3087
- assert_xpath '(//*[@id="toc"]//li)[2]/a[text() = "Section 2"]', output, 1
3088
- end
3089
-
3090
- test 'should honor id, title, role and level attributes on toc macro' do
3091
- input = <<-EOS
3092
- = Article
3093
- :toc:
3094
- :toc-placement: macro
3095
- :toc-title: Ignored
3096
- :toc-class: ignored
3097
- :toclevels: 5
3098
- :tocdepth: 1
3099
-
3100
- Preamble.
3101
-
3102
- [[contents]]
3103
- [role="contents"]
3104
- .Contents
3105
- toc::[levels={tocdepth}]
3106
-
3107
- == Section 1
3108
-
3109
- === Section 1.1
3110
-
3111
- ==== Section 1.1.1
3112
-
3113
- ==== Section 1.1.2
3114
-
3115
- === Section 1.2
3116
-
3117
- == Section 2
3118
-
3119
- Fin.
3120
- EOS
3121
-
3122
- output = convert_string input
3123
- assert_css '#toc', output, 0
3124
- assert_css '#toctitle', output, 0
3125
- assert_css '#preamble #contents', output, 1
3126
- assert_css '#preamble #contents.contents', output, 1
3127
- assert_xpath '//*[@id="contents"]/*[@class="title"][text() = "Contents"]', output, 1
3128
- assert_css '#contents li', output, 2
3129
- assert_xpath '(//*[@id="contents"]//li)[1]/a[text() = "Section 1"]', output, 1
3130
- assert_xpath '(//*[@id="contents"]//li)[2]/a[text() = "Section 2"]', output, 1
3131
- end
3132
-
3133
- test 'child toc levels should not have additional bullet at parent level in html' do
3134
- input = <<-EOS
3135
- = Article
3136
- :toc:
3137
-
3138
- == Section One
3139
-
3140
- It was a dark and stormy night...
3141
-
3142
- == Section Two
3143
-
3144
- They couldn't believe their eyes when...
3145
-
3146
- === Interlude
3147
-
3148
- While they were waiting...
3149
-
3150
- == Section Three
3151
-
3152
- That's all she wrote!
3153
- EOS
3154
- output = convert_string input
3155
- assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc"]', output, 1
3156
- assert_xpath '//*[@id="header"]//*[@id="toc"]/*[@id="toctitle"][text()="Table of Contents"]', output, 1
3157
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul', output, 1
3158
- assert_xpath '//*[@id="header"]//*[@id="toc"]//ul', output, 2
3159
- assert_xpath '//*[@id="header"]//*[@id="toc"]//li', output, 4
3160
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[2]/a[@href="#_section_two"][text()="Section Two"]', output, 1
3161
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li', output, 1
3162
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li[2]/ul/li', output, 1
3163
- assert_xpath '//*[@id="header"]//*[@id="toc"]/ul/li/ul/li/a[@href="#_interlude"][text()="Interlude"]', output, 1
3164
- assert_xpath '((//*[@id="header"]//*[@id="toc"]/ul)[1]/li)[3]/a[@href="#_section_three"][text()="Section Three"]', output, 1
3165
- end
3166
-
3167
- test 'should not display a table of contents if document has no sections' do
3168
- input_src = <<-EOS
3169
- = Document Title
3170
- :toc:
3171
-
3172
- toc::[]
3173
-
3174
- This document has no sections.
3175
-
3176
- It only has content.
3177
- EOS
3178
-
3179
- ['', 'left', 'preamble', 'macro'].each do |placement|
3180
- input = input_src.gsub(':toc:', "\\& #{placement}")
3181
- output = convert_string input
3182
- assert_css '#toctitle', output, 0
3183
- end
3184
- end
3185
-
3186
- test 'should drop anchors from contents of entries in table of contents' do
3187
- input = <<-EOS
3188
- = Document Title
3189
- :toc:
3190
-
3191
- == [[un]]Section One
3192
-
3193
- content
3194
-
3195
- == [[two]][[deux]]Section Two
3196
-
3197
- content
3198
-
3199
- == Plant Trees by https://ecosia.org[Searching]
3200
-
3201
- content
3202
- EOS
3203
-
3204
- output = convert_string_to_embedded input
3205
- assert_xpath '/*[@id="toc"]', output, 1
3206
- toc_links = xmlnodes_at_xpath '/*[@id="toc"]//li', output
3207
- assert_equal 3, toc_links.size
3208
- assert_equal '<a href="#_section_one">Section One</a>', toc_links[0].inner_html
3209
- assert_equal '<a href="#_section_two">Section Two</a>', toc_links[1].inner_html
3210
- assert_equal '<a href="#_plant_trees_by_searching">Plant Trees by Searching</a>', toc_links[2].inner_html
3211
- end
3212
-
3213
- test 'should not remove non-anchor tags from contents of entries in table of contents' do
3214
- input = <<-EOS
3215
- = Document Title
3216
- :toc:
3217
- :icons: font
3218
-
3219
- == `run` command
3220
-
3221
- content
3222
-
3223
- == icon:bug[] Issues
3224
-
3225
- content
3226
-
3227
- == https://ecosia.org[_Sustainable_ Searches]
3228
-
3229
- content
3230
- EOS
3231
-
3232
- output = convert_string_to_embedded input, :safe => :safe
3233
- assert_xpath '/*[@id="toc"]', output, 1
3234
- toc_links = xmlnodes_at_xpath '/*[@id="toc"]//li', output
3235
- assert_equal 3, toc_links.size
3236
- assert_equal '<a href="#_run_command"><code>run</code> command</a>', toc_links[0].inner_html
3237
- assert_equal '<a href="#_issues"><span class="icon"><i class="fa fa-bug"></i></span> Issues</a>', toc_links[1].inner_html
3238
- assert_equal '<a href="#_sustainable_searches"><em>Sustainable</em> Searches</a>', toc_links[2].inner_html
3239
- end
3240
- end
3241
-
3242
- context 'article doctype' do
3243
- test 'should create only sections in docbook backend' do
3244
- input = <<-EOS
3245
- = Article
3246
- Doc Writer
3247
-
3248
- == Section 1
3249
-
3250
- The adventure.
3251
-
3252
- === Subsection One
3253
-
3254
- It was a dark and stormy night...
3255
-
3256
- === Subsection Two
3257
-
3258
- They couldn't believe their eyes when...
3259
-
3260
- == Section 2
3261
-
3262
- The return.
3263
-
3264
- === Subsection Three
3265
-
3266
- While they were returning...
3267
-
3268
- === Subsection Four
3269
-
3270
- That's all she wrote!
3271
- EOS
3272
-
3273
- output = convert_string input, :backend => 'docbook'
3274
- assert_xpath '//part', output, 0
3275
- assert_xpath '//chapter', output, 0
3276
- assert_xpath '/article/section', output, 2
3277
- assert_xpath '/article/section[1]/title[text() = "Section 1"]', output, 1
3278
- assert_xpath '/article/section[2]/title[text() = "Section 2"]', output, 1
3279
- assert_xpath '/article/section/section', output, 4
3280
- assert_xpath '/article/section[1]/section[1]/title[text() = "Subsection One"]', output, 1
3281
- assert_xpath '/article/section[2]/section[1]/title[text() = "Subsection Three"]', output, 1
3282
- end
3283
- end
3284
-
3285
- context 'book doctype' do
3286
- test 'document title with level 0 headings' do
3287
- input = <<-EOS
3288
- = Book
3289
- Doc Writer
3290
- :doctype: book
3291
-
3292
- = Chapter One
3293
-
3294
- [partintro]
3295
- It was a dark and stormy night...
3296
-
3297
- == Scene One
3298
-
3299
- Someone's gonna get axed.
3300
-
3301
- = Chapter Two
3302
-
3303
- [partintro]
3304
- They couldn't believe their eyes when...
3305
-
3306
- == Interlude
3307
-
3308
- While they were waiting...
3309
-
3310
- = Chapter Three
3311
-
3312
- == Scene One
3313
-
3314
- That's all she wrote!
3315
- EOS
3316
-
3317
- output = convert_string(input)
3318
- assert_css 'body.book', output, 1
3319
- assert_css 'h1', output, 4
3320
- assert_css '#header h1', output, 1
3321
- assert_css '#content h1', output, 3
3322
- assert_css '#content h1.sect0', output, 3
3323
- assert_css 'h2', output, 3
3324
- assert_css '#content h2', output, 3
3325
- assert_xpath '//h1[@id="_chapter_one"][text() = "Chapter One"]', output, 1
3326
- assert_xpath '//h1[@id="_chapter_two"][text() = "Chapter Two"]', output, 1
3327
- assert_xpath '//h1[@id="_chapter_three"][text() = "Chapter Three"]', output, 1
3328
- end
3329
-
3330
- test 'should print error if level 0 section comes after nested section and doctype is not book' do
3331
- input = <<-EOS
3332
- = Document Title
3333
-
3334
- == Level 1 Section
3335
-
3336
- === Level 2 Section
3337
-
3338
- = Level 0 Section
3339
- EOS
3340
-
3341
- using_memory_logger do |logger|
3342
- convert_string input
3343
- assert_message logger, :ERROR, '<stdin>: line 7: level 0 sections can only be used when doctype is book', Hash
3344
- end
3345
- end
3346
-
3347
- test 'should add class matching role to part' do
3348
- input = <<-EOS
3349
- = Book Title
3350
- :doctype: book
3351
-
3352
- [.newbie]
3353
- = Part 1
3354
-
3355
- == Chapter A
3356
-
3357
- content
3358
-
3359
- = Part 2
3360
-
3361
- == Chapter B
3362
-
3363
- content
3364
- EOS
3365
-
3366
- result = convert_string_to_embedded input
3367
- assert_css 'h1.sect0', result, 2
3368
- assert_css 'h1.sect0.newbie', result, 1
3369
- assert_css 'h1.sect0.newbie#_part_1', result, 1
3370
- end
3371
-
3372
- test 'should assign appropriate sectname for section type' do
3373
- input = <<-EOS
3374
- = Book Title
3375
- :doctype: book
3376
- :idprefix:
3377
- :idseparator: -
3378
-
3379
- = Part Title
3380
-
3381
- == Chapter Title
3382
-
3383
- === Section Title
3384
-
3385
- content
3386
-
3387
- [appendix]
3388
- == Appendix Title
3389
-
3390
- === Appendix Section Title
3391
-
3392
- content
3393
- EOS
3394
-
3395
- doc = document_from_string input
3396
- assert_equal 'header', doc.header.sectname
3397
- assert_equal 'part', (doc.find_by :id => 'part-title')[0].sectname
3398
- assert_equal 'chapter', (doc.find_by :id => 'chapter-title')[0].sectname
3399
- assert_equal 'section', (doc.find_by :id => 'section-title')[0].sectname
3400
- assert_equal 'appendix', (doc.find_by :id => 'appendix-title')[0].sectname
3401
- assert_equal 'section', (doc.find_by :id => 'appendix-section-title')[0].sectname
3402
- end
3403
-
3404
- test 'should add partintro style to child paragraph of part' do
3405
- input = <<-EOS
3406
- = Book
3407
- :doctype: book
3408
-
3409
- = Part 1
3410
-
3411
- part intro
3412
-
3413
- == Chapter 1
3414
- EOS
3415
-
3416
- doc = document_from_string input
3417
- partintro = doc.blocks.first.blocks.first
3418
- assert_equal :open, partintro.context
3419
- assert_equal 'partintro', partintro.style
3420
- end
3421
-
3422
- test 'should add partintro style to child open block of part' do
3423
- input = <<-EOS
3424
- = Book
3425
- :doctype: book
3426
-
3427
- = Part 1
3428
-
3429
- --
3430
- part intro
3431
- --
3432
-
3433
- == Chapter 1
3434
- EOS
3435
-
3436
- doc = document_from_string input
3437
- partintro = doc.blocks.first.blocks.first
3438
- assert_equal :open, partintro.context
3439
- assert_equal 'partintro', partintro.style
3440
- end
3441
-
3442
- test 'should wrap child paragraphs of part in partintro open block' do
3443
- input = <<-EOS
3444
- = Book
3445
- :doctype: book
3446
-
3447
- = Part 1
3448
-
3449
- part intro
3450
-
3451
- more part intro
3452
-
3453
- == Chapter 1
3454
- EOS
3455
-
3456
- doc = document_from_string input
3457
- partintro = doc.blocks.first.blocks.first
3458
- assert_equal :open, partintro.context
3459
- assert_equal 'partintro', partintro.style
3460
- assert_equal 2, partintro.blocks.size
3461
- assert_equal :paragraph, partintro.blocks[0].context
3462
- assert_equal :paragraph, partintro.blocks[1].context
3463
- end
3464
-
3465
- test 'should warn if part has no sections' do
3466
- input = <<-EOS
3467
- = Book
3468
- :doctype: book
3469
-
3470
- = Part 1
3471
-
3472
- [partintro]
3473
- intro
3474
- EOS
3475
-
3476
- using_memory_logger do |logger|
3477
- document_from_string input
3478
- assert_message logger, :ERROR, '<stdin>: line 8: invalid part, must have at least one section (e.g., chapter, appendix, etc.)', Hash
3479
- end
3480
- end
3481
-
3482
- test 'should create parts and chapters in docbook backend' do
3483
- input = <<-EOS
3484
- = Book
3485
- Doc Writer
3486
- :doctype: book
3487
-
3488
- = Part 1
3489
-
3490
- [partintro]
3491
- The adventure.
3492
-
3493
- == Chapter One
3494
-
3495
- It was a dark and stormy night...
3496
-
3497
- == Chapter Two
3498
-
3499
- They couldn't believe their eyes when...
3500
-
3501
- = Part 2
3502
-
3503
- [partintro]
3504
- The return.
3505
-
3506
- == Chapter Three
3507
-
3508
- While they were returning...
3509
-
3510
- == Chapter Four
3511
-
3512
- That's all she wrote!
3513
- EOS
3514
-
3515
- output = convert_string input, :backend => 'docbook'
3516
- assert_xpath '//chapter/chapter', output, 0
3517
- assert_xpath '/book/part', output, 2
3518
- assert_xpath '/book/part[1]/title[text() = "Part 1"]', output, 1
3519
- assert_xpath '/book/part[2]/title[text() = "Part 2"]', output, 1
3520
- assert_xpath '/book/part/chapter', output, 4
3521
- assert_xpath '/book/part[1]/chapter[1]/title[text() = "Chapter One"]', output, 1
3522
- assert_xpath '/book/part[2]/chapter[1]/title[text() = "Chapter Three"]', output, 1
3523
- end
3524
-
3525
- test 'subsections in preface and appendix should start at level 2' do
3526
- input = <<-EOS
3527
- = Multipart Book
3528
- Doc Writer
3529
- :doctype: book
3530
-
3531
- [preface]
3532
- = Preface
3533
-
3534
- Preface content
3535
-
3536
- === Preface subsection
3537
-
3538
- Preface subsection content
3539
-
3540
- = Part 1
3541
-
3542
- .Part intro title
3543
- [partintro]
3544
- Part intro content
3545
-
3546
- == Chapter 1
3547
-
3548
- content
3549
-
3550
- [appendix]
3551
- = Appendix
3552
-
3553
- Appendix content
3554
-
3555
- === Appendix subsection
3556
-
3557
- Appendix subsection content
3558
- EOS
3559
-
3560
- output = nil
3561
- using_memory_logger do |logger|
3562
- output = convert_string input, :backend => 'docbook'
3563
- assert logger.empty?
3564
- end
3565
- assert_xpath '/book/preface', output, 1
3566
- assert_xpath '/book/preface/section', output, 1
3567
- assert_xpath '/book/part', output, 1
3568
- assert_xpath '/book/part/partintro', output, 1
3569
- assert_xpath '/book/part/partintro/title', output, 1
3570
- assert_xpath '/book/part/partintro/simpara', output, 1
3571
- assert_xpath '/book/appendix', output, 1
3572
- assert_xpath '/book/appendix/section', output, 1
3573
- end
3574
- end
3575
- end