asciidoctor 0.1.4 → 1.5.0

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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +209 -25
  3. data/{LICENSE → LICENSE.adoc} +4 -3
  4. data/README.adoc +392 -395
  5. data/Rakefile +94 -137
  6. data/benchmark/benchmark.rb +127 -0
  7. data/benchmark/sample-data/mdbasics.adoc +334 -0
  8. data/bin/asciidoctor +5 -8
  9. data/bin/asciidoctor-safe +4 -8
  10. data/compat/asciidoc.conf +78 -11
  11. data/compat/font-awesome-3-compat.css +397 -0
  12. data/data/stylesheets/asciidoctor-default.css +399 -0
  13. data/data/stylesheets/coderay-asciidoctor.css +89 -0
  14. data/features/open_block.feature +92 -0
  15. data/features/pass_block.feature +66 -0
  16. data/features/step_definitions.rb +42 -0
  17. data/features/text_formatting.feature +55 -0
  18. data/features/xref.feature +116 -0
  19. data/lib/asciidoctor.rb +1155 -605
  20. data/lib/asciidoctor/abstract_block.rb +157 -71
  21. data/lib/asciidoctor/abstract_node.rb +150 -93
  22. data/lib/asciidoctor/attribute_list.rb +85 -90
  23. data/lib/asciidoctor/block.rb +51 -24
  24. data/lib/asciidoctor/callouts.rb +4 -7
  25. data/lib/asciidoctor/cli.rb +3 -0
  26. data/lib/asciidoctor/cli/invoker.rb +86 -76
  27. data/lib/asciidoctor/cli/options.rb +111 -61
  28. data/lib/asciidoctor/converter.rb +232 -0
  29. data/lib/asciidoctor/converter/base.rb +58 -0
  30. data/lib/asciidoctor/converter/composite.rb +66 -0
  31. data/lib/asciidoctor/converter/docbook45.rb +94 -0
  32. data/lib/asciidoctor/converter/docbook5.rb +684 -0
  33. data/lib/asciidoctor/converter/factory.rb +225 -0
  34. data/lib/asciidoctor/converter/html5.rb +1081 -0
  35. data/lib/asciidoctor/converter/template.rb +296 -0
  36. data/lib/asciidoctor/core_ext.rb +7 -0
  37. data/lib/asciidoctor/core_ext/object/nil_or_empty.rb +23 -0
  38. data/lib/asciidoctor/core_ext/string/chr.rb +6 -0
  39. data/lib/asciidoctor/core_ext/symbol/length.rb +6 -0
  40. data/lib/asciidoctor/document.rb +590 -304
  41. data/lib/asciidoctor/extensions.rb +1100 -308
  42. data/lib/asciidoctor/helpers.rb +109 -46
  43. data/lib/asciidoctor/inline.rb +16 -9
  44. data/lib/asciidoctor/list.rb +23 -15
  45. data/lib/asciidoctor/opal_ext.rb +4 -0
  46. data/lib/asciidoctor/opal_ext/comparable.rb +38 -0
  47. data/lib/asciidoctor/opal_ext/dir.rb +13 -0
  48. data/lib/asciidoctor/opal_ext/error.rb +2 -0
  49. data/lib/asciidoctor/opal_ext/file.rb +125 -0
  50. data/lib/asciidoctor/{lexer.rb → parser.rb} +646 -455
  51. data/lib/asciidoctor/path_resolver.rb +141 -77
  52. data/lib/asciidoctor/reader.rb +257 -187
  53. data/lib/asciidoctor/section.rb +12 -16
  54. data/lib/asciidoctor/stylesheets.rb +91 -0
  55. data/lib/asciidoctor/substitutors.rb +1548 -0
  56. data/lib/asciidoctor/table.rb +73 -57
  57. data/lib/asciidoctor/timings.rb +39 -0
  58. data/lib/asciidoctor/version.rb +1 -1
  59. data/man/asciidoctor.1 +22 -14
  60. data/man/asciidoctor.adoc +18 -10
  61. data/test/attributes_test.rb +314 -14
  62. data/test/blocks_test.rb +763 -118
  63. data/test/converter_test.rb +352 -0
  64. data/test/document_test.rb +518 -199
  65. data/test/extensions_test.rb +273 -103
  66. data/test/fixtures/asciidoc_index.txt +27 -13
  67. data/test/fixtures/basic-docinfo.xml +1 -1
  68. data/test/fixtures/chapter-a.adoc +3 -0
  69. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
  70. data/test/fixtures/docinfo.xml +1 -1
  71. data/test/fixtures/include-file.asciidoc +2 -0
  72. data/test/fixtures/master.adoc +5 -0
  73. data/test/invoker_test.rb +173 -61
  74. data/test/links_test.rb +97 -21
  75. data/test/lists_test.rb +181 -22
  76. data/test/options_test.rb +86 -2
  77. data/test/paragraphs_test.rb +47 -5
  78. data/test/{lexer_test.rb → parser_test.rb} +128 -57
  79. data/test/paths_test.rb +36 -1
  80. data/test/preamble_test.rb +25 -17
  81. data/test/reader_test.rb +404 -249
  82. data/test/sections_test.rb +623 -58
  83. data/test/substitutions_test.rb +609 -132
  84. data/test/tables_test.rb +198 -24
  85. data/test/test_helper.rb +101 -31
  86. data/test/text_test.rb +88 -31
  87. metadata +160 -64
  88. data/Gemfile +0 -12
  89. data/Guardfile +0 -18
  90. data/asciidoctor.gemspec +0 -143
  91. data/lib/asciidoctor/backends/_stylesheets.rb +0 -466
  92. data/lib/asciidoctor/backends/base_template.rb +0 -114
  93. data/lib/asciidoctor/backends/docbook45.rb +0 -774
  94. data/lib/asciidoctor/backends/docbook5.rb +0 -103
  95. data/lib/asciidoctor/backends/html5.rb +0 -1214
  96. data/lib/asciidoctor/renderer.rb +0 -259
  97. data/lib/asciidoctor/substituters.rb +0 -1083
  98. data/test/fixtures/asciidoc.txt +0 -105
  99. data/test/fixtures/ascshort.txt +0 -32
  100. data/test/fixtures/list_elements.asciidoc +0 -10
  101. data/test/renderer_test.rb +0 -162
@@ -1,5 +1,8 @@
1
- require 'test_helper'
2
- require 'pathname'
1
+ # encoding: UTF-8
2
+ unless defined? ASCIIDOCTOR_PROJECT_DIR
3
+ $: << File.dirname(__FILE__); $:.uniq!
4
+ require 'test_helper'
5
+ end
3
6
 
4
7
  context "Blocks" do
5
8
  context 'Line Breaks' do
@@ -34,7 +37,7 @@ first paragraph
34
37
  second paragraph
35
38
  EOS
36
39
  output = render_embedded_string input
37
- assert_no_match(/line comment/, output)
40
+ refute_match(/line comment/, output)
38
41
  assert_xpath '//p', output, 2
39
42
  end
40
43
 
@@ -45,7 +48,7 @@ first line
45
48
  second line
46
49
  EOS
47
50
  output = render_embedded_string input
48
- assert_no_match(/line comment/, output)
51
+ refute_match(/line comment/, output)
49
52
  assert_xpath '//p', output, 1
50
53
  assert_xpath "//p[1][text()='first line\nsecond line']", output, 1
51
54
  end
@@ -61,7 +64,7 @@ block comment
61
64
  second paragraph
62
65
  EOS
63
66
  output = render_embedded_string input
64
- assert_no_match(/block comment/, output)
67
+ refute_match(/block comment/, output)
65
68
  assert_xpath '//p', output, 2
66
69
  end
67
70
 
@@ -74,7 +77,7 @@ block comment
74
77
  second paragraph
75
78
  EOS
76
79
  output = render_embedded_string input
