asciidoctor 1.5.2 → 1.5.3
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 +107 -1
- data/LICENSE.adoc +1 -1
- data/README.adoc +155 -230
- data/Rakefile +2 -1
- data/bin/asciidoctor +5 -1
- data/data/stylesheets/asciidoctor-default.css +37 -29
- data/data/stylesheets/coderay-asciidoctor.css +3 -3
- data/features/text_formatting.feature +2 -0
- data/lib/asciidoctor.rb +46 -21
- data/lib/asciidoctor/abstract_block.rb +14 -8
- data/lib/asciidoctor/abstract_node.rb +77 -24
- data/lib/asciidoctor/attribute_list.rb +1 -1
- data/lib/asciidoctor/block.rb +2 -3
- data/lib/asciidoctor/cli/options.rb +14 -15
- data/lib/asciidoctor/converter/docbook45.rb +8 -8
- data/lib/asciidoctor/converter/docbook5.rb +25 -17
- data/lib/asciidoctor/converter/factory.rb +6 -1
- data/lib/asciidoctor/converter/html5.rb +159 -117
- data/lib/asciidoctor/converter/manpage.rb +671 -0
- data/lib/asciidoctor/converter/template.rb +24 -17
- data/lib/asciidoctor/document.rb +89 -47
- data/lib/asciidoctor/extensions.rb +22 -21
- data/lib/asciidoctor/helpers.rb +73 -16
- data/lib/asciidoctor/list.rb +26 -5
- data/lib/asciidoctor/parser.rb +179 -122
- data/lib/asciidoctor/path_resolver.rb +6 -10
- data/lib/asciidoctor/reader.rb +37 -34
- data/lib/asciidoctor/stylesheets.rb +16 -10
- data/lib/asciidoctor/substitutors.rb +98 -21
- data/lib/asciidoctor/table.rb +21 -17
- data/lib/asciidoctor/timings.rb +3 -3
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +155 -89
- data/man/asciidoctor.adoc +19 -11
- data/test/attributes_test.rb +86 -0
- data/test/blocks_test.rb +203 -15
- data/test/converter_test.rb +15 -2
- data/test/document_test.rb +290 -36
- data/test/extensions_test.rb +22 -3
- data/test/fixtures/circle.svg +8 -0
- data/test/fixtures/subs-docinfo.html +2 -0
- data/test/fixtures/subs.adoc +7 -0
- data/test/invoker_test.rb +25 -0
- data/test/links_test.rb +17 -0
- data/test/lists_test.rb +173 -0
- data/test/options_test.rb +2 -2
- data/test/paragraphs_test.rb +2 -2
- data/test/parser_test.rb +56 -13
- data/test/reader_test.rb +35 -3
- data/test/sections_test.rb +59 -0
- data/test/substitutions_test.rb +53 -14
- data/test/tables_test.rb +158 -2
- data/test/test_helper.rb +7 -2
- metadata +22 -11
- data/benchmark/benchmark.rb +0 -129
- data/benchmark/sample-data/mdbasics.adoc +0 -334
- data/lib/asciidoctor/opal_ext.rb +0 -26
- data/lib/asciidoctor/opal_ext/comparable.rb +0 -38
- data/lib/asciidoctor/opal_ext/dir.rb +0 -13
- data/lib/asciidoctor/opal_ext/error.rb +0 -2
- data/lib/asciidoctor/opal_ext/file.rb +0 -145
data/test/attributes_test.rb
CHANGED
@@ -312,6 +312,19 @@ content
|
|
312
312
|
assert_equal 'baz', (node.attr 'foo')
|
313
313
|
end
|
314
314
|
|
315
|
+
test 'set_attr should set header attribute in loaded document' do
|
316
|
+
input = <<-EOS
|
317
|
+
:uri: http://example.org
|
318
|
+
|
319
|
+
{uri}
|
320
|
+
EOS
|
321
|
+
|
322
|
+
doc = Asciidoctor.load input, :attributes => { 'uri' => 'https://github.com' }
|
323
|
+
doc.set_attr 'uri', 'https://google.com'
|
324
|
+
output = doc.convert
|
325
|
+
assert_xpath '//a[@href="https://google.com"]', output, 1
|
326
|
+
end
|
327
|
+
|
315
328
|
test 'verify toc attribute matrix' do
|
316
329
|
expected_data = <<-EOS
|
317
330
|
#attributes |toc|toc-position|toc-placement|toc-class
|
@@ -1054,6 +1067,79 @@ Text
|
|
1054
1067
|
assert para.attributes.has_key?('option2-option')
|
1055
1068
|
end
|
1056
1069
|
|
1070
|
+
test 'a role can be added using add_role when the node has no roles' do
|
1071
|
+
input = <<-EOS
|
1072
|
+
A normal paragraph
|
1073
|
+
EOS
|
1074
|
+
doc = document_from_string(input)
|
1075
|
+
para = doc.blocks.first
|
1076
|
+
para.add_role 'role1'
|
1077
|
+
assert_equal 'role1', para.attributes['role']
|
1078
|
+
assert para.has_role? 'role1'
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
test 'a role can be added using add_role when the node already has a role' do
|
1082
|
+
input = <<-EOS
|
1083
|
+
[.role1]
|
1084
|
+
A normal paragraph
|
1085
|
+
EOS
|
1086
|
+
doc = document_from_string(input)
|
1087
|
+
para = doc.blocks.first
|
1088
|
+
para.add_role 'role2'
|
1089
|
+
assert_equal 'role1 role2', para.attributes['role']
|
1090
|
+
assert para.has_role? 'role1'
|
1091
|
+
assert para.has_role? 'role2'
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
test 'a role is not added using add_role if the node already has that role' do
|
1095
|
+
input = <<-EOS
|
1096
|
+
[.role1]
|
1097
|
+
A normal paragraph
|
1098
|
+
EOS
|
1099
|
+
doc = document_from_string(input)
|
1100
|
+
para = doc.blocks.first
|
1101
|
+
para.add_role 'role1'
|
1102
|
+
assert_equal 'role1', para.attributes['role']
|
1103
|
+
assert para.has_role? 'role1'
|
1104
|
+
end
|
1105
|
+
|
1106
|
+
test 'an existing role can be removed using remove_role' do
|
1107
|
+
input = <<-EOS
|
1108
|
+
[.role1.role2]
|
1109
|
+
A normal paragraph
|
1110
|
+
EOS
|
1111
|
+
doc = document_from_string(input)
|
1112
|
+
para = doc.blocks.first
|
1113
|
+
para.remove_role 'role1'
|
1114
|
+
assert_equal 'role2', para.attributes['role']
|
1115
|
+
assert para.has_role? 'role2'
|
1116
|
+
assert !para.has_role?('role1')
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
test 'roles are not changed when a non-existent role is removed using remove_role' do
|
1120
|
+
input = <<-EOS
|
1121
|
+
[.role1]
|
1122
|
+
A normal paragraph
|
1123
|
+
EOS
|
1124
|
+
doc = document_from_string(input)
|
1125
|
+
para = doc.blocks.first
|
1126
|
+
para.remove_role 'role2'
|
1127
|
+
assert_equal 'role1', para.attributes['role']
|
1128
|
+
assert para.has_role? 'role1'
|
1129
|
+
assert !para.has_role?('role2')
|
1130
|
+
end
|
1131
|
+
|
1132
|
+
test 'roles are not changed when using remove_role if the node has no roles' do
|
1133
|
+
input = <<-EOS
|
1134
|
+
A normal paragraph
|
1135
|
+
EOS
|
1136
|
+
doc = document_from_string(input)
|
1137
|
+
para = doc.blocks.first
|
1138
|
+
para.remove_role 'role1'
|
1139
|
+
assert_equal nil, para.attributes['role']
|
1140
|
+
assert !para.has_role?('role1')
|
1141
|
+
end
|
1142
|
+
|
1057
1143
|
test 'option can be specified in first position of block style using shorthand syntax' do
|
1058
1144
|
input = <<-EOS
|
1059
1145
|
[%interactive]
|
data/test/blocks_test.rb
CHANGED
@@ -823,6 +823,33 @@ end
|
|
823
823
|
assert_equal expected.chomp, result
|
824
824
|
end
|
825
825
|
|
826
|
+
test 'should not remove block indent if indent attribute is -1' do
|
827
|
+
input = <<-EOS
|
828
|
+
[indent="-1"]
|
829
|
+
----
|
830
|
+
def names
|
831
|
+
|
832
|
+
@names.split ' '
|
833
|
+
|
834
|
+
end
|
835
|
+
----
|
836
|
+
EOS
|
837
|
+
|
838
|
+
expected = <<-EOS
|
839
|
+
def names
|
840
|
+
|
841
|
+
@names.split ' '
|
842
|
+
|
843
|
+
end
|
844
|
+
EOS
|
845
|
+
|
846
|
+
output = render_embedded_string input
|
847
|
+
assert_css 'pre', output, 1
|
848
|
+
assert_css '.listingblock pre', output, 1
|
849
|
+
result = xmlnodes_at_xpath('//pre', output, 1).text
|
850
|
+
assert_equal expected.chomp, result
|
851
|
+
end
|
852
|
+
|
826
853
|
test 'should set block indent to value specified by indent attribute' do
|
827
854
|
input = <<-EOS
|
828
855
|
[indent="1"]
|
@@ -837,9 +864,9 @@ end
|
|
837
864
|
|
838
865
|
expected = <<-EOS
|
839
866
|
def names
|
840
|
-
|
867
|
+
|
841
868
|
@names.split ' '
|
842
|
-
|
869
|
+
|
843
870
|
end
|
844
871
|
EOS
|
845
872
|
|
@@ -850,6 +877,64 @@ end
|
|
850
877
|
assert_equal expected.chomp, result
|
851
878
|
end
|
852
879
|
|
880
|
+
test 'should set block indent to value specified by indent document attribute' do
|
881
|
+
input = <<-EOS
|
882
|
+
:source-indent: 1
|
883
|
+
|
884
|
+
[source,ruby]
|
885
|
+
----
|
886
|
+
def names
|
887
|
+
|
888
|
+
@names.split ' '
|
889
|
+
|
890
|
+
end
|
891
|
+
----
|
892
|
+
EOS
|
893
|
+
|
894
|
+
expected = <<-EOS
|
895
|
+
def names
|
896
|
+
|
897
|
+
@names.split ' '
|
898
|
+
|
899
|
+
end
|
900
|
+
EOS
|
901
|
+
|
902
|
+
output = render_embedded_string input
|
903
|
+
assert_css 'pre', output, 1
|
904
|
+
assert_css '.listingblock pre', output, 1
|
905
|
+
result = xmlnodes_at_xpath('//pre', output, 1).text
|
906
|
+
assert_equal expected.chomp, result
|
907
|
+
end
|
908
|
+
|
909
|
+
test 'should expand tabs if tabsize attribute is positive' do
|
910
|
+
input = <<-EOS
|
911
|
+
:tabsize: 4
|
912
|
+
|
913
|
+
[indent=0]
|
914
|
+
----
|
915
|
+
def names
|
916
|
+
|
917
|
+
@names.split ' '
|
918
|
+
|
919
|
+
end
|
920
|
+
----
|
921
|
+
EOS
|
922
|
+
|
923
|
+
expected = <<-EOS
|
924
|
+
def names
|
925
|
+
|
926
|
+
@names.split ' '
|
927
|
+
|
928
|
+
end
|
929
|
+
EOS
|
930
|
+
|
931
|
+
output = render_embedded_string input
|
932
|
+
assert_css 'pre', output, 1
|
933
|
+
assert_css '.listingblock pre', output, 1
|
934
|
+
result = xmlnodes_at_xpath('//pre', output, 1).text
|
935
|
+
assert_equal expected.chomp, result
|
936
|
+
end
|
937
|
+
|
853
938
|
test 'literal block should honor nowrap option' do
|
854
939
|
input = <<-EOS
|
855
940
|
[options="nowrap"]
|
@@ -1200,11 +1285,9 @@ x+b/(2a)<+-sqrt((b^2)/(4a^2)-c/a)
|
|
1200
1285
|
++++
|
1201
1286
|
EOS
|
1202
1287
|
|
1203
|
-
expect =
|
1204
|
-
<
|
1205
|
-
|
1206
|
-
</informalequation>
|
1207
|
-
EOS
|
1288
|
+
expect = %(<informalequation>
|
1289
|
+
<mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"><mml:mi>x</mml:mi><mml:mo>+</mml:mo><mml:mfrac><mml:mi>b</mml:mi><mml:mrow><mml:mn>2</mml:mn><mml:mi>a</mml:mi></mml:mrow></mml:mfrac><mml:mo><</mml:mo><mml:mo>±</mml:mo><mml:msqrt><mml:mrow><mml:mfrac><mml:msup><mml:mi>b</mml:mi><mml:mn>2</mml:mn></mml:msup><mml:mrow><mml:mn>4</mml:mn><mml:msup><mml:mi>a</mml:mi><mml:mn>2</mml:mn></mml:msup></mml:mrow></mml:mfrac><mml:mo>−</mml:mo><mml:mfrac><mml:mi>c</mml:mi><mml:mi>a</mml:mi></mml:mfrac></mml:mrow></mml:msqrt></mml:math>
|
1290
|
+
</informalequation>)
|
1208
1291
|
|
1209
1292
|
output = render_embedded_string input, :backend => :docbook
|
1210
1293
|
assert_equal expect.strip, output.strip
|
@@ -1364,6 +1447,111 @@ image::images/tiger.png[Tiger]
|
|
1364
1447
|
assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
|
1365
1448
|
end
|
1366
1449
|
|
1450
|
+
test 'renders SVG image using img element by default' do
|
1451
|
+
input = <<-EOS
|
1452
|
+
image::tiger.svg[Tiger]
|
1453
|
+
EOS
|
1454
|
+
|
1455
|
+
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER
|
1456
|
+
assert_xpath '/*[@class="imageblock"]//img[@src="tiger.svg"][@alt="Tiger"]', output, 1
|
1457
|
+
end
|
1458
|
+
|
1459
|
+
test 'renders interactive SVG image with alt text using object element' do
|
1460
|
+
input = <<-EOS
|
1461
|
+
:imagesdir: images
|
1462
|
+
|
1463
|
+
[%interactive]
|
1464
|
+
image::tiger.svg[Tiger,100]
|
1465
|
+
EOS
|
1466
|
+
|
1467
|
+
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER
|
1468
|
+
assert_xpath '/*[@class="imageblock"]//object[@type="image/svg+xml"][@data="images/tiger.svg"][@width="100"]/span[@class="alt"][text()="Tiger"]', output, 1
|
1469
|
+
end
|
1470
|
+
|
1471
|
+
test 'renders SVG image with alt text using img element when safe mode is secure' do
|
1472
|
+
input = <<-EOS
|
1473
|
+
[%interactive]
|
1474
|
+
image::images/tiger.svg[Tiger,100]
|
1475
|
+
EOS
|
1476
|
+
|
1477
|
+
output = render_embedded_string input
|
1478
|
+
assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.svg"][@alt="Tiger"]', output, 1
|
1479
|
+
end
|
1480
|
+
|
1481
|
+
test 'inserts fallback image for SVG inside object element using same dimensions' do
|
1482
|
+
input = <<-EOS
|
1483
|
+
:imagesdir: images
|
1484
|
+
|
1485
|
+
[%interactive]
|
1486
|
+
image::tiger.svg[Tiger,100,fallback=tiger.png]
|
1487
|
+
EOS
|
1488
|
+
|
1489
|
+
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER
|
1490
|
+
assert_xpath '/*[@class="imageblock"]//object[@type="image/svg+xml"][@data="images/tiger.svg"][@width="100"]/img[@src="images/tiger.png"][@width="100"]', output, 1
|
1491
|
+
end
|
1492
|
+
|
1493
|
+
test 'detects SVG image URI that contains a query string' do
|
1494
|
+
input = <<-EOS
|
1495
|
+
:imagesdir: images
|
1496
|
+
|
1497
|
+
[%interactive]
|
1498
|
+
image::http://example.org/tiger.svg?foo=bar[Tiger,100]
|
1499
|
+
EOS
|
1500
|
+
|
1501
|
+
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER
|
1502
|
+
assert_xpath '/*[@class="imageblock"]//object[@type="image/svg+xml"][@data="http://example.org/tiger.svg?foo=bar"][@width="100"]/span[@class="alt"][text()="Tiger"]', output, 1
|
1503
|
+
end
|
1504
|
+
|
1505
|
+
test 'detects SVG image when format attribute is svg' do
|
1506
|
+
input = <<-EOS
|
1507
|
+
:imagesdir: images
|
1508
|
+
|
1509
|
+
[%interactive]
|
1510
|
+
image::http://example.org/tiger-svg[Tiger,100,format=svg]
|
1511
|
+
EOS
|
1512
|
+
|
1513
|
+
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER
|
1514
|
+
assert_xpath '/*[@class="imageblock"]//object[@type="image/svg+xml"][@data="http://example.org/tiger-svg"][@width="100"]/span[@class="alt"][text()="Tiger"]', output, 1
|
1515
|
+
end
|
1516
|
+
|
1517
|
+
test 'renders inline SVG image using svg element' do
|
1518
|
+
input = <<-EOS
|
1519
|
+
:imagesdir: fixtures
|
1520
|
+
|
1521
|
+
[%inline]
|
1522
|
+
image::circle.svg[Tiger,100]
|
1523
|
+
EOS
|
1524
|
+
|
1525
|
+
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'docdir' => ::File.dirname(__FILE__) }
|
1526
|
+
assert_match(/<svg [^>]*width="100px"[^>]*>/, output, 1)
|
1527
|
+
refute_match(/<svg [^>]*width="500px"[^>]*>/, output)
|
1528
|
+
refute_match(/<svg [^>]*height="500px"[^>]*>/, output)
|
1529
|
+
refute_match(/<svg [^>]*style="width:500px;height:500px"[^>]*>/, output)
|
1530
|
+
end
|
1531
|
+
|
1532
|
+
test 'renders inline SVG image using svg element even when data-uri is set' do
|
1533
|
+
input = <<-EOS
|
1534
|
+
:imagesdir: fixtures
|
1535
|
+
:data-uri:
|
1536
|
+
|
1537
|
+
[%inline]
|
1538
|
+
image::circle.svg[Tiger,100]
|
1539
|
+
EOS
|
1540
|
+
|
1541
|
+
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'docdir' => ::File.dirname(__FILE__) }
|
1542
|
+
assert_match(/<svg [^>]*width="100px">/, output, 1)
|
1543
|
+
end
|
1544
|
+
|
1545
|
+
test 'renders alt text for inline svg element if svg cannot be read' do
|
1546
|
+
input = <<-EOS
|
1547
|
+
[%inline]
|
1548
|
+
image::no-such-image.svg[Alt Text]
|
1549
|
+
EOS
|
1550
|
+
|
1551
|
+
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER
|
1552
|
+
assert_xpath '//span[@class="alt"][text()="Alt Text"]', output, 1
|
1553
|
+
end
|
1554
|
+
|
1367
1555
|
test 'can render block image with alt text defined in macro containing escaped square bracket' do
|
1368
1556
|
input = <<-EOS
|
1369
1557
|
image::images/tiger.png[A [Bengal\\] Tiger]
|
@@ -1805,7 +1993,7 @@ video::67480300[vimeo, 400, 300, start=60, options=autoplay]
|
|
1805
1993
|
output = render_embedded_string input
|
1806
1994
|
assert_css 'video', output, 0
|
1807
1995
|
assert_css 'iframe', output, 1
|
1808
|
-
assert_css 'iframe[src="
|
1996
|
+
assert_css 'iframe[src="https://player.vimeo.com/video/67480300#at=60?autoplay=1"]', output, 1
|
1809
1997
|
assert_css 'iframe[width="400"]', output, 1
|
1810
1998
|
assert_css 'iframe[height="300"]', output, 1
|
1811
1999
|
end
|
@@ -1817,7 +2005,7 @@ video::U8GBXvdmHT4/PLg7s6cbtAD15Das5LK9mXt_g59DLWxKUe[youtube, 640, 360, start=6
|
|
1817
2005
|
output = render_embedded_string input
|
1818
2006
|
assert_css 'video', output, 0
|
1819
2007
|
assert_css 'iframe', output, 1
|
1820
|
-
assert_css 'iframe[src="
|
2008
|
+
assert_css 'iframe[src="https://www.youtube.com/embed/U8GBXvdmHT4?rel=0&start=60&autoplay=1&list=PLg7s6cbtAD15Das5LK9mXt_g59DLWxKUe&modestbranding=1&theme=light"]', output, 1
|
1821
2009
|
assert_css 'iframe[width="640"]', output, 1
|
1822
2010
|
assert_css 'iframe[height="360"]', output, 1
|
1823
2011
|
end
|
@@ -1829,7 +2017,7 @@ video::SCZF6I-Rc4I,AsKGOeonbIs,HwrPhOp6-aM[youtube, 640, 360, start=60, options=
|
|
1829
2017
|
output = render_embedded_string input
|
1830
2018
|
assert_css 'video', output, 0
|
1831
2019
|
assert_css 'iframe', output, 1
|
1832
|
-
assert_css 'iframe[src="
|
2020
|
+
assert_css 'iframe[src="https://www.youtube.com/embed/SCZF6I-Rc4I?rel=0&start=60&autoplay=1&playlist=AsKGOeonbIs,HwrPhOp6-aM"]', output, 1
|
1833
2021
|
assert_css 'iframe[width="640"]', output, 1
|
1834
2022
|
assert_css 'iframe[height="360"]', output, 1
|
1835
2023
|
end
|
@@ -1961,7 +2149,7 @@ You can use icons for admonitions by setting the 'icons' attribute.
|
|
1961
2149
|
EOS
|
1962
2150
|
|
1963
2151
|
output = render_string input, :safe => Asciidoctor::SafeMode::SERVER
|
1964
|
-
assert_css 'html > head > link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.
|
2152
|
+
assert_css 'html > head > link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css"]', output, 1
|
1965
2153
|
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/i[@class="fa icon-tip"]', output, 1
|
1966
2154
|
end
|
1967
2155
|
|
@@ -1978,8 +2166,8 @@ puts "AsciiDoc, FTW!"
|
|
1978
2166
|
EOS
|
1979
2167
|
|
1980
2168
|
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
|
1981
|
-
assert_css 'html > head > link[rel="stylesheet"][href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.
|
1982
|
-
assert_css 'html >
|
2169
|
+
assert_css 'html > head > link[rel="stylesheet"][href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css"]', output, 1
|
2170
|
+
assert_css 'html > body > script[src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"]', output, 1
|
1983
2171
|
end
|
1984
2172
|
|
1985
2173
|
test 'should use no uri scheme for assets when asset-uri-scheme is blank' do
|
@@ -1995,8 +2183,8 @@ puts "AsciiDoc, FTW!"
|
|
1995
2183
|
EOS
|
1996
2184
|
|
1997
2185
|
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
|
1998
|
-
assert_css 'html > head > link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.
|
1999
|
-
assert_css 'html >
|
2186
|
+
assert_css 'html > head > link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css"]', output, 1
|
2187
|
+
assert_css 'html > body > script[src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"]', output, 1
|
2000
2188
|
end
|
2001
2189
|
end
|
2002
2190
|
|
data/test/converter_test.rb
CHANGED
@@ -26,13 +26,13 @@ context 'Converter' do
|
|
26
26
|
assert_equal :xhtml, selected.templates['paragraph'].options[:format]
|
27
27
|
end
|
28
28
|
|
29
|
-
test 'should set Slim format to
|
29
|
+
test 'should set Slim format to html for html5 backend' do
|
30
30
|
doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false
|
31
31
|
assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
|
32
32
|
selected = doc.converter.find_converter('paragraph')
|
33
33
|
assert selected.is_a? Asciidoctor::Converter::TemplateConverter
|
34
34
|
assert selected.templates['paragraph'].is_a? Slim::Template
|
35
|
-
assert_equal :
|
35
|
+
assert_equal :html, selected.templates['paragraph'].options[:format]
|
36
36
|
end
|
37
37
|
|
38
38
|
test 'should set Slim format to nil for docbook backend' do
|
@@ -44,6 +44,19 @@ context 'Converter' do
|
|
44
44
|
assert_nil selected.templates['paragraph'].options[:format]
|
45
45
|
end
|
46
46
|
|
47
|
+
test 'should set safe mode of Slim AsciiDoc engine to match document safe mode when Slim >= 3' do
|
48
|
+
doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false, :safe => :unsafe
|
49
|
+
assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
|
50
|
+
selected = doc.converter.find_converter('paragraph')
|
51
|
+
assert selected.is_a? Asciidoctor::Converter::TemplateConverter
|
52
|
+
slim_asciidoc_opts = selected.instance_variable_get(:@engine_options)[:slim][:asciidoc]
|
53
|
+
if ::Slim::VERSION >= '3.0'
|
54
|
+
assert_equal({ :safe => Asciidoctor::SafeMode::UNSAFE }, slim_asciidoc_opts)
|
55
|
+
else
|
56
|
+
assert_nil slim_asciidoc_opts
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
47
60
|
test 'should support custom template engine options for known engine' do
|
48
61
|
doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false, :template_engine_options => { :slim => { :pretty => true } }
|
49
62
|
assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
|
data/test/document_test.rb
CHANGED
@@ -138,7 +138,9 @@ context 'Document' do
|
|
138
138
|
exception = assert_raises ArgumentError do
|
139
139
|
Asciidoctor.load_file(sample_input_path, :safe => Asciidoctor::SafeMode::SAFE)
|
140
140
|
end
|
141
|
-
assert_match(/Failed to
|
141
|
+
assert_match(/Failed to load AsciiDoc document/, exception.message)
|
142
|
+
# verify we have the correct backtrace (should be in at least first 5 lines)
|
143
|
+
assert_match((RUBY_ENGINE == 'rbx' ? /parser\.rb/ : /helpers\.rb/), exception.backtrace[0..4].join("\n"))
|
142
144
|
end if RUBY_MIN_VERSION_1_9
|
143
145
|
|
144
146
|
test 'should load input IO' do
|
@@ -317,7 +319,7 @@ preamble
|
|
317
319
|
assert_equal 1, section_1.lineno
|
318
320
|
end
|
319
321
|
|
320
|
-
test 'find_by should return Array of blocks that match criteria' do
|
322
|
+
test 'find_by should return Array of blocks anywhere in document tree that match criteria' do
|
321
323
|
input = <<-EOS
|
322
324
|
= Document Title
|
323
325
|
|
@@ -334,7 +336,7 @@ Exhibit A::
|
|
334
336
|
image::tiger.png[Tiger]
|
335
337
|
--
|
336
338
|
|
337
|
-
image::
|
339
|
+
image::shoe.png[Shoe]
|
338
340
|
|
339
341
|
== Section B
|
340
342
|
|
@@ -347,7 +349,124 @@ paragraph
|
|
347
349
|
assert_equal :image, result[0].context
|
348
350
|
assert_equal 'tiger.png', result[0].attr('target')
|
349
351
|
assert_equal :image, result[1].context
|
350
|
-
assert_equal '
|
352
|
+
assert_equal 'shoe.png', result[1].attr('target')
|
353
|
+
end
|
354
|
+
|
355
|
+
test 'find_by should return an empty Array if no matches are found' do
|
356
|
+
input = <<-EOS
|
357
|
+
paragraph
|
358
|
+
EOS
|
359
|
+
doc = Asciidoctor.load input
|
360
|
+
result = doc.find_by :context => :section
|
361
|
+
refute_nil result
|
362
|
+
assert_equal 0, result.size
|
363
|
+
end
|
364
|
+
|
365
|
+
test 'find_by should return Array of blocks that match style criteria' do
|
366
|
+
input = <<-EOS
|
367
|
+
[square]
|
368
|
+
* one
|
369
|
+
* two
|
370
|
+
* three
|
371
|
+
|
372
|
+
---
|
373
|
+
|
374
|
+
* apples
|
375
|
+
* bananas
|
376
|
+
* pears
|
377
|
+
EOS
|
378
|
+
|
379
|
+
doc = Asciidoctor.load input
|
380
|
+
result = doc.find_by :context => :ulist, :style => 'square'
|
381
|
+
assert_equal 1, result.size
|
382
|
+
assert_equal :ulist, result[0].context
|
383
|
+
end
|
384
|
+
|
385
|
+
test 'find_by should return Array of blocks that match role criteria' do
|
386
|
+
input = <<-EOS
|
387
|
+
[#tiger.animal]
|
388
|
+
image::tiger.png[Tiger]
|
389
|
+
|
390
|
+
image::shoe.png[Shoe]
|
391
|
+
EOS
|
392
|
+
|
393
|
+
doc = Asciidoctor.load input
|
394
|
+
result = doc.find_by :context => :image, :role => 'animal'
|
395
|
+
assert_equal 1, result.size
|
396
|
+
assert_equal :image, result[0].context
|
397
|
+
assert_equal 'tiger.png', result[0].attr('target')
|
398
|
+
end
|
399
|
+
|
400
|
+
test 'find_by should return the document title section if context selector is :section' do
|
401
|
+
input = <<-EOS
|
402
|
+
= Document Title
|
403
|
+
|
404
|
+
preamble
|
405
|
+
|
406
|
+
== Section One
|
407
|
+
|
408
|
+
content
|
409
|
+
EOS
|
410
|
+
doc = Asciidoctor.load input
|
411
|
+
result = doc.find_by :context => :section
|
412
|
+
refute_nil result
|
413
|
+
assert_equal 2, result.size
|
414
|
+
assert_equal :section, result[0].context
|
415
|
+
assert_equal 'Document Title', result[0].title
|
416
|
+
end
|
417
|
+
|
418
|
+
test 'find_by should only return results for which the block argument yields true' do
|
419
|
+
input = <<-EOS
|
420
|
+
== Section
|
421
|
+
|
422
|
+
content
|
423
|
+
|
424
|
+
=== Subsection
|
425
|
+
|
426
|
+
content
|
427
|
+
EOS
|
428
|
+
doc = Asciidoctor.load input
|
429
|
+
result = doc.find_by(:context => :section) {|sect| sect.level == 1 }
|
430
|
+
refute_nil result
|
431
|
+
assert_equal 1, result.size
|
432
|
+
assert_equal :section, result[0].context
|
433
|
+
assert_equal 'Section', result[0].title
|
434
|
+
end
|
435
|
+
|
436
|
+
test 'find_by should only return one result when matching by id' do
|
437
|
+
input = <<-EOS
|
438
|
+
== Section
|
439
|
+
|
440
|
+
content
|
441
|
+
|
442
|
+
[#subsection]
|
443
|
+
=== Subsection
|
444
|
+
|
445
|
+
content
|
446
|
+
EOS
|
447
|
+
doc = Asciidoctor.load input
|
448
|
+
result = doc.find_by(:context => :section, :id => 'subsection')
|
449
|
+
refute_nil result
|
450
|
+
assert_equal 1, result.size
|
451
|
+
assert_equal :section, result[0].context
|
452
|
+
assert_equal 'Subsection', result[0].title
|
453
|
+
end
|
454
|
+
|
455
|
+
test 'find_by should return an empty Array if the id criteria matches but the block argument yields false' do
|
456
|
+
input = <<-EOS
|
457
|
+
== Section
|
458
|
+
|
459
|
+
content
|
460
|
+
|
461
|
+
[#subsection]
|
462
|
+
=== Subsection
|
463
|
+
|
464
|
+
content
|
465
|
+
EOS
|
466
|
+
doc = Asciidoctor.load input
|
467
|
+
result = doc.find_by(:context => :section, :id => 'subsection') {|sect| false }
|
468
|
+
refute_nil result
|
469
|
+
assert_equal 0, result.size
|
351
470
|
end
|
352
471
|
end
|
353
472
|
|
@@ -634,23 +753,38 @@ text
|
|
634
753
|
test 'should include docinfo files for html backend' do
|
635
754
|
sample_input_path = fixture_path('basic.asciidoc')
|
636
755
|
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
756
|
+
cases = {
|
757
|
+
'docinfo' => { :head_script => 1, :meta => 0, :top_link => 0, :footer_script => 1 },
|
758
|
+
'docinfo=private' => { :head_script => 1, :meta => 0, :top_link => 0, :footer_script => 1 },
|
759
|
+
'docinfo1' => { :head_script => 0, :meta => 1, :top_link => 1, :footer_script => 0 },
|
760
|
+
'docinfo=shared' => { :head_script => 0, :meta => 1, :top_link => 1, :footer_script => 0 },
|
761
|
+
'docinfo2' => { :head_script => 1, :meta => 1, :top_link => 1, :footer_script => 1 },
|
762
|
+
'docinfo docinfo2' => { :head_script => 1, :meta => 1, :top_link => 1, :footer_script => 1 },
|
763
|
+
'docinfo=private,shared' => { :head_script => 1, :meta => 1, :top_link => 1, :footer_script => 1 },
|
764
|
+
'docinfo=private-head' => { :head_script => 1, :meta => 0, :top_link => 0, :footer_script => 0 },
|
765
|
+
'docinfo=shared-head' => { :head_script => 0, :meta => 1, :top_link => 0, :footer_script => 0 },
|
766
|
+
'docinfo=private-footer' => { :head_script => 0, :meta => 0, :top_link => 0, :footer_script => 1 },
|
767
|
+
'docinfo=shared-footer' => { :head_script => 0, :meta => 0, :top_link => 1, :footer_script => 0 },
|
768
|
+
'docinfo=private-head\ ,\ shared-footer' => { :head_script => 1, :meta => 0, :top_link => 1, :footer_script => 0 }
|
769
|
+
}
|
642
770
|
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
771
|
+
cases.each do |attr_val, markup|
|
772
|
+
output = Asciidoctor.convert_file sample_input_path, :to_file => false,
|
773
|
+
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => %(linkcss copycss! #{attr_val})
|
774
|
+
assert !output.empty?
|
775
|
+
assert_css 'script[src="modernizr.js"]', output, markup[:head_script]
|
776
|
+
assert_css 'meta[http-equiv="imagetoolbar"]', output, markup[:meta]
|
777
|
+
assert_css 'body > a#top', output, markup[:top_link]
|
778
|
+
assert_css 'body > script', output, markup[:footer_script]
|
779
|
+
end
|
780
|
+
end
|
648
781
|
|
782
|
+
test 'should include docinfo footer even if nofooter attribute is set' do
|
783
|
+
sample_input_path = fixture_path('basic.asciidoc')
|
649
784
|
output = Asciidoctor.convert_file sample_input_path, :to_file => false,
|
650
|
-
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'
|
785
|
+
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => '', 'nofooter' => ''}
|
651
786
|
assert !output.empty?
|
652
|
-
assert_css '
|
653
|
-
assert_css 'meta[http-equiv="imagetoolbar"]', output, 1
|
787
|
+
assert_css 'body > a#top', output, 1
|
654
788
|
end
|
655
789
|
|
656
790
|
test 'should include docinfo files for html backend with custom docinfodir' do
|
@@ -817,12 +951,25 @@ text
|
|
817
951
|
assert_css 'productname', output, 0
|
818
952
|
assert_css 'copyright', output, 0
|
819
953
|
end
|
954
|
+
|
955
|
+
test 'should apply explicit substitutions to docinfo files' do
|
956
|
+
sample_input_path = fixture_path('subs.adoc')
|
957
|
+
|
958
|
+
output = Asciidoctor.convert_file sample_input_path, :to_file => false,
|
959
|
+
:header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => '', 'docinfosubs' => 'attributes,replacements', 'linkcss' => ''}
|
960
|
+
assert !output.empty?
|
961
|
+
assert_css 'script[src="bootstrap.3.2.0.min.js"]', output, 1
|
962
|
+
assert_xpath %(//meta[@name="copyright"][@content="#{entity 169} OpenDevise"]), output, 1
|
963
|
+
end
|
820
964
|
end
|
821
965
|
|
822
966
|
context 'MathJax' do
|
823
967
|
test 'should add MathJax script to HTML head if stem attribute is set' do
|
824
968
|
output = render_string '', :attributes => {'stem' => ''}
|
825
969
|
assert_match('<script type="text/x-mathjax-config">', output)
|
970
|
+
assert_match('inlineMath: [["\\\\(", "\\\\)"]]', output)
|
971
|
+
assert_match('displayMath: [["\\\\[", "\\\\]"]]', output)
|
972
|
+
assert_match('delimiters: [["\\\\$", "\\\\$"]]', output)
|
826
973
|
end
|
827
974
|
end
|
828
975
|
|
@@ -878,11 +1025,40 @@ text
|
|
878
1025
|
assert_nil doc.header
|
879
1026
|
end
|
880
1027
|
|
1028
|
+
test 'title partition API with default separator' do
|
1029
|
+
title = Asciidoctor::Document::Title.new 'Main Title: And More: Subtitle'
|
1030
|
+
assert_equal 'Main Title: And More', title.main
|
1031
|
+
assert_equal 'Subtitle', title.subtitle
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
test 'title partition API with custom separator' do
|
1035
|
+
title = Asciidoctor::Document::Title.new 'Main Title:: And More:: Subtitle', :separator => '::'
|
1036
|
+
assert_equal 'Main Title:: And More', title.main
|
1037
|
+
assert_equal 'Subtitle', title.subtitle
|
1038
|
+
end
|
1039
|
+
|
881
1040
|
test 'document with subtitle' do
|
882
1041
|
input = <<-EOS
|
883
1042
|
= Main Title: *Subtitle*
|
884
1043
|
Author Name
|
885
1044
|
|
1045
|
+
content
|
1046
|
+
EOS
|
1047
|
+
|
1048
|
+
doc = document_from_string input
|
1049
|
+
title = doc.doctitle :partition => true, :sanitize => true
|
1050
|
+
assert title.subtitle?
|
1051
|
+
assert title.sanitized?
|
1052
|
+
assert_equal 'Main Title', title.main
|
1053
|
+
assert_equal 'Subtitle', title.subtitle
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
test 'document with subtitle and custom separator' do
|
1057
|
+
input = <<-EOS
|
1058
|
+
[separator=::]
|
1059
|
+
= Main Title:: *Subtitle*
|
1060
|
+
Author Name
|
1061
|
+
|
886
1062
|
content
|
887
1063
|
EOS
|
888
1064
|
|
@@ -1003,7 +1179,7 @@ text
|
|
1003
1179
|
|
1004
1180
|
test 'should sanitize contents of HTML title element' do
|
1005
1181
|
input = <<-EOS
|
1006
|
-
= *Document* image:logo.png[] _Title_ image:another-logo.png[]
|
1182
|
+
= *Document* image:logo.png[] _Title_ image:another-logo.png[another logo]
|
1007
1183
|
|
1008
1184
|
content
|
1009
1185
|
EOS
|
@@ -1012,7 +1188,7 @@ content
|
|
1012
1188
|
assert_xpath '/html/head/title[text()="Document Title"]', output, 1
|
1013
1189
|
nodes = xmlnodes_at_xpath('//*[@id="header"]/h1', output, 1)
|
1014
1190
|
assert_equal 1, nodes.size
|
1015
|
-
assert_match(
|
1191
|
+
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)
|
1016
1192
|
end
|
1017
1193
|
|
1018
1194
|
test 'should not choke on empty source' do
|
@@ -1231,6 +1407,17 @@ content
|
|
1231
1407
|
assert_xpath '//*[@id="content"]', result, 1
|
1232
1408
|
end
|
1233
1409
|
|
1410
|
+
test 'does not render footer if nofooter is set' do
|
1411
|
+
input = <<-EOS
|
1412
|
+
:nofooter:
|
1413
|
+
|
1414
|
+
content
|
1415
|
+
EOS
|
1416
|
+
|
1417
|
+
result = render_string input
|
1418
|
+
assert_xpath '//*[@id="footer"]', result, 0
|
1419
|
+
end
|
1420
|
+
|
1234
1421
|
test 'can disable last updated in footer' do
|
1235
1422
|
doc = document_from_string "= Document Title\n\npreamble", :attributes => {'last-update-label!' => ''}
|
1236
1423
|
result = doc.render
|
@@ -1327,6 +1514,11 @@ Text that has supporting information{empty}footnote:[An example footnote.].
|
|
1327
1514
|
|
1328
1515
|
output = render_embedded_string input
|
1329
1516
|
assert_css '#footnotes', output, 1
|
1517
|
+
assert_css '#footnotes .footnote', output, 1
|
1518
|
+
assert_css '#footnotes .footnote#_footnote_1', output, 1
|
1519
|
+
assert_xpath '/div[@id="footnotes"]/div[@id="_footnote_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
|
1520
|
+
text = xmlnodes_at_xpath '/div[@id="footnotes"]/div[@id="_footnote_1"]/text()', output, 1
|
1521
|
+
assert_equal '. An example footnote.', text.text.strip
|
1330
1522
|
end
|
1331
1523
|
|
1332
1524
|
test 'does not render footnotes block in embedded document if nofootnotes attribute is set' do
|
@@ -1374,6 +1566,42 @@ content
|
|
1374
1566
|
assert_equal 'xml', (doc.attr 'htmlsyntax')
|
1375
1567
|
end
|
1376
1568
|
|
1569
|
+
test 'honor htmlsyntax attribute passed via API if backend is html' do
|
1570
|
+
input = <<-EOS
|
1571
|
+
---
|
1572
|
+
EOS
|
1573
|
+
doc = document_from_string input, :safe => :safe, :attributes => { 'htmlsyntax' => 'xml' }
|
1574
|
+
assert_equal 'html5', doc.backend
|
1575
|
+
assert_equal 'xml', (doc.attr 'htmlsyntax')
|
1576
|
+
result = doc.convert :header_footer => false
|
1577
|
+
assert_equal '<hr/>', result
|
1578
|
+
end
|
1579
|
+
|
1580
|
+
test 'honor htmlsyntax attribute in document header if followed by backend attribute' do
|
1581
|
+
input = <<-EOS
|
1582
|
+
:htmlsyntax: xml
|
1583
|
+
:backend: html5
|
1584
|
+
|
1585
|
+
---
|
1586
|
+
EOS
|
1587
|
+
doc = document_from_string input, :safe => :safe
|
1588
|
+
assert_equal 'html5', doc.backend
|
1589
|
+
assert_equal 'xml', (doc.attr 'htmlsyntax')
|
1590
|
+
result = doc.convert :header_footer => false
|
1591
|
+
assert_equal '<hr/>', result
|
1592
|
+
end
|
1593
|
+
|
1594
|
+
test 'does not honor htmlsyntax attribute in document header if not followed by backend attribute' do
|
1595
|
+
input = <<-EOS
|
1596
|
+
:backend: html5
|
1597
|
+
:htmlsyntax: xml
|
1598
|
+
|
1599
|
+
---
|
1600
|
+
EOS
|
1601
|
+
result = render_embedded_string input, :safe => :safe
|
1602
|
+
assert_equal '<hr>', result
|
1603
|
+
end
|
1604
|
+
|
1377
1605
|
test 'should close all short tags when htmlsyntax is xml' do
|
1378
1606
|
input = <<-EOS
|
1379
1607
|
= Document Title
|
@@ -1428,23 +1656,6 @@ two
|
|
1428
1656
|
rescue => e
|
1429
1657
|
flunk "xhtml5 backend did not generate well-formed XML: #{e.message}\n#{result}"
|
1430
1658
|
end
|
1431
|
-
#refute_match(/<meta [^>]+[^\/]>/, result)
|
1432
|
-
#refute_match(/<link [^>]+[^\/]>/, result)
|
1433
|
-
#refute_match(/<img [^>]+[^\/]>/, result)
|
1434
|
-
#refute_match(/<input [^>]+[^\/]>/, result)
|
1435
|
-
#assert_match(/<input [^>]+checked="checked"/, result)
|
1436
|
-
#assert_match(/<input [^>]+disabled="disabled"/, result)
|
1437
|
-
#refute_match(/<col [^>]+[^\/]>/, result)
|
1438
|
-
#refute_match(/<[bh]r>/, result)
|
1439
|
-
#assert_match(/video [^>]+loop="loop"/, result)
|
1440
|
-
#assert_match(/video [^>]+autoplay="autoplay"/, result)
|
1441
|
-
#assert_match(/video [^>]+controls="controls"/, result)
|
1442
|
-
#assert_match(/audio [^>]+loop="loop"/, result)
|
1443
|
-
#assert_match(/audio [^>]+autoplay="autoplay"/, result)
|
1444
|
-
#assert_match(/audio [^>]+controls="controls"/, result)
|
1445
|
-
#assert_match(/iframe [^>]+webkitallowfullscreen="webkitallowfullscreen"/i, result)
|
1446
|
-
#assert_match(/iframe [^>]+mozallowfullscreen="mozallowfullscreen"/i, result)
|
1447
|
-
#assert_match(/iframe [^>]+allowfullscreen="allowfullscreen"/i, result)
|
1448
1659
|
end
|
1449
1660
|
|
1450
1661
|
test 'xhtml backend should emit elements in proper namespace' do
|
@@ -1823,6 +2034,28 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
|
1823
2034
|
assert_xpath '//h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]/p[text()="asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats"]', output, 1
|
1824
2035
|
assert_xpath '//*[@id="content"]/*[@class="sect1"]/h2[text()="SYNOPSIS"]', output, 1
|
1825
2036
|
end
|
2037
|
+
|
2038
|
+
test 'should output special header block in embeddable HTML for manpage doctype' do
|
2039
|
+
input = <<-EOS
|
2040
|
+
= asciidoctor(1)
|
2041
|
+
:doctype: manpage
|
2042
|
+
:showtitle:
|
2043
|
+
|
2044
|
+
== NAME
|
2045
|
+
|
2046
|
+
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
2047
|
+
|
2048
|
+
== SYNOPSIS
|
2049
|
+
|
2050
|
+
*asciidoctor* ['OPTION']... 'FILE'..
|
2051
|
+
EOS
|
2052
|
+
|
2053
|
+
output = render_string input, :header_footer => false
|
2054
|
+
assert_xpath '/h1[text()="asciidoctor(1) Manual Page"]', output, 1
|
2055
|
+
assert_xpath '/h1/following-sibling::h2[text()="NAME"]', output, 1
|
2056
|
+
assert_xpath '/h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]', output, 1
|
2057
|
+
assert_xpath '/h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]/p[text()="asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats"]', output, 1
|
2058
|
+
end
|
1826
2059
|
end
|
1827
2060
|
|
1828
2061
|
context 'Secure Asset Path' do
|
@@ -1859,4 +2092,25 @@ text
|
|
1859
2092
|
assert_match(/missing converter for backend 'unknownBackend'/, exception.message)
|
1860
2093
|
end
|
1861
2094
|
end
|
2095
|
+
|
2096
|
+
context 'Timing report' do
|
2097
|
+
test 'print_report does not lose precision' do
|
2098
|
+
timings = Asciidoctor::Timings.new
|
2099
|
+
log = timings.instance_variable_get(:@log)
|
2100
|
+
log[:read] = 0.00001
|
2101
|
+
log[:parse] = 0.00003
|
2102
|
+
log[:convert] = 0.00005
|
2103
|
+
timings.print_report(sink = StringIO.new)
|
2104
|
+
expect = ['0.00004', '0.00005', '0.00009']
|
2105
|
+
result = sink.string.split("\n").map {|l| l.sub(/.*:\s*([\d.]+)/, '\1') }
|
2106
|
+
assert_equal expect, result
|
2107
|
+
end
|
2108
|
+
|
2109
|
+
test 'print_report should print 0 for untimed phases' do
|
2110
|
+
Asciidoctor::Timings.new.print_report(sink = StringIO.new)
|
2111
|
+
expect = [].fill('0.00000', 0..2)
|
2112
|
+
result = sink.string.split("\n").map {|l| l.sub(/.*:\s*([\d.]+)/, '\1') }
|
2113
|
+
assert_equal expect, result
|
2114
|
+
end
|
2115
|
+
end
|
1862
2116
|
end
|