asciidoctor 0.1.3 → 0.1.4
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 +4 -4
- data/CHANGELOG.adoc +387 -0
- data/README.adoc +358 -348
- data/asciidoctor.gemspec +30 -9
- data/bin/asciidoctor +3 -0
- data/bin/asciidoctor-safe +3 -0
- data/compat/asciidoc.conf +76 -4
- data/lib/asciidoctor.rb +174 -79
- data/lib/asciidoctor/abstract_block.rb +131 -101
- data/lib/asciidoctor/abstract_node.rb +108 -26
- data/lib/asciidoctor/attribute_list.rb +1 -1
- data/lib/asciidoctor/backends/_stylesheets.rb +204 -62
- data/lib/asciidoctor/backends/base_template.rb +11 -22
- data/lib/asciidoctor/backends/docbook45.rb +158 -163
- data/lib/asciidoctor/backends/docbook5.rb +103 -0
- data/lib/asciidoctor/backends/html5.rb +662 -445
- data/lib/asciidoctor/block.rb +54 -44
- data/lib/asciidoctor/cli/invoker.rb +41 -20
- data/lib/asciidoctor/cli/options.rb +66 -20
- data/lib/asciidoctor/debug.rb +1 -1
- data/lib/asciidoctor/document.rb +265 -100
- data/lib/asciidoctor/extensions.rb +443 -0
- data/lib/asciidoctor/helpers.rb +38 -6
- data/lib/asciidoctor/inline.rb +5 -5
- data/lib/asciidoctor/lexer.rb +532 -250
- data/lib/asciidoctor/{list_item.rb → list.rb} +33 -13
- data/lib/asciidoctor/path_resolver.rb +28 -2
- data/lib/asciidoctor/reader.rb +814 -455
- data/lib/asciidoctor/renderer.rb +128 -42
- data/lib/asciidoctor/section.rb +55 -41
- data/lib/asciidoctor/substituters.rb +380 -107
- data/lib/asciidoctor/table.rb +40 -30
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +32 -96
- data/man/{asciidoctor.ad → asciidoctor.adoc} +57 -48
- data/test/attributes_test.rb +200 -27
- data/test/blocks_test.rb +361 -22
- data/test/document_test.rb +496 -81
- data/test/extensions_test.rb +448 -0
- data/test/fixtures/basic-docinfo-footer.html +6 -0
- data/test/fixtures/basic-docinfo-footer.xml +8 -0
- data/test/fixtures/basic-docinfo.xml +3 -3
- data/test/fixtures/basic.asciidoc +1 -0
- data/test/fixtures/child-include.adoc +5 -0
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
- data/test/fixtures/docinfo-footer.html +1 -0
- data/test/fixtures/docinfo-footer.xml +9 -0
- data/test/fixtures/docinfo.xml +1 -0
- data/test/fixtures/grandchild-include.adoc +3 -0
- data/test/fixtures/parent-include-restricted.adoc +5 -0
- data/test/fixtures/parent-include.adoc +5 -0
- data/test/invoker_test.rb +82 -8
- data/test/lexer_test.rb +21 -3
- data/test/links_test.rb +34 -2
- data/test/lists_test.rb +304 -7
- data/test/options_test.rb +19 -3
- data/test/paragraphs_test.rb +13 -0
- data/test/paths_test.rb +22 -0
- data/test/preamble_test.rb +20 -0
- data/test/reader_test.rb +1096 -644
- data/test/renderer_test.rb +152 -12
- data/test/sections_test.rb +417 -76
- data/test/substitutions_test.rb +339 -138
- data/test/tables_test.rb +109 -4
- data/test/test_helper.rb +79 -13
- data/test/text_test.rb +111 -11
- metadata +54 -18
data/test/document_test.rb
CHANGED
@@ -66,6 +66,23 @@ context 'Document' do
|
|
66
66
|
rescue
|
67
67
|
end
|
68
68
|
end
|
69
|
+
|
70
|
+
test 'toc and numbered should be enabled by default for DocBook backend' do
|
71
|
+
doc = Asciidoctor::Document.new [], :backend => 'docbook'
|
72
|
+
assert doc.attr?('toc')
|
73
|
+
assert doc.attr?('numbered')
|
74
|
+
end
|
75
|
+
|
76
|
+
test 'should be able to disable toc and numbered in document header for DocBook backend' do
|
77
|
+
input = <<-EOS
|
78
|
+
= Document Title
|
79
|
+
:toc!:
|
80
|
+
:numbered!:
|
81
|
+
EOS
|
82
|
+
doc = document_from_string input, :backend => 'docbook'
|
83
|
+
assert !doc.attr?('toc')
|
84
|
+
assert !doc.attr?('numbered')
|
85
|
+
end
|
69
86
|
end
|
70
87
|
|
71
88
|
context 'Load APIs' do
|
@@ -182,6 +199,26 @@ preamble
|
|
182
199
|
doc = Asciidoctor.load('text', :attributes => nil)
|
183
200
|
assert doc.attributes.is_a?(Hash)
|
184
201
|
end
|
202
|
+
|
203
|
+
test 'should accept attributes if hash like' do
|
204
|
+
class Hashish
|
205
|
+
def initialize
|
206
|
+
@table = {'toc' => ''}
|
207
|
+
end
|
208
|
+
|
209
|
+
def keys
|
210
|
+
@table.keys
|
211
|
+
end
|
212
|
+
|
213
|
+
def [](key)
|
214
|
+
@table[key]
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
doc = Asciidoctor.load('text', :attributes => Hashish.new)
|
219
|
+
assert doc.attributes.is_a?(Hash)
|
220
|
+
assert doc.attributes.has_key?('toc')
|
221
|
+
end
|
185
222
|
end
|
186
223
|
|
187
224
|
context 'Render APIs' do
|
@@ -209,86 +246,25 @@ preamble
|
|
209
246
|
assert_css '#section-a', output, 1
|
210
247
|
end
|
211
248
|
|
212
|
-
test 'should
|
213
|
-
sample_input_path = fixture_path('basic.asciidoc')
|
214
|
-
|
215
|
-
output = Asciidoctor.render_file(sample_input_path,
|
216
|
-
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''})
|
217
|
-
assert !output.empty?
|
218
|
-
assert_css 'script[src="modernizr.js"]', output, 1
|
219
|
-
assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
|
220
|
-
|
221
|
-
output = Asciidoctor.render_file(sample_input_path,
|
222
|
-
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''})
|
223
|
-
assert !output.empty?
|
224
|
-
assert_css 'script[src="modernizr.js"]', output, 0
|
225
|
-
assert_css 'meta[http-equiv="imagetoolbar"]', output, 1
|
226
|
-
|
227
|
-
output = Asciidoctor.render_file(sample_input_path,
|
228
|
-
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''})
|
229
|
-
assert !output.empty?
|
230
|
-
assert_css 'script[src="modernizr.js"]', output, 1
|
231
|
-
assert_css 'meta[http-equiv="imagetoolbar"]', output, 1
|
232
|
-
end
|
233
|
-
|
234
|
-
test 'should include docinfo files for docbook backend' do
|
235
|
-
sample_input_path = fixture_path('basic.asciidoc')
|
236
|
-
|
237
|
-
output = Asciidoctor.render_file(sample_input_path,
|
238
|
-
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''})
|
239
|
-
assert !output.empty?
|
240
|
-
assert_css 'productname', output, 0
|
241
|
-
assert_css 'copyright', output, 1
|
242
|
-
|
243
|
-
output = Asciidoctor.render_file(sample_input_path,
|
244
|
-
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''})
|
245
|
-
assert !output.empty?
|
246
|
-
assert_css 'productname', output, 1
|
247
|
-
assert_css 'copyright', output, 0
|
248
|
-
|
249
|
-
output = Asciidoctor.render_file(sample_input_path,
|
250
|
-
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''})
|
251
|
-
assert !output.empty?
|
252
|
-
assert_css 'productname', output, 1
|
253
|
-
assert_css 'copyright', output, 1
|
254
|
-
end
|
255
|
-
|
256
|
-
test 'should not include docinfo files by default' do
|
249
|
+
test 'should link to default stylesheet by default when safe mode is SECURE or greater' do
|
257
250
|
sample_input_path = fixture_path('basic.asciidoc')
|
258
|
-
|
259
|
-
|
260
|
-
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER)
|
261
|
-
assert !output.empty?
|
262
|
-
assert_css 'script[src="modernizr.js"]', output, 0
|
263
|
-
assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
|
264
|
-
|
265
|
-
output = Asciidoctor.render_file(sample_input_path,
|
266
|
-
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER)
|
267
|
-
assert !output.empty?
|
268
|
-
assert_css 'productname', output, 0
|
269
|
-
assert_css 'copyright', output, 0
|
251
|
+
output = Asciidoctor.render_file(sample_input_path, :header_footer => true)
|
252
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
|
270
253
|
end
|
271
254
|
|
272
|
-
test 'should
|
273
|
-
|
274
|
-
|
275
|
-
output = Asciidoctor.render_file(sample_input_path,
|
276
|
-
:header_footer => true, :attributes => {'docinfo2' => ''})
|
277
|
-
assert !output.empty?
|
278
|
-
assert_css 'script[src="modernizr.js"]', output, 0
|
279
|
-
assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
|
255
|
+
test 'should embed default stylesheet by default if SafeMode is less than SECURE' do
|
256
|
+
input = <<-EOS
|
257
|
+
= Document Title
|
280
258
|
|
281
|
-
|
282
|
-
|
283
|
-
assert !output.empty?
|
284
|
-
assert_css 'productname', output, 0
|
285
|
-
assert_css 'copyright', output, 0
|
286
|
-
end
|
259
|
+
text
|
260
|
+
EOS
|
287
261
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
262
|
+
output = Asciidoctor.render(input, :safe => Asciidoctor::SafeMode::SERVER, :header_footer => true)
|
263
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
|
264
|
+
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
265
|
+
styles = stylenode.first.content
|
266
|
+
assert !styles.nil?
|
267
|
+
assert !styles.strip.empty?
|
292
268
|
end
|
293
269
|
|
294
270
|
test 'should link to default stylesheet by default if linkcss is unset in document' do
|
@@ -494,6 +470,134 @@ text
|
|
494
470
|
end
|
495
471
|
end
|
496
472
|
|
473
|
+
context 'Docinfo files' do
|
474
|
+
test 'should include docinfo files for html backend' do
|
475
|
+
sample_input_path = fixture_path('basic.asciidoc')
|
476
|
+
|
477
|
+
output = Asciidoctor.render_file(sample_input_path,
|
478
|
+
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''})
|
479
|
+
assert !output.empty?
|
480
|
+
assert_css 'script[src="modernizr.js"]', output, 1
|
481
|
+
assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
|
482
|
+
|
483
|
+
output = Asciidoctor.render_file(sample_input_path,
|
484
|
+
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''})
|
485
|
+
assert !output.empty?
|
486
|
+
assert_css 'script[src="modernizr.js"]', output, 0
|
487
|
+
assert_css 'meta[http-equiv="imagetoolbar"]', output, 1
|
488
|
+
|
489
|
+
output = Asciidoctor.render_file(sample_input_path,
|
490
|
+
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''})
|
491
|
+
assert !output.empty?
|
492
|
+
assert_css 'script[src="modernizr.js"]', output, 1
|
493
|
+
assert_css 'meta[http-equiv="imagetoolbar"]', output, 1
|
494
|
+
end
|
495
|
+
|
496
|
+
test 'should include docinfo files for docbook backend' do
|
497
|
+
sample_input_path = fixture_path('basic.asciidoc')
|
498
|
+
|
499
|
+
output = Asciidoctor.render_file(sample_input_path,
|
500
|
+
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''})
|
501
|
+
assert !output.empty?
|
502
|
+
assert_css 'productname', output, 0
|
503
|
+
assert_css 'copyright', output, 1
|
504
|
+
|
505
|
+
output = Asciidoctor.render_file(sample_input_path,
|
506
|
+
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''})
|
507
|
+
assert !output.empty?
|
508
|
+
assert_css 'productname', output, 1
|
509
|
+
assert_css 'edition', output, 1
|
510
|
+
assert_xpath '//xmlns:edition[text()="1.0"]', output, 1 # verifies substitutions are performed
|
511
|
+
assert_css 'copyright', output, 0
|
512
|
+
|
513
|
+
output = Asciidoctor.render_file(sample_input_path,
|
514
|
+
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''})
|
515
|
+
assert !output.empty?
|
516
|
+
assert_css 'productname', output, 1
|
517
|
+
assert_css 'edition', output, 1
|
518
|
+
assert_xpath '//xmlns:edition[text()="1.0"]', output, 1 # verifies substitutions are performed
|
519
|
+
assert_css 'copyright', output, 1
|
520
|
+
end
|
521
|
+
|
522
|
+
test 'should include docinfo footer files for html backend' do
|
523
|
+
sample_input_path = fixture_path('basic.asciidoc')
|
524
|
+
|
525
|
+
output = Asciidoctor.render_file(sample_input_path,
|
526
|
+
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''})
|
527
|
+
assert !output.empty?
|
528
|
+
assert_css 'body script', output, 1
|
529
|
+
assert_css 'a#top', output, 0
|
530
|
+
|
531
|
+
output = Asciidoctor.render_file(sample_input_path,
|
532
|
+
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''})
|
533
|
+
assert !output.empty?
|
534
|
+
assert_css 'body script', output, 0
|
535
|
+
assert_css 'a#top', output, 1
|
536
|
+
|
537
|
+
output = Asciidoctor.render_file(sample_input_path,
|
538
|
+
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''})
|
539
|
+
assert !output.empty?
|
540
|
+
assert_css 'body script', output, 1
|
541
|
+
assert_css 'a#top', output, 1
|
542
|
+
end
|
543
|
+
|
544
|
+
test 'should include docinfo footer files for docbook backend' do
|
545
|
+
sample_input_path = fixture_path('basic.asciidoc')
|
546
|
+
|
547
|
+
output = Asciidoctor.render_file(sample_input_path,
|
548
|
+
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''})
|
549
|
+
assert !output.empty?
|
550
|
+
assert_css 'article > revhistory', output, 1
|
551
|
+
assert_xpath '/xmlns:article/xmlns:revhistory/xmlns:revision/xmlns:revnumber[text()="1.0"]', output, 1 # verifies substitutions are performed
|
552
|
+
assert_css 'glossary#_glossary', output, 0
|
553
|
+
|
554
|
+
output = Asciidoctor.render_file(sample_input_path,
|
555
|
+
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''})
|
556
|
+
assert !output.empty?
|
557
|
+
assert_css 'article > revhistory', output, 0
|
558
|
+
assert_css 'glossary#_glossary', output, 1
|
559
|
+
|
560
|
+
output = Asciidoctor.render_file(sample_input_path,
|
561
|
+
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''})
|
562
|
+
assert !output.empty?
|
563
|
+
assert_css 'article > revhistory', output, 1
|
564
|
+
assert_xpath '/xmlns:article/xmlns:revhistory/xmlns:revision/xmlns:revnumber[text()="1.0"]', output, 1 # verifies substitutions are performed
|
565
|
+
assert_css 'glossary#_glossary', output, 1
|
566
|
+
end
|
567
|
+
|
568
|
+
test 'should not include docinfo files by default' do
|
569
|
+
sample_input_path = fixture_path('basic.asciidoc')
|
570
|
+
|
571
|
+
output = Asciidoctor.render_file(sample_input_path,
|
572
|
+
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER)
|
573
|
+
assert !output.empty?
|
574
|
+
assert_css 'script[src="modernizr.js"]', output, 0
|
575
|
+
assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
|
576
|
+
|
577
|
+
output = Asciidoctor.render_file(sample_input_path,
|
578
|
+
:header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER)
|
579
|
+
assert !output.empty?
|
580
|
+
assert_css 'productname', output, 0
|
581
|
+
assert_css 'copyright', output, 0
|
582
|
+
end
|
583
|
+
|
584
|
+
test 'should not include docinfo files if safe mode is SECURE or greater' do
|
585
|
+
sample_input_path = fixture_path('basic.asciidoc')
|
586
|
+
|
587
|
+
output = Asciidoctor.render_file(sample_input_path,
|
588
|
+
:header_footer => true, :attributes => {'docinfo2' => ''})
|
589
|
+
assert !output.empty?
|
590
|
+
assert_css 'script[src="modernizr.js"]', output, 0
|
591
|
+
assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
|
592
|
+
|
593
|
+
output = Asciidoctor.render_file(sample_input_path,
|
594
|
+
:header_footer => true, :backend => 'docbook', :attributes => {'docinfo2' => ''})
|
595
|
+
assert !output.empty?
|
596
|
+
assert_css 'productname', output, 0
|
597
|
+
assert_css 'copyright', output, 0
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
497
601
|
context 'Renderer' do
|
498
602
|
test 'built-in HTML5 views are registered by default' do
|
499
603
|
doc = document_from_string ''
|
@@ -507,8 +611,8 @@ text
|
|
507
611
|
assert !views.nil?
|
508
612
|
assert_equal 36, views.size
|
509
613
|
assert views.has_key? 'document'
|
510
|
-
assert
|
511
|
-
|
614
|
+
assert Asciidoctor.const_defined?(:HTML5)
|
615
|
+
assert Asciidoctor::HTML5.const_defined?(:DocumentTemplate)
|
512
616
|
end
|
513
617
|
|
514
618
|
test 'built-in DocBook45 views are registered when backend is docbook45' do
|
@@ -523,11 +627,40 @@ text
|
|
523
627
|
assert !views.nil?
|
524
628
|
assert_equal 36, views.size
|
525
629
|
assert views.has_key? 'document'
|
526
|
-
assert
|
630
|
+
assert Asciidoctor.const_defined?(:DocBook45)
|
631
|
+
assert Asciidoctor::DocBook45.const_defined?(:DocumentTemplate)
|
632
|
+
end
|
633
|
+
|
634
|
+
test 'built-in DocBook5 views are registered when backend is docbook5' do
|
635
|
+
doc = document_from_string '', :attributes => {'backend' => 'docbook5'}
|
636
|
+
renderer = doc.renderer
|
637
|
+
assert_equal 'docbook5', doc.attributes['backend']
|
638
|
+
assert doc.attributes.has_key? 'backend-docbook5'
|
639
|
+
assert_equal 'docbook', doc.attributes['basebackend']
|
640
|
+
assert doc.attributes.has_key? 'basebackend-docbook'
|
641
|
+
assert !renderer.nil?
|
642
|
+
views = renderer.views
|
643
|
+
assert !views.nil?
|
644
|
+
assert_equal 36, views.size
|
645
|
+
assert views.has_key? 'document'
|
646
|
+
assert Asciidoctor.const_defined?(:DocBook5)
|
647
|
+
assert Asciidoctor::DocBook5.const_defined?(:DocumentTemplate)
|
648
|
+
end
|
649
|
+
|
650
|
+
test 'eRuby implementation should default to ERB' do
|
651
|
+
# intentionally use built-in templates for this test
|
652
|
+
doc = Asciidoctor::Document.new [], :header_footer => true
|
653
|
+
renderer = doc.renderer
|
654
|
+
views = renderer.views
|
655
|
+
assert !views.nil?
|
656
|
+
assert views.has_key? 'document'
|
657
|
+
assert views['document'].is_a?(Asciidoctor::HTML5::DocumentTemplate)
|
527
658
|
assert_equal 'ERB', views['document'].eruby.to_s
|
659
|
+
assert_equal 'ERB', views['document'].template.class.to_s
|
528
660
|
end
|
529
661
|
|
530
662
|
test 'can set erubis as eRuby implementation' do
|
663
|
+
# intentionally use built-in templates for this test
|
531
664
|
doc = Asciidoctor::Document.new [], :eruby => 'erubis', :header_footer => true
|
532
665
|
assert $LOADED_FEATURES.detect {|p| p == 'erubis.rb' || p.end_with?('/erubis.rb') }.nil?
|
533
666
|
renderer = doc.renderer
|
@@ -535,6 +668,7 @@ text
|
|
535
668
|
views = renderer.views
|
536
669
|
assert !views.nil?
|
537
670
|
assert views.has_key? 'document'
|
671
|
+
assert views['document'].is_a?(Asciidoctor::HTML5::DocumentTemplate)
|
538
672
|
assert_equal 'Erubis::FastEruby', views['document'].eruby.to_s
|
539
673
|
assert_equal 'Erubis::FastEruby', views['document'].template.class.to_s
|
540
674
|
end
|
@@ -655,6 +789,20 @@ text
|
|
655
789
|
assert_css '#header h1', output, 1
|
656
790
|
assert_css '#content h1', output, 0
|
657
791
|
end
|
792
|
+
|
793
|
+
test 'should sanitize contents of HTML title element' do
|
794
|
+
input = <<-EOS
|
795
|
+
= *Document* image:logo.png[] _Title_ image:another-logo.png[]
|
796
|
+
|
797
|
+
content
|
798
|
+
EOS
|
799
|
+
|
800
|
+
output = render_string input
|
801
|
+
assert_xpath '/html/head/title[text()="Document Title"]', output, 1
|
802
|
+
nodes = xmlnodes_at_xpath('//*[@id="header"]/h1', output, 1)
|
803
|
+
assert_equal 1, nodes.size
|
804
|
+
assert_match(/<h1><strong>Document<\/strong> <span class="image"><img src="logo.png" alt="logo"><\/span> <em>Title<\/em> <span class="image"><img src="another-logo.png" alt="another-logo"><\/span><\/h1>/, output)
|
805
|
+
end
|
658
806
|
|
659
807
|
test 'should not choke on empty source' do
|
660
808
|
doc = Asciidoctor::Document.new ''
|
@@ -690,7 +838,7 @@ more info...
|
|
690
838
|
assert_xpath '//*[@id="header"]/span[@id="revremark"][text() = "See changelog."]', output, 1
|
691
839
|
end
|
692
840
|
|
693
|
-
test 'with metadata to
|
841
|
+
test 'with metadata to DocBook45' do
|
694
842
|
input = <<-EOS
|
695
843
|
= AsciiDoc
|
696
844
|
Stuart Rackham <founder@asciidoc.org>
|
@@ -715,6 +863,24 @@ more info...
|
|
715
863
|
assert_xpath '/article/articleinfo/revhistory/revision/revremark[text() = "See changelog."]', output, 1
|
716
864
|
end
|
717
865
|
|
866
|
+
test 'with metadata to DocBook5' do
|
867
|
+
input = <<-EOS
|
868
|
+
= AsciiDoc
|
869
|
+
Stuart Rackham <founder@asciidoc.org>
|
870
|
+
|
871
|
+
== Version 8.6.8
|
872
|
+
|
873
|
+
more info...
|
874
|
+
EOS
|
875
|
+
output = render_string input, :backend => 'docbook5'
|
876
|
+
assert_xpath '/article/info', output, 1
|
877
|
+
assert_xpath '/article/info/title[text() = "AsciiDoc"]', output, 1
|
878
|
+
assert_xpath '/article/info/author/personname', output, 1
|
879
|
+
assert_xpath '/article/info/author/personname/firstname[text() = "Stuart"]', output, 1
|
880
|
+
assert_xpath '/article/info/author/personname/surname[text() = "Rackham"]', output, 1
|
881
|
+
assert_xpath '/article/info/author/email[text() = "founder@asciidoc.org"]', output, 1
|
882
|
+
end
|
883
|
+
|
718
884
|
test 'with author defined using attribute entry to DocBook' do
|
719
885
|
input = <<-EOS
|
720
886
|
= Document Title
|
@@ -732,6 +898,27 @@ content
|
|
732
898
|
assert_xpath '//articleinfo/authorinitials[text() = "DW"]', output, 1
|
733
899
|
end
|
734
900
|
|
901
|
+
test 'should include multiple authors in HTML output' do
|
902
|
+
input = <<-EOS
|
903
|
+
= Document Title
|
904
|
+
Doc Writer <thedoctor@asciidoc.org>; Junior Writer <junior@asciidoctor.org>
|
905
|
+
|
906
|
+
content
|
907
|
+
EOS
|
908
|
+
|
909
|
+
output = render_string input
|
910
|
+
assert_xpath '//span[@id="author"]', output, 1
|
911
|
+
assert_xpath '//span[@id="author"][text()="Doc Writer"]', output, 1
|
912
|
+
assert_xpath '//span[@id="email"]', output, 1
|
913
|
+
assert_xpath '//span[@id="email"]/a', output, 1
|
914
|
+
assert_xpath '//span[@id="email"]/a[@href="mailto:thedoctor@asciidoc.org"][text()="thedoctor@asciidoc.org"]', output, 1
|
915
|
+
assert_xpath '//span[@id="author2"]', output, 1
|
916
|
+
assert_xpath '//span[@id="author2"][text()="Junior Writer"]', output, 1
|
917
|
+
assert_xpath '//span[@id="email2"]', output, 1
|
918
|
+
assert_xpath '//span[@id="email2"]/a', output, 1
|
919
|
+
assert_xpath '//span[@id="email2"]/a[@href="mailto:junior@asciidoctor.org"][text()="junior@asciidoctor.org"]', output, 1
|
920
|
+
end
|
921
|
+
|
735
922
|
test 'should create authorgroup in DocBook when multiple authors' do
|
736
923
|
input = <<-EOS
|
737
924
|
= Document Title
|
@@ -779,6 +966,13 @@ content
|
|
779
966
|
assert_xpath '//*[@id="preamble"]', result, 1
|
780
967
|
end
|
781
968
|
|
969
|
+
test 'can disable last updated in footer' do
|
970
|
+
doc = document_from_string "= Document Title\n\npreamble", :attributes => {'last-update-label!' => ''}
|
971
|
+
result = doc.render
|
972
|
+
assert_xpath '//*[@id="footer-text"]', result, 1
|
973
|
+
assert_xpath '//*[@id="footer-text"][normalize-space(text())=""]', result, 1
|
974
|
+
end
|
975
|
+
|
782
976
|
test 'no header footer' do
|
783
977
|
doc = document_from_string "= Title\n\npreamble", :header_footer => false
|
784
978
|
assert doc.attr?('embedded')
|
@@ -790,8 +984,31 @@ content
|
|
790
984
|
assert_xpath '/*[@id="preamble"]', result, 1
|
791
985
|
end
|
792
986
|
|
793
|
-
test 'enable title
|
794
|
-
|
987
|
+
test 'enable title in embedded document by unassigning notitle attribute' do
|
988
|
+
input = <<-EOS
|
989
|
+
= Document Title
|
990
|
+
|
991
|
+
content
|
992
|
+
EOS
|
993
|
+
|
994
|
+
result = render_string input, :header_footer => false, :attributes => {'notitle!' => ''}
|
995
|
+
assert_xpath '/html', result, 0
|
996
|
+
assert_xpath '/h1', result, 1
|
997
|
+
assert_xpath '/*[@id="header"]', result, 0
|
998
|
+
assert_xpath '/*[@id="footer"]', result, 0
|
999
|
+
assert_xpath '/*[@id="preamble"]', result, 1
|
1000
|
+
assert_xpath '(/*)[1]/self::h1', result, 1
|
1001
|
+
assert_xpath '(/*)[2]/self::*[@id="preamble"]', result, 1
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
test 'enable title in embedded document by assigning showtitle attribute' do
|
1005
|
+
input = <<-EOS
|
1006
|
+
= Document Title
|
1007
|
+
|
1008
|
+
content
|
1009
|
+
EOS
|
1010
|
+
|
1011
|
+
result = render_string input, :header_footer => false, :attributes => {'showtitle' => ''}
|
795
1012
|
assert_xpath '/html', result, 0
|
796
1013
|
assert_xpath '/h1', result, 1
|
797
1014
|
assert_xpath '/*[@id="header"]', result, 0
|
@@ -900,6 +1117,11 @@ section body
|
|
900
1117
|
assert_xpath '/article/simpara[text() = "text"]', result, 1
|
901
1118
|
end
|
902
1119
|
|
1120
|
+
test 'docbook45 backend doctype article no xmlns' do
|
1121
|
+
result = render_string('text', :keep_namespaces => true, :attributes => {'backend' => 'docbook45', 'doctype' => 'article', 'noxmlns' => ''})
|
1122
|
+
assert_no_match(RE_XMLNS_ATTRIBUTE, result)
|
1123
|
+
end
|
1124
|
+
|
903
1125
|
test 'docbook45 backend doctype book' do
|
904
1126
|
input = <<-EOS
|
905
1127
|
= Title
|
@@ -926,6 +1148,11 @@ chapter body
|
|
926
1148
|
assert_xpath '/book/simpara[text() = "text"]', result, 1
|
927
1149
|
end
|
928
1150
|
|
1151
|
+
test 'docbook45 backend doctype book no xmlns' do
|
1152
|
+
result = render_string('text', :keep_namespaces => true, :attributes => {'backend' => 'docbook45', 'doctype' => 'book', 'noxmlns' => ''})
|
1153
|
+
assert_no_match(RE_XMLNS_ATTRIBUTE, result)
|
1154
|
+
end
|
1155
|
+
|
929
1156
|
test 'docbook45 backend parses out subtitle' do
|
930
1157
|
input = <<-EOS
|
931
1158
|
= Document Title: Subtitle
|
@@ -939,6 +1166,64 @@ text
|
|
939
1166
|
assert_xpath '/book/bookinfo/subtitle[text() = "Subtitle"]', result, 1
|
940
1167
|
end
|
941
1168
|
|
1169
|
+
test 'docbook5 backend doctype article' do
|
1170
|
+
input = <<-EOS
|
1171
|
+
= Title
|
1172
|
+
Author Name
|
1173
|
+
|
1174
|
+
preamble
|
1175
|
+
|
1176
|
+
== First Section
|
1177
|
+
|
1178
|
+
section body
|
1179
|
+
EOS
|
1180
|
+
result = render_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5'})
|
1181
|
+
assert_xpath '/xmlns:article', result, 1
|
1182
|
+
doc = xmlnodes_at_xpath('/xmlns:article', result, 1).first
|
1183
|
+
assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
|
1184
|
+
assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xlink']
|
1185
|
+
assert_xpath '/xmlns:article[@version="5.0"]', result, 1
|
1186
|
+
assert_xpath '/xmlns:article/xmlns:info/xmlns:title[text() = "Title"]', result, 1
|
1187
|
+
assert_xpath '/xmlns:article/xmlns:simpara[text() = "preamble"]', result, 1
|
1188
|
+
assert_xpath '/xmlns:article/xmlns:section', result, 1
|
1189
|
+
section = xmlnodes_at_xpath('/xmlns:article/xmlns:section', result, 1).first
|
1190
|
+
# nokogiri can't make up its mind
|
1191
|
+
id_attr = section.attribute('id') || section.attribute('xml:id')
|
1192
|
+
assert_not_nil id_attr
|
1193
|
+
assert_not_nil id_attr.namespace
|
1194
|
+
assert_equal 'xml', id_attr.namespace.prefix
|
1195
|
+
assert_equal '_first_section', id_attr.value
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
test 'docbook5 backend doctype book' do
|
1199
|
+
input = <<-EOS
|
1200
|
+
= Title
|
1201
|
+
Author Name
|
1202
|
+
|
1203
|
+
preamble
|
1204
|
+
|
1205
|
+
== First Chapter
|
1206
|
+
|
1207
|
+
chapter body
|
1208
|
+
EOS
|
1209
|
+
result = render_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5', 'doctype' => 'book'})
|
1210
|
+
assert_xpath '/xmlns:book', result, 1
|
1211
|
+
doc = xmlnodes_at_xpath('/xmlns:book', result, 1).first
|
1212
|
+
assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
|
1213
|
+
assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xlink']
|
1214
|
+
assert_xpath '/xmlns:book[@version="5.0"]', result, 1
|
1215
|
+
assert_xpath '/xmlns:book/xmlns:info/xmlns:title[text() = "Title"]', result, 1
|
1216
|
+
assert_xpath '/xmlns:book/xmlns:preface/xmlns:simpara[text() = "preamble"]', result, 1
|
1217
|
+
assert_xpath '/xmlns:book/xmlns:chapter', result, 1
|
1218
|
+
chapter = xmlnodes_at_xpath('/xmlns:book/xmlns:chapter', result, 1).first
|
1219
|
+
# nokogiri can't make up its mind
|
1220
|
+
id_attr = chapter.attribute('id') || chapter.attribute('xml:id')
|
1221
|
+
assert_not_nil id_attr
|
1222
|
+
assert_not_nil id_attr.namespace
|
1223
|
+
assert_equal 'xml', id_attr.namespace.prefix
|
1224
|
+
assert_equal '_first_chapter', id_attr.value
|
1225
|
+
end
|
1226
|
+
|
942
1227
|
test 'should be able to set backend using :backend option key' do
|
943
1228
|
doc = Asciidoctor::Document.new([], :backend => 'html5')
|
944
1229
|
assert_equal 'html5', doc.attributes['backend']
|
@@ -998,5 +1283,135 @@ preamble
|
|
998
1283
|
assert_equal '', doc.attr('toc')
|
999
1284
|
assert_equal 'Dan Allen', doc.attr('author')
|
1000
1285
|
end
|
1286
|
+
|
1287
|
+
test 'should parse mantitle and manvolnum from document title for manpage doctype' do
|
1288
|
+
input = <<-EOS
|
1289
|
+
= asciidoctor ( 1 )
|
1290
|
+
:doctype: manpage
|
1291
|
+
|
1292
|
+
== NAME
|
1293
|
+
|
1294
|
+
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
1295
|
+
EOS
|
1296
|
+
|
1297
|
+
doc = document_from_string input
|
1298
|
+
assert_equal 'asciidoctor', doc.attr('mantitle')
|
1299
|
+
assert_equal '1', doc.attr('manvolnum')
|
1300
|
+
end
|
1301
|
+
|
1302
|
+
test 'should perform attribute substitution on mantitle in manpage doctype' do
|
1303
|
+
input = <<-EOS
|
1304
|
+
= {app}(1)
|
1305
|
+
:doctype: manpage
|
1306
|
+
:app: asciidoctor
|
1307
|
+
|
1308
|
+
== NAME
|
1309
|
+
|
1310
|
+
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
1311
|
+
EOS
|
1312
|
+
|
1313
|
+
doc = document_from_string input
|
1314
|
+
assert_equal 'asciidoctor', doc.attr('mantitle')
|
1315
|
+
end
|
1316
|
+
|
1317
|
+
test 'should consume name section as manname and manpurpose for manpage doctype' do
|
1318
|
+
input = <<-EOS
|
1319
|
+
= asciidoctor(1)
|
1320
|
+
:doctype: manpage
|
1321
|
+
|
1322
|
+
== NAME
|
1323
|
+
|
1324
|
+
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
1325
|
+
EOS
|
1326
|
+
|
1327
|
+
doc = document_from_string input
|
1328
|
+
assert_equal 'asciidoctor', doc.attr('manname')
|
1329
|
+
assert_equal 'converts AsciiDoc source files to HTML, DocBook and other formats', doc.attr('manpurpose')
|
1330
|
+
assert_equal 0, doc.blocks.size
|
1331
|
+
end
|
1332
|
+
|
1333
|
+
test 'should set docname and outfilesuffix from manname and manvolnum for manpage backend and doctype' do
|
1334
|
+
input = <<-EOS
|
1335
|
+
= asciidoctor(1)
|
1336
|
+
:doctype: manpage
|
1337
|
+
|
1338
|
+
== NAME
|
1339
|
+
|
1340
|
+
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
1341
|
+
EOS
|
1342
|
+
|
1343
|
+
doc = document_from_string input, :backend => 'manpage'
|
1344
|
+
assert_equal 'asciidoctor', doc.attributes['docname']
|
1345
|
+
assert_equal '.1', doc.attributes['outfilesuffix']
|
1346
|
+
end
|
1347
|
+
|
1348
|
+
test 'should mark synopsis as special section in manpage doctype' do
|
1349
|
+
input = <<-EOS
|
1350
|
+
= asciidoctor(1)
|
1351
|
+
:doctype: manpage
|
1352
|
+
|
1353
|
+
== NAME
|
1354
|
+
|
1355
|
+
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
1356
|
+
|
1357
|
+
== SYNOPSIS
|
1358
|
+
|
1359
|
+
*asciidoctor* ['OPTION']... 'FILE'..
|
1360
|
+
EOS
|
1361
|
+
|
1362
|
+
doc = document_from_string input
|
1363
|
+
synopsis_section = doc.blocks.first
|
1364
|
+
assert_not_nil synopsis_section
|
1365
|
+
assert_equal :section, synopsis_section.context
|
1366
|
+
assert synopsis_section.special
|
1367
|
+
assert_equal 'synopsis', synopsis_section.sectname
|
1368
|
+
end
|
1369
|
+
|
1370
|
+
test 'should output special header block in HTML for manpage doctype' do
|
1371
|
+
input = <<-EOS
|
1372
|
+
= asciidoctor(1)
|
1373
|
+
:doctype: manpage
|
1374
|
+
|
1375
|
+
== NAME
|
1376
|
+
|
1377
|
+
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
1378
|
+
|
1379
|
+
== SYNOPSIS
|
1380
|
+
|
1381
|
+
*asciidoctor* ['OPTION']... 'FILE'..
|
1382
|
+
EOS
|
1383
|
+
|
1384
|
+
output = render_string input
|
1385
|
+
assert_css 'body.manpage', output, 1
|
1386
|
+
assert_xpath '//body/*[@id="header"]/h1[text()="asciidoctor(1) Manual Page"]', output, 1
|
1387
|
+
assert_xpath '//body/*[@id="header"]/h1/following-sibling::h2[text()="NAME"]', output, 1
|
1388
|
+
assert_xpath '//h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]', output, 1
|
1389
|
+
assert_xpath '//h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]/p[text()="asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats"]', output, 1
|
1390
|
+
assert_xpath '//*[@id="content"]/*[@class="sect1"]/h2[text()="SYNOPSIS"]', output, 1
|
1391
|
+
end
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
context 'Secure Asset Path' do
|
1395
|
+
test 'allows us to specify a path relative to the current dir' do
|
1396
|
+
doc = Asciidoctor::Document.new
|
1397
|
+
legit_path = Dir.pwd + '/foo'
|
1398
|
+
assert_equal legit_path, doc.normalize_asset_path(legit_path)
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
test 'keeps naughty absolute paths from getting outside' do
|
1402
|
+
naughty_path = "#{disk_root}etc/passwd"
|
1403
|
+
doc = Asciidoctor::Document.new
|
1404
|
+
secure_path = doc.normalize_asset_path(naughty_path)
|
1405
|
+
assert naughty_path != secure_path
|
1406
|
+
assert_match(/^#{doc.base_dir}/, secure_path)
|
1407
|
+
end
|
1408
|
+
|
1409
|
+
test 'keeps naughty relative paths from getting outside' do
|
1410
|
+
naughty_path = 'safe/ok/../../../../../etc/passwd'
|
1411
|
+
doc = Asciidoctor::Document.new
|
1412
|
+
secure_path = doc.normalize_asset_path(naughty_path)
|
1413
|
+
assert naughty_path != secure_path
|
1414
|
+
assert_match(/^#{doc.base_dir}/, secure_path)
|
1415
|
+
end
|
1001
1416
|
end
|
1002
1417
|
end
|