asciidoctor 1.5.5 → 1.5.6

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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +216 -1
  3. data/CONTRIBUTING.adoc +2 -2
  4. data/Gemfile +20 -1
  5. data/LICENSE.adoc +1 -1
  6. data/README-fr.adoc +4 -3
  7. data/README-jp.adoc +11 -10
  8. data/README-zh_CN.adoc +4 -3
  9. data/README.adoc +17 -202
  10. data/Rakefile +41 -25
  11. data/asciidoctor.gemspec +9 -10
  12. data/data/locale/attributes.adoc +216 -34
  13. data/data/stylesheets/asciidoctor-default.css +23 -16
  14. data/features/step_definitions.rb +15 -19
  15. data/features/xref.feature +584 -20
  16. data/lib/asciidoctor.rb +292 -278
  17. data/lib/asciidoctor/abstract_block.rb +155 -94
  18. data/lib/asciidoctor/abstract_node.rb +108 -94
  19. data/lib/asciidoctor/attribute_list.rb +30 -22
  20. data/lib/asciidoctor/block.rb +7 -7
  21. data/lib/asciidoctor/cli/invoker.rb +47 -34
  22. data/lib/asciidoctor/cli/options.rb +22 -11
  23. data/lib/asciidoctor/converter.rb +3 -3
  24. data/lib/asciidoctor/converter/base.rb +2 -2
  25. data/lib/asciidoctor/converter/composite.rb +1 -1
  26. data/lib/asciidoctor/converter/docbook45.rb +2 -2
  27. data/lib/asciidoctor/converter/docbook5.rb +132 -87
  28. data/lib/asciidoctor/converter/factory.rb +0 -1
  29. data/lib/asciidoctor/converter/html5.rb +116 -98
  30. data/lib/asciidoctor/converter/manpage.rb +51 -52
  31. data/lib/asciidoctor/converter/template.rb +47 -36
  32. data/lib/asciidoctor/core_ext.rb +8 -2
  33. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +4 -0
  34. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +6 -0
  35. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +5 -0
  36. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +1 -1
  37. data/lib/asciidoctor/core_ext/1.8.7/string/{limit.rb → limit_bytesize.rb} +7 -6
  38. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +6 -0
  39. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +1 -1
  40. data/lib/asciidoctor/core_ext/nil_or_empty.rb +5 -5
  41. data/lib/asciidoctor/core_ext/regexp/is_match.rb +3 -0
  42. data/lib/asciidoctor/core_ext/string/{limit.rb → limit_bytesize.rb} +2 -2
  43. data/lib/asciidoctor/document.rb +216 -213
  44. data/lib/asciidoctor/extensions.rb +318 -185
  45. data/lib/asciidoctor/helpers.rb +35 -35
  46. data/lib/asciidoctor/inline.rb +32 -1
  47. data/lib/asciidoctor/list.rb +22 -6
  48. data/lib/asciidoctor/parser.rb +1008 -1038
  49. data/lib/asciidoctor/path_resolver.rb +46 -50
  50. data/lib/asciidoctor/reader.rb +275 -251
  51. data/lib/asciidoctor/section.rb +86 -58
  52. data/lib/asciidoctor/stylesheets.rb +6 -6
  53. data/lib/asciidoctor/substitutors.rb +567 -649
  54. data/lib/asciidoctor/table.rb +163 -108
  55. data/lib/asciidoctor/version.rb +1 -1
  56. data/man/asciidoctor.1 +18 -16
  57. data/man/asciidoctor.adoc +15 -13
  58. data/test/attributes_test.rb +138 -22
  59. data/test/blocks_test.rb +377 -97
  60. data/test/converter_test.rb +13 -0
  61. data/test/document_test.rb +244 -34
  62. data/test/extensions_test.rb +409 -42
  63. data/test/fixtures/asciidoc_index.txt +521 -0
  64. data/test/fixtures/basic-docinfo-footer.html +6 -0
  65. data/test/fixtures/basic-docinfo-footer.xml +8 -0
  66. data/test/fixtures/basic-docinfo.html +1 -0
  67. data/test/fixtures/basic-docinfo.xml +4 -0
  68. data/test/fixtures/basic.asciidoc +5 -0
  69. data/test/fixtures/chapter-a.adoc +3 -0
  70. data/test/fixtures/child-include.adoc +5 -0
  71. data/test/fixtures/circle.svg +9 -0
  72. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
  73. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
  74. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
  75. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
  76. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
  77. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
  78. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
  79. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
  80. data/test/fixtures/custom-docinfodir/basic-docinfo.html +1 -0
  81. data/test/fixtures/custom-docinfodir/docinfo.html +1 -0
  82. data/test/fixtures/docinfo-footer.html +1 -0
  83. data/test/fixtures/docinfo-footer.xml +9 -0
  84. data/test/fixtures/docinfo.html +1 -0
  85. data/test/fixtures/docinfo.xml +3 -0
  86. data/test/fixtures/dot.gif +0 -0
  87. data/test/fixtures/encoding.asciidoc +13 -0
  88. data/test/fixtures/grandchild-include.adoc +3 -0
  89. data/test/fixtures/hello-asciidoctor.pdf +69 -0
  90. data/test/fixtures/include-file.asciidoc +24 -0
  91. data/test/fixtures/include-file.ml +3 -0
  92. data/test/fixtures/include-file.xml +5 -0
  93. data/test/fixtures/master.adoc +5 -0
  94. data/test/fixtures/mismatched-end-tag.adoc +7 -0
  95. data/test/fixtures/parent-include-restricted.adoc +5 -0
  96. data/test/fixtures/parent-include.adoc +5 -0
  97. data/test/fixtures/sample.asciidoc +26 -0
  98. data/test/fixtures/stylesheets/custom.css +3 -0
  99. data/test/fixtures/subs-docinfo.html +2 -0
  100. data/test/fixtures/subs.adoc +7 -0
  101. data/test/fixtures/tagged-class-enclosed.rb +26 -0
  102. data/test/fixtures/tagged-class.rb +23 -0
  103. data/test/fixtures/tip.gif +0 -0
  104. data/test/invoker_test.rb +82 -4
  105. data/test/links_test.rb +312 -37
  106. data/test/lists_test.rb +204 -25
  107. data/test/manpage_test.rb +191 -4
  108. data/test/options_test.rb +18 -1
  109. data/test/paragraphs_test.rb +32 -7
  110. data/test/parser_test.rb +150 -30
  111. data/test/paths_test.rb +47 -13
  112. data/test/preamble_test.rb +1 -1
  113. data/test/reader_test.rb +366 -126
  114. data/test/sections_test.rb +203 -56
  115. data/test/substitutions_test.rb +339 -131
  116. data/test/tables_test.rb +315 -15
  117. data/test/test_helper.rb +400 -0
  118. data/test/text_test.rb +5 -5
  119. metadata +110 -22