77
- assert_no_match(/block comment/, output)
80
+ refute_match(/block comment/, output)
78
81
  assert_xpath '//p', output, 2
79
82
  end
80
83
 
@@ -89,7 +92,7 @@ block comment
89
92
 
90
93
  EOS
91
94
  output = render_embedded_string input
92
- assert_no_match(/block comment/, output)
95
+ refute_match(/block comment/, output)
93
96
  end
94
97
 
95
98
  test "trailing endlines after block comment at end of document does not create paragraph" do
@@ -247,10 +250,10 @@ ____
247
250
  assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
248
251
  assert_css '.quoteblock > .attribution', output, 1
249
252
  assert_css '.quoteblock > .attribution > cite', output, 1
250
- assert_css '.quoteblock > .attribution > cite + br', output, 1
253
+ assert_css '.quoteblock > .attribution > br + cite', output, 1
251
254
  assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Book (1999)"]', output, 1
252
255
  attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
253
- author = attribution.children.last
256
+ author = attribution.children.first
254
257
  assert_equal "#{expand_entity 8212} Famous Person", author.text.strip
255
258
  end
256
259
 
@@ -367,10 +370,10 @@ Some more inspiring words.
367
370
  assert_xpath %(//*[@class = "quoteblock"]//p[text() = "A famous quote.\nSome more inspiring words."]), output, 1
368
371
  assert_css '.quoteblock > .attribution', output, 1
369
372
  assert_css '.quoteblock > .attribution > cite', output, 1
370
- assert_css '.quoteblock > .attribution > cite + br', output, 1
373
+ assert_css '.quoteblock > .attribution > br + cite', output, 1
371
374
  assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Source, Volume 1 (1999)"]', output, 1
372
375
  attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
373
- author = attribution.children.last
376
+ author = attribution.children.first
374
377
  assert_equal "#{expand_entity 8212} Famous Person", author.text.strip
375
378
  end
376
379
 
@@ -386,10 +389,10 @@ Some more inspiring words."
386
389
  assert_xpath %(//*[@class = "quoteblock"]/blockquote[normalize-space(text()) = "A famous quote. Some more inspiring words."]), output, 1
387
390
  assert_css '.quoteblock > .attribution', output, 1
388
391
  assert_css '.quoteblock > .attribution > cite', output, 1
389
- assert_css '.quoteblock > .attribution > cite + br', output, 1
392
+ assert_css '.quoteblock > .attribution > br + cite', output, 1
390
393
  assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Source, Volume 1 (1999)"]', output, 1
391
394
  attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
392
- author = attribution.children.last
395
+ author = attribution.children.first
393
396
  assert_equal "#{expand_entity 8212} Famous Person", author.text.strip
394
397
  end
395
398
 
@@ -421,10 +424,10 @@ ____
421
424
  assert_css '.verseblock > pre', output, 1
422
425
  assert_css '.verseblock > .attribution', output, 1
423
426
  assert_css '.verseblock > .attribution > cite', output, 1
424
- assert_css '.verseblock > .attribution > cite + br', output, 1
427
+ assert_css '.verseblock > .attribution > br + cite', output, 1
425
428
  assert_xpath '//*[@class = "verseblock"]/*[@class = "attribution"]/cite[text() = "Famous Poem"]', output, 1
426
429
  attribution = xmlnodes_at_xpath '//*[@class = "verseblock"]/*[@class = "attribution"]', output, 1
427
- author = attribution.children.last
430
+ author = attribution.children.first
428
431
  assert_equal "#{expand_entity 8212} Famous Poet", author.text.strip
429
432
  end
430
433
 
@@ -463,7 +466,7 @@ ____
463
466
  assert_css '.verseblock .literalblock', output, 0
464
467
  end
465
468
 
466
- test 'verse should only have specialcharacters subs' do
469
+ test 'verse should have normal subs' do
467
470
  input = <<-EOS
468
471
  [verse]
469
472
  ____
@@ -472,7 +475,7 @@ ____
472
475
  EOS
473
476
 
474
477
  verse = block_from_string input
475
- assert_equal [:specialcharacters], verse.subs
478
+ assert_equal Asciidoctor::Substitutors::SUBS[:normal], verse.subs
476
479
  end
477
480
 
478
481
  test 'should not recognize callouts in a verse' do
@@ -487,6 +490,18 @@ ____
487
490
  output = render_embedded_string input
488
491
  assert_xpath '//pre[text()="La la la <1>"]', output, 1
489
492
  end
493
+
494
+ test 'should perform normal subs on a verse block' do
495
+ input = <<-EOS
496
+ [verse]
497
+ ____
498
+ _GET /groups/link:#group-id[\{group-id\}]_
499
+ ____
500
+ EOS
501
+
502
+ output = render_embedded_string input
503
+ assert output.include?('<pre class="content"><em>GET /groups/<a href="#group-id">{group-id}</a></em></pre>')
504
+ end
490
505
  end
491
506
 
492
507
  context "Example Blocks" do
@@ -581,7 +596,7 @@ Just write.
581
596
  doc = document_from_string input
582
597
  assert_equal 'Look!', doc.blocks.first.caption
583
598
  output = doc.render
584
- assert_no_match(/Look/, output)
599
+ refute_match(/Look/, output)
585
600
  end
586
601
 
587
602
  test 'automatic caption can be turned off and on and modified' do
@@ -677,8 +692,8 @@ line two
677
692
  line three
678
693
  ....
679
694
  EOS
680
- [true, false].each {|compact|
681
- output = render_string input, :compact => compact
695
+ [true, false].each {|header_footer|
696
+ output = render_string input, :header_footer => header_footer
682
697
  assert_xpath '//pre', output, 1
683
698
  assert_xpath '//pre/text()', output, 1
684
699
  text = xmlnodes_at_xpath('//pre/text()', output, 1).text
@@ -686,12 +701,8 @@ EOS
686
701
  assert_equal 5, lines.size
687
702
  expected = "line one\n\nline two\n\nline three".lines.entries
688
703
  assert_equal expected, lines
689
- blank_lines = output.scan(/\n[[:blank:]]*\n/).size
690
- if compact
691
- assert_equal 2, blank_lines
692
- else
693
- assert blank_lines >= 2
694
- end
704
+ blank_lines = output.scan(/\n[ \t]*\n/).size
705
+ assert blank_lines >= 2
695
706
  }
696
707
  end
697
708
 
@@ -706,8 +717,8 @@ line two
706
717
  line three
707
718
  ----
708
719
  EOS
709
- [true, false].each {|compact|
710
- output = render_string input, :compact => compact
720
+ [true, false].each {|header_footer|
721
+ output = render_string input, header_footer => header_footer
711
722
  assert_xpath '//pre/code', output, 1
712
723
  assert_xpath '//pre/code/text()', output, 1
713
724
  text = xmlnodes_at_xpath('//pre/code/text()', output, 1).text
@@ -715,17 +726,14 @@ EOS
715
726
  assert_equal 5, lines.size
716
727
  expected = "line one\n\nline two\n\nline three".lines.entries
717
728
  assert_equal expected, lines
718
- blank_lines = output.scan(/\n[[:blank:]]*\n/).size
719
- if compact
720
- assert_equal 2, blank_lines
721
- else
722
- assert blank_lines >= 2
723
- end
729
+ blank_lines = output.scan(/\n[ \t]*\n/).size
730
+ assert blank_lines >= 2
724
731
  }
725
732
  end
726
733
 
727
734
  test "should preserve endlines in verse block" do
728
735
  input = <<-EOS
736
+ --
729
737
  [verse]
730
738
  ____
731
739
  line one
@@ -734,9 +742,10 @@ line two
734
742
 
735
743
  line three
736
744
  ____
745
+ --
737
746
  EOS
738
- [true, false].each {|compact|
739
- output = render_string input, :compact => compact
747
+ [true, false].each {|header_footer|
748
+ output = render_string input, :header_footer => header_footer
740
749
  assert_xpath '//*[@class="verseblock"]/pre', output, 1
741
750
  assert_xpath '//*[@class="verseblock"]/pre/text()', output, 1
742
751
  text = xmlnodes_at_xpath('//*[@class="verseblock"]/pre/text()', output, 1).text
@@ -744,30 +753,31 @@ EOS
744
753
  assert_equal 5, lines.size
745
754
  expected = "line one\n\nline two\n\nline three".lines.entries
746
755
  assert_equal expected, lines
747
- blank_lines = output.scan(/\n[[:blank:]]*\n/).size
748
- if compact
749
- assert_equal 2, blank_lines
750
- else
751
- assert blank_lines >= 2
752
- end
756
+ blank_lines = output.scan(/\n[ \t]*\n/).size
757
+ assert blank_lines >= 2
753
758
  }
754
759
  end
755
760
 
756
- test 'should not compact nested document twice' do
761
+ test 'should strip leading and trailing blank lines when rendering verbatim block' do
757
762
  input = <<-EOS
758
- |===
759
- a|....
760
- line one
763
+ [subs="attributes"]
764
+ ....
761
765
 
762
- line two
763
766
 
764
- line three
767
+ first line
768
+
769
+ last line
770
+
771
+ {empty}
772
+
765
773
  ....
766
- |===
767
774
  EOS
768
775
 
769
- output = render_string input, :compact => true
770
- assert_xpath %(//pre[text() = "line one\n\nline two\n\nline three"]), output, 1
776
+ doc = document_from_string input, :header_footer => false
777
+ block = doc.blocks.first
778
+ assert_equal ['', '', ' first line', '', 'last line', '', '{empty}', ''], block.lines
779
+ result = doc.render
780
+ assert_xpath %(//pre[text()=" first line\n\nlast line"]), result, 1
771
781
  end
772
782
 
773
783
  test 'should process block with CRLF endlines' do
@@ -780,7 +790,7 @@ source line 2\r
780
790
  EOS
781
791
 
782
792
  output = render_embedded_string input
783
- assert_no_match(/\[source\]/, output)
793
+ refute_match(/\[source\]/, output)
784
794
  assert_xpath '/*[@class="listingblock"]//pre', output, 1
785
795
  assert_xpath '/*[@class="listingblock"]//pre/code', output, 1
786
796
  assert_xpath %(/*[@class="listingblock"]//pre/code[text()="source line 1\nsource line 2"]), output, 1
@@ -909,7 +919,7 @@ AssertionError
909
919
 
910
920
  assert_css '.listingblock pre', output, 1
911
921
  assert_css '.listingblock pre strong', output, 1
912
- assert_css '.listingblock pre em', output, 1
922
+ assert_css '.listingblock pre em', output, 0
913
923
 
914
924
  input2 = <<-EOS
915
925
  [subs="specialcharacters,macros"]
@@ -1028,36 +1038,245 @@ This is a passthrough block.
1028
1038
  assert_equal 'This is a passthrough block.', block.source
1029
1039
  end
1030
1040
 
1031
- test 'performs passthrough subs on a passthrough block' do
1041
+ test 'does not perform subs on a passthrough block by default' do
1032
1042
  input = <<-EOS
1033
1043
  :type: passthrough
1034
1044
 
1035
1045
  ++++
1036
1046
  This is a '{type}' block.
1037
1047
  http://asciidoc.org
1048
+ image:tiger.png[]
1038
1049
  ++++
1039
1050
  EOS
1040
1051
 
1041
- expected = %(This is a 'passthrough' block.\n<a href="http://asciidoc.org">http://asciidoc.org</a>)
1052
+ expected = %(This is a '{type}' block.\nhttp://asciidoc.org\nimage:tiger.png[])
1042
1053
  output = render_embedded_string input
1043
1054
  assert_equal expected, output.strip
1044
1055
  end
1045
1056
 
1046
- test 'passthrough block honors explicit subs list' do
1057
+ test 'does not perform subs on a passthrough block with pass style by default' do
1047
1058
  input = <<-EOS
1048
1059
  :type: passthrough
1049
1060
 
1050
- [subs="attributes, quotes"]
1061
+ [pass]
1051
1062
  ++++
1052
1063
  This is a '{type}' block.
1053
1064
  http://asciidoc.org
1065
+ image:tiger.png[]
1054
1066
  ++++
1055
1067
  EOS
1056
1068
 
1057
- expected = %(This is a <em>passthrough</em> block.\nhttp://asciidoc.org)
1069
+ expected = %(This is a '{type}' block.\nhttp://asciidoc.org\nimage:tiger.png[])
1058
1070
  output = render_embedded_string input
1059
1071
  assert_equal expected, output.strip
1060
1072
  end
1073
+
1074
+ test 'passthrough block honors explicit subs list' do
1075
+ input = <<-EOS
1076
+ :type: passthrough
1077
+
1078
+ [subs="attributes,quotes,macros"]
1079
+ ++++
1080
+ This is a _{type}_ block.
1081
+ http://asciidoc.org
1082
+ ++++
1083
+ EOS
1084
+
1085
+ expected = %(This is a <em>passthrough</em> block.\n<a href="http://asciidoc.org" class="bare">http://asciidoc.org</a>)
1086
+ output = render_embedded_string input
1087
+ assert_equal expected, output.strip
1088
+ end
1089
+
1090
+ test 'should strip leading and trailing blank lines when rendering raw block' do
1091
+ input = <<-EOS
1092
+ ++++
1093
+ line above
1094
+ ++++
1095
+
1096
+ ++++
1097
+
1098
+
1099
+ first line
1100
+
1101
+ last line
1102
+
1103
+
1104
+ ++++
1105
+
1106
+ ++++
1107
+ line below
1108
+ ++++
1109
+ EOS
1110
+
1111
+ doc = document_from_string input, :header_footer => false
1112
+ block = doc.blocks[1]
1113
+ assert_equal ['', '', ' first line', '', 'last line', '', ''], block.lines
1114
+ result = doc.render
1115
+ assert_equal "line above\n first line\n\nlast line\nline below", result, 1
1116
+ end
1117
+ end
1118
+
1119
+ context 'Math blocks' do
1120
+ test 'should add LaTeX math delimiters around latexmath block content' do
1121
+ input = <<-'EOS'
1122
+ [latexmath]
1123
+ ++++
1124
+ \sqrt{3x-1}+(1+x)^2 < y
1125
+ ++++
1126
+ EOS
1127
+
1128
+ output = render_embedded_string input
1129
+ assert_css '.stemblock', output, 1
1130
+ nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output, 1
1131
+ assert_equal '\[\sqrt{3x-1}+(1+x)^2 &lt; y\]', nodes.first.to_s.strip
1132
+ end
1133
+
1134
+ test 'should not add LaTeX math delimiters around latexmath block content if already present' do
1135
+ input = <<-'EOS'
1136
+ [latexmath]
1137
+ ++++
1138
+ \[\sqrt{3x-1}+(1+x)^2 < y\]
1139
+ ++++
1140
+ EOS
1141
+
1142
+ output = render_embedded_string input
1143
+ assert_css '.stemblock', output, 1
1144
+ nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output, 1
1145
+ assert_equal '\[\sqrt{3x-1}+(1+x)^2 &lt; y\]', nodes.first.to_s.strip
1146
+ end
1147
+
1148
+ test 'should render latexmath block in alt of equation in DocBook backend' do
1149
+ input = <<-'EOS'
1150
+ [latexmath]
1151
+ ++++
1152
+ \sqrt{3x-1}+(1+x)^2 < y
1153
+ ++++
1154
+ EOS
1155
+
1156
+ expect = <<-'EOS'
1157
+ <informalequation>
1158
+ <alt><![CDATA[\sqrt{3x-1}+(1+x)^2 < y]]></alt>
1159
+ <mediaobject><textobject><phrase></phrase></textobject></mediaobject>
1160
+ </informalequation>
1161
+ EOS
1162
+
1163
+ output = render_embedded_string input, :backend => :docbook
1164
+ assert_equal expect.strip, output.strip
1165
+ end
1166
+
1167
+ test 'should add AsciiMath delimiters around asciimath block content' do
1168
+ input = <<-'EOS'
1169
+ [asciimath]
1170
+ ++++
1171
+ sqrt(3x-1)+(1+x)^2 < y
1172
+ ++++
1173
+ EOS
1174
+
1175
+ output = render_embedded_string input
1176
+ assert_css '.stemblock', output, 1
1177
+ nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output, 1
1178
+ assert_equal '\$sqrt(3x-1)+(1+x)^2 &lt; y\$', nodes.first.to_s.strip
1179
+ end
1180
+
1181
+ test 'should not add AsciiMath delimiters around asciimath block content if already present' do
1182
+ input = <<-'EOS'
1183
+ [asciimath]
1184
+ ++++
1185
+ \$sqrt(3x-1)+(1+x)^2 < y\$
1186
+ ++++
1187
+ EOS
1188
+
1189
+ output = render_embedded_string input
1190
+ assert_css '.stemblock', output, 1
1191
+ nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output, 1
1192
+ assert_equal '\$sqrt(3x-1)+(1+x)^2 &lt; y\$', nodes.first.to_s.strip
1193
+ end
1194
+
1195
+ test 'should render asciimath block in textobject of equation in DocBook backend' do
1196
+ input = <<-'EOS'
1197
+ [asciimath]
1198
+ ++++
1199
+ x+b/(2a)<+-sqrt((b^2)/(4a^2)-c/a)
1200
+ ++++
1201
+ EOS
1202
+
1203
+ expect = <<-'EOS'
1204
+ <informalequation>
1205
+ <mediaobject><textobject><phrase><![CDATA[x+b/(2a)<+-sqrt((b^2)/(4a^2)-c/a)]]></phrase></textobject></mediaobject>
1206
+ </informalequation>
1207
+ EOS
1208
+
1209
+ output = render_embedded_string input, :backend => :docbook
1210
+ assert_equal expect.strip, output.strip
1211
+ end
1212
+
1213
+ test 'should output title for latexmath block if defined' do
1214
+ input = <<-'EOS'
1215
+ .The Lorenz Equations
1216
+ [latexmath]
1217
+ ++++
1218
+ \begin{aligned}
1219
+ \dot{x} & = \sigma(y-x) \\
1220
+ \dot{y} & = \rho x - y - xz \\
1221
+ \dot{z} & = -\beta z + xy
1222
+ \end{aligned}
1223
+ ++++
1224
+ EOS
1225
+
1226
+ output = render_embedded_string input
1227
+ assert_css '.stemblock', output, 1
1228
+ assert_css '.stemblock .title', output, 1
1229
+ assert_xpath '//*[@class="title"][text()="The Lorenz Equations"]', output, 1
1230
+ end
1231
+
1232
+ test 'should output title for asciimath block if defined' do
1233
+ input = <<-'EOS'
1234
+ .Simple fraction
1235
+ [asciimath]
1236
+ ++++
1237
+ a//b
1238
+ ++++
1239
+ EOS
1240
+
1241
+ output = render_embedded_string input
1242
+ assert_css '.stemblock', output, 1
1243
+ assert_css '.stemblock .title', output, 1
1244
+ assert_xpath '//*[@class="title"][text()="Simple fraction"]', output, 1
1245
+ end
1246
+
1247
+ test 'should add AsciiMath delimiters around stem block content if stem attribute != latexmath' do
1248
+ input = <<-'EOS'
1249
+ [stem]
1250
+ ++++
1251
+ sqrt(3x-1)+(1+x)^2 < y
1252
+ ++++
1253
+ EOS
1254
+
1255
+ [
1256
+ {},
1257
+ {'stem' => ''},
1258
+ {'stem' => 'asciimath'}
1259
+ ].each do |attributes|
1260
+ output = render_embedded_string input, :attributes => attributes
1261
+ assert_css '.stemblock', output, 1
1262
+ nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output, 1
1263
+ assert_equal '\$sqrt(3x-1)+(1+x)^2 &lt; y\$', nodes.first.to_s.strip
1264
+ end
1265
+ end
1266
+
1267
+ test 'should add LaTeX math delimiters around stem block content if stem attribute is latexmath' do
1268
+ input = <<-'EOS'
1269
+ [stem]
1270
+ ++++
1271
+ \sqrt{3x-1}+(1+x)^2 < y
1272
+ ++++
1273
+ EOS
1274
+
1275
+ output = render_embedded_string input, :attributes => {'stem' => 'latexmath'}
1276
+ assert_css '.stemblock', output, 1
1277
+ nodes = xmlnodes_at_xpath '//*[@class="content"]/child::text()', output, 1
1278
+ assert_equal '\[\sqrt{3x-1}+(1+x)^2 &lt; y\]', nodes.first.to_s.strip
1279
+ end
1061
1280
  end
1062
1281
 
1063
1282
  context 'Metadata' do
@@ -1141,8 +1360,8 @@ Block content
1141
1360
  image::images/tiger.png[Tiger]
1142
1361
  EOS
1143
1362
 
1144
- output = render_string input
1145
- assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
1363
+ output = render_embedded_string input
1364
+ assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
1146
1365
  end
1147
1366
 
1148
1367
  test 'can render block image with alt text defined in macro containing escaped square bracket' do
@@ -1161,8 +1380,8 @@ image::images/tiger.png[A [Bengal\\] Tiger]
1161
1380
  image::images/tiger.png[]
1162
1381
  EOS
1163
1382
 
1164
- output = render_string input
1165
- assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
1383
+ output = render_embedded_string input
1384
+ assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
1166
1385
  end
1167
1386
 
1168
1387
  test 'alt text in macro overrides alt text above macro' do
@@ -1171,8 +1390,26 @@ image::images/tiger.png[]
1171
1390
  image::images/tiger.png[Tiger]
1172
1391
  EOS
1173
1392
 
1174
- output = render_string input
1175
- assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
1393
+ output = render_embedded_string input
1394
+ assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
1395
+ end
1396
+
1397
+ test 'alt text is escaped in HTML backend' do
1398
+ input = <<-EOS
1399
+ image::images/open.png[File > Open]
1400
+ EOS
1401
+
1402
+ output = render_embedded_string input
1403
+ assert_match(/File &gt; Open/, output)
1404
+ end
1405
+
1406
+ test 'alt text is escaped in DocBook backend' do
1407
+ input = <<-EOS
1408
+ image::images/open.png[File > Open]
1409
+ EOS
1410
+
1411
+ output = render_embedded_string input, :backend => :docbook
1412
+ assert_match(/File &gt; Open/, output)
1176
1413
  end
1177
1414
 
1178
1415
  test "can render block image with auto-generated alt text" do
@@ -1180,8 +1417,8 @@ image::images/tiger.png[Tiger]
1180
1417
  image::images/tiger.png[]
1181
1418
  EOS
1182
1419
 
1183
- output = render_string input
1184
- assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="tiger"]', output, 1
1420
+ output = render_embedded_string input
1421
+ assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="tiger"]', output, 1
1185
1422
  end
1186
1423
 
1187
1424
  test "can render block image with alt text and height and width" do
@@ -1189,8 +1426,8 @@ image::images/tiger.png[]
1189
1426
  image::images/tiger.png[Tiger, 200, 300]
1190
1427
  EOS
1191
1428
 
1192
- output = render_string input
1193
- assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"][@width="200"][@height="300"]', output, 1
1429
+ output = render_embedded_string input
1430
+ assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"][@width="200"][@height="300"]', output, 1
1194
1431
  end
1195
1432
 
1196
1433
  test "can render block image with link" do
@@ -1198,8 +1435,8 @@ image::images/tiger.png[Tiger, 200, 300]
1198
1435
  image::images/tiger.png[Tiger, link='http://en.wikipedia.org/wiki/Tiger']
1199
1436
  EOS
1200
1437
 
1201
- output = render_string input
1202
- assert_xpath '//*[@class="imageblock"]//a[@class="image"][@href="http://en.wikipedia.org/wiki/Tiger"]/img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
1438
+ output = render_embedded_string input
1439
+ assert_xpath '/*[@class="imageblock"]//a[@class="image"][@href="http://en.wikipedia.org/wiki/Tiger"]/img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
1203
1440
  end
1204
1441
 
1205
1442
  test "can render block image with caption" do
@@ -1229,6 +1466,48 @@ image::images/tiger.png[Tiger]
1229
1466
  assert !doc.attributes.has_key?('figure-number')
1230
1467
  end
1231
1468
 
1469
+ test 'can align image in DocBook backend' do
1470
+ input = <<-EOS
1471
+ image::images/sunset.jpg[Sunset, align="right"]
1472
+ EOS
1473
+
1474
+ output = render_embedded_string input, :backend => :docbook
1475
+ assert_xpath '//imagedata', output, 1
1476
+ assert_xpath '//imagedata[@align="right"]', output, 1
1477
+ end
1478
+
1479
+ test 'can scale image in DocBook backend' do
1480
+ input = <<-EOS
1481
+ image::images/sunset.jpg[Sunset, scale="200"]
1482
+ EOS
1483
+
1484
+ output = render_embedded_string input, :backend => :docbook
1485
+ assert_xpath '//imagedata', output, 1
1486
+ assert_xpath '//imagedata[@scale="200"]', output, 1
1487
+ end
1488
+
1489
+ test 'can scale image width in DocBook backend' do
1490
+ input = <<-EOS
1491
+ image::images/sunset.jpg[Sunset, scaledwidth="25%"]
1492
+ EOS
1493
+
1494
+ output = render_embedded_string input, :backend => :docbook
1495
+ assert_xpath '//imagedata', output, 1
1496
+ assert_xpath '//imagedata[@width="25%"]', output, 1
1497
+ assert_xpath '//imagedata[@scalefit="1"]', output, 1
1498
+ end
1499
+
1500
+ test 'adds % to scaled width if no units given in DocBook backend ' do
1501
+ input = <<-EOS
1502
+ image::images/sunset.jpg[Sunset, scaledwidth="25"]
1503
+ EOS
1504
+
1505
+ output = render_embedded_string input, :backend => :docbook
1506
+ assert_xpath '//imagedata', output, 1
1507
+ assert_xpath '//imagedata[@width="25%"]', output, 1
1508
+ assert_xpath '//imagedata[@scalefit="1"]', output, 1
1509
+ end
1510
+
1232
1511
  test 'keeps line unprocessed if image target is missing attribute reference and attribute-missing is skip' do
1233
1512
  input = <<-EOS
1234
1513
  :attribute-missing: skip
@@ -1284,8 +1563,8 @@ image::{bogus}[]
1284
1563
  image::http://asciidoc.org/images/tiger.png[Tiger]
1285
1564
  EOS
1286
1565
 
1287
- output = render_string input
1288
- assert_xpath '//*[@class="imageblock"]//img[@src="http://asciidoc.org/images/tiger.png"][@alt="Tiger"]', output, 1
1566
+ output = render_embedded_string input
1567
+ assert_xpath '/*[@class="imageblock"]//img[@src="http://asciidoc.org/images/tiger.png"][@alt="Tiger"]', output, 1
1289
1568
  end
1290
1569
 
1291
1570
  test 'can resolve image relative to imagesdir' do
@@ -1295,8 +1574,8 @@ image::http://asciidoc.org/images/tiger.png[Tiger]
1295
1574
  image::tiger.png[Tiger]
1296
1575
  EOS
1297
1576
 
1298
- output = render_string input
1299
- assert_xpath '//*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
1577
+ output = render_embedded_string input
1578
+ assert_xpath '/*[@class="imageblock"]//img[@src="images/tiger.png"][@alt="Tiger"]', output, 1
1300
1579
  end
1301
1580
 
1302
1581
  test 'embeds base64-encoded data uri for image when data-uri attribute is set' do
@@ -1310,7 +1589,66 @@ image::dot.gif[Dot]
1310
1589
  doc = document_from_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
1311
1590
  assert_equal 'fixtures', doc.attributes['imagesdir']
1312
1591
  output = doc.render
1313
- assert_xpath '//*[@class="imageblock"]//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
1592
+ assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
1593
+ end
1594
+
1595
+ test 'embeds base64-encoded data uri for remote image when data-uri attribute is set' do
1596
+ input = <<-EOS
1597
+ :data-uri:
1598
+
1599
+ image::http://#{resolve_localhost}:9876/fixtures/dot.gif[Dot]
1600
+ EOS
1601
+
1602
+ output = using_test_webserver do
1603
+ render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
1604
+ end
1605
+
1606
+ assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
1607
+ end
1608
+
1609
+ test 'embeds base64-encoded data uri for remote image when imagesdir is a URI and data-uri attribute is set' do
1610
+ input = <<-EOS
1611
+ :data-uri:
1612
+ :imagesdir: http://#{resolve_localhost}:9876/fixtures
1613
+
1614
+ image::dot.gif[Dot]
1615
+ EOS
1616
+
1617
+ output = using_test_webserver do
1618
+ render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
1619
+ end
1620
+
1621
+ assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
1622
+ end
1623
+
1624
+ test 'uses remote image uri when data-uri attribute is set and image cannot be retrieved' do
1625
+ image_uri = "http://#{resolve_localhost}:9876/fixtures/missing-image.gif"
1626
+ input = <<-EOS
1627
+ :data-uri:
1628
+
1629
+ image::#{image_uri}[Missing image]
1630
+ EOS
1631
+
1632
+ output = using_test_webserver do
1633
+ render_embedded_string input, :safe => :safe, :attributes => {'allow-uri-read' => ''}
1634
+ end
1635
+
1636
+ assert_xpath %(/*[@class="imageblock"]//img[@src="#{image_uri}"][@alt="Missing image"]), output, 1
1637
+ end
1638
+
1639
+ test 'uses remote image uri when data-uri attribute is set and allow-uri-read is not set' do
1640
+ image_uri = "http://#{resolve_localhost}:9876/fixtures/dot.gif"
1641
+ input = <<-EOS
1642
+ :data-uri:
1643
+
1644
+ image::#{image_uri}[Dot]
1645
+ EOS
1646
+
1647
+ output = using_test_webserver do
1648
+ render_embedded_string input, :safe => :safe
1649
+ end
1650
+
1651
+ assert_xpath %(/*[@class="imageblock"]//img[@src="#{image_uri}"][@alt="Dot"]), output, 1
1314
1652
  end
1315
1653
 
1316
1654
  # this test will cause a warning to be printed to the console (until we have a message facility)
@@ -1327,7 +1665,7 @@ image::dot.gif[Dot]
1327
1665
  output = doc.render
1328
1666
  # image target resolves to fixtures/dot.gif relative to docdir (which is explicitly set to the directory of this file)
1329
1667
  # the reference cannot fall outside of the document directory in safe mode
1330
- assert_xpath '//*[@class="imageblock"]//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
1668
+ assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
1331
1669
  end
1332
1670
 
1333
1671
  test 'cleans reference to ancestor directories in target before reading image if safe mode level is at least SAFE' do
@@ -1343,7 +1681,7 @@ image::../..//fixtures/./../../fixtures/dot.gif[Dot]
1343
1681
  output = doc.render
1344
1682
  # image target resolves to fixtures/dot.gif relative to docdir (which is explicitly set to the directory of this file)
1345
1683
  # the reference cannot fall outside of the document directory in safe mode
1346
- assert_xpath '//*[@class="imageblock"]//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
1684
+ assert_xpath '//img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Dot"]', output, 1
1347
1685
  end
1348
1686
  end
1349
1687
 
@@ -1383,6 +1721,36 @@ video::cats-vs-dogs.avi[options="autoplay,nocontrols,loop"]
1383
1721
  assert_css 'video[loop]', output, 1
1384
1722
  end
1385
1723
 
1724
+ test 'video macro should add time range anchor with start time if start attribute is set' do
1725
+ input = <<-EOS
1726
+ video::cats-vs-dogs.avi[start="30"]
1727
+ EOS
1728
+
1729
+ output = render_embedded_string input
1730
+ assert_css 'video', output, 1
1731
+ assert_xpath '//video[@src="cats-vs-dogs.avi#t=30"]', output, 1
1732
+ end
1733
+
1734
+ test 'video macro should add time range anchor with end time if end attribute is set' do
1735
+ input = <<-EOS
1736
+ video::cats-vs-dogs.avi[end="30"]
1737
+ EOS
1738
+
1739
+ output = render_embedded_string input
1740
+ assert_css 'video', output, 1
1741
+ assert_xpath '//video[@src="cats-vs-dogs.avi#t=,30"]', output, 1
1742
+ end
1743
+
1744
+ test 'video macro should add time range anchor with start and end time if start and end attributes are set' do
1745
+ input = <<-EOS
1746
+ video::cats-vs-dogs.avi[start="30",end="60"]
1747
+ EOS
1748
+
1749
+ output = render_embedded_string input
1750
+ assert_css 'video', output, 1
1751
+ assert_xpath '//video[@src="cats-vs-dogs.avi#t=30,60"]', output, 1
1752
+ end
1753
+
1386
1754
  test 'video macro should use imagesdir attribute to resolve target and poster' do
1387
1755
  input = <<-EOS
1388
1756
  :imagesdir: assets
@@ -1561,8 +1929,42 @@ You can use icons for admonitions by setting the 'icons' attribute.
1561
1929
  EOS
1562
1930
 
1563
1931
  output = render_string input, :safe => Asciidoctor::SafeMode::SERVER
1564
- assert_css 'html > head > link[rel="stylesheet"][href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/3.2.1/css/font-awesome.min.css"]', output, 1
1565
- assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/i[@class="icon-tip"]', output, 1
1932
+ assert_css 'html > head > link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/font-awesome.min.css"]', output, 1
1933
+ assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/i[@class="fa icon-tip"]', output, 1
1934
+ end
1935
+
1936
+ test 'should use http uri scheme for assets when asset-uri-scheme is http' do
1937
+ input = <<-EOS
1938
+ :asset-uri-scheme: http
1939
+ :icons: font
1940
+ :source-highlighter: highlightjs
1941
+
1942
+ TIP: You can control the URI scheme used for assets with the asset-uri-scheme attribute
1943
+
1944
+ [source,ruby]
1945
+ puts "AsciiDoc, FTW!"
1946
+ EOS
1947
+
1948
+ output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
1949
+ assert_css 'html > head > link[rel="stylesheet"][href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/font-awesome.min.css"]', output, 1
1950
+ assert_css 'html > head > script[src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/highlight.min.js"]', output, 1
1951
+ end
1952
+
1953
+ test 'should use no uri scheme for assets when asset-uri-scheme is blank' do
1954
+ input = <<-EOS
1955
+ :asset-uri-scheme:
1956
+ :icons: font
1957
+ :source-highlighter: highlightjs
1958
+
1959
+ TIP: You can control the URI scheme used for assets with the asset-uri-scheme attribute
1960
+
1961
+ [source,ruby]
1962
+ puts "AsciiDoc, FTW!"
1963
+ EOS
1964
+
1965
+ output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
1966
+ assert_css 'html > head > link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/font-awesome.min.css"]', output, 1
1967
+ assert_css 'html > head > script[src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/highlight.min.js"]', output, 1
1566
1968
  end
1567
1969
  end
1568
1970
 
@@ -1612,19 +2014,6 @@ puts "Hello, World!"
1612
2014
  assert_css '.listingblock pre code', output, 1
1613
2015
  assert_css '.listingblock pre code:not([class])', output, 1
1614
2016
  end
1615
-
1616
- test 'should support fenced code block using tildes' do
1617
- input = <<-EOS
1618
- ~~~
1619
- puts "Hello, World!"
1620
- ~~~
1621
- EOS
1622
-
1623
- output = render_embedded_string input
1624
- assert_css '.listingblock', output, 1
1625
- assert_css '.listingblock pre code', output, 1
1626
- assert_css '.listingblock pre code:not([class])', output, 1
1627
- end
1628
2017
 
1629
2018
  test 'should not recognize fenced code blocks with more than three delimiters' do
1630
2019
  input = <<-EOS
@@ -1647,15 +2036,15 @@ alert("Hello, World!")
1647
2036
  puts "Hello, World!"
1648
2037
  ```
1649
2038
 
1650
- ~~~ javascript
2039
+ ``` javascript
1651
2040
  alert("Hello, World!")
1652
- ~~~
2041
+ ```
1653
2042
  EOS
1654
2043
 
1655
2044
  output = render_embedded_string input
1656
2045
  assert_css '.listingblock', output, 2
1657
- assert_css '.listingblock pre code.ruby', output, 1
1658
- assert_css '.listingblock pre code.javascript', output, 1
2046
+ assert_css '.listingblock pre code.language-ruby[data-lang=ruby]', output, 1
2047
+ assert_css '.listingblock pre code.language-javascript[data-lang=javascript]', output, 1
1659
2048
  end
1660
2049
 
1661
2050
  test 'should support fenced code blocks with languages and numbering' do
@@ -1664,15 +2053,15 @@ alert("Hello, World!")
1664
2053
  puts "Hello, World!"
1665
2054
  ```
1666
2055
 
1667
- ~~~ javascript, numbered
2056
+ ``` javascript, numbered
1668
2057
  alert("Hello, World!")
1669
- ~~~
2058
+ ```
1670
2059
  EOS
1671
2060
 
1672
2061
  output = render_embedded_string input
1673
2062
  assert_css '.listingblock', output, 2
1674
- assert_css '.listingblock pre code.ruby', output, 1
1675
- assert_css '.listingblock pre code.javascript', output, 1
2063
+ assert_css '.listingblock pre code.language-ruby[data-lang=ruby]', output, 1
2064
+ assert_css '.listingblock pre code.language-javascript[data-lang=javascript]', output, 1
1676
2065
  end
1677
2066
 
1678
2067
  test 'should highlight source if source-highlighter attribute is coderay' do
@@ -1687,8 +2076,42 @@ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
1687
2076
  ----
1688
2077
  EOS
1689
2078
  output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :linkcss_default => true
1690
- assert_xpath '//pre[@class="CodeRay"]/code[@class="ruby language-ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
1691
- assert_match(/\.CodeRay \{/, output)
2079
+ assert_xpath '//pre[@class="CodeRay highlight"]/code[@data-lang="ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
2080
+ assert_match(/\.CodeRay *\{/, output)
2081
+ end
2082
+
2083
+ test 'should read source language from source-language document attribute if not specified on source block' do
2084
+ input = <<-EOS
2085
+ :source-highlighter: coderay
2086
+ :source-language: ruby
2087
+
2088
+ [source]
2089
+ ----
2090
+ require 'coderay'
2091
+
2092
+ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
2093
+ ----
2094
+ EOS
2095
+ output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SAFE, :linkcss_default => true
2096
+ assert_xpath '//pre[@class="CodeRay highlight"]/code[@data-lang="ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
2097
+ end
2098
+
2099
+ test 'should rename document attribute named language to source-language when compat-mode is enabled' do
2100
+ input = <<-EOS
2101
+ :language: ruby
2102
+
2103
+ {source-language}
2104
+ EOS
2105
+
2106
+ assert_equal 'ruby', render_string(input, :doctype => :inline, :attributes => {'compat-mode' => ''})
2107
+
2108
+ input = <<-EOS
2109
+ :language: ruby
2110
+
2111
+ {source-language}
2112
+ EOS
2113
+
2114
+ assert_equal '{source-language}', render_string(input, :doctype => :inline)
1692
2115
  end
1693
2116
 
1694
2117
  test 'should replace callout marks but not highlight them if source-highlighter attribute is coderay' do
@@ -1711,10 +2134,10 @@ exit 0 # <5><6>
1711
2134
  <6> Reports success
1712
2135
  EOS
1713
2136
  output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SAFE
1714
- assert_match(/<span class="content">coderay<\/span>.* <b>\(1\)<\/b>$/, output)
1715
- assert_match(/<span class="content">puts 'Hello, world!'<\/span>.* <b>\(2\)<\/b>$/, output)
1716
- assert_match(/puts html * <b>\(3\)<\/b> <b>\(4\)<\/b>$/, output)
1717
- assert_match(/exit.* <b>\(5\)<\/b> <b>\(6\)<\/b><\/code>/, output)
2137
+ assert_match(/<span class="content">coderay<\/span>.* <b class="conum">\(1\)<\/b>$/, output)
2138
+ assert_match(/<span class="content">puts 'Hello, world!'<\/span>.* <b class="conum">\(2\)<\/b>$/, output)
2139
+ assert_match(/puts html * <b class="conum">\(3\)<\/b> <b class="conum">\(4\)<\/b>$/, output)
2140
+ assert_match(/exit.* <b class="conum">\(5\)<\/b> <b class="conum">\(6\)<\/b><\/code>/, output)
1718
2141
  end
1719
2142
 
1720
2143
  test 'should restore callout marks to correct lines if source highlighter is coderay and table line numbering is enabled' do
@@ -1738,10 +2161,31 @@ exit 0 # <5><6>
1738
2161
  <6> Reports success
1739
2162
  EOS
1740
2163
  output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SAFE
1741
- assert_match(/<span class="content">coderay<\/span>.* <b>\(1\)<\/b>$/, output)
1742
- assert_match(/<span class="content">puts 'Hello, world!'<\/span>.* <b>\(2\)<\/b>$/, output)
1743
- assert_match(/puts html * <b>\(3\)<\/b> <b>\(4\)<\/b>$/, output)
1744
- assert_match(/exit.* <b>\(5\)<\/b> <b>\(6\)<\/b><\/pre>/, output)
2164
+ assert_match(/<span class="content">coderay<\/span>.* <b class="conum">\(1\)<\/b>$/, output)
2165
+ assert_match(/<span class="content">puts 'Hello, world!'<\/span>.* <b class="conum">\(2\)<\/b>$/, output)
2166
+ assert_match(/puts html * <b class="conum">\(3\)<\/b> <b class="conum">\(4\)<\/b>$/, output)
2167
+ assert_match(/exit.* <b class="conum">\(5\)<\/b> <b class="conum">\(6\)<\/b><\/pre>/, output)
2168
+ end
2169
+
2170
+ test 'should preserve passthrough placeholders when highlighting source using coderay' do
2171
+ input = <<-EOS
2172
+ :source-highlighter: coderay
2173
+
2174
+ [source,java]
2175
+ [subs="specialcharacters,macros,callouts"]
2176
+ ----
2177
+ public class Printer {
2178
+ public static void main(String[] args) {
2179
+ System.pass:quotes[_out_].println("*asterisks* make text pass:quotes[*bold*]");
2180
+ }
2181
+ }
2182
+ ----
2183
+ EOS
2184
+ output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
2185
+ assert_match(/\.<em>out<\/em>\./, output, 1)
2186
+ assert_match(/\*asterisks\*/, output, 1)
2187
+ assert_match(/<strong>bold<\/strong>/, output, 1)
2188
+ assert !output.include?(Asciidoctor::Substitutors::PASS_START)
1745
2189
  end
1746
2190
 
1747
2191
  test 'should link to CodeRay stylesheet if source-highlighter is coderay and linkcss is set' do
@@ -1756,8 +2200,8 @@ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
1756
2200
  ----
1757
2201
  EOS
1758
2202
  output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss' => ''}
1759
- assert_xpath '//pre[@class="CodeRay"]/code[@class="ruby language-ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
1760
- assert_css 'link[rel="stylesheet"][href="./asciidoctor-coderay.css"]', output, 1
2203
+ assert_xpath '//pre[@class="CodeRay highlight"]/code[@data-lang="ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
2204
+ assert_css 'link[rel="stylesheet"][href="./coderay-asciidoctor.css"]', output, 1
1761
2205
  end
1762
2206
 
1763
2207
  test 'should highlight source inline if source-highlighter attribute is coderay and coderay-css is style' do
@@ -1773,8 +2217,8 @@ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
1773
2217
  ----
1774
2218
  EOS
1775
2219
  output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :linkcss_default => true
1776
- assert_xpath '//pre[@class="CodeRay"]/code[@class="ruby language-ruby"]//span[@style = "color:#036;font-weight:bold"][text() = "CodeRay"]', output, 1
1777
- assert_no_match(/\.CodeRay \{/, output)
2220
+ assert_xpath '//pre[@class="CodeRay highlight"]/code[@data-lang="ruby"]//span[@style = "color:#036;font-weight:bold"][text() = "CodeRay"]', output, 1
2221
+ refute_match(/\.CodeRay \{/, output)
1778
2222
  end
1779
2223
 
1780
2224
  test 'should include remote highlight.js assets if source-highlighter attribute is highlightjs' do
@@ -1794,6 +2238,19 @@ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
1794
2238
  assert_match(/hljs.initHighlightingOnLoad/, output)
1795
2239
  end
1796
2240
 
2241
+ test 'should add language classes to child code element when source-highlighter is prettify' do
2242
+ input = <<-EOS
2243
+ [source,ruby]
2244
+ ----
2245
+ puts "foo"
2246
+ ----
2247
+ EOS
2248
+
2249
+ output = render_embedded_string input, :attributes => {'source-highlighter' => 'prettify'}
2250
+ assert_css 'pre[class="prettyprint highlight"]', output, 1
2251
+ assert_css 'pre > code.language-ruby[data-lang="ruby"]', output, 1
2252
+ end
2253
+
1797
2254
  test 'should set lang attribute on pre when source-highlighter is html-pipeline' do
1798
2255
  input = <<-EOS
1799
2256
  [source,ruby]
@@ -1835,6 +2292,10 @@ This article is about stuff.
1835
2292
 
1836
2293
  And other stuff.
1837
2294
  --
2295
+
2296
+ == Section One
2297
+
2298
+ content
1838
2299
  EOS
1839
2300
 
1840
2301
  output = render_string input
@@ -1854,6 +2315,10 @@ And other stuff.
1854
2315
  --
1855
2316
  This article is about stuff.
1856
2317
  --
2318
+
2319
+ == Section One
2320
+
2321
+ content
1857
2322
  EOS
1858
2323
 
1859
2324
  output = render_string input
@@ -1886,8 +2351,15 @@ Abstract for book with title is valid
1886
2351
  Abstract for book without title is invalid.
1887
2352
  EOS
1888
2353
 
1889
- output = render_string input
2354
+ warnings = nil
2355
+ output = nil
2356
+ redirect_streams do |stdout, stderr|
2357
+ output = render_string input
2358
+ warnings = stderr.string
2359
+ end
1890
2360
  assert_css '.abstract', output, 0
2361
+ refute_nil warnings
2362
+ assert_match(/WARNING:.*abstract block/, warnings)
1891
2363
  end
1892
2364
 
1893
2365
  test 'should make abstract on open block without title rendered to DocBook' do
@@ -1945,8 +2417,15 @@ Abstract for book with title is valid
1945
2417
  Abstract for book is invalid.
1946
2418
  EOS
1947
2419
 
1948
- output = render_string input, :backend => 'docbook'
2420
+ output = nil
2421
+ warnings = nil
2422
+ redirect_streams do |stdout, stderr|
2423
+ output = render_string input, :backend => 'docbook'
2424
+ warnings = stderr.string
2425
+ end
1949
2426
  assert_css 'abstract', output, 0
2427
+ refute_nil warnings
2428
+ assert_match(/WARNING:.*abstract block/, warnings)
1950
2429
  end
1951
2430
 
1952
2431
  # TODO partintro shouldn't be recognized if doctype is not book, should be in proper place
@@ -1963,6 +2442,10 @@ This is a part intro.
1963
2442
 
1964
2443
  It can have multiple paragraphs.
1965
2444
  --
2445
+
2446
+ == Chapter 1
2447
+
2448
+ content
1966
2449
  EOS
1967
2450
 
1968
2451
  output = render_string input
@@ -1986,6 +2469,10 @@ It can have multiple paragraphs.
1986
2469
  --
1987
2470
  This is a part intro with a title.
1988
2471
  --
2472
+
2473
+ == Chapter 1
2474
+
2475
+ content
1989
2476
  EOS
1990
2477
 
1991
2478
  output = render_string input
@@ -2034,9 +2521,13 @@ This is a part intro.
2034
2521
 
2035
2522
  It can have multiple paragraphs.
2036
2523
  --
2524
+
2525
+ == Chapter 1
2526
+
2527
+ content
2037
2528
  EOS
2038
2529
 
2039
- output = render_string input, :backend => 'docbook'
2530
+ output = render_string input, :backend => 'docbook45'
2040
2531
  assert_css 'partintro', output, 1
2041
2532
  assert_css 'part#_part_1 > partintro', output, 1
2042
2533
  assert_css 'partintro > simpara', output, 2
@@ -2054,9 +2545,13 @@ It can have multiple paragraphs.
2054
2545
  --
2055
2546
  This is a part intro with a title.
2056
2547
  --
2548
+
2549
+ == Chapter 1
2550
+
2551
+ content
2057
2552
  EOS
2058
2553
 
2059
- output = render_string input, :backend => 'docbook'
2554
+ output = render_string input, :backend => 'docbook45'
2060
2555
  assert_css 'partintro', output, 1
2061
2556
  assert_css 'part#_part_1 > partintro', output, 1
2062
2557
  assert_css 'partintro > title', output, 1
@@ -2087,4 +2582,154 @@ part intro paragraph
2087
2582
  end
2088
2583
  end
2089
2584
 
2585
+ context 'Substitutions' do
2586
+ test 'should be able to append subs to default block substitution list' do
2587
+ input = <<-EOS
2588
+ :application: Asciidoctor
2589
+
2590
+ [subs="+attributes,+macros"]
2591
+ ....
2592
+ {application}
2593
+ ....
2594
+ EOS
2595
+
2596
+ doc = document_from_string input
2597
+ block = doc.blocks.first
2598
+ assert_equal [:specialcharacters, :attributes, :macros], block.subs
2599
+ end
2600
+
2601
+ test 'should be able to prepend subs to default block substitution list' do
2602
+ input = <<-EOS
2603
+ :application: Asciidoctor
2604
+
2605
+ [subs="attributes+"]
2606
+ ....
2607
+ {application}
2608
+ ....
2609
+ EOS
2610
+
2611
+ doc = document_from_string input
2612
+ block = doc.blocks.first
2613
+ assert_equal [:attributes, :specialcharacters], block.subs
2614
+ end
2615
+
2616
+ test 'should be able to remove subs to default block substitution list' do
2617
+ input = <<-EOS
2618
+ [subs="-quotes,-replacements"]
2619
+ content
2620
+ EOS
2621
+
2622
+ doc = document_from_string input
2623
+ block = doc.blocks.first
2624
+ assert_equal [:specialcharacters, :attributes, :macros, :post_replacements], block.subs
2625
+ end
2626
+
2627
+ test 'should be able to prepend, append and remove subs from default block substitution list' do
2628
+ input = <<-EOS
2629
+ :application: asciidoctor
2630
+
2631
+ [subs="attributes+,-verbatim,+specialcharacters,+macros"]
2632
+ ....
2633
+ http://{application}.org[{gt}{gt}] <1>
2634
+ ....
2635
+ EOS
2636
+
2637
+ doc = document_from_string input, :header_footer => false
2638
+ block = doc.blocks.first
2639
+ assert_equal [:attributes, :specialcharacters, :macros], block.subs
2640
+ result = doc.render
2641
+ assert result.include?('<pre><a href="http://asciidoctor.org">&gt;&gt;</a> &lt;1&gt;</pre>')
2642
+ end
2643
+
2644
+ test 'should be able to set subs then modify them' do
2645
+ input = <<-EOS
2646
+ [subs="verbatim,-callouts"]
2647
+ _hey now_ <1>
2648
+ EOS
2649
+
2650
+ doc = document_from_string input, :header_footer => false
2651
+ block = doc.blocks.first
2652
+ assert_equal [:specialcharacters], block.subs
2653
+ result = doc.render
2654
+ assert result.include?('_hey now_ &lt;1&gt;')
2655
+ end
2656
+ end
2657
+
2658
+ context 'References' do
2659
+ test 'should not recognize block anchor with illegal id characters' do
2660
+ input = <<-EOS
2661
+ [[illegal$id,Reference Text]]
2662
+ ----
2663
+ content
2664
+ ----
2665
+ EOS
2666
+
2667
+ doc = document_from_string input
2668
+ block = doc.blocks.first
2669
+ assert_nil block.id
2670
+ assert_nil(block.attr 'reftext')
2671
+ assert !doc.references[:ids].has_key?('illegal$id')
2672
+ end
2673
+
2674
+ test 'should use specified id and reftext when registering block reference' do
2675
+ input = <<-EOS
2676
+ [[debian,Debian Install]]
2677
+ .Installation on Debian
2678
+ ----
2679
+ $ apt-get install asciidoctor
2680
+ ----
2681
+ EOS
2682
+
2683
+ doc = document_from_string input
2684
+ reftext = doc.references[:ids]['debian']
2685
+ refute_nil reftext
2686
+ assert_equal 'Debian Install', reftext
2687
+ end
2688
+
2689
+ test 'should allow square brackets in block reference text' do
2690
+ input = <<-EOS
2691
+ [[debian,[Debian] Install]]
2692
+ .Installation on Debian
2693
+ ----
2694
+ $ apt-get install asciidoctor
2695
+ ----
2696
+ EOS
2697
+
2698
+ doc = document_from_string input
2699
+ reftext = doc.references[:ids]['debian']
2700
+ refute_nil reftext
2701
+ assert_equal '[Debian] Install', reftext
2702
+ end
2703
+
2704
+ test 'should allow comma in block reference text' do
2705
+ input = <<-EOS
2706
+ [[debian, Debian, Ubuntu]]
2707
+ .Installation on Debian
2708
+ ----
2709
+ $ apt-get install asciidoctor
2710
+ ----
2711
+ EOS
2712
+
2713
+ doc = document_from_string input
2714
+ reftext = doc.references[:ids]['debian']
2715
+ refute_nil reftext
2716
+ assert_equal 'Debian, Ubuntu', reftext
2717
+ end
2718
+
2719
+ test 'should use specified reftext when registering block reference' do
2720
+ input = <<-EOS
2721
+ [[debian]]
2722
+ [reftext="Debian Install"]
2723
+ .Installation on Debian
2724
+ ----
2725
+ $ apt-get install asciidoctor
2726
+ ----
2727
+ EOS
2728
+
2729
+ doc = document_from_string input
2730
+ reftext = doc.references[:ids]['debian']
2731
+ refute_nil reftext
2732
+ assert_equal 'Debian Install', reftext
2733
+ end
2734
+ end
2090
2735
  end