asciidoctor 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of asciidoctor might be problematic. Click here for more details.

Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +10 -0
  3. data/Guardfile +18 -0
  4. data/LICENSE +1 -1
  5. data/README.adoc +65 -21
  6. data/Rakefile +10 -0
  7. data/asciidoctor.gemspec +17 -35
  8. data/compat/asciidoc.conf +130 -13
  9. data/lib/asciidoctor.rb +107 -87
  10. data/lib/asciidoctor/abstract_block.rb +6 -2
  11. data/lib/asciidoctor/abstract_node.rb +21 -13
  12. data/lib/asciidoctor/attribute_list.rb +2 -5
  13. data/{stylesheets/asciidoctor.css → lib/asciidoctor/backends/_stylesheets.rb} +96 -46
  14. data/lib/asciidoctor/backends/base_template.rb +9 -4
  15. data/lib/asciidoctor/backends/docbook45.rb +246 -138
  16. data/lib/asciidoctor/backends/html5.rb +580 -381
  17. data/lib/asciidoctor/block.rb +2 -50
  18. data/lib/asciidoctor/cli/options.rb +9 -8
  19. data/lib/asciidoctor/document.rb +35 -45
  20. data/lib/asciidoctor/helpers.rb +10 -0
  21. data/lib/asciidoctor/lexer.rb +456 -148
  22. data/lib/asciidoctor/list_item.rb +0 -21
  23. data/lib/asciidoctor/path_resolver.rb +18 -12
  24. data/lib/asciidoctor/reader.rb +71 -26
  25. data/lib/asciidoctor/renderer.rb +2 -19
  26. data/lib/asciidoctor/section.rb +0 -1
  27. data/lib/asciidoctor/substituters.rb +150 -36
  28. data/lib/asciidoctor/table.rb +30 -24
  29. data/lib/asciidoctor/version.rb +1 -1
  30. data/man/asciidoctor.1 +22 -16
  31. data/man/asciidoctor.ad +24 -16
  32. data/test/attributes_test.rb +50 -0
  33. data/test/blocks_test.rb +660 -9
  34. data/test/document_test.rb +191 -14
  35. data/test/fixtures/encoding.asciidoc +8 -0
  36. data/test/invoker_test.rb +47 -0
  37. data/test/lexer_test.rb +172 -0
  38. data/test/links_test.rb +28 -0
  39. data/test/lists_test.rb +172 -13
  40. data/test/options_test.rb +29 -2
  41. data/test/paragraphs_test.rb +105 -47
  42. data/test/paths_test.rb +3 -3
  43. data/test/reader_test.rb +46 -0
  44. data/test/sections_test.rb +365 -12
  45. data/test/substitutions_test.rb +127 -11
  46. data/test/tables_test.rb +81 -14
  47. data/test/test_helper.rb +18 -7
  48. data/test/text_test.rb +17 -5
  49. metadata +9 -36
@@ -9,7 +9,7 @@ context 'Substitutions' do
9
9
  para = block_from_string("[blue]'http://asciidoc.org[AsciiDoc]' & [red]*Ruby*\n&#167; Making +++<u>documentation</u>+++ together +\nsince (C) {inception_year}.")
10
10
  para.document.attributes['inception_year'] = '2012'
11
11
  result = para.apply_normal_subs(para.buffer)
