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.

Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +1 -1
  3. data/LICENSE +2 -2
  4. data/README.adoc +461 -0
  5. data/asciidoctor.gemspec +27 -16
  6. data/compat/asciidoc.conf +139 -0
  7. data/lib/asciidoctor.rb +212 -69
  8. data/lib/asciidoctor/abstract_block.rb +41 -0
  9. data/lib/asciidoctor/abstract_node.rb +128 -81
  10. data/lib/asciidoctor/attribute_list.rb +5 -2
  11. data/lib/asciidoctor/backends/base_template.rb +16 -4
  12. data/lib/asciidoctor/backends/docbook45.rb +112 -42
  13. data/lib/asciidoctor/backends/html5.rb +206 -90
  14. data/lib/asciidoctor/block.rb +5 -5
  15. data/lib/asciidoctor/cli/invoker.rb +38 -34
  16. data/lib/asciidoctor/cli/options.rb +3 -3
  17. data/lib/asciidoctor/document.rb +115 -13
  18. data/lib/asciidoctor/helpers.rb +16 -0
  19. data/lib/asciidoctor/lexer.rb +486 -359
  20. data/lib/asciidoctor/path_resolver.rb +360 -0
  21. data/lib/asciidoctor/reader.rb +122 -23
  22. data/lib/asciidoctor/renderer.rb +1 -33
  23. data/lib/asciidoctor/section.rb +1 -1
  24. data/lib/asciidoctor/substituters.rb +103 -19
  25. data/lib/asciidoctor/version.rb +1 -1
  26. data/man/asciidoctor.1 +6 -6
  27. data/man/asciidoctor.ad +5 -3
  28. data/stylesheets/asciidoctor.css +274 -0
  29. data/test/attributes_test.rb +133 -10
  30. data/test/blocks_test.rb +302 -17
  31. data/test/document_test.rb +269 -6
  32. data/test/fixtures/basic-docinfo.html +1 -0
  33. data/test/fixtures/basic-docinfo.xml +4 -0
  34. data/test/fixtures/basic.asciidoc +4 -0
  35. data/test/fixtures/docinfo.html +1 -0
  36. data/test/fixtures/docinfo.xml +2 -0
  37. data/test/fixtures/include-file.asciidoc +22 -1
  38. data/test/fixtures/stylesheets/custom.css +3 -0
  39. data/test/invoker_test.rb +38 -6
  40. data/test/lexer_test.rb +64 -21
  41. data/test/links_test.rb +4 -0
  42. data/test/lists_test.rb +251 -12
  43. data/test/paragraphs_test.rb +225 -30
  44. data/test/paths_test.rb +174 -0
  45. data/test/reader_test.rb +89 -2
  46. data/test/sections_test.rb +518 -16
  47. data/test/substitutions_test.rb +121 -10
  48. data/test/tables_test.rb +53 -13
  49. data/test/test_helper.rb +2 -2
  50. data/test/text_test.rb +5 -5
  51. metadata +46 -50
  52. data/README.asciidoc +0 -296
  53. data/lib/asciidoctor/errors.rb +0 -5
@@ -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"]/tt[text()="asciidoctor"]', output, 1
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 "Block attributes" do
369
- test "Position attributes assigned to block" do
431
+ context 'Block attributes' do
432
+ test 'Positional attributes assigned to block' do
370
433
  input = <<-EOS
371
- [quote, Name, Source]
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 'Name', qb.attributes['attribution']
381
- assert_equal 'Source', qb.attributes['citetitle']
443
+ assert_equal 'author', qb.attributes['attribution']
444
+ assert_equal 'source', qb.attributes['citetitle']
382
445
  end
383
446
 
384
- test "Normal substitutions are performed on single-quoted attributes" do
447
+ test 'Normal substitutions are performed on single-quoted attributes' do
385
448
  input = <<-EOS
386
- [quote, Name, 'http://wikipedia.org[Source]']
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 'Name', qb.attributes['attribution']
396
- assert_equal '<a href="http://wikipedia.org">Source</a>', qb.attributes['citetitle']
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
@@ -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&lt;String, String&gt; <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 "Images" do
506
- test "can render block image with alt text" do
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 'should pass through image that is a uri reference' do
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: ../fixtures
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 '../fixtures', doc.attributes['imagesdir']
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