asciidoctor 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/Gemfile +1 -1
- data/LICENSE +2 -2
- data/README.adoc +461 -0
- data/asciidoctor.gemspec +27 -16
- data/compat/asciidoc.conf +139 -0
- data/lib/asciidoctor.rb +212 -69
- data/lib/asciidoctor/abstract_block.rb +41 -0
- data/lib/asciidoctor/abstract_node.rb +128 -81
- data/lib/asciidoctor/attribute_list.rb +5 -2
- data/lib/asciidoctor/backends/base_template.rb +16 -4
- data/lib/asciidoctor/backends/docbook45.rb +112 -42
- data/lib/asciidoctor/backends/html5.rb +206 -90
- data/lib/asciidoctor/block.rb +5 -5
- data/lib/asciidoctor/cli/invoker.rb +38 -34
- data/lib/asciidoctor/cli/options.rb +3 -3
- data/lib/asciidoctor/document.rb +115 -13
- data/lib/asciidoctor/helpers.rb +16 -0
- data/lib/asciidoctor/lexer.rb +486 -359
- data/lib/asciidoctor/path_resolver.rb +360 -0
- data/lib/asciidoctor/reader.rb +122 -23
- data/lib/asciidoctor/renderer.rb +1 -33
- data/lib/asciidoctor/section.rb +1 -1
- data/lib/asciidoctor/substituters.rb +103 -19
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +6 -6
- data/man/asciidoctor.ad +5 -3
- data/stylesheets/asciidoctor.css +274 -0
- data/test/attributes_test.rb +133 -10
- data/test/blocks_test.rb +302 -17
- data/test/document_test.rb +269 -6
- data/test/fixtures/basic-docinfo.html +1 -0
- data/test/fixtures/basic-docinfo.xml +4 -0
- data/test/fixtures/basic.asciidoc +4 -0
- data/test/fixtures/docinfo.html +1 -0
- data/test/fixtures/docinfo.xml +2 -0
- data/test/fixtures/include-file.asciidoc +22 -1
- data/test/fixtures/stylesheets/custom.css +3 -0
- data/test/invoker_test.rb +38 -6
- data/test/lexer_test.rb +64 -21
- data/test/links_test.rb +4 -0
- data/test/lists_test.rb +251 -12
- data/test/paragraphs_test.rb +225 -30
- data/test/paths_test.rb +174 -0
- data/test/reader_test.rb +89 -2
- data/test/sections_test.rb +518 -16
- data/test/substitutions_test.rb +121 -10
- data/test/tables_test.rb +53 -13
- data/test/test_helper.rb +2 -2
- data/test/text_test.rb +5 -5
- metadata +46 -50
- data/README.asciidoc +0 -296
- data/lib/asciidoctor/errors.rb +0 -5
data/test/reader_test.rb
CHANGED
@@ -153,13 +153,14 @@ This is a paragraph outside the block.
|
|
153
153
|
end
|
154
154
|
|
155
155
|
context 'Include Macro' do
|
156
|
-
test 'include macro is disabled by default' do
|
156
|
+
test 'include macro is disabled by default and becomes a link' do
|
157
157
|
input = <<-EOS
|
158
158
|
include::include-file.asciidoc[]
|
159
159
|
EOS
|
160
160
|
para = block_from_string input, :attributes => { 'include-depth' => 0 }
|
161
161
|
assert_equal 1, para.buffer.size
|
162
|
-
assert_equal 'include::include-file.asciidoc[]', para.buffer.join
|
162
|
+
#assert_equal 'include::include-file.asciidoc[]', para.buffer.join
|
163
|
+
assert_equal 'link:include-file.asciidoc[include-file.asciidoc]', para.buffer.join
|
163
164
|
end
|
164
165
|
|
165
166
|
test 'include macro is enabled when safe mode is less than SECURE' do
|
@@ -172,6 +173,76 @@ include::fixtures/include-file.asciidoc[]
|
|
172
173
|
assert_match(/included content/, output)
|
173
174
|
end
|
174
175
|
|
176
|
+
test 'missing file referenced by include macro does not crash processor' do
|
177
|
+
input = <<-EOS
|
178
|
+
include::fixtures/no-such-file.ad[]
|
179
|
+
EOS
|
180
|
+
|
181
|
+
begin
|
182
|
+
doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
|
183
|
+
assert_equal 0, doc.blocks.size
|
184
|
+
rescue
|
185
|
+
flunk('include macro should not raise exception on missing file')
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
test 'include macro supports line selection' do
|
190
|
+
input = <<-EOS
|
191
|
+
include::fixtures/include-file.asciidoc[lines=1;3..4;6..-1]
|
192
|
+
EOS
|
193
|
+
|
194
|
+
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :attributes => {'docdir' => File.dirname(__FILE__)}
|
195
|
+
assert_match(/first line/, output)
|
196
|
+
assert_no_match(/second line/, output)
|
197
|
+
assert_match(/third line/, output)
|
198
|
+
assert_match(/fourth line/, output)
|
199
|
+
assert_no_match(/fifth line/, output)
|
200
|
+
assert_match(/sixth line/, output)
|
201
|
+
assert_match(/seventh line/, output)
|
202
|
+
assert_match(/eighth line/, output)
|
203
|
+
assert_match(/last line of included content/, output)
|
204
|
+
end
|
205
|
+
|
206
|
+
test 'include macro supports line selection using quoted attribute value' do
|
207
|
+
input = <<-EOS
|
208
|
+
include::fixtures/include-file.asciidoc[lines="1, 3..4 , 6 .. -1"]
|
209
|
+
EOS
|
210
|
+
|
211
|
+
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :attributes => {'docdir' => File.dirname(__FILE__)}
|
212
|
+
assert_match(/first line/, output)
|
213
|
+
assert_no_match(/second line/, output)
|
214
|
+
assert_match(/third line/, output)
|
215
|
+
assert_match(/fourth line/, output)
|
216
|
+
assert_no_match(/fifth line/, output)
|
217
|
+
assert_match(/sixth line/, output)
|
218
|
+
assert_match(/seventh line/, output)
|
219
|
+
assert_match(/eighth line/, output)
|
220
|
+
assert_match(/last line of included content/, output)
|
221
|
+
end
|
222
|
+
|
223
|
+
test 'include macro supports tagged selection' do
|
224
|
+
input = <<-EOS
|
225
|
+
include::fixtures/include-file.asciidoc[tags=snippetA;snippetB]
|
226
|
+
EOS
|
227
|
+
|
228
|
+
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :attributes => {'docdir' => File.dirname(__FILE__)}
|
229
|
+
assert_match(/snippetA content/, output)
|
230
|
+
assert_match(/snippetB content/, output)
|
231
|
+
assert_no_match(/non-tagged content/, output)
|
232
|
+
assert_no_match(/included content/, output)
|
233
|
+
end
|
234
|
+
|
235
|
+
test 'lines attribute takes precedence over tags attribute in include macro' do
|
236
|
+
input = <<-EOS
|
237
|
+
include::fixtures/include-file.asciidoc[lines=1, tags=snippetA;snippetB]
|
238
|
+
EOS
|
239
|
+
|
240
|
+
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :attributes => {'docdir' => File.dirname(__FILE__)}
|
241
|
+
assert_match(/first line of included content/, output)
|
242
|
+
assert_no_match(/snippetA content/, output)
|
243
|
+
assert_no_match(/snippetB content/, output)
|
244
|
+
end
|
245
|
+
|
175
246
|
test "block is called to handle an include macro" do
|
176
247
|
input = <<-EOS
|
177
248
|
first line
|
@@ -329,6 +400,22 @@ There was much rejoicing.
|
|
329
400
|
assert_equal "On our quest we go...\nThere is a holy grail!\nThere was much rejoicing.", lines.join.strip
|
330
401
|
end
|
331
402
|
|
403
|
+
test 'ifndef with defined attribute does not include text in brackets' do
|
404
|
+
input = <<-EOS
|
405
|
+
On our quest we go...
|
406
|
+
ifndef::hardships[There is a holy grail!]
|
407
|
+
There was no rejoicing.
|
408
|
+
EOS
|
409
|
+
|
410
|
+
doc = Asciidoctor::Document.new [], :attributes => {'hardships' => ''}
|
411
|
+
reader = Asciidoctor::Reader.new(input.lines.entries, doc, true)
|
412
|
+
lines = []
|
413
|
+
while reader.has_more_lines?
|
414
|
+
lines << reader.get_line
|
415
|
+
end
|
416
|
+
assert_equal "On our quest we go...\nThere was no rejoicing.", lines.join.strip
|
417
|
+
end
|
418
|
+
|
332
419
|
test 'include with non-matching nested exclude' do
|
333
420
|
input = <<-EOS
|
334
421
|
ifdef::grail[]
|
data/test/sections_test.rb
CHANGED
@@ -257,6 +257,23 @@ not in section
|
|
257
257
|
assert floatingtitle.is_a?(Asciidoctor::Block)
|
258
258
|
assert !floatingtitle.is_a?(Asciidoctor::Section)
|
259
259
|
assert_equal :floating_title, floatingtitle.context
|
260
|
+
assert_equal '_plain_ol_heading', floatingtitle.id
|
261
|
+
assert doc.references[:ids].has_key?('_plain_ol_heading')
|
262
|
+
end
|
263
|
+
|
264
|
+
test 'can assign explicit id to floating title' do
|
265
|
+
input = <<-EOS
|
266
|
+
[[unchained]]
|
267
|
+
[float]
|
268
|
+
=== Plain Ol' Heading
|
269
|
+
|
270
|
+
not in section
|
271
|
+
EOS
|
272
|
+
|
273
|
+
doc = document_from_string input
|
274
|
+
floating_title = doc.blocks.first
|
275
|
+
assert_equal 'unchained', floating_title.id
|
276
|
+
assert doc.references[:ids].has_key?('unchained')
|
260
277
|
end
|
261
278
|
|
262
279
|
test 'should not include floating title in toc' do
|
@@ -321,6 +338,115 @@ not in section
|
|
321
338
|
end
|
322
339
|
end
|
323
340
|
|
341
|
+
context 'Level offset' do
|
342
|
+
test 'should print error if standalone document is included without level offset' do
|
343
|
+
input = <<-EOS
|
344
|
+
= Master Document
|
345
|
+
Doc Writer
|
346
|
+
|
347
|
+
text in master
|
348
|
+
|
349
|
+
// begin simulated include::[]
|
350
|
+
= Standalone Document
|
351
|
+
:author: Junior Writer
|
352
|
+
|
353
|
+
text in standalone
|
354
|
+
|
355
|
+
// end simulated include::[]
|
356
|
+
EOS
|
357
|
+
|
358
|
+
output = nil
|
359
|
+
errors = nil
|
360
|
+
redirect_streams do |stdout, stderr|
|
361
|
+
output = render_string input
|
362
|
+
errors = stdout.string
|
363
|
+
end
|
364
|
+
|
365
|
+
assert !errors.empty?
|
366
|
+
assert_match(/section title out of sequence/, errors)
|
367
|
+
end
|
368
|
+
|
369
|
+
test 'should add level offset to section level' do
|
370
|
+
input = <<-EOS
|
371
|
+
= Master Document
|
372
|
+
Doc Writer
|
373
|
+
|
374
|
+
Master document written by {author}.
|
375
|
+
|
376
|
+
:leveloffset: 1
|
377
|
+
|
378
|
+
// begin simulated include::[]
|
379
|
+
= Standalone Document
|
380
|
+
:author: Junior Writer
|
381
|
+
|
382
|
+
Standalone document written by {author}.
|
383
|
+
|
384
|
+
== Section in Standalone
|
385
|
+
|
386
|
+
Standalone section text.
|
387
|
+
// end simulated include::[]
|
388
|
+
|
389
|
+
:leveloffset!:
|
390
|
+
|
391
|
+
== Section in Master
|
392
|
+
|
393
|
+
Master section text.
|
394
|
+
EOS
|
395
|
+
|
396
|
+
output = nil
|
397
|
+
errors = nil
|
398
|
+
redirect_streams do |stdout, stderr|
|
399
|
+
output = render_string input
|
400
|
+
errors = stdout.string
|
401
|
+
end
|
402
|
+
|
403
|
+
assert errors.empty?
|
404
|
+
assert_match(/Master document written by Doc Writer/, output)
|
405
|
+
assert_match(/Standalone document written by Junior Writer/, output)
|
406
|
+
assert_xpath '//*[@class="sect1"]/h2[text() = "Standalone Document"]', output, 1
|
407
|
+
assert_xpath '//*[@class="sect2"]/h3[text() = "Section in Standalone"]', output, 1
|
408
|
+
assert_xpath '//*[@class="sect1"]/h2[text() = "Section in Master"]', output, 1
|
409
|
+
end
|
410
|
+
|
411
|
+
test 'level offset should be added to floating title' do
|
412
|
+
input = <<-EOS
|
413
|
+
= Master Document
|
414
|
+
Doc Writer
|
415
|
+
|
416
|
+
:leveloffset: 1
|
417
|
+
|
418
|
+
[float]
|
419
|
+
= Floating Title
|
420
|
+
EOS
|
421
|
+
|
422
|
+
output = render_string input
|
423
|
+
assert_xpath '//h2[@class="float"][text() = "Floating Title"]', output, 1
|
424
|
+
end
|
425
|
+
|
426
|
+
test 'should be able to reset level offset' do
|
427
|
+
input = <<-EOS
|
428
|
+
= Master Document
|
429
|
+
Doc Writer
|
430
|
+
|
431
|
+
Master preamble.
|
432
|
+
|
433
|
+
:leveloffset: 1
|
434
|
+
|
435
|
+
= Standalone Document
|
436
|
+
|
437
|
+
Standalone preamble.
|
438
|
+
|
439
|
+
:leveloffset!:
|
440
|
+
|
441
|
+
== Level 1 Section
|
442
|
+
EOS
|
443
|
+
|
444
|
+
output = render_string input
|
445
|
+
assert_xpath '//*[@class = "sect1"]/h2[text() = "Standalone Document"]', output, 1
|
446
|
+
assert_xpath '//*[@class = "sect1"]/h2[text() = "Level 1 Section"]', output, 1
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
324
450
|
context 'Section Numbering' do
|
325
451
|
test 'should create section number with one entry for level 1' do
|
326
452
|
sect1 = Asciidoctor::Section.new(nil)
|
@@ -560,6 +686,28 @@ Terms
|
|
560
686
|
assert_xpath '//*[@id="toc"]/ol//li/a[text()="Gotchas"]', output, 1
|
561
687
|
assert_xpath '//*[@id="toc"]/ol//li/a[text()="Glossary"]', output, 1
|
562
688
|
end
|
689
|
+
|
690
|
+
test 'level 0 special sections in multipart book should be rendered as level 1' do
|
691
|
+
input = <<-EOS
|
692
|
+
= Multipart Book
|
693
|
+
Doc Writer
|
694
|
+
:doctype: book
|
695
|
+
|
696
|
+
[preface]
|
697
|
+
= Preface
|
698
|
+
|
699
|
+
Preface text
|
700
|
+
|
701
|
+
[appendix]
|
702
|
+
= Appendix
|
703
|
+
|
704
|
+
Appendix text
|
705
|
+
EOS
|
706
|
+
|
707
|
+
output = render_string input
|
708
|
+
assert_xpath '//h2[@id = "_preface"]', output, 1
|
709
|
+
assert_xpath '//h2[@id = "_appendix"]', output, 1
|
710
|
+
end
|
563
711
|
end
|
564
712
|
|
565
713
|
context "heading patterns in blocks" do
|
@@ -606,7 +754,7 @@ This should be a tip, not a heading.
|
|
606
754
|
====
|
607
755
|
EOS
|
608
756
|
output = render_string input
|
609
|
-
assert_xpath "//*[@class='admonitionblock']//p[text() = 'This should be a tip, not a heading.']", output, 1
|
757
|
+
assert_xpath "//*[@class='admonitionblock tip']//p[text() = 'This should be a tip, not a heading.']", output, 1
|
610
758
|
end
|
611
759
|
|
612
760
|
test "should not match a heading in a labeled list" do
|
@@ -669,10 +817,9 @@ fin.
|
|
669
817
|
end
|
670
818
|
|
671
819
|
context 'Table of Contents' do
|
672
|
-
test 'should render table of contents if toc attribute is set' do
|
820
|
+
test 'should render table of contents in header if toc attribute is set' do
|
673
821
|
input = <<-EOS
|
674
|
-
Article
|
675
|
-
=======
|
822
|
+
= Article
|
676
823
|
:toc:
|
677
824
|
|
678
825
|
== Section One
|
@@ -692,22 +839,288 @@ While they were waiting...
|
|
692
839
|
That's all she wrote!
|
693
840
|
EOS
|
694
841
|
output = render_string input
|
695
|
-
assert_xpath '//*[@id="toc"]', output, 1
|
696
|
-
assert_xpath '//*[@id="toc"]/*[@id="toctitle"][text()="Table of Contents"]', output, 1
|
697
|
-
assert_xpath '//*[@id="toc"]/ol', output, 1
|
698
|
-
assert_xpath '//*[@id="toc"]//ol', output, 2
|
699
|
-
assert_xpath '//*[@id="toc"]/ol/li', output, 4
|
700
|
-
assert_xpath '//*[@id="toc"]/ol/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
|
701
|
-
assert_xpath '//*[@id="toc"]/ol/li/ol/li', output, 1
|
702
|
-
assert_xpath '//*[@id="toc"]/ol/li/ol/li/a[@href="#_interlude"][text()="2.1. Interlude"]', output, 1
|
842
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc"]', output, 1
|
843
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"]/*[@id="toctitle"][text()="Table of Contents"]', output, 1
|
844
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"]/ol', output, 1
|
845
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"]//ol', output, 2
|
846
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"]/ol/li', output, 4
|
847
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"]/ol/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
|
848
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"]/ol/li/ol/li', output, 1
|
849
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"]/ol/li/ol/li/a[@href="#_interlude"][text()="2.1. Interlude"]', output, 1
|
850
|
+
end
|
851
|
+
|
852
|
+
test 'should render table of contents in header if toc2 attribute is set' do
|
853
|
+
input = <<-EOS
|
854
|
+
= Article
|
855
|
+
:toc2:
|
856
|
+
|
857
|
+
== Section One
|
858
|
+
|
859
|
+
It was a dark and stormy night...
|
860
|
+
|
861
|
+
== Section Two
|
862
|
+
|
863
|
+
They couldn't believe their eyes when...
|
864
|
+
EOS
|
865
|
+
|
866
|
+
output = render_string input
|
867
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"][@class="toc2"]', output, 1
|
868
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"]/ol/li[1]/a[@href="#_section_one"][text()="1. Section One"]', output, 1
|
869
|
+
end
|
870
|
+
|
871
|
+
test 'should use document attributes toc-class, toc-title and toclevels to create toc' do
|
872
|
+
input = <<-EOS
|
873
|
+
= Article
|
874
|
+
:toc:
|
875
|
+
:toc-title: Contents
|
876
|
+
:toc-class: toc2
|
877
|
+
:toclevels: 1
|
878
|
+
|
879
|
+
== Section 1
|
880
|
+
|
881
|
+
=== Section 1.1
|
882
|
+
|
883
|
+
==== Section 1.1.1
|
884
|
+
|
885
|
+
==== Section 1.1.2
|
886
|
+
|
887
|
+
=== Section 1.2
|
888
|
+
|
889
|
+
== Section 2
|
890
|
+
|
891
|
+
Fin.
|
892
|
+
EOS
|
893
|
+
output = render_string input
|
894
|
+
assert_css '#header #toc', output, 1
|
895
|
+
assert_css '#header #toc.toc2', output, 1
|
896
|
+
assert_css '#header #toc li', output, 2
|
897
|
+
assert_css '#header #toc #toctitle', output, 1
|
898
|
+
assert_xpath '//*[@id="header"]//*[@id="toc"]/*[@id="toctitle"][text()="Contents"]', output, 1
|
899
|
+
end
|
900
|
+
|
901
|
+
test 'should not render table of contents if toc-placement attribute is unset' do
|
902
|
+
input = <<-EOS
|
903
|
+
= Article
|
904
|
+
:toc-placement!:
|
905
|
+
|
906
|
+
== Section One
|
907
|
+
|
908
|
+
It was a dark and stormy night...
|
909
|
+
|
910
|
+
== Section Two
|
911
|
+
|
912
|
+
They couldn't believe their eyes when...
|
913
|
+
EOS
|
914
|
+
|
915
|
+
output = render_string input
|
916
|
+
assert_xpath '//*[@id="toc"]', output, 0
|
917
|
+
end
|
918
|
+
|
919
|
+
test 'should render table of contents at location of toc macro' do
|
920
|
+
input = <<-EOS
|
921
|
+
= Article
|
922
|
+
:toc:
|
923
|
+
:toc-placement!:
|
924
|
+
|
925
|
+
Once upon a time...
|
926
|
+
|
927
|
+
toc::[]
|
928
|
+
|
929
|
+
== Section One
|
930
|
+
|
931
|
+
It was a dark and stormy night...
|
932
|
+
|
933
|
+
== Section Two
|
934
|
+
|
935
|
+
They couldn't believe their eyes when...
|
936
|
+
EOS
|
937
|
+
|
938
|
+
output = render_string input
|
939
|
+
assert_css '#preamble #toc', output, 1
|
940
|
+
assert_css '#preamble .paragraph + #toc', output, 1
|
941
|
+
end
|
942
|
+
|
943
|
+
test 'should render table of contents at location of toc macro in embedded document' do
|
944
|
+
input = <<-EOS
|
945
|
+
= Article
|
946
|
+
:toc:
|
947
|
+
:toc-placement!:
|
948
|
+
|
949
|
+
Once upon a time...
|
950
|
+
|
951
|
+
toc::[]
|
952
|
+
|
953
|
+
== Section One
|
954
|
+
|
955
|
+
It was a dark and stormy night...
|
956
|
+
|
957
|
+
== Section Two
|
958
|
+
|
959
|
+
They couldn't believe their eyes when...
|
960
|
+
EOS
|
961
|
+
|
962
|
+
output = render_string input, :header_footer => false
|
963
|
+
assert_css '#preamble:root #toc', output, 1
|
964
|
+
assert_css '#preamble:root .paragraph + #toc', output, 1
|
965
|
+
end
|
966
|
+
|
967
|
+
test 'should not assign toc id to more than one toc' do
|
968
|
+
input = <<-EOS
|
969
|
+
= Article
|
970
|
+
:toc:
|
971
|
+
|
972
|
+
Once upon a time...
|
973
|
+
|
974
|
+
toc::[]
|
975
|
+
|
976
|
+
== Section One
|
977
|
+
|
978
|
+
It was a dark and stormy night...
|
979
|
+
|
980
|
+
== Section Two
|
981
|
+
|
982
|
+
They couldn't believe their eyes when...
|
983
|
+
EOS
|
984
|
+
|
985
|
+
output = render_string input
|
986
|
+
|
987
|
+
assert_css '#toc', output, 1
|
988
|
+
assert_css '#toctitle', output, 1
|
989
|
+
assert_xpath '(//*[@class="toc"])[2][not(@id)]', output, 1
|
990
|
+
assert_xpath '(//*[@class="toc"])[2]/*[@class="title"][not(@id)]', output, 1
|
991
|
+
end
|
992
|
+
|
993
|
+
test 'should use global attributes for toc-title, toc-class and toclevels for toc macro' do
|
994
|
+
input = <<-EOS
|
995
|
+
= Article
|
996
|
+
:toc:
|
997
|
+
:toc-placement!:
|
998
|
+
:toc-title: Contents
|
999
|
+
:toc-class: contents
|
1000
|
+
:toclevels: 1
|
1001
|
+
|
1002
|
+
Preamble.
|
1003
|
+
|
1004
|
+
toc::[]
|
1005
|
+
|
1006
|
+
== Section 1
|
1007
|
+
|
1008
|
+
=== Section 1.1
|
1009
|
+
|
1010
|
+
==== Section 1.1.1
|
1011
|
+
|
1012
|
+
==== Section 1.1.2
|
1013
|
+
|
1014
|
+
=== Section 1.2
|
1015
|
+
|
1016
|
+
== Section 2
|
1017
|
+
|
1018
|
+
Fin.
|
1019
|
+
EOS
|
1020
|
+
|
1021
|
+
output = render_string input
|
1022
|
+
assert_css '#toc', output, 1
|
1023
|
+
assert_css '#toctitle', output, 1
|
1024
|
+
assert_css '#preamble #toc', output, 1
|
1025
|
+
assert_css '#preamble #toc.contents', output, 1
|
1026
|
+
assert_xpath '//*[@id="toc"]/*[@class="title"][text() = "Contents"]', output, 1
|
1027
|
+
assert_css '#toc li', output, 2
|
1028
|
+
assert_xpath '(//*[@id="toc"]//li)[1]/a[text() = "1. Section 1"]', output, 1
|
1029
|
+
assert_xpath '(//*[@id="toc"]//li)[2]/a[text() = "2. Section 2"]', output, 1
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
test 'should honor id, title, role and level attributes on toc macro' do
|
1033
|
+
input = <<-EOS
|
1034
|
+
= Article
|
1035
|
+
:toc:
|
1036
|
+
:toc-placement!:
|
1037
|
+
:toc-title: Ignored
|
1038
|
+
:toc-class: ignored
|
1039
|
+
:toclevels: 5
|
1040
|
+
:tocdepth: 1
|
1041
|
+
|
1042
|
+
Preamble.
|
1043
|
+
|
1044
|
+
[[contents]]
|
1045
|
+
[role="contents"]
|
1046
|
+
.Contents
|
1047
|
+
toc::[levels={tocdepth}]
|
1048
|
+
|
1049
|
+
== Section 1
|
1050
|
+
|
1051
|
+
=== Section 1.1
|
1052
|
+
|
1053
|
+
==== Section 1.1.1
|
1054
|
+
|
1055
|
+
==== Section 1.1.2
|
1056
|
+
|
1057
|
+
=== Section 1.2
|
1058
|
+
|
1059
|
+
== Section 2
|
1060
|
+
|
1061
|
+
Fin.
|
1062
|
+
EOS
|
1063
|
+
|
1064
|
+
output = render_string input
|
1065
|
+
assert_css '#toc', output, 0
|
1066
|
+
assert_css '#toctitle', output, 0
|
1067
|
+
assert_css '#preamble #contents', output, 1
|
1068
|
+
assert_css '#preamble #contents.contents', output, 1
|
1069
|
+
assert_xpath '//*[@id="contents"]/*[@class="title"][text() = "Contents"]', output, 1
|
1070
|
+
assert_css '#contents li', output, 2
|
1071
|
+
assert_xpath '(//*[@id="contents"]//li)[1]/a[text() = "1. Section 1"]', output, 1
|
1072
|
+
assert_xpath '(//*[@id="contents"]//li)[2]/a[text() = "2. Section 2"]', output, 1
|
703
1073
|
end
|
704
1074
|
end
|
705
1075
|
|
706
|
-
context
|
707
|
-
test
|
1076
|
+
context 'article doctype' do
|
1077
|
+
test 'should create sections only in docbook backend' do
|
708
1078
|
input = <<-EOS
|
709
|
-
|
710
|
-
|
1079
|
+
= Article
|
1080
|
+
Doc Writer
|
1081
|
+
|
1082
|
+
== Section 1
|
1083
|
+
|
1084
|
+
The adventure.
|
1085
|
+
|
1086
|
+
=== Subsection One
|
1087
|
+
|
1088
|
+
It was a dark and stormy night...
|
1089
|
+
|
1090
|
+
=== Subsection Two
|
1091
|
+
|
1092
|
+
They couldn't believe their eyes when...
|
1093
|
+
|
1094
|
+
== Section 2
|
1095
|
+
|
1096
|
+
The return.
|
1097
|
+
|
1098
|
+
=== Subsection Three
|
1099
|
+
|
1100
|
+
While they were returning...
|
1101
|
+
|
1102
|
+
=== Subsection Four
|
1103
|
+
|
1104
|
+
That's all she wrote!
|
1105
|
+
EOS
|
1106
|
+
|
1107
|
+
output = render_string input, :backend => 'docbook'
|
1108
|
+
assert_xpath '//part', output, 0
|
1109
|
+
assert_xpath '//chapter', output, 0
|
1110
|
+
assert_xpath '/article/section', output, 2
|
1111
|
+
assert_xpath '/article/section[1]/title[text() = "Section 1"]', output, 1
|
1112
|
+
assert_xpath '/article/section[2]/title[text() = "Section 2"]', output, 1
|
1113
|
+
assert_xpath '/article/section/section', output, 4
|
1114
|
+
assert_xpath '/article/section[1]/section[1]/title[text() = "Subsection One"]', output, 1
|
1115
|
+
assert_xpath '/article/section[2]/section[1]/title[text() = "Subsection Three"]', output, 1
|
1116
|
+
end
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
context 'book doctype' do
|
1120
|
+
test 'document title with level 0 headings' do
|
1121
|
+
input = <<-EOS
|
1122
|
+
= Book
|
1123
|
+
Doc Writer
|
711
1124
|
:doctype: book
|
712
1125
|
|
713
1126
|
= Chapter One
|
@@ -734,5 +1147,94 @@ That's all she wrote!
|
|
734
1147
|
assert_xpath '//h1[@id="_chapter_two"][text() = "Chapter Two"]', output, 1
|
735
1148
|
assert_xpath '//h1[@id="_chapter_three"][text() = "Chapter Three"]', output, 1
|
736
1149
|
end
|
1150
|
+
|
1151
|
+
test 'should create parts and chapters in docbook backend' do
|
1152
|
+
input = <<-EOS
|
1153
|
+
= Book
|
1154
|
+
Doc Writer
|
1155
|
+
:doctype: book
|
1156
|
+
|
1157
|
+
= Part 1
|
1158
|
+
|
1159
|
+
The adventure.
|
1160
|
+
|
1161
|
+
== Chapter One
|
1162
|
+
|
1163
|
+
It was a dark and stormy night...
|
1164
|
+
|
1165
|
+
== Chapter Two
|
1166
|
+
|
1167
|
+
They couldn't believe their eyes when...
|
1168
|
+
|
1169
|
+
= Part 2
|
1170
|
+
|
1171
|
+
The return.
|
1172
|
+
|
1173
|
+
== Chapter Three
|
1174
|
+
|
1175
|
+
While they were returning...
|
1176
|
+
|
1177
|
+
== Chapter Four
|
1178
|
+
|
1179
|
+
That's all she wrote!
|
1180
|
+
EOS
|
1181
|
+
|
1182
|
+
output = render_string input, :backend => 'docbook'
|
1183
|
+
assert_xpath '//chapter/chapter', output, 0
|
1184
|
+
assert_xpath '/book/part', output, 2
|
1185
|
+
assert_xpath '/book/part[1]/title[text() = "Part 1"]', output, 1
|
1186
|
+
assert_xpath '/book/part[2]/title[text() = "Part 2"]', output, 1
|
1187
|
+
assert_xpath '/book/part/chapter', output, 4
|
1188
|
+
assert_xpath '/book/part[1]/chapter[1]/title[text() = "Chapter One"]', output, 1
|
1189
|
+
assert_xpath '/book/part[2]/chapter[1]/title[text() = "Chapter Three"]', output, 1
|
1190
|
+
end
|
1191
|
+
|
1192
|
+
test 'subsections in preface and appendix should start at level 2' do
|
1193
|
+
input = <<-EOS
|
1194
|
+
= Multipart Book
|
1195
|
+
Doc Writer
|
1196
|
+
:doctype: book
|
1197
|
+
|
1198
|
+
[preface]
|
1199
|
+
= Preface
|
1200
|
+
|
1201
|
+
Preface content
|
1202
|
+
|
1203
|
+
=== Preface subsection
|
1204
|
+
|
1205
|
+
Preface subsection content
|
1206
|
+
|
1207
|
+
= Part 1
|
1208
|
+
|
1209
|
+
.Part intro title
|
1210
|
+
[partintro]
|
1211
|
+
Part intro content
|
1212
|
+
|
1213
|
+
[appendix]
|
1214
|
+
= Appendix
|
1215
|
+
|
1216
|
+
Appendix content
|
1217
|
+
|
1218
|
+
=== Appendix subsection
|
1219
|
+
|
1220
|
+
Appendix subsection content
|
1221
|
+
EOS
|
1222
|
+
|
1223
|
+
output = nil
|
1224
|
+
errors = nil
|
1225
|
+
redirect_streams do |stdout, stderr|
|
1226
|
+
output = render_string input, :backend => 'docbook'
|
1227
|
+
errors = stdout.string
|
1228
|
+
end
|
1229
|
+
assert errors.empty?
|
1230
|
+
assert_xpath '/book/preface', output, 1
|
1231
|
+
assert_xpath '/book/preface/section', output, 1
|
1232
|
+
assert_xpath '/book/part', output, 1
|
1233
|
+
assert_xpath '/book/part/partintro', output, 1
|
1234
|
+
assert_xpath '/book/part/partintro/title', output, 1
|
1235
|
+
assert_xpath '/book/part/partintro/simpara', output, 1
|
1236
|
+
assert_xpath '/book/appendix', output, 1
|
1237
|
+
assert_xpath '/book/appendix/section', output, 1
|
1238
|
+
end
|
737
1239
|
end
|
738
1240
|
end
|