12
- assert_equal %{<em><span class="blue"><a href="http://asciidoc.org">AsciiDoc</a></span></em> &amp; <strong><span class="red">Ruby</span></strong>\n&#167; Making <u>documentation</u> together<br>\nsince &#169; 2012.}, result
12
+ assert_equal %{<em class="blue"><a href="http://asciidoc.org">AsciiDoc</a></em> &amp; <strong class="red">Ruby</strong>\n&#167; Making <u>documentation</u> together<br>\nsince &#169; 2012.}, result
13
13
  end
14
14
  end
15
15
 
@@ -195,7 +195,7 @@ context 'Substitutions' do
195
195
 
196
196
  test 'unconstrained strong chars with role' do
197
197
  para = block_from_string(%q{Git[blue]**Hub**})
198
- assert_equal %q{Git<strong><span class="blue">Hub</span></strong>}, para.sub_quotes(para.buffer.join)
198
+ assert_equal %q{Git<strong class="blue">Hub</strong>}, para.sub_quotes(para.buffer.join)
199
199
  end
200
200
 
201
201
  # TODO this is not the same result as AsciiDoc, though I don't understand why AsciiDoc gets what it gets
@@ -221,7 +221,7 @@ context 'Substitutions' do
221
221
 
222
222
  test 'unconstrained emphasis chars with role' do
223
223
  para = block_from_string(%q{[gray]__Git__Hub})
224
- assert_equal %q{<em><span class="gray">Git</span></em>Hub}, para.sub_quotes(para.buffer.join)
224
+ assert_equal %q{<em class="gray">Git</em>Hub}, para.sub_quotes(para.buffer.join)
225
225
  end
226
226
 
227
227
  test 'escaped unconstrained emphasis chars with role' do
@@ -614,13 +614,129 @@ context 'Substitutions' do
614
614
  assert_equal ['Big cats', 'Tigers'], terms[0]
615
615
  assert_equal ['panthera tigris'], terms[1]
616
616
  end
617
+
618
+ context 'Button macro' do
619
+ test 'btn macro' do
620
+ para = block_from_string('btn:[Save]', :attributes => {'experimental' => ''})
621
+ assert_equal %q{<b class="button">Save</b>}, para.sub_macros(para.buffer.join)
622
+ end
623
+
624
+ test 'btn macro for docbook backend' do
625
+ para = block_from_string('btn:[Save]', :backend => 'docbook', :attributes => {'experimental' => ''})
626
+ assert_equal %q{<guibutton>Save</guibutton>}, para.sub_macros(para.buffer.join)
627
+ end
628
+ end
629
+
630
+ context 'Keyboard macro' do
631
+ test 'kbd macro with single key' do
632
+ para = block_from_string('kbd:[F3]', :attributes => {'experimental' => ''})
633
+ assert_equal %q{<kbd>F3</kbd>}, para.sub_macros(para.buffer.join)
634
+ end
635
+
636
+ test 'kbd macro with single key, docbook backend' do
637
+ para = block_from_string('kbd:[F3]', :backend => 'docbook', :attributes => {'experimental' => ''})
638
+ assert_equal %q{<keycap>F3</keycap>}, para.sub_macros(para.buffer.join)
639
+ end
640
+
641
+ test 'kbd macro with key combination' do
642
+ para = block_from_string('kbd:[Ctrl+Shift+T]', :attributes => {'experimental' => ''})
643
+ assert_equal %q{<kbd class="keyseq"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd></kbd>}, para.sub_macros(para.buffer.join)
644
+ end
645
+
646
+ test 'kbd macro with key combination with spaces' do
647
+ para = block_from_string('kbd:[Ctrl + Shift + T]', :attributes => {'experimental' => ''})
648
+ assert_equal %q{<kbd class="keyseq"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd></kbd>}, para.sub_macros(para.buffer.join)
649
+ end
650
+
651
+ test 'kbd macro with key combination delimited by commas' do
652
+ para = block_from_string('kbd:[Ctrl,Shift,T]', :attributes => {'experimental' => ''})
653
+ assert_equal %q{<kbd class="keyseq"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd></kbd>}, para.sub_macros(para.buffer.join)
654
+ end
655
+
656
+ test 'kbd macro with key combination containing a plus key no spaces' do
657
+ para = block_from_string('kbd:[Ctrl++]', :attributes => {'experimental' => ''})
658
+ assert_equal %q{<kbd class="keyseq"><kbd>Ctrl</kbd>+<kbd>+</kbd></kbd>}, para.sub_macros(para.buffer.join)
659
+ end
660
+
661
+ test 'kbd macro with key combination delimited by commands containing a comma key' do
662
+ para = block_from_string('kbd:[Ctrl,,]', :attributes => {'experimental' => ''})
663
+ assert_equal %q{<kbd class="keyseq"><kbd>Ctrl</kbd>+<kbd>,</kbd></kbd>}, para.sub_macros(para.buffer.join)
664
+ end
665
+
666
+ test 'kbd macro with key combination containing a plus key with spaces' do
667
+ para = block_from_string('kbd:[Ctrl + +]', :attributes => {'experimental' => ''})
668
+ assert_equal %q{<kbd class="keyseq"><kbd>Ctrl</kbd>+<kbd>+</kbd></kbd>}, para.sub_macros(para.buffer.join)
669
+ end
670
+
671
+ test 'kbd macro with key combination containing escaped bracket' do
672
+ para = block_from_string('kbd:[Ctrl + \]]', :attributes => {'experimental' => ''})
673
+ assert_equal %q{<kbd class="keyseq"><kbd>Ctrl</kbd>+<kbd>]</kbd></kbd>}, para.sub_macros(para.buffer.join)
674
+ end
675
+
676
+ test 'kbd macro with key combination, docbook backend' do
677
+ para = block_from_string('kbd:[Ctrl+Shift+T]', :backend => 'docbook', :attributes => {'experimental' => ''})
678
+ assert_equal %q{<keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>T</keycap></keycombo>}, para.sub_macros(para.buffer.join)
679
+ end
680
+ end
681
+
682
+ context 'Menu macro' do
683
+ test 'should process menu using macro sytnax' do
684
+ para = block_from_string('menu:File[]', :attributes => {'experimental' => ''})
685
+ assert_equal %q{<span class="menu">File</span>}, para.sub_macros(para.buffer.join)
686
+ end
687
+
688
+ test 'should process menu for docbook backend' do
689
+ para = block_from_string('menu:File[]', :backend => 'docbook', :attributes => {'experimental' => ''})
690
+ assert_equal %q{<guimenu>File</guimenu>}, para.sub_macros(para.buffer.join)
691
+ end
692
+
693
+ test 'should process menu with menu item using macro syntax' do
694
+ para = block_from_string('menu:File[Save As&#8230;]', :attributes => {'experimental' => ''})
695
+ assert_equal %q{<span class="menuseq"><span class="menu">File</span>&#160;&#9656; <span class="menuitem">Save As&#8230;</span></span>}, para.sub_macros(para.buffer.join)
696
+ end
697
+
698
+ test 'should process menu with menu item for docbook backend' do
699
+ para = block_from_string('menu:File[Save As&#8230;]', :backend => 'docbook', :attributes => {'experimental' => ''})
700
+ assert_equal %q{<menuchoice><guimenu>File</guimenu> <guimenuitem>Save As&#8230;</guimenuitem></menuchoice>}, para.sub_macros(para.buffer.join)
701
+ end
702
+
703
+ test 'should process menu with menu item in submenu using macro syntax' do
704
+ para = block_from_string('menu:Tools[Project &gt; Build]', :attributes => {'experimental' => ''})
705
+ assert_equal %q{<span class="menuseq"><span class="menu">Tools</span>&#160;&#9656; <span class="submenu">Project</span>&#160;&#9656; <span class="menuitem">Build</span></span>}, para.sub_macros(para.buffer.join)
706
+ end
707
+
708
+ test 'should process menu with menu item in submenu for docbook backend' do
709
+ para = block_from_string('menu:Tools[Project &gt; Build]', :backend => 'docbook', :attributes => {'experimental' => ''})
710
+ assert_equal %q{<menuchoice><guimenu>Tools</guimenu> <guisubmenu>Project</guisubmenu> <guimenuitem>Build</guimenuitem></menuchoice>}, para.sub_macros(para.buffer.join)
711
+ end
712
+
713
+ test 'should process menu with menu item in submenu using macro syntax and comma delimiter' do
714
+ para = block_from_string('menu:Tools[Project, Build]', :attributes => {'experimental' => ''})
715
+ assert_equal %q{<span class="menuseq"><span class="menu">Tools</span>&#160;&#9656; <span class="submenu">Project</span>&#160;&#9656; <span class="menuitem">Build</span></span>}, para.sub_macros(para.buffer.join)
716
+ end
717
+
718
+ test 'should process menu with menu item using inline syntax' do
719
+ para = block_from_string('"File &gt; Save As&#8230;"', :attributes => {'experimental' => ''})
720
+ assert_equal %q{<span class="menuseq"><span class="menu">File</span>&#160;&#9656; <span class="menuitem">Save As&#8230;</span></span>}, para.sub_macros(para.buffer.join)
721
+ end
722
+
723
+ test 'should process menu with menu item in submenu using inline syntax' do
724
+ para = block_from_string('"Tools &gt; Project &gt; Build"', :attributes => {'experimental' => ''})
725
+ assert_equal %q{<span class="menuseq"><span class="menu">Tools</span>&#160;&#9656; <span class="submenu">Project</span>&#160;&#9656; <span class="menuitem">Build</span></span>}, para.sub_macros(para.buffer.join)
726
+ end
727
+
728
+ test 'inline syntax should not closing quote of XML attribute' do
729
+ para = block_from_string('<span class="xmltag">&lt;node&gt;</span><span class="classname">r</span>', :attributes => {'experimental' => ''})
730
+ assert_equal %q{<span class="xmltag">&lt;node&gt;</span><span class="classname">r</span>}, para.sub_macros(para.buffer.join)
731
+ end
732
+ end
617
733
  end
618
734
 
619
735
  context 'Passthroughs' do
620
736
  test 'collect inline triple plus passthroughs' do
621
737
  para = block_from_string('+++<code>inline code</code>+++')
622
738
  result = para.extract_passthroughs(para.buffer.join)
623
- assert_equal "\x0" + '0' + "\x0", result
739
+ assert_equal "\e" + '0' + "\e", result
624
740
  assert_equal 1, para.passthroughs.size
625
741
  assert_equal '<code>inline code</code>', para.passthroughs.first[:text]
626
742
  assert para.passthroughs.first[:subs].empty?
@@ -629,7 +745,7 @@ context 'Substitutions' do
629
745
  test 'collect multi-line inline triple plus passthroughs' do
630
746
  para = block_from_string("+++<code>inline\ncode</code>+++")
631
747
  result = para.extract_passthroughs(para.buffer.join)
632
- assert_equal "\x0" + '0' + "\x0", result
748
+ assert_equal "\e" + '0' + "\e", result
633
749
  assert_equal 1, para.passthroughs.size
634
750
  assert_equal "<code>inline\ncode</code>", para.passthroughs.first[:text]
635
751
  assert para.passthroughs.first[:subs].empty?
@@ -638,7 +754,7 @@ context 'Substitutions' do
638
754
  test 'collect inline double dollar passthroughs' do
639
755
  para = block_from_string('$$<code>{code}</code>$$')
640
756
  result = para.extract_passthroughs(para.buffer.join)
641
- assert_equal "\x0" + '0' + "\x0", result
757
+ assert_equal "\e" + '0' + "\e", result
642
758
  assert_equal 1, para.passthroughs.size
643
759
  assert_equal '<code>{code}</code>', para.passthroughs.first[:text]
644
760
  assert_equal [:specialcharacters], para.passthroughs.first[:subs]
@@ -647,7 +763,7 @@ context 'Substitutions' do
647
763
  test 'collect multi-line inline double dollar passthroughs' do
648
764
  para = block_from_string("$$<code>\n{code}\n</code>$$")
649
765
  result = para.extract_passthroughs(para.buffer.join)
650
- assert_equal "\x0" + '0' + "\x0", result
766
+ assert_equal "\e" + '0' + "\e", result
651
767
  assert_equal 1, para.passthroughs.size
652
768
  assert_equal "<code>\n{code}\n</code>", para.passthroughs.first[:text]
653
769
  assert_equal [:specialcharacters], para.passthroughs.first[:subs]
@@ -656,7 +772,7 @@ context 'Substitutions' do
656
772
  test 'collect passthroughs from inline pass macro' do
657
773
  para = block_from_string(%Q{pass:specialcharacters,quotes[<code>['code'\\]</code>]})
658
774
  result = para.extract_passthroughs(para.buffer.join)
659
- assert_equal "\x0" + '0' + "\x0", result
775
+ assert_equal "\e" + '0' + "\e", result
660
776
  assert_equal 1, para.passthroughs.size
661
777
  assert_equal %q{<code>['code']</code>}, para.passthroughs.first[:text]
662
778
  assert_equal [:specialcharacters, :quotes], para.passthroughs.first[:subs]
@@ -665,7 +781,7 @@ context 'Substitutions' do
665
781
  test 'collect multi-line passthroughs from inline pass macro' do
666
782
  para = block_from_string(%Q{pass:specialcharacters,quotes[<code>['more\ncode'\\]</code>]})
667
783
  result = para.extract_passthroughs(para.buffer.join)
668
- assert_equal "\x0" + '0' + "\x0", result
784
+ assert_equal "\e" + '0' + "\e", result
669
785
  assert_equal 1, para.passthroughs.size
670
786
  assert_equal %Q{<code>['more\ncode']</code>}, para.passthroughs.first[:text]
671
787
  assert_equal [:specialcharacters, :quotes], para.passthroughs.first[:subs]
@@ -673,7 +789,7 @@ context 'Substitutions' do
673
789
 
674
790
  # NOTE placeholder is surrounded by text to prevent reader from stripping trailing boundary char (unique to test scenario)
675
791
  test 'restore inline passthroughs without subs' do
676
- para = block_from_string("some \x0" + '0' + "\x0 to study")
792
+ para = block_from_string("some \e" + '0' + "\e to study")
677
793
  para.passthroughs << {:text => '<code>inline code</code>', :subs => []}
678
794
  result = para.restore_passthroughs(para.buffer.join)
679
795
  assert_equal "some <code>inline code</code> to study", result
@@ -681,7 +797,7 @@ context 'Substitutions' do
681
797
 
682
798
  # NOTE placeholder is surrounded by text to prevent reader from stripping trailing boundary char (unique to test scenario)
683
799
  test 'restore inline passthroughs with subs' do
684
- para = block_from_string("some \x0" + '0' + "\x0 to study in the \x0" + '1' + "\x0 programming language")
800
+ para = block_from_string("some \e" + '0' + "\e to study in the \e" + '1' + "\e programming language")
685
801
  para.passthroughs << {:text => '<code>{code}</code>', :subs => [:specialcharacters]}
686
802
  para.passthroughs << {:text => '{language}', :subs => [:specialcharacters]}
687
803
  result = para.restore_passthroughs(para.buffer.join)
data/test/tables_test.rb CHANGED
@@ -21,8 +21,8 @@ context 'Tables' do
21
21
  assert_css 'table td', output, 9
22
22
  assert_css 'table > tbody > tr > td.tableblock.halign-left.valign-top > p.tableblock', output, 9
23
23
  cells.each_with_index {|row, rowi|
24
- assert_css "table tr:nth-child(#{rowi + 1}) > td", output, row.size
25
- assert_css "table tr:nth-child(#{rowi + 1}) > td > p", output, row.size
24
+ assert_css "table > tbody > tr:nth-child(#{rowi + 1}) > td", output, row.size
25
+ assert_css "table > tbody > tr:nth-child(#{rowi + 1}) > td > p", output, row.size
26
26
  row.each_with_index {|cell, celli|
27
27
  assert_xpath "(//tr)[#{rowi + 1}]/td[#{celli + 1}]/p[text()='#{cell}']", output, 1
28
28
  }
@@ -312,21 +312,21 @@ d|9 2+>|10
312
312
  assert_css 'table > tbody > tr:nth-child(3) > td', output, 1
313
313
  assert_css 'table > tbody > tr:nth-child(4) > td', output, 2
314
314
 
315
- assert_css 'table tr:nth-child(1) > td:nth-child(1).halign-left.valign-top p em', output, 1
316
- assert_css 'table tr:nth-child(1) > td:nth-child(2).halign-right.valign-top p strong', output, 1
317
- assert_css 'table tr:nth-child(1) > td:nth-child(3).halign-center.valign-top p', output, 1
318
- assert_css 'table tr:nth-child(1) > td:nth-child(3).halign-center.valign-top p *', output, 0
319
- assert_css 'table tr:nth-child(1) > td:nth-child(4).halign-right.valign-top p strong', output, 1
315
+ assert_css 'table > tbody > tr:nth-child(1) > td:nth-child(1).halign-left.valign-top p em', output, 1
316
+ assert_css 'table > tbody > tr:nth-child(1) > td:nth-child(2).halign-right.valign-top p strong', output, 1
317
+ assert_css 'table > tbody > tr:nth-child(1) > td:nth-child(3).halign-center.valign-top p', output, 1
318
+ assert_css 'table > tbody > tr:nth-child(1) > td:nth-child(3).halign-center.valign-top p *', output, 0
319
+ assert_css 'table > tbody > tr:nth-child(1) > td:nth-child(4).halign-right.valign-top p strong', output, 1
320
320
 
321
- assert_css 'table tr:nth-child(2) > td:nth-child(1).halign-center.valign-top p em', output, 1
322
- assert_css 'table tr:nth-child(2) > td:nth-child(2).halign-center.valign-middle[colspan="2"][rowspan="2"] p code', output, 1
323
- assert_css 'table tr:nth-child(2) > td:nth-child(3).halign-left.valign-bottom[rowspan="3"] p code', output, 1
321
+ assert_css 'table > tbody > tr:nth-child(2) > td:nth-child(1).halign-center.valign-top p em', output, 1
322
+ assert_css 'table > tbody > tr:nth-child(2) > td:nth-child(2).halign-center.valign-middle[colspan="2"][rowspan="2"] p code', output, 1
323
+ assert_css 'table > tbody > tr:nth-child(2) > td:nth-child(3).halign-left.valign-bottom[rowspan="3"] p code', output, 1
324
324
 
325
- assert_css 'table tr:nth-child(3) > td:nth-child(1).halign-center.valign-top p em', output, 1
325
+ assert_css 'table > tbody > tr:nth-child(3) > td:nth-child(1).halign-center.valign-top p em', output, 1
326
326
 
327
- assert_css 'table tr:nth-child(4) > td:nth-child(1).halign-left.valign-top p', output, 1
328
- assert_css 'table tr:nth-child(4) > td:nth-child(1).halign-left.valign-top p em', output, 0
329
- assert_css 'table tr:nth-child(4) > td:nth-child(2).halign-right.valign-top[colspan="2"] p code', output, 1
327
+ assert_css 'table > tbody > tr:nth-child(4) > td:nth-child(1).halign-left.valign-top p', output, 1
328
+ assert_css 'table > tbody > tr:nth-child(4) > td:nth-child(1).halign-left.valign-top p em', output, 0
329
+ assert_css 'table > tbody > tr:nth-child(4) > td:nth-child(2).halign-right.valign-top[colspan="2"] p code', output, 1
330
330
  end
331
331
 
332
332
  test 'supports repeating cells' do
@@ -474,6 +474,43 @@ output file name is used.
474
474
  assert_css 'table > tbody > tr > td:nth-child(2) table', output, 1
475
475
  assert_css 'table > tbody > tr > td:nth-child(2) table > tbody > tr > td', output, 2
476
476
  end
477
+
478
+ test 'nested document in AsciiDoc cell should not see doctitle of parent' do
479
+ input = <<-EOS
480
+ = Document Title
481
+
482
+ [cols="1a"]
483
+ |===
484
+ |AsciiDoc content
485
+ |===
486
+ EOS
487
+
488
+ output = render_string input
489
+ assert_css 'table', output, 1
490
+ assert_css 'table > tbody > tr > td', output, 1
491
+ assert_css 'table > tbody > tr > td #preamble', output, 0
492
+ assert_css 'table > tbody > tr > td .paragraph', output, 1
493
+ end
494
+
495
+ test 'cell background color' do
496
+ input = <<-EOS
497
+ [cols="1e,1", options="header"]
498
+ |===
499
+ |{set:cellbgcolor:green}green
500
+ |{set:cellbgcolor!}
501
+ plain
502
+ |{set:cellbgcolor:red}red
503
+ |{set:cellbgcolor!}
504
+ plain
505
+ |===
506
+ EOS
507
+
508
+ output = render_embedded_string input
509
+ assert_xpath '(/table/thead/tr/th)[1][@style="background-color:green;"]', output, 1
510
+ assert_xpath '(/table/thead/tr/th)[2][@style="background-color:green;"]', output, 0
511
+ assert_xpath '(/table/tbody/tr/td)[1][@style="background-color:red;"]', output, 1
512
+ assert_xpath '(/table/tbody/tr/td)[2][@style="background-color:green;"]', output, 0
513
+ end
477
514
  end
478
515
 
479
516
  context 'DSV' do
@@ -497,6 +534,21 @@ nobody:x:99:99:Nobody:/:/sbin/nologin
497
534
  assert_xpath '//tr[4]/td[5]/p/text()', output, 0
498
535
  assert_xpath '//tr[3]/td[5]/p[text()="MySQL:Server"]', output, 1
499
536
  end
537
+
538
+ test 'dsv format shorthand' do
539
+ input = <<-EOS
540
+ :===
541
+ a:b:c
542
+ 1:2:3
543
+ :===
544
+ EOS
545
+ output = render_embedded_string input
546
+ assert_css 'table', output, 1
547
+ assert_css 'table > colgroup > col', output, 3
548
+ assert_css 'table > tbody > tr', output, 2
549
+ assert_css 'table > tbody > tr:nth-child(1) > td', output, 3
550
+ assert_css 'table > tbody > tr:nth-child(2) > td', output, 3
551
+ end
500
552
  end
501
553
 
502
554
  context 'CSV' do
@@ -523,6 +575,21 @@ air, moon roof, loaded",4799.00
523
575
  assert_xpath '((//tbody/tr)[4]/td)[4]/p[text()="MUST SELL! air, moon roof, loaded"]', output, 1
524
576
  end
525
577
 
578
+ test 'csv format shorthand' do
579
+ input = <<-EOS
580
+ ,===
581
+ a,b,c
582
+ 1,2,3
583
+ ,===
584
+ EOS
585
+ output = render_embedded_string input
586
+ assert_css 'table', output, 1
587
+ assert_css 'table > colgroup > col', output, 3
588
+ assert_css 'table > tbody > tr', output, 2
589
+ assert_css 'table > tbody > tr:nth-child(1) > td', output, 3
590
+ assert_css 'table > tbody > tr:nth-child(2) > td', output, 3
591
+ end
592
+
526
593
  test 'custom separator' do
527
594
  input = <<-EOS
528
595
  [format="csv", separator=";"]
data/test/test_helper.rb CHANGED
@@ -4,12 +4,6 @@ require 'test/unit'
4
4
 
5
5
  require "#{File.expand_path(File.dirname(__FILE__))}/../lib/asciidoctor.rb"
6
6
 
7
- begin
8
- require 'mocha/setup'
9
- rescue LoadError
10
- require 'mocha'
11
- end
12
- require 'htmlentities'
13
7
  require 'nokogiri'
14
8
  require 'pending'
15
9
 
@@ -82,6 +76,11 @@ class Test::Unit::TestCase
82
76
  count == 1 ? results.first : results
83
77
  end
84
78
 
79
+ # Generate an xpath attribute matcher that matches a name in the class attribute
80
+ def contains_class(name)
81
+ %(contains(concat(' ', normalize-space(@class), ' '), ' #{name} '))
82
+ end
83
+
85
84
  def assert_css(css, content, count = nil)
86
85
  assert_path(:css, css, content, count)
87
86
  end
@@ -100,7 +99,13 @@ class Test::Unit::TestCase
100
99
 
101
100
  results = xmlnodes_at_path type, path, content
102
101
 
103
- if (count && results.length != count)
102
+ if (count == true || count == false)
103
+ if (count != results)
104
+ flunk "#{type_name} #{path} yielded #{results} rather than #{count} for:\n#{content}"
105
+ else
106
+ assert true
107
+ end
108
+ elsif (count && results.length != count)
104
109
  flunk "#{type_name} #{path} yielded #{results.length} elements rather than #{count} for:\n#{content}"
105
110
  elsif (count.nil? && results.empty?)
106
111
  flunk "#{type_name} #{path} not found in:\n#{content}"
@@ -145,6 +150,12 @@ class Test::Unit::TestCase
145
150
  [Asciidoctor::Lexer.parse_header_metadata(reader), reader]
146
151
  end
147
152
 
153
+ # Expand the character for an entity such as &#8212; so
154
+ # it can be used to match in an XPath expression
155
+ def expand_entity(number)
156
+ [number].pack('U*')
157
+ end
158
+
148
159
  def invoke_cli_to_buffer(argv = [], filename = 'sample.asciidoc', &block)
149
160
  invoke_cli(argv, filename, [StringIO.new, StringIO.new], &block)
150
161
  end
data/test/text_test.rb CHANGED
@@ -1,27 +1,28 @@
1
+ # encoding: UTF-8
1
2
  require 'test_helper'
2
3
 
3
4
  context "Text" do
4
5
  test "proper encoding to handle utf8 characters in document using html backend" do
5
6
  output = example_document(:encoding).render
6
- assert_xpath '//p', output, 2
7
+ assert_xpath '//p', output, 4
7
8
  assert_xpath '//a', output, 1
8
9
  end
9
10
 
10
11
  test "proper encoding to handle utf8 characters in embedded document using html backend" do
11
12
  output = example_document(:encoding, :header_footer => false).render
12
- assert_xpath '//p', output, 2
13
+ assert_xpath '//p', output, 4
13
14
  assert_xpath '//a', output, 1
14
15
  end
15
16
 
16
17
  test "proper encoding to handle utf8 characters in document using docbook backend" do
17
18
  output = example_document(:encoding, :attributes => {'backend' => 'docbook'}).render
18
- assert_xpath '//simpara', output, 2
19
+ assert_xpath '//simpara', output, 4
19
20
  assert_xpath '//ulink', output, 1
20
21
  end
21
22
 
22
23
  test "proper encoding to handle utf8 characters in embedded document using docbook backend" do
23
24
  output = example_document(:encoding, :header_footer => false, :attributes => {'backend' => 'docbook'}).render
24
- assert_xpath '//simpara', output, 2
25
+ assert_xpath '//simpara', output, 4
25
26
  assert_xpath '//ulink', output, 1
26
27
  end
27
28
 
@@ -31,11 +32,22 @@ context "Text" do
31
32
  input << "[verse]\n"
32
33
  input.concat(File.readlines(sample_doc_path(:encoding)))
33
34
  doc = Asciidoctor::Document.new
34
- reader = Asciidoctor::Reader.new input
35
+ reader = Asciidoctor::Reader.new(input, doc, true)
35
36
  block = Asciidoctor::Lexer.next_block(reader, doc)
36
37
  assert_xpath '//pre', block.render.gsub(/^\s*\n/, ''), 1
37
38
  end
38
39
 
40
+ test "proper encoding to handle utf8 characters from included file" do
41
+ input = <<-EOS
42
+ include::fixtures/encoding.asciidoc[tags=romé]
43
+ EOS
44
+ doc = Asciidoctor::Document.new [], :safe => Asciidoctor::SafeMode::SAFE, :base_dir => File.expand_path(File.dirname(__FILE__))
45
+ reader = Asciidoctor::Reader.new(input, doc, true)
46
+ block = Asciidoctor::Lexer.next_block(reader, doc)
47
+ output = block.render
48
+ assert_css '.paragraph', output, 1
49
+ end
50
+
39
51
  test 'escaped text markup' do
40
52
  assert_match(/All your &lt;em&gt;inline&lt;\/em&gt; markup belongs to &lt;strong&gt;us&lt;\/strong&gt;!/,
41
53
  render_string('All your <em>inline</em> markup belongs to <strong>us</strong>!'))