@@ -999,7 +999,7 @@ literal
999
999
  assert_xpath '(//*[@class="ulist"])[1]/following-sibling::*[@class="literalblock"]/*[@class="title"]', output, 1
1000
1000
  end
1001
1001
 
1002
- test "lines with alternating markers of bulleted and labeled list types separated by blank lines should be nested" do
1002
+ test "lines with alternating markers of bulleted and description list types separated by blank lines should be nested" do
1003
1003
  input = <<-EOS
1004
1004
  List
1005
1005
  ====
@@ -1480,7 +1480,7 @@ attached paragraph
1480
1480
  end
1481
1481
  end
1482
1482
 
1483
- test 'indented labeled list item inside outline list item offset by a blank line should be recognized as a nested list' do
1483
+ test 'indented description list item inside outline list item offset by a blank line should be recognized as a nested list' do
1484
1484
  input = <<-EOS
1485
1485
  * item 1
1486
1486
 
@@ -1952,7 +1952,7 @@ term2::
1952
1952
  assert_xpath '//dl/dt', output, 2
1953
1953
  assert_xpath '//dl/dt/following-sibling::dd', output, 2
1954
1954
  assert_xpath '(//dl/dt)[1][normalize-space(text()) = "term1"]', output, 1
1955
- assert_xpath %((//dl/dt)[1]/following-sibling::dd/p[text() = "def1#{entity 8201}#{entity 8212}#{entity 8201}and a note"]), output, 1
1955
+ assert_xpath %((//dl/dt)[1]/following-sibling::dd/p[text() = "def1#{decode_char 8201}#{decode_char 8212}#{decode_char 8201}and a note"]), output, 1
1956
1956
  assert_xpath '(//dl/dt)[2][normalize-space(text()) = "term2"]', output, 1
1957
1957
  assert_xpath '(//dl/dt)[2]/following-sibling::dd/p[text() = "def2"]', output, 1
1958
1958
  end
@@ -2058,7 +2058,7 @@ def2
2058
2058
  assert_xpath '(//dl/dt)[2]/a[@id = "term2"]', output, 1
2059
2059
  end
2060
2060
 
2061
- test "missing space before term does not produce labeled list" do
2061
+ test "missing space before term does not produce description list" do
2062
2062
  input = <<-EOS
2063
2063
  term1::def1
2064
2064
  term2::def2
@@ -2067,7 +2067,7 @@ term2::def2
2067
2067
  assert_xpath '//dl', output, 0
2068
2068
  end
2069
2069
 
2070
- test "literal block inside labeled list" do
2070
+ test "literal block inside description list" do
2071
2071
  input = <<-EOS
2072
2072
  term::
2073
2073
  +
@@ -2086,7 +2086,7 @@ anotherterm:: def
2086
2086
  assert_xpath '(//dl/dd)[2]/p[text() = "def"]', output, 1
2087
2087
  end
2088
2088
 
2089
- test "literal block inside labeled list with trailing line continuation" do
2089
+ test "literal block inside description list with trailing line continuation" do
2090
2090
  input = <<-EOS
2091
2091
  term::
2092
2092
  +
@@ -2106,7 +2106,7 @@ anotherterm:: def
2106
2106
  assert_xpath '(//dl/dd)[2]/p[text() = "def"]', output, 1
2107
2107
  end
2108
2108
 
2109
- test "multiple listing blocks inside labeled list" do
2109
+ test "multiple listing blocks inside description list" do
2110
2110
  input = <<-EOS
2111
2111
  term::
2112
2112
  +
@@ -2131,7 +2131,7 @@ anotherterm:: def
2131
2131
  assert_xpath '(//dl/dd)[2]/p[text() = "def"]', output, 1
2132
2132
  end
2133
2133
 
2134
- test "open block inside labeled list" do
2134
+ test "open block inside description list" do
2135
2135
  input = <<-EOS
2136
2136
  term::
2137
2137
  +
@@ -2147,7 +2147,7 @@ anotherterm:: def
2147
2147
  assert_xpath '(//dl/dd)[1]//*[@class="openblock"]//p', output, 2
2148
2148
  end
2149
2149
 
2150
- test "paragraph attached by a list continuation on either side in a labeled list" do
2150
+ test "paragraph attached by a list continuation on either side in a description list" do
2151
2151
  input = <<-EOS
2152
2152
  term1:: def1
2153
2153
  +
@@ -2163,7 +2163,7 @@ term2:: def2
2163
2163
  assert_xpath '(//dl/dd)[1]/p/following-sibling::*[@class="paragraph"]/p[text() = "more detail"]', output, 1
2164
2164
  end
2165
2165
 
2166
- test "paragraph attached by a list continuation on either side to a multi-line element in a labeled list" do
2166
+ test "paragraph attached by a list continuation on either side to a multi-line element in a description list" do
2167
2167
  input = <<-EOS
2168
2168
  term1::
2169
2169
  def1
@@ -2180,7 +2180,7 @@ term2:: def2
2180
2180
  assert_xpath '(//dl/dd)[1]/p/following-sibling::*[@class="paragraph"]/p[text() = "more detail"]', output, 1
2181
2181
  end
2182
2182
 
2183
- test "verse paragraph inside a labeled list" do
2183
+ test "verse paragraph inside a description list" do
2184
2184
  input = <<-EOS
2185
2185
  term1:: def
2186
2186
  +
@@ -2194,7 +2194,7 @@ term2:: def
2194
2194
  assert_xpath '(//dl/dd)[1]/*[@class="verseblock"]/pre[text() = "la la la"]', output, 1
2195
2195
  end
2196
2196
 
2197
- test "list inside a labeled list" do
2197
+ test "list inside a description list" do
2198
2198
  input = <<-EOS
2199
2199
  term1::
2200
2200
  * level 1
@@ -2209,7 +2209,7 @@ term2:: def
2209
2209
  assert_xpath '((//dl/dd)[1]//ul)[1]//ul', output, 1
2210
2210
  end
2211
2211
 
2212
- test "list inside a labeled list offset by blank lines" do
2212
+ test "list inside a description list offset by blank lines" do
2213
2213
  input = <<-EOS
2214
2214
  term1::
2215
2215
 
@@ -2299,7 +2299,7 @@ A new paragraph.
2299
2299
  assert_xpath '(//*[@class="dlist"]/following-sibling::*[@class="paragraph"])[1]/p[text() = "A new paragraph."]', output, 1
2300
2300
  end
2301
2301
 
2302
- test 'should not match comment line that looks like labeled list term' do
2302
+ test 'should not match comment line that looks like description list term' do
2303
2303
  input = <<-EOS
2304
2304
  * item
2305
2305
 
@@ -2773,6 +2773,103 @@ last question::
2773
2773
  assert_css 'bibliodiv > bibliomixed:nth-child(2) > bibliomisc > anchor', output, 1
2774
2774
  assert_css 'bibliodiv > bibliomixed:nth-child(2) > bibliomisc > anchor[xreflabel="[walsh-muellner]"]', output, 1
2775
2775
  end
2776
+
2777
+ test 'should automatically add bibliography style to top-level lists in bibliography section' do
2778
+ input = <<-EOS
2779
+ [bibliography]
2780
+ == Bibliography
2781
+
2782
+ .Books
2783
+ * [[[taoup]]] Eric Steven Raymond. _The Art of Unix
2784
+ Programming_. Addison-Wesley. ISBN 0-13-142901-9.
2785
+ * [[[walsh-muellner]]] Norman Walsh & Leonard Muellner.
2786
+ _DocBook - The Definitive Guide_. O'Reilly & Associates. 1999.
2787
+ ISBN 1-56592-580-7.
2788
+
2789
+ .Periodicals
2790
+ * [[[doc-writer]]] Doc Writer. _Documentation As Code_. Static Times, 54. August 2016.
2791
+ EOS
2792
+ doc = document_from_string input
2793
+ ulists = doc.find_by :context => :ulist
2794
+ assert_equal 2, ulists.size
2795
+ assert_equal ulists[0].style, 'bibliography'
2796
+ assert_equal ulists[1].style, 'bibliography'
2797
+ end
2798
+
2799
+ test 'should not recognize bibliography anchor that begins with a digit' do
2800
+ input = <<-EOS
2801
+ [bibliography]
2802
+ - [[[1984]]] George Orwell. '1984'. New American Library. 1950.
2803
+ EOS
2804
+
2805
+ output = render_embedded_string input
2806
+ assert_includes output, '[[[1984]]]'
2807
+ assert_xpath '//a[@id="1984"]', output, 0
2808
+ end
2809
+
2810
+ test 'should recognize bibliography anchor that contains a digit but does not start with one' do
2811
+ input = <<-EOS
2812
+ [bibliography]
2813
+ - [[[_1984]]] George Orwell. '1984'. New American Library. 1950.
2814
+ EOS
2815
+
2816
+ output = render_embedded_string input
2817
+ refute_includes output, '[[[_1984]]]'
2818
+ assert_includes output, '[_1984]'
2819
+ assert_xpath '//a[@id="_1984"]', output, 1
2820
+ end
2821
+
2822
+ test 'should catalog bibliography anchors in bibliography list' do
2823
+ input = <<-EOS
2824
+ = Article Title
2825
+
2826
+ Please read #{'<<'}Fowler_1997>>.
2827
+
2828
+ [bibliography]
2829
+ == References
2830
+
2831
+ * [[[Fowler_1997]]] Fowler M. _Analysis Patterns: Reusable Object Models_. Addison-Wesley. 1997.
2832
+ EOS
2833
+
2834
+ doc = document_from_string input
2835
+ ids = doc.catalog[:ids]
2836
+ assert ids.key?('Fowler_1997')
2837
+ assert_equal '[Fowler_1997]', ids['Fowler_1997']
2838
+ end
2839
+
2840
+ test 'should use reftext from bibliography anchor at xref and entry' do
2841
+ input = <<-EOS
2842
+ = Article Title
2843
+
2844
+ Please read #{'<<'}Fowler_1997>>.
2845
+
2846
+ [bibliography]
2847
+ == References
2848
+
2849
+ * [[[Fowler_1997,1]]] Fowler M. _Analysis Patterns: Reusable Object Models_. Addison-Wesley. 1997.
2850
+ EOS
2851
+
2852
+ doc = document_from_string input, :header_footer => false
2853
+ ids = doc.catalog[:ids]
2854
+ assert ids.key?('Fowler_1997')
2855
+ assert_equal '[1]', ids['Fowler_1997']
2856
+ result = doc.convert :header_footer => false
2857
+ assert_xpath '//a[@href="#Fowler_1997"]', result, 1
2858
+ assert_xpath '//a[@href="#Fowler_1997"][text()="[1]"]', result, 1
2859
+ assert_xpath '//a[@id="Fowler_1997"]', result, 1
2860
+ text = (xmlnodes_at_xpath '(//a[@id="Fowler_1997"])[1]/following-sibling::text()', result, 1).text
2861
+ assert text.start_with?('[1] ')
2862
+ end
2863
+
2864
+ test 'should assign reftext of bibliography anchor to xreflabel in DocBook backend' do
2865
+ input = <<-EOS
2866
+ [bibliography]
2867
+ * [[[Fowler_1997,1]]] Fowler M. _Analysis Patterns: Reusable Object Models_. Addison-Wesley. 1997.
2868
+ EOS
2869
+
2870
+ result = render_embedded_string input, :backend => :docbook
2871
+ assert_includes result, '<anchor xml:id="Fowler_1997" xreflabel="[1]"/>'
2872
+ end
2776
2873
  end
2777
2874
  end
2778
2875
 
@@ -3339,7 +3436,7 @@ para
3339
3436
  assert_xpath '//*[@class="dlist"]//dd/*[@class="paragraph"]/p[text()="para"]', output, 1
3340
3437
  end
3341
3438
 
3342
- test 'attached paragraph does not break on adjacent nested labeled list term' do
3439
+ test 'attached paragraph does not break on adjacent nested description list term' do
3343
3440
  input = <<-EOS
3344
3441
  term1:: def
3345
3442
  +
@@ -3356,7 +3453,7 @@ not a term::: def
3356
3453
 
3357
3454
  # FIXME pending
3358
3455
  =begin
3359
- test 'attached paragraph does not break on adjacent sibling labeled list term' do
3456
+ test 'attached paragraph does not break on adjacent sibling description list term' do
3360
3457
  input = <<-EOS
3361
3458
  term1:: def
3362
3459
  +
@@ -3372,7 +3469,7 @@ not a term:: def
3372
3469
  end
3373
3470
  =end
3374
3471
 
3375
- test 'attached styled paragraph does not break on adjacent nested labeled list term' do
3472
+ test 'attached styled paragraph does not break on adjacent nested description list term' do
3376
3473
  input = <<-EOS
3377
3474
  term1:: def
3378
3475
  +
@@ -3965,7 +4062,32 @@ puts doc.render # <2>
3965
4062
  assert_xpath '((//calloutlist)[2]/callout)[2][@arearefs = "CO2-2"]', output, 1
3966
4063
  end
3967
4064
 
3968
- test 'callout list with block content' do
4065
+ test 'callout list retains block content' do
4066
+ input = <<-EOS
4067
+ [source, ruby]
4068
+ ----
4069
+ require 'asciidoctor' # <1>
4070
+ doc = Asciidoctor::Document.new('Hello, World!') # <2>
4071
+ puts doc.render # <3>
4072
+ ----
4073
+ <1> Imports the library
4074
+ as a RubyGem
4075
+ <2> Creates a new document
4076
+ * Scans the lines for known blocks
4077
+ * Converts the lines into blocks
4078
+ <3> Renders the document
4079
+ +
4080
+ You can write this to file rather than printing to stdout.
4081
+ EOS
4082
+ output = render_embedded_string input
4083
+ assert_xpath '//ol/li', output, 3
4084
+ assert_xpath %((//ol/li)[1]/p[text()="Imports the library\nas a RubyGem"]), output, 1
4085
+ assert_xpath %((//ol/li)[2]//ul), output, 1
4086
+ assert_xpath %((//ol/li)[2]//ul/li), output, 2
4087
+ assert_xpath %((//ol/li)[3]//p), output, 2
4088
+ end
4089
+
4090
+ test 'callout list retains block content when converted to DocBook' do
3969
4091
  input = <<-EOS
3970
4092
  [source, ruby]
3971
4093
  ----
@@ -4066,17 +4188,18 @@ Second line <2-->
4066
4188
  assert_xpath '//b', output, 0
4067
4189
  end
4068
4190
 
4069
- test 'should not recognize callouts in an indented labeled list paragraph' do
4191
+ test 'should not recognize callouts in an indented description list paragraph' do
4070
4192
  input = <<-EOS
4071
4193
  foo::
4072
4194
  bar <1>
4073
4195
 
4074
4196
  <1> Not pointing to a callout
4075
4197
  EOS
4076
- output = render_embedded_string input
4198
+ output, warnings = redirect_streams {|_, err| [(render_embedded_string input), err.string] }
4077
4199
  assert_xpath '//dl//b', output, 0
4078
4200
  assert_xpath '//dl/dd/p[text()="bar <1>"]', output, 1
4079
4201
  assert_xpath '//ol/li/p[text()="Not pointing to a callout"]', output, 1
4202
+ assert_includes warnings, 'line 4: no callouts refer to list item 1'
4080
4203
  end
4081
4204
 
4082
4205
  test 'should not recognize callouts in an indented outline list paragraph' do
@@ -4086,10 +4209,28 @@ foo::
4086
4209
 
4087
4210
  <1> Not pointing to a callout
4088
4211
  EOS
4089
- output = render_embedded_string input
4212
+ output, warnings = redirect_streams {|_, err| [(render_embedded_string input), err.string] }
4090
4213
  assert_xpath '//ul//b', output, 0
4091
4214
  assert_xpath %(//ul/li/p[text()="foo\nbar <1>"]), output, 1
4092
4215
  assert_xpath '//ol/li/p[text()="Not pointing to a callout"]', output, 1
4216
+ assert_includes warnings, 'line 4: no callouts refer to list item 1'
4217
+ end
4218
+
4219
+ test 'should warn if numbers in callout list are out of sequence' do
4220
+ input = <<-EOS
4221
+ ----
4222
+ <beans> <1>
4223
+ <bean class="com.example.HelloWorld"/>
4224
+ </beans>
4225
+ ----
4226
+ <1> Container of beans.
4227
+ Beans are fun.
4228
+ <3> An actual bean.
4229
+ EOS
4230
+ output, warnings = redirect_streams {|_, err| [(render_embedded_string input), err.string] }
4231
+ assert_xpath '//ol/li', output, 2
4232
+ assert_includes warnings, 'line 8: callout list item index: expected 2 got 3'
4233
+ assert_includes warnings, 'line 8: no callouts refer to list item 2'
4093
4234
  end
4094
4235
 
4095
4236
  test 'should remove line comment chars that precedes callout number' do
@@ -4228,10 +4369,10 @@ context 'Checklists' do
4228
4369
 
4229
4370
  output = render_embedded_string input
4230
4371
  assert_css '.ulist.checklist', output, 1
4231
- assert_xpath %((/*[@class="ulist checklist"]/ul/li)[1]/p[text()="#{expand_entity 10063} todo"]), output, 1
4232
- assert_xpath %((/*[@class="ulist checklist"]/ul/li)[2]/p[text()="#{expand_entity 10003} done"]), output, 1
4233
- assert_xpath %((/*[@class="ulist checklist"]/ul/li)[3]/p[text()="#{expand_entity 10063} another todo"]), output, 1
4234
- assert_xpath %((/*[@class="ulist checklist"]/ul/li)[4]/p[text()="#{expand_entity 10003} another done"]), output, 1
4372
+ assert_xpath %((/*[@class="ulist checklist"]/ul/li)[1]/p[text()="#{decode_char 10063} todo"]), output, 1
4373
+ assert_xpath %((/*[@class="ulist checklist"]/ul/li)[2]/p[text()="#{decode_char 10003} done"]), output, 1
4374
+ assert_xpath %((/*[@class="ulist checklist"]/ul/li)[3]/p[text()="#{decode_char 10063} another todo"]), output, 1
4375
+ assert_xpath %((/*[@class="ulist checklist"]/ul/li)[4]/p[text()="#{decode_char 10003} another done"]), output, 1
4235
4376
  assert_xpath '(/*[@class="ulist checklist"]/ul/li)[5]/p[text()="plain"]', output, 1
4236
4377
  end
4237
4378
 
@@ -4377,4 +4518,42 @@ listing block in list item 1
4377
4518
  assert !list.items.first.simple?
4378
4519
  assert list.items.first.compound?
4379
4520
  end
4521
+
4522
+ test 'should allow text of ListItem to be assigned' do
4523
+ input = <<-EOS
4524
+ * one
4525
+ * two
4526
+ * three
4527
+ EOS
4528
+
4529
+ doc = document_from_string input
4530
+ list = (doc.find_by :context => :ulist).first
4531
+ assert_equal 3, list.items.size
4532
+ assert_equal 'one', list.items[0].text
4533
+ list.items[0].text = 'un'
4534
+ assert_equal 'un', list.items[0].text
4535
+ end
4536
+
4537
+ test 'should allow API control over substitutions applied to ListItem text' do
4538
+ input = <<-EOS
4539
+ * *one*
4540
+ * _two_
4541
+ * `three`
4542
+ * #four#
4543
+ EOS
4544
+
4545
+ doc = document_from_string input
4546
+ list = (doc.find_by :context => :ulist).first
4547
+ assert_equal 4, list.items.size
4548
+ list.items[0].remove_sub :quotes
4549
+ assert_equal '*one*', list.items[0].text
4550
+ refute_includes list.items[0].subs, :quotes
4551
+ list.items[1].subs.clear
4552
+ assert_empty list.items[1].subs
4553
+ assert_equal '_two_', list.items[1].text
4554
+ list.items[2].subs.replace [:specialcharacters]
4555
+ assert_equal [:specialcharacters], list.items[2].subs
4556
+ assert_equal '`three`', list.items[2].text
4557
+ assert_equal '<mark>four</mark>', list.items[3].text
4558
+ end
4380
4559
  end
@@ -24,17 +24,42 @@ EOS
24
24
 
25
25
  context 'Manpage' do
26
26
  context 'Configuration' do
27
+ test 'should set proper manpage-related attributes' do
28
+ input = SAMPLE_MANPAGE_HEADER
29
+ doc = Asciidoctor.load input, :backend => :manpage
30
+ assert_equal 'man', doc.attributes['filetype']
31
+ assert_equal '', doc.attributes['filetype-man']
32
+ assert_equal '1', doc.attributes['manvolnum']
33
+ assert_equal '.1', doc.attributes['outfilesuffix']
34
+ assert_equal 'command', doc.attributes['manname']
35
+ assert_equal 'command', doc.attributes['mantitle']
36
+ assert_equal 'does stuff', doc.attributes['manpurpose']
37
+ assert_equal 'command', doc.attributes['docname']
38
+ end
39
+
27
40
  test 'should define default linkstyle' do
28
41
  input = SAMPLE_MANPAGE_HEADER
29
42
  output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
30
- assert_match(/^\.LINKSTYLE blue R < >$/, output)
43
+ assert_includes output.lines, %(.LINKSTYLE blue R < >\n)
31
44
  end
32
45
 
33
46
  test 'should use linkstyle defined by man-linkstyle attribute' do
34
47
  input = SAMPLE_MANPAGE_HEADER
35
48
  output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true,
36
49
  :attributes => { 'man-linkstyle' => 'cyan B \[fo] \[fc]' }
37
- assert_match(/^\.LINKSTYLE cyan B \\\[fo\] \\\[fc\]$/, output)
50
+ assert_includes output.lines, %(.LINKSTYLE cyan B \\[fo] \\[fc]\n)
51
+ end
52
+
53
+ test 'should require specialchars in value of man-linkstyle attribute defined in document to be escaped' do
54
+ input = %(:man-linkstyle: cyan R < >
55
+ #{SAMPLE_MANPAGE_HEADER})
56
+ output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
57
+ assert_includes output.lines, %(.LINKSTYLE cyan R &lt; &gt;\n)
58
+
59
+ input = %(:man-linkstyle: pass:[cyan R < >]
60
+ #{SAMPLE_MANPAGE_HEADER})
61
+ output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
62
+ assert_includes output.lines, %(.LINKSTYLE cyan R < >\n)
38
63
  end
39
64
  end
40
65
 
@@ -92,6 +117,17 @@ baz)
92
117
  output = Asciidoctor.convert input, :backend => :manpage
93
118
  assert_match '\(rsfB makes text bold', output
94
119
  end
120
+
121
+ test 'should preserve inline breaks' do
122
+ input = %(#{SAMPLE_MANPAGE_HEADER}
123
+
124
+ Before break. +
125
+ After break.)
126
+ output = Asciidoctor.convert input, :backend => :manpage
127
+ assert_equal 'Before break.
128
+ .br
129
+ After break.', output.lines.entries[-3..-1].join
130
+ end
95
131
  end
96
132
 
97
133
  context 'URL macro' do
@@ -182,6 +218,137 @@ before asking.', output.lines.entries[-4..-1].join
182
218
  end
183
219
  end
184
220
 
221
+ context 'Table' do
222
+ test 'should manify normal table cell content' do
223
+ input = %(#{SAMPLE_MANPAGE_HEADER}
224
+
225
+ [%header%footer,cols=2*]
226
+ |===
227
+ |*Col A* |_Col B_
228
+ |*bold* |`mono`
229
+ |_italic_ | #mark#
230
+ |===)
231
+ output = Asciidoctor.convert input, :backend => :manpage
232
+ refute_match(/<\/?BOUNDARY>/, output)
233
+ end
234
+
235
+ test 'should manify table title' do
236
+ input = %(#{SAMPLE_MANPAGE_HEADER}
237
+
238
+ .Table of options
239
+ |===
240
+ | Name | Description | Default
241
+
242
+ | dim
243
+ | dimension of the object
244
+ | 3
245
+ |===)
246
+ output = Asciidoctor.convert input, :backend => :manpage
247
+ assert output.end_with? '.it 1 an-trap
248
+ .nr an-no-space-flag 1
249
+ .nr an-break-flag 1
250
+ .br
251
+ .B Table 1. Table of options
252
+ .TS
253
+ allbox tab(:);
254
+ lt lt lt.
255
+ T{
256
+ .sp
257
+ Name
258
+ T}:T{
259
+ .sp
260
+ Description
261
+ T}:T{
262
+ .sp
263
+ Default
264
+ T}
265
+ T{
266
+ .sp
267
+ dim
268
+ T}:T{
269
+ .sp
270
+ dimension of the object
271
+ T}:T{
272
+ .sp
273
+ 3
274
+ T}
275
+ .TE
276
+ .sp'
277
+ end
278
+
279
+ test 'should manify and preserve whitespace in literal table cell' do
280
+ input = %(#{SAMPLE_MANPAGE_HEADER}
281
+
282
+ |===
283
+ |a l|b
284
+ c _d_
285
+ .
286
+ |===)
287
+ output = Asciidoctor.convert input, :backend => :manpage
288
+ assert output.end_with? '.TS
289
+ allbox tab(:);
290
+ lt lt.
291
+ T{
292
+ .sp
293
+ a
294
+ T}:T{
295
+ .sp
296
+ .nf
297
+ b
298
+ c _d_
299
+ \\&.
300
+ .fi
301
+ T}
302
+ .TE
303
+ .sp'
304
+ end
305
+
306
+ test 'should manify and preserve whitespace in verse table cell' do
307
+ input = %(#{SAMPLE_MANPAGE_HEADER}
308
+
309
+ |===
310
+ |a v|b
311
+ c _d_
312
+ .
313
+ |===)
314
+ output = Asciidoctor.convert input, :backend => :manpage
315
+ assert output.end_with? '.TS
316
+ allbox tab(:);
317
+ lt lt.
318
+ T{
319
+ .sp
320
+ a
321
+ T}:T{
322
+ .sp
323
+ .nf
324
+ b
325
+ c \\fId\\fP
326
+ \\&.
327
+ .fi
328
+ T}
329
+ .TE
330
+ .sp'
331
+ end
332
+ end
333
+
334
+ context 'Images' do
335
+ test 'should replace inline image with alt text' do
336
+ input = %(#{SAMPLE_MANPAGE_HEADER}
337
+
338
+ The Magic 8 Ball says image:signs-point-to-yes.jpg[].)
339
+ output = Asciidoctor.convert input, :backend => :manpage
340
+ assert_includes output, 'The Magic 8 Ball says [signs point to yes].'
341
+ end
342
+
343
+ test 'should place link after alt text for inline image if link is defined' do
344
+ input = %(#{SAMPLE_MANPAGE_HEADER}
345
+
346
+ The Magic 8 Ball says image:signs-point-to-yes.jpg[link=https://en.wikipedia.org/wiki/Magic_8-Ball].)
347
+ output = Asciidoctor.convert input, :backend => :manpage
348
+ assert_includes output, 'The Magic 8 Ball says [signs point to yes] <https://en.wikipedia.org/wiki/Magic_8\-Ball>.'
349
+ end
350
+ end
351
+
185
352
  context 'Callout List' do
186
353
  test 'should generate callout list using proper formatting commands' do
187
354
  input = %(#{SAMPLE_MANPAGE_HEADER}
@@ -210,9 +377,29 @@ T}
210
377
  assert_match(/Date: 2009-02-08/, output)
211
378
  assert_match(/^\.TH "COMMAND" "1" "2009-02-08" "Command 1.2.3" "Command Manual"$/, output)
212
379
  ensure
213
- ENV['SOURCE_DATE_EPOCH'] = old_source_date_epoch if old_source_date_epoch
380
+ if old_source_date_epoch
381
+ ENV['SOURCE_DATE_EPOCH'] = old_source_date_epoch
382
+ else
383
+ ENV.delete 'SOURCE_DATE_EPOCH'
384
+ end
214
385
  end
215
386
  end
216
- end
217
387
 
388
+ test 'should fail if SOURCE_DATE_EPOCH is malformed' do
389
+ old_source_date_epoch = ENV.delete 'SOURCE_DATE_EPOCH'
390
+ begin
391
+ ENV['SOURCE_DATE_EPOCH'] = 'aaaaaaaa'
392
+ Asciidoctor.convert SAMPLE_MANPAGE_HEADER, :backend => :manpage, :header_footer => true
393
+ assert false
394
+ rescue
395
+ assert true
396
+ ensure
397
+ if old_source_date_epoch
398
+ ENV['SOURCE_DATE_EPOCH'] = old_source_date_epoch
399
+ else
400
+ ENV.delete 'SOURCE_DATE_EPOCH'
401
+ end
402
+ end
403
+ end
404
+ end
218
405
  end