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/attributes_test.rb
CHANGED
@@ -181,6 +181,69 @@ Yo, {myfrog}!
|
|
181
181
|
assert_match(/_cool_title/, result.css('h2').first.attr('id'))
|
182
182
|
end
|
183
183
|
|
184
|
+
test 'interpolates attribute defined in header inside attribute entry in header' do
|
185
|
+
input = <<-EOS
|
186
|
+
= Title
|
187
|
+
Author Name
|
188
|
+
:attribute-a: value
|
189
|
+
:attribute-b: {attribute-a}
|
190
|
+
|
191
|
+
preamble
|
192
|
+
EOS
|
193
|
+
doc = document_from_string(input, :parse_header_only => true)
|
194
|
+
assert_equal 'value', doc.attributes['attribute-b']
|
195
|
+
end
|
196
|
+
|
197
|
+
test 'interpolates author attribute inside attribute entry in header' do
|
198
|
+
input = <<-EOS
|
199
|
+
= Title
|
200
|
+
Author Name
|
201
|
+
:name: {author}
|
202
|
+
|
203
|
+
preamble
|
204
|
+
EOS
|
205
|
+
doc = document_from_string(input, :parse_header_only => true)
|
206
|
+
assert_equal 'Author Name', doc.attributes['name']
|
207
|
+
end
|
208
|
+
|
209
|
+
test 'interpolates revinfo attribute inside attribute entry in header' do
|
210
|
+
input = <<-EOS
|
211
|
+
= Title
|
212
|
+
Author Name
|
213
|
+
2013-01-01
|
214
|
+
:date: {revdate}
|
215
|
+
|
216
|
+
preamble
|
217
|
+
EOS
|
218
|
+
doc = document_from_string(input, :parse_header_only => true)
|
219
|
+
assert_equal '2013-01-01', doc.attributes['date']
|
220
|
+
end
|
221
|
+
|
222
|
+
test 'attribute entries can resolve previously defined attributes' do
|
223
|
+
input = <<-EOS
|
224
|
+
= Title
|
225
|
+
Author Name
|
226
|
+
v1.0, 2010-01-01: First release!
|
227
|
+
:a: value
|
228
|
+
:a2: {a}
|
229
|
+
:revdate2: {revdate}
|
230
|
+
|
231
|
+
{a} == {a2}
|
232
|
+
|
233
|
+
{revdate} == {revdate2}
|
234
|
+
EOS
|
235
|
+
|
236
|
+
doc = document_from_string input
|
237
|
+
assert_equal '2010-01-01', doc.attr('revdate')
|
238
|
+
assert_equal '2010-01-01', doc.attr('revdate2')
|
239
|
+
assert_equal 'value', doc.attr('a')
|
240
|
+
assert_equal 'value', doc.attr('a2')
|
241
|
+
|
242
|
+
output = doc.render
|
243
|
+
assert output.include?('value == value')
|
244
|
+
assert output.include?('2010-01-01 == 2010-01-01')
|
245
|
+
end
|
246
|
+
|
184
247
|
test 'substitutes inside block title' do
|
185
248
|
input = <<-EOS
|
186
249
|
:gem_name: asciidoctor
|
@@ -189,7 +252,7 @@ Yo, {myfrog}!
|
|
189
252
|
To use {gem_name}, the first thing to do is to import it in your Ruby source file.
|
190
253
|
EOS
|
191
254
|
output = render_embedded_string input
|
192
|
-
assert_xpath '//*[@class="title"]/
|
255
|
+
assert_xpath '//*[@class="title"]/code[text()="asciidoctor"]', output, 1
|
193
256
|
end
|
194
257
|
|
195
258
|
test 'renders attribute until it is deleted' do
|
@@ -365,10 +428,10 @@ of the attribute named foo in your document.
|
|
365
428
|
|
366
429
|
end
|
367
430
|
|
368
|
-
context
|
369
|
-
test
|
431
|
+
context 'Block attributes' do
|
432
|
+
test 'Positional attributes assigned to block' do
|
370
433
|
input = <<-EOS
|
371
|
-
[quote,
|
434
|
+
[quote, author, source]
|
372
435
|
____
|
373
436
|
A famous quote.
|
374
437
|
____
|
@@ -377,13 +440,13 @@ ____
|
|
377
440
|
qb = doc.blocks.first
|
378
441
|
assert_equal 'quote', qb.attributes['style']
|
379
442
|
assert_equal 'quote', qb.attr(:style)
|
380
|
-
assert_equal '
|
381
|
-
assert_equal '
|
443
|
+
assert_equal 'author', qb.attributes['attribution']
|
444
|
+
assert_equal 'source', qb.attributes['citetitle']
|
382
445
|
end
|
383
446
|
|
384
|
-
test
|
447
|
+
test 'Normal substitutions are performed on single-quoted attributes' do
|
385
448
|
input = <<-EOS
|
386
|
-
[quote,
|
449
|
+
[quote, author, 'http://wikipedia.org[source]']
|
387
450
|
____
|
388
451
|
A famous quote.
|
389
452
|
____
|
@@ -392,8 +455,68 @@ ____
|
|
392
455
|
qb = doc.blocks.first
|
393
456
|
assert_equal 'quote', qb.attributes['style']
|
394
457
|
assert_equal 'quote', qb.attr(:style)
|
395
|
-
assert_equal '
|
396
|
-
assert_equal '<a href="http://wikipedia.org">
|
458
|
+
assert_equal 'author', qb.attributes['attribution']
|
459
|
+
assert_equal '<a href="http://wikipedia.org">source</a>', qb.attributes['citetitle']
|
460
|
+
end
|
461
|
+
|
462
|
+
test 'attribute list may begin with space' do
|
463
|
+
input = <<-EOS
|
464
|
+
[ quote]
|
465
|
+
____
|
466
|
+
A famous quote.
|
467
|
+
____
|
468
|
+
EOS
|
469
|
+
|
470
|
+
doc = document_from_string input
|
471
|
+
qb = doc.blocks.first
|
472
|
+
assert_equal 'quote', qb.attributes['style']
|
473
|
+
end
|
474
|
+
|
475
|
+
test 'attribute list may begin with comma' do
|
476
|
+
input = <<-EOS
|
477
|
+
[, author, source]
|
478
|
+
____
|
479
|
+
A famous quote.
|
480
|
+
____
|
481
|
+
EOS
|
482
|
+
|
483
|
+
doc = document_from_string input
|
484
|
+
qb = doc.blocks.first
|
485
|
+
assert_equal 'quote', qb.attributes['style']
|
486
|
+
assert_equal 'author', qb.attributes['attribution']
|
487
|
+
assert_equal 'source', qb.attributes['citetitle']
|
488
|
+
end
|
489
|
+
|
490
|
+
test 'first attribute in list may be double quoted' do
|
491
|
+
input = <<-EOS
|
492
|
+
["quote", "author", "source", role="famous"]
|
493
|
+
____
|
494
|
+
A famous quote.
|
495
|
+
____
|
496
|
+
EOS
|
497
|
+
|
498
|
+
doc = document_from_string input
|
499
|
+
qb = doc.blocks.first
|
500
|
+
assert_equal 'quote', qb.attributes['style']
|
501
|
+
assert_equal 'author', qb.attributes['attribution']
|
502
|
+
assert_equal 'source', qb.attributes['citetitle']
|
503
|
+
assert_equal 'famous', qb.attributes['role']
|
504
|
+
end
|
505
|
+
|
506
|
+
test 'first attribute in list may be single quoted' do
|
507
|
+
input = <<-EOS
|
508
|
+
['quote', 'author', 'source', role='famous']
|
509
|
+
____
|
510
|
+
A famous quote.
|
511
|
+
____
|
512
|
+
EOS
|
513
|
+
|
514
|
+
doc = document_from_string input
|
515
|
+
qb = doc.blocks.first
|
516
|
+
assert_equal 'quote', qb.attributes['style']
|
517
|
+
assert_equal 'author', qb.attributes['attribution']
|
518
|
+
assert_equal 'source', qb.attributes['citetitle']
|
519
|
+
assert_equal 'famous', qb.attributes['role']
|
397
520
|
end
|
398
521
|
|
399
522
|
test "Attribute substitutions are performed on attribute list before parsing attributes" do
|
data/test/blocks_test.rb
CHANGED
@@ -18,9 +18,9 @@ context "Blocks" do
|
|
18
18
|
|
19
19
|
test "page break" do
|
20
20
|
output = render_embedded_string("page 1\n\n<<<\n\npage 2")
|
21
|
-
assert_xpath '/*[@style="page-break-after: always"]', output, 1
|
22
|
-
assert_xpath '/*[@style="page-break-after: always"]/preceding-sibling::div/p[text()="page 1"]', output, 1
|
23
|
-
assert_xpath '/*[@style="page-break-after: always"]/following-sibling::div/p[text()="page 2"]', output, 1
|
21
|
+
assert_xpath '/*[@style="page-break-after: always;"]', output, 1
|
22
|
+
assert_xpath '/*[@style="page-break-after: always;"]/preceding-sibling::div/p[text()="page 1"]', output, 1
|
23
|
+
assert_xpath '/*[@style="page-break-after: always;"]/following-sibling::div/p[text()="page 2"]', output, 1
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -239,7 +239,7 @@ TIP: Override the caption of an admonition block using an attribute entry
|
|
239
239
|
EOS
|
240
240
|
|
241
241
|
output = render_embedded_string input
|
242
|
-
assert_xpath '/*[@class="admonitionblock"]//*[@class="icon"]/*[@class="title"][text()="Pro Tip"]', output, 1
|
242
|
+
assert_xpath '/*[@class="admonitionblock tip"]//*[@class="icon"]/*[@class="title"][text()="Pro Tip"]', output, 1
|
243
243
|
end
|
244
244
|
|
245
245
|
test 'can override caption of admonition block using document attribute' do
|
@@ -250,7 +250,7 @@ TIP: Override the caption of an admonition block using an attribute entry
|
|
250
250
|
EOS
|
251
251
|
|
252
252
|
output = render_embedded_string input
|
253
|
-
assert_xpath '/*[@class="admonitionblock"]//*[@class="icon"]/*[@class="title"][text()="Pro Tip"]', output, 1
|
253
|
+
assert_xpath '/*[@class="admonitionblock tip"]//*[@class="icon"]/*[@class="title"][text()="Pro Tip"]', output, 1
|
254
254
|
end
|
255
255
|
|
256
256
|
test 'blank caption document attribute should not blank admonition block caption' do
|
@@ -261,7 +261,7 @@ TIP: Override the caption of an admonition block using an attribute entry
|
|
261
261
|
EOS
|
262
262
|
|
263
263
|
output = render_embedded_string input
|
264
|
-
assert_xpath '/*[@class="admonitionblock"]//*[@class="icon"]/*[@class="title"][text()="Tip"]', output, 1
|
264
|
+
assert_xpath '/*[@class="admonitionblock tip"]//*[@class="icon"]/*[@class="title"][text()="Tip"]', output, 1
|
265
265
|
end
|
266
266
|
end
|
267
267
|
|
@@ -367,6 +367,23 @@ EOS
|
|
367
367
|
}
|
368
368
|
end
|
369
369
|
|
370
|
+
test 'should not compact nested document twice' do
|
371
|
+
input = <<-EOS
|
372
|
+
|===
|
373
|
+
a|....
|
374
|
+
line one
|
375
|
+
|
376
|
+
line two
|
377
|
+
|
378
|
+
line three
|
379
|
+
....
|
380
|
+
|===
|
381
|
+
EOS
|
382
|
+
|
383
|
+
output = render_string input, :compact => true
|
384
|
+
assert_xpath %(//pre[text() = "line one\n\nline two\n\nline three"]), output, 1
|
385
|
+
end
|
386
|
+
|
370
387
|
test 'should process block with CRLF endlines' do
|
371
388
|
input = <<-EOS
|
372
389
|
[source]\r
|
@@ -382,6 +399,54 @@ source line 2\r
|
|
382
399
|
assert_xpath '/*[@class="listingblock"]//pre/code', output, 1
|
383
400
|
assert_xpath %(/*[@class="listingblock"]//pre/code[text()="source line 1\nsource line 2"]), output, 1
|
384
401
|
end
|
402
|
+
|
403
|
+
test 'literal block should honor explicit subs list' do
|
404
|
+
input = <<-EOS
|
405
|
+
[subs="verbatim,quotes"]
|
406
|
+
----
|
407
|
+
Map<String, String> *attributes*; //<1>
|
408
|
+
----
|
409
|
+
EOS
|
410
|
+
|
411
|
+
output = render_embedded_string input
|
412
|
+
assert output.include?('Map<String, String> <strong>attributes</strong>;')
|
413
|
+
assert output.include?('1')
|
414
|
+
end
|
415
|
+
|
416
|
+
test 'listing block should honor explicit subs list' do
|
417
|
+
input = <<-EOS
|
418
|
+
[subs="specialcharacters,quotes"]
|
419
|
+
----
|
420
|
+
$ *python functional_tests.py*
|
421
|
+
Traceback (most recent call last):
|
422
|
+
File "functional_tests.py", line 4, in <module>
|
423
|
+
assert 'Django' in browser.title
|
424
|
+
AssertionError
|
425
|
+
----
|
426
|
+
EOS
|
427
|
+
|
428
|
+
output = render_embedded_string input
|
429
|
+
|
430
|
+
assert_css '.listingblock pre', output, 1
|
431
|
+
assert_css '.listingblock pre strong', output, 1
|
432
|
+
assert_css '.listingblock pre em', output, 1
|
433
|
+
|
434
|
+
input2 = <<-EOS
|
435
|
+
[subs="specialcharacters,macros"]
|
436
|
+
----
|
437
|
+
$ pass:quotes[*python functional_tests.py*]
|
438
|
+
Traceback (most recent call last):
|
439
|
+
File "functional_tests.py", line 4, in <module>
|
440
|
+
assert pass:quotes['Django'] in browser.title
|
441
|
+
AssertionError
|
442
|
+
----
|
443
|
+
EOS
|
444
|
+
|
445
|
+
output2 = render_embedded_string input2
|
446
|
+
# FIXME JRuby is adding extra trailing endlines in the second document,
|
447
|
+
# so rstrip is necessary
|
448
|
+
assert_equal output.rstrip, output2.rstrip
|
449
|
+
end
|
385
450
|
end
|
386
451
|
|
387
452
|
context "Open Blocks" do
|
@@ -500,10 +565,36 @@ paragraph
|
|
500
565
|
output = render_string input
|
501
566
|
assert_xpath '//*[@class="sect1"]//*[@class="paragraph"]/*[@class="title"][text() = "Block title"]', output, 1
|
502
567
|
end
|
568
|
+
|
569
|
+
test 'empty attribute list should not appear in output' do
|
570
|
+
input = <<-EOS
|
571
|
+
[]
|
572
|
+
--
|
573
|
+
Block content
|
574
|
+
--
|
575
|
+
EOS
|
576
|
+
|
577
|
+
output = render_embedded_string input
|
578
|
+
assert output.include?('Block content')
|
579
|
+
assert !output.include?('[]')
|
580
|
+
end
|
581
|
+
|
582
|
+
test 'empty block anchor should not appear in output' do
|
583
|
+
input = <<-EOS
|
584
|
+
[[]]
|
585
|
+
--
|
586
|
+
Block content
|
587
|
+
--
|
588
|
+
EOS
|
589
|
+
|
590
|
+
output = render_embedded_string input
|
591
|
+
assert output.include?('Block content')
|
592
|
+
assert !output.include?('[[]]')
|
593
|
+
end
|
503
594
|
end
|
504
595
|
|
505
|
-
context
|
506
|
-
test
|
596
|
+
context 'Images' do
|
597
|
+
test 'can render block image with alt text defined in macro' do
|
507
598
|
input = <<-EOS
|
508
599
|
image::images/tiger.png[Tiger]
|
509
600
|
EOS
|
@@ -512,6 +603,36 @@ image::images/tiger.png[Tiger]
|
|
512
603
|
assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
513
604
|
end
|
514
605
|
|
606
|
+
test 'can render block image with alt text defined in macro containing escaped square bracket' do
|
607
|
+
input = <<-EOS
|
608
|
+
image::images/tiger.png[A [Bengal\\] Tiger]
|
609
|
+
EOS
|
610
|
+
|
611
|
+
output = render_string input
|
612
|
+
img = xmlnodes_at_xpath '//img', output, 1
|
613
|
+
assert_equal 'A [Bengal] Tiger', img.attr('alt').value
|
614
|
+
end
|
615
|
+
|
616
|
+
test 'can render block image with alt text defined in block attribute above macro' do
|
617
|
+
input = <<-EOS
|
618
|
+
[Tiger]
|
619
|
+
image::images/tiger.png[]
|
620
|
+
EOS
|
621
|
+
|
622
|
+
output = render_string input
|
623
|
+
assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
624
|
+
end
|
625
|
+
|
626
|
+
test 'alt text in macro overrides alt text above macro' do
|
627
|
+
input = <<-EOS
|
628
|
+
[Alt Text]
|
629
|
+
image::images/tiger.png[Tiger]
|
630
|
+
EOS
|
631
|
+
|
632
|
+
output = render_string input
|
633
|
+
assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
634
|
+
end
|
635
|
+
|
515
636
|
test "can render block image with auto-generated alt text" do
|
516
637
|
input = <<-EOS
|
517
638
|
image::images/tiger.png[]
|
@@ -552,7 +673,43 @@ image::images/tiger.png[Tiger]
|
|
552
673
|
assert_equal 1, doc.attributes['figure-number']
|
553
674
|
end
|
554
675
|
|
555
|
-
test '
|
676
|
+
test 'can render block image with explicit caption' do
|
677
|
+
input = <<-EOS
|
678
|
+
[caption="Voila! "]
|
679
|
+
.The AsciiDoc Tiger
|
680
|
+
image::images/tiger.png[Tiger]
|
681
|
+
EOS
|
682
|
+
|
683
|
+
doc = document_from_string input
|
684
|
+
output = doc.render
|
685
|
+
assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
686
|
+
assert_xpath '//*[@class="imageblock"]/*[@class="title"][text() = "Voila! The AsciiDoc Tiger"]', output, 1
|
687
|
+
assert !doc.attributes.has_key?('figure-number')
|
688
|
+
end
|
689
|
+
|
690
|
+
test 'drops line if image target is missing attribute reference' do
|
691
|
+
input = <<-EOS
|
692
|
+
image::{bogus}[]
|
693
|
+
EOS
|
694
|
+
|
695
|
+
output = render_embedded_string input
|
696
|
+
assert output.strip.empty?
|
697
|
+
end
|
698
|
+
|
699
|
+
test 'dropped image does not break processing of following section' do
|
700
|
+
input = <<-EOS
|
701
|
+
image::{bogus}[]
|
702
|
+
|
703
|
+
== Section Title
|
704
|
+
EOS
|
705
|
+
|
706
|
+
output = render_embedded_string input
|
707
|
+
assert_css 'img', output, 0
|
708
|
+
assert_css 'h2', output, 1
|
709
|
+
assert !output.include?('== Section Title')
|
710
|
+
end
|
711
|
+
|
712
|
+
test 'should pass through image that references uri' do
|
556
713
|
input = <<-EOS
|
557
714
|
:imagesdir: images
|
558
715
|
|
@@ -589,19 +746,147 @@ image::dot.gif[Dot]
|
|
589
746
|
end
|
590
747
|
|
591
748
|
# this test will cause a warning to be printed to the console (until we have a message facility)
|
592
|
-
test 'cleans reference to ancestor directories before reading image if safe mode level is at least SAFE' do
|
749
|
+
test 'cleans reference to ancestor directories in imagesdir before reading image if safe mode level is at least SAFE' do
|
593
750
|
input = <<-EOS
|
594
751
|
:data-uri:
|
595
|
-
:imagesdir:
|
752
|
+
:imagesdir: ../..//fixtures/./../../fixtures
|
596
753
|
|
597
754
|
image::dot.gif[Dot]
|
598
755
|
EOS
|
599
756
|
|
600
757
|
doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
|
601
|
-
assert_equal '
|
758
|
+
assert_equal '../..//fixtures/./../../fixtures', doc.attributes['imagesdir']
|
602
759
|
output = doc.render
|
760
|
+
# image target resolves to fixtures/dot.gif relative to docdir (which is explicitly set to the directory of this file)
|
761
|
+
# the reference cannot fall outside of the document directory in safe mode
|
603
762
|
assert_xpath '//*[@class="imageblock"]//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
|
604
763
|
end
|
764
|
+
|
765
|
+
test 'cleans reference to ancestor directories in target before reading image if safe mode level is at least SAFE' do
|
766
|
+
input = <<-EOS
|
767
|
+
:data-uri:
|
768
|
+
:imagesdir: ./
|
769
|
+
|
770
|
+
image::../..//fixtures/./../../fixtures/dot.gif[Dot]
|
771
|
+
EOS
|
772
|
+
|
773
|
+
doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
|
774
|
+
assert_equal './', doc.attributes['imagesdir']
|
775
|
+
output = doc.render
|
776
|
+
# image target resolves to fixtures/dot.gif relative to docdir (which is explicitly set to the directory of this file)
|
777
|
+
# the reference cannot fall outside of the document directory in safe mode
|
778
|
+
assert_xpath '//*[@class="imageblock"]//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
|
779
|
+
end
|
780
|
+
end
|
781
|
+
|
782
|
+
context 'Media' do
|
783
|
+
test 'should detect and render video macro' do
|
784
|
+
input = <<-EOS
|
785
|
+
video::cats-vs-dogs.avi[]
|
786
|
+
EOS
|
787
|
+
|
788
|
+
output = render_embedded_string input
|
789
|
+
assert_css 'video', output, 1
|
790
|
+
assert_css 'video[src="cats-vs-dogs.avi"]', output, 1
|
791
|
+
end
|
792
|
+
|
793
|
+
test 'should detect and render video macro with positional attributes for poster and dimensions' do
|
794
|
+
input = <<-EOS
|
795
|
+
video::cats-vs-dogs.avi[cats-and-dogs.png, 200, 300]
|
796
|
+
EOS
|
797
|
+
|
798
|
+
output = render_embedded_string input
|
799
|
+
assert_css 'video', output, 1
|
800
|
+
assert_css 'video[src="cats-vs-dogs.avi"]', output, 1
|
801
|
+
assert_css 'video[poster="cats-and-dogs.png"]', output, 1
|
802
|
+
assert_css 'video[width="200"]', output, 1
|
803
|
+
assert_css 'video[height="300"]', output, 1
|
804
|
+
end
|
805
|
+
|
806
|
+
test 'video macro should honor all options' do
|
807
|
+
input = <<-EOS
|
808
|
+
video::cats-vs-dogs.avi[options="autoplay,nocontrols,loop"]
|
809
|
+
EOS
|
810
|
+
|
811
|
+
output = render_embedded_string input
|
812
|
+
assert_css 'video', output, 1
|
813
|
+
assert_css 'video[autoplay]', output, 1
|
814
|
+
assert_css 'video:not([controls])', output, 1
|
815
|
+
assert_css 'video[loop]', output, 1
|
816
|
+
end
|
817
|
+
|
818
|
+
test 'video macro should use imagesdir attribute to resolve target and poster' do
|
819
|
+
input = <<-EOS
|
820
|
+
:imagesdir: assets
|
821
|
+
|
822
|
+
video::cats-vs-dogs.avi[cats-and-dogs.png, 200, 300]
|
823
|
+
EOS
|
824
|
+
|
825
|
+
output = render_embedded_string input
|
826
|
+
assert_css 'video', output, 1
|
827
|
+
assert_css 'video[src="assets/cats-vs-dogs.avi"]', output, 1
|
828
|
+
assert_css 'video[poster="assets/cats-and-dogs.png"]', output, 1
|
829
|
+
assert_css 'video[width="200"]', output, 1
|
830
|
+
assert_css 'video[height="300"]', output, 1
|
831
|
+
end
|
832
|
+
|
833
|
+
test 'video macro should not use imagesdir attribute to resolve target if target is a URL' do
|
834
|
+
input = <<-EOS
|
835
|
+
:imagesdir: assets
|
836
|
+
|
837
|
+
video::http://example.org/videos/cats-vs-dogs.avi[]
|
838
|
+
EOS
|
839
|
+
|
840
|
+
output = render_embedded_string input
|
841
|
+
assert_css 'video', output, 1
|
842
|
+
assert_css 'video[src="http://example.org/videos/cats-vs-dogs.avi"]', output, 1
|
843
|
+
end
|
844
|
+
|
845
|
+
test 'should detect and render audio macro' do
|
846
|
+
input = <<-EOS
|
847
|
+
audio::podcast.mp3[]
|
848
|
+
EOS
|
849
|
+
|
850
|
+
output = render_embedded_string input
|
851
|
+
assert_css 'audio', output, 1
|
852
|
+
assert_css 'audio[src="podcast.mp3"]', output, 1
|
853
|
+
end
|
854
|
+
|
855
|
+
test 'audio macro should use imagesdir attribute to resolve target' do
|
856
|
+
input = <<-EOS
|
857
|
+
:imagesdir: assets
|
858
|
+
|
859
|
+
audio::podcast.mp3[]
|
860
|
+
EOS
|
861
|
+
|
862
|
+
output = render_embedded_string input
|
863
|
+
assert_css 'audio', output, 1
|
864
|
+
assert_css 'audio[src="assets/podcast.mp3"]', output, 1
|
865
|
+
end
|
866
|
+
|
867
|
+
test 'audio macro should not use imagesdir attribute to resolve target if target is a URL' do
|
868
|
+
input = <<-EOS
|
869
|
+
:imagesdir: assets
|
870
|
+
|
871
|
+
video::http://example.org/podcast.mp3[]
|
872
|
+
EOS
|
873
|
+
|
874
|
+
output = render_embedded_string input
|
875
|
+
assert_css 'video', output, 1
|
876
|
+
assert_css 'video[src="http://example.org/podcast.mp3"]', output, 1
|
877
|
+
end
|
878
|
+
|
879
|
+
test 'audio macro should honor all options' do
|
880
|
+
input = <<-EOS
|
881
|
+
audio::podcast.mp3[options="autoplay,nocontrols,loop"]
|
882
|
+
EOS
|
883
|
+
|
884
|
+
output = render_embedded_string input
|
885
|
+
assert_css 'audio', output, 1
|
886
|
+
assert_css 'audio[autoplay]', output, 1
|
887
|
+
assert_css 'audio:not([controls])', output, 1
|
888
|
+
assert_css 'audio[loop]', output, 1
|
889
|
+
end
|
605
890
|
end
|
606
891
|
|
607
892
|
context 'Admonition icons' do
|
@@ -614,7 +899,7 @@ You can use icons for admonitions by setting the 'icons' attribute.
|
|
614
899
|
EOS
|
615
900
|
|
616
901
|
output = render_string input, :safe => Asciidoctor::SafeMode::SERVER
|
617
|
-
assert_xpath '//*[@class="admonitionblock"]//*[@class="icon"]/img[@src="images/icons/tip.png"][@alt="Tip"]', output, 1
|
902
|
+
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="./images/icons/tip.png"][@alt="Tip"]', output, 1
|
618
903
|
end
|
619
904
|
|
620
905
|
test 'can resolve icon relative to custom iconsdir' do
|
@@ -627,7 +912,7 @@ You can use icons for admonitions by setting the 'icons' attribute.
|
|
627
912
|
EOS
|
628
913
|
|
629
914
|
output = render_string input, :safe => Asciidoctor::SafeMode::SERVER
|
630
|
-
assert_xpath '//*[@class="admonitionblock"]//*[@class="icon"]/img[@src="icons/tip.png"][@alt="Tip"]', output, 1
|
915
|
+
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="icons/tip.png"][@alt="Tip"]', output, 1
|
631
916
|
end
|
632
917
|
|
633
918
|
test 'embeds base64-encoded data uri of icon when data-uri attribute is set and safe mode level is less than SECURE' do
|
@@ -642,7 +927,7 @@ You can use icons for admonitions by setting the 'icons' attribute.
|
|
642
927
|
EOS
|
643
928
|
|
644
929
|
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
|
645
|
-
assert_xpath '//*[@class="admonitionblock"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
|
930
|
+
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
|
646
931
|
end
|
647
932
|
|
648
933
|
test 'does not embed base64-encoded data uri of icon when safe mode level is SECURE or greater' do
|
@@ -657,7 +942,7 @@ You can use icons for admonitions by setting the 'icons' attribute.
|
|
657
942
|
EOS
|
658
943
|
|
659
944
|
output = render_string input, :attributes => {'icons' => ''}
|
660
|
-
assert_xpath '//*[@class="admonitionblock"]//*[@class="icon"]/img[@src="fixtures/tip.gif"][@alt="Tip"]', output, 1
|
945
|
+
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="fixtures/tip.gif"][@alt="Tip"]', output, 1
|
661
946
|
end
|
662
947
|
|
663
948
|
test 'cleans reference to ancestor directories before reading icon if safe mode level is at least SAFE' do
|
@@ -672,7 +957,7 @@ You can use icons for admonitions by setting the 'icons' attribute.
|
|
672
957
|
EOS
|
673
958
|
|
674
959
|
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
|
675
|
-
assert_xpath '//*[@class="admonitionblock"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
|
960
|
+
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
|
676
961
|
end
|
677
962
|
end
|
678
963
|
|