asciidoctor 1.5.8 → 2.0.0.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +162 -17
- data/LICENSE +1 -1
- data/README-de.adoc +12 -13
- data/README-fr.adoc +11 -12
- data/README-jp.adoc +11 -12
- data/README-zh_CN.adoc +12 -13
- data/README.adoc +6 -7
- data/asciidoctor.gemspec +19 -24
- data/bin/asciidoctor +5 -4
- data/data/reference/syntax.adoc +283 -0
- data/data/stylesheets/asciidoctor-default.css +56 -52
- data/data/stylesheets/coderay-asciidoctor.css +7 -9
- data/lib/asciidoctor.rb +171 -232
- data/lib/asciidoctor/abstract_block.rb +96 -105
- data/lib/asciidoctor/abstract_node.rb +118 -139
- data/lib/asciidoctor/attribute_list.rb +10 -14
- data/lib/asciidoctor/block.rb +20 -19
- data/lib/asciidoctor/callouts.rb +4 -2
- data/lib/asciidoctor/cli.rb +3 -2
- data/lib/asciidoctor/cli/invoker.rb +14 -21
- data/lib/asciidoctor/cli/options.rb +64 -54
- data/lib/asciidoctor/converter.rb +357 -185
- data/lib/asciidoctor/converter/composite.rb +40 -48
- data/lib/asciidoctor/converter/docbook5.rb +604 -640
- data/lib/asciidoctor/converter/html5.rb +949 -963
- data/lib/asciidoctor/converter/manpage.rb +569 -548
- data/lib/asciidoctor/converter/template.rb +231 -272
- data/lib/asciidoctor/core_ext.rb +5 -18
- data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
- data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
- data/lib/asciidoctor/document.rb +399 -377
- data/lib/asciidoctor/extensions.rb +72 -140
- data/lib/asciidoctor/helpers.rb +122 -83
- data/lib/asciidoctor/inline.rb +5 -1
- data/lib/asciidoctor/list.rb +13 -11
- data/lib/asciidoctor/logging.rb +17 -16
- data/lib/asciidoctor/parser.rb +390 -423
- data/lib/asciidoctor/path_resolver.rb +10 -5
- data/lib/asciidoctor/reader.rb +286 -263
- data/lib/asciidoctor/rouge_ext.rb +39 -0
- data/lib/asciidoctor/section.rb +9 -8
- data/lib/asciidoctor/stylesheets.rb +19 -37
- data/lib/asciidoctor/substitutors.rb +364 -509
- data/lib/asciidoctor/syntax_highlighter.rb +238 -0
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
- data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
- data/lib/asciidoctor/table.rb +73 -66
- data/lib/asciidoctor/timings.rb +4 -2
- data/lib/asciidoctor/version.rb +2 -1
- data/lib/asciidoctor/writer.rb +30 -0
- data/man/asciidoctor.1 +19 -15
- data/man/asciidoctor.adoc +14 -12
- metadata +69 -216
- data/CONTRIBUTING.adoc +0 -185
- data/Gemfile +0 -60
- data/Rakefile +0 -129
- data/bin/asciidoctor-safe +0 -15
- data/features/open_block.feature +0 -92
- data/features/pass_block.feature +0 -66
- data/features/step_definitions.rb +0 -49
- data/features/text_formatting.feature +0 -57
- data/features/xref.feature +0 -1039
- data/lib/asciidoctor/converter/base.rb +0 -59
- data/lib/asciidoctor/converter/docbook45.rb +0 -93
- data/lib/asciidoctor/converter/factory.rb +0 -226
- data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
- data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
- data/test/api_test.rb +0 -1240
- data/test/attribute_list_test.rb +0 -242
- data/test/attributes_test.rb +0 -1623
- data/test/blocks_test.rb +0 -3870
- data/test/converter_test.rb +0 -470
- data/test/document_test.rb +0 -1853
- data/test/extensions_test.rb +0 -1560
- data/test/fixtures/asciidoc_index.txt +0 -521
- data/test/fixtures/basic-docinfo-footer.html +0 -6
- data/test/fixtures/basic-docinfo-footer.xml +0 -8
- data/test/fixtures/basic-docinfo.html +0 -1
- data/test/fixtures/basic-docinfo.xml +0 -4
- data/test/fixtures/basic.asciidoc +0 -5
- data/test/fixtures/chapter-a.adoc +0 -3
- data/test/fixtures/child-include.adoc +0 -5
- data/test/fixtures/circle.svg +0 -9
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
- data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
- data/test/fixtures/docinfo-footer.html +0 -1
- data/test/fixtures/docinfo-footer.xml +0 -9
- data/test/fixtures/docinfo.html +0 -1
- data/test/fixtures/docinfo.xml +0 -3
- data/test/fixtures/doctime-localtime.adoc +0 -2
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +0 -13
- data/test/fixtures/file-with-missing-include.adoc +0 -1
- data/test/fixtures/grandchild-include.adoc +0 -3
- data/test/fixtures/hello-asciidoctor.pdf +0 -69
- data/test/fixtures/include-file.asciidoc +0 -24
- data/test/fixtures/include-file.jsx +0 -8
- data/test/fixtures/include-file.ml +0 -3
- data/test/fixtures/include-file.xml +0 -5
- data/test/fixtures/lists.adoc +0 -96
- data/test/fixtures/master.adoc +0 -5
- data/test/fixtures/mismatched-end-tag.adoc +0 -7
- data/test/fixtures/other-chapters.adoc +0 -11
- data/test/fixtures/outer-include.adoc +0 -5
- data/test/fixtures/parent-include-restricted.adoc +0 -5
- data/test/fixtures/parent-include.adoc +0 -5
- data/test/fixtures/sample.asciidoc +0 -30
- data/test/fixtures/section-a.adoc +0 -4
- data/test/fixtures/stylesheets/custom.css +0 -3
- data/test/fixtures/subdir/index.adoc +0 -3
- data/test/fixtures/subdir/inner-include.adoc +0 -3
- data/test/fixtures/subdir/middle-include.adoc +0 -5
- data/test/fixtures/subs-docinfo.html +0 -2
- data/test/fixtures/subs.adoc +0 -6
- data/test/fixtures/tagged-class-enclosed.rb +0 -25
- data/test/fixtures/tagged-class.rb +0 -23
- data/test/fixtures/tip.gif +0 -0
- data/test/fixtures/unclosed-tag.adoc +0 -3
- data/test/fixtures/unexpected-end-tag.adoc +0 -4
- data/test/invoker_test.rb +0 -745
- data/test/links_test.rb +0 -855
- data/test/lists_test.rb +0 -5151
- data/test/logger_test.rb +0 -211
- data/test/manpage_test.rb +0 -660
- data/test/options_test.rb +0 -262
- data/test/paragraphs_test.rb +0 -562
- data/test/parser_test.rb +0 -742
- data/test/paths_test.rb +0 -395
- data/test/preamble_test.rb +0 -173
- data/test/reader_test.rb +0 -2161
- data/test/sections_test.rb +0 -3575
- data/test/substitutions_test.rb +0 -2066
- data/test/tables_test.rb +0 -2036
- data/test/test_helper.rb +0 -447
- data/test/text_test.rb +0 -309
data/test/sections_test.rb
DELETED
@@ -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 & Company¹ "Ice Cream Brothers" あ')
|
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 ®&© 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
|