asciidoctor 1.5.8 → 2.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +162 -17
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +12 -13
  5. data/README-fr.adoc +11 -12
  6. data/README-jp.adoc +11 -12
  7. data/README-zh_CN.adoc +12 -13
  8. data/README.adoc +6 -7
  9. data/asciidoctor.gemspec +19 -24
  10. data/bin/asciidoctor +5 -4
  11. data/data/reference/syntax.adoc +283 -0
  12. data/data/stylesheets/asciidoctor-default.css +56 -52
  13. data/data/stylesheets/coderay-asciidoctor.css +7 -9
  14. data/lib/asciidoctor.rb +171 -232
  15. data/lib/asciidoctor/abstract_block.rb +96 -105
  16. data/lib/asciidoctor/abstract_node.rb +118 -139
  17. data/lib/asciidoctor/attribute_list.rb +10 -14
  18. data/lib/asciidoctor/block.rb +20 -19
  19. data/lib/asciidoctor/callouts.rb +4 -2
  20. data/lib/asciidoctor/cli.rb +3 -2
  21. data/lib/asciidoctor/cli/invoker.rb +14 -21
  22. data/lib/asciidoctor/cli/options.rb +64 -54
  23. data/lib/asciidoctor/converter.rb +357 -185
  24. data/lib/asciidoctor/converter/composite.rb +40 -48
  25. data/lib/asciidoctor/converter/docbook5.rb +604 -640
  26. data/lib/asciidoctor/converter/html5.rb +949 -963
  27. data/lib/asciidoctor/converter/manpage.rb +569 -548
  28. data/lib/asciidoctor/converter/template.rb +231 -272
  29. data/lib/asciidoctor/core_ext.rb +5 -18
  30. data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
  31. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  32. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  33. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  34. data/lib/asciidoctor/document.rb +399 -377
  35. data/lib/asciidoctor/extensions.rb +72 -140
  36. data/lib/asciidoctor/helpers.rb +122 -83
  37. data/lib/asciidoctor/inline.rb +5 -1
  38. data/lib/asciidoctor/list.rb +13 -11
  39. data/lib/asciidoctor/logging.rb +17 -16
  40. data/lib/asciidoctor/parser.rb +390 -423
  41. data/lib/asciidoctor/path_resolver.rb +10 -5
  42. data/lib/asciidoctor/reader.rb +286 -263
  43. data/lib/asciidoctor/rouge_ext.rb +39 -0
  44. data/lib/asciidoctor/section.rb +9 -8
  45. data/lib/asciidoctor/stylesheets.rb +19 -37
  46. data/lib/asciidoctor/substitutors.rb +364 -509
  47. data/lib/asciidoctor/syntax_highlighter.rb +238 -0
  48. data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
  49. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
  50. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  51. data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
  52. data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
  53. data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
  54. data/lib/asciidoctor/table.rb +73 -66
  55. data/lib/asciidoctor/timings.rb +4 -2
  56. data/lib/asciidoctor/version.rb +2 -1
  57. data/lib/asciidoctor/writer.rb +30 -0
  58. data/man/asciidoctor.1 +19 -15
  59. data/man/asciidoctor.adoc +14 -12
  60. metadata +69 -216
  61. data/CONTRIBUTING.adoc +0 -185
  62. data/Gemfile +0 -60
  63. data/Rakefile +0 -129
  64. data/bin/asciidoctor-safe +0 -15
  65. data/features/open_block.feature +0 -92
  66. data/features/pass_block.feature +0 -66
  67. data/features/step_definitions.rb +0 -49
  68. data/features/text_formatting.feature +0 -57
  69. data/features/xref.feature +0 -1039
  70. data/lib/asciidoctor/converter/base.rb +0 -59
  71. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  72. data/lib/asciidoctor/converter/factory.rb +0 -226
  73. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  74. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  75. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  76. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  77. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  78. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  79. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  80. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  81. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  82. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  83. data/test/api_test.rb +0 -1240
  84. data/test/attribute_list_test.rb +0 -242
  85. data/test/attributes_test.rb +0 -1623
  86. data/test/blocks_test.rb +0 -3870
  87. data/test/converter_test.rb +0 -470
  88. data/test/document_test.rb +0 -1853
  89. data/test/extensions_test.rb +0 -1560
  90. data/test/fixtures/asciidoc_index.txt +0 -521
  91. data/test/fixtures/basic-docinfo-footer.html +0 -6
  92. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  93. data/test/fixtures/basic-docinfo.html +0 -1
  94. data/test/fixtures/basic-docinfo.xml +0 -4
  95. data/test/fixtures/basic.asciidoc +0 -5
  96. data/test/fixtures/chapter-a.adoc +0 -3
  97. data/test/fixtures/child-include.adoc +0 -5
  98. data/test/fixtures/circle.svg +0 -9
  99. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  100. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  101. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  102. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  103. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  104. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  105. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  106. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  107. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  108. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  109. data/test/fixtures/docinfo-footer.html +0 -1
  110. data/test/fixtures/docinfo-footer.xml +0 -9
  111. data/test/fixtures/docinfo.html +0 -1
  112. data/test/fixtures/docinfo.xml +0 -3
  113. data/test/fixtures/doctime-localtime.adoc +0 -2
  114. data/test/fixtures/dot.gif +0 -0
  115. data/test/fixtures/encoding.asciidoc +0 -13
  116. data/test/fixtures/file-with-missing-include.adoc +0 -1
  117. data/test/fixtures/grandchild-include.adoc +0 -3
  118. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  119. data/test/fixtures/include-file.asciidoc +0 -24
  120. data/test/fixtures/include-file.jsx +0 -8
  121. data/test/fixtures/include-file.ml +0 -3
  122. data/test/fixtures/include-file.xml +0 -5
  123. data/test/fixtures/lists.adoc +0 -96
  124. data/test/fixtures/master.adoc +0 -5
  125. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  126. data/test/fixtures/other-chapters.adoc +0 -11
  127. data/test/fixtures/outer-include.adoc +0 -5
  128. data/test/fixtures/parent-include-restricted.adoc +0 -5
  129. data/test/fixtures/parent-include.adoc +0 -5
  130. data/test/fixtures/sample.asciidoc +0 -30
  131. data/test/fixtures/section-a.adoc +0 -4
  132. data/test/fixtures/stylesheets/custom.css +0 -3
  133. data/test/fixtures/subdir/index.adoc +0 -3
  134. data/test/fixtures/subdir/inner-include.adoc +0 -3
  135. data/test/fixtures/subdir/middle-include.adoc +0 -5
  136. data/test/fixtures/subs-docinfo.html +0 -2
  137. data/test/fixtures/subs.adoc +0 -6
  138. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  139. data/test/fixtures/tagged-class.rb +0 -23
  140. data/test/fixtures/tip.gif +0 -0
  141. data/test/fixtures/unclosed-tag.adoc +0 -3
  142. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  143. data/test/invoker_test.rb +0 -745
  144. data/test/links_test.rb +0 -855
  145. data/test/lists_test.rb +0 -5151
  146. data/test/logger_test.rb +0 -211
  147. data/test/manpage_test.rb +0 -660
  148. data/test/options_test.rb +0 -262
  149. data/test/paragraphs_test.rb +0 -562
  150. data/test/parser_test.rb +0 -742
  151. data/test/paths_test.rb +0 -395
  152. data/test/preamble_test.rb +0 -173
  153. data/test/reader_test.rb +0 -2161
  154. data/test/sections_test.rb +0 -3575
  155. data/test/substitutions_test.rb +0 -2066
  156. data/test/tables_test.rb +0 -2036
  157. data/test/test_helper.rb +0 -447
  158. data/test/text_test.rb +0 -309
@@ -1,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