asciidoctor 1.5.8 → 2.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +162 -17
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +12 -13
  5. data/README-fr.adoc +11 -12
  6. data/README-jp.adoc +11 -12
  7. data/README-zh_CN.adoc +12 -13
  8. data/README.adoc +6 -7
  9. data/asciidoctor.gemspec +19 -24
  10. data/bin/asciidoctor +5 -4
  11. data/data/reference/syntax.adoc +283 -0
  12. data/data/stylesheets/asciidoctor-default.css +56 -52
  13. data/data/stylesheets/coderay-asciidoctor.css +7 -9
  14. data/lib/asciidoctor.rb +171 -232
  15. data/lib/asciidoctor/abstract_block.rb +96 -105
  16. data/lib/asciidoctor/abstract_node.rb +118 -139
  17. data/lib/asciidoctor/attribute_list.rb +10 -14
  18. data/lib/asciidoctor/block.rb +20 -19
  19. data/lib/asciidoctor/callouts.rb +4 -2
  20. data/lib/asciidoctor/cli.rb +3 -2
  21. data/lib/asciidoctor/cli/invoker.rb +14 -21
  22. data/lib/asciidoctor/cli/options.rb +64 -54
  23. data/lib/asciidoctor/converter.rb +357 -185
  24. data/lib/asciidoctor/converter/composite.rb +40 -48
  25. data/lib/asciidoctor/converter/docbook5.rb +604 -640
  26. data/lib/asciidoctor/converter/html5.rb +949 -963
  27. data/lib/asciidoctor/converter/manpage.rb +569 -548
  28. data/lib/asciidoctor/converter/template.rb +231 -272
  29. data/lib/asciidoctor/core_ext.rb +5 -18
  30. data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
  31. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  32. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  33. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  34. data/lib/asciidoctor/document.rb +399 -377
  35. data/lib/asciidoctor/extensions.rb +72 -140
  36. data/lib/asciidoctor/helpers.rb +122 -83
  37. data/lib/asciidoctor/inline.rb +5 -1
  38. data/lib/asciidoctor/list.rb +13 -11
  39. data/lib/asciidoctor/logging.rb +17 -16
  40. data/lib/asciidoctor/parser.rb +390 -423
  41. data/lib/asciidoctor/path_resolver.rb +10 -5
  42. data/lib/asciidoctor/reader.rb +286 -263
  43. data/lib/asciidoctor/rouge_ext.rb +39 -0
  44. data/lib/asciidoctor/section.rb +9 -8
  45. data/lib/asciidoctor/stylesheets.rb +19 -37
  46. data/lib/asciidoctor/substitutors.rb +364 -509
  47. data/lib/asciidoctor/syntax_highlighter.rb +238 -0
  48. data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
  49. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
  50. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  51. data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
  52. data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
  53. data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
  54. data/lib/asciidoctor/table.rb +73 -66
  55. data/lib/asciidoctor/timings.rb +4 -2
  56. data/lib/asciidoctor/version.rb +2 -1
  57. data/lib/asciidoctor/writer.rb +30 -0
  58. data/man/asciidoctor.1 +19 -15
  59. data/man/asciidoctor.adoc +14 -12
  60. metadata +69 -216
  61. data/CONTRIBUTING.adoc +0 -185
  62. data/Gemfile +0 -60
  63. data/Rakefile +0 -129
  64. data/bin/asciidoctor-safe +0 -15
  65. data/features/open_block.feature +0 -92
  66. data/features/pass_block.feature +0 -66
  67. data/features/step_definitions.rb +0 -49
  68. data/features/text_formatting.feature +0 -57
  69. data/features/xref.feature +0 -1039
  70. data/lib/asciidoctor/converter/base.rb +0 -59
  71. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  72. data/lib/asciidoctor/converter/factory.rb +0 -226
  73. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  74. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  75. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  76. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  77. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  78. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  79. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  80. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  81. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  82. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  83. data/test/api_test.rb +0 -1240
  84. data/test/attribute_list_test.rb +0 -242
  85. data/test/attributes_test.rb +0 -1623
  86. data/test/blocks_test.rb +0 -3870
  87. data/test/converter_test.rb +0 -470
  88. data/test/document_test.rb +0 -1853
  89. data/test/extensions_test.rb +0 -1560
  90. data/test/fixtures/asciidoc_index.txt +0 -521
  91. data/test/fixtures/basic-docinfo-footer.html +0 -6
  92. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  93. data/test/fixtures/basic-docinfo.html +0 -1
  94. data/test/fixtures/basic-docinfo.xml +0 -4
  95. data/test/fixtures/basic.asciidoc +0 -5
  96. data/test/fixtures/chapter-a.adoc +0 -3
  97. data/test/fixtures/child-include.adoc +0 -5
  98. data/test/fixtures/circle.svg +0 -9
  99. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  100. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  101. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  102. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  103. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  104. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  105. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  106. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  107. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  108. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  109. data/test/fixtures/docinfo-footer.html +0 -1
  110. data/test/fixtures/docinfo-footer.xml +0 -9
  111. data/test/fixtures/docinfo.html +0 -1
  112. data/test/fixtures/docinfo.xml +0 -3
  113. data/test/fixtures/doctime-localtime.adoc +0 -2
  114. data/test/fixtures/dot.gif +0 -0
  115. data/test/fixtures/encoding.asciidoc +0 -13
  116. data/test/fixtures/file-with-missing-include.adoc +0 -1
  117. data/test/fixtures/grandchild-include.adoc +0 -3
  118. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  119. data/test/fixtures/include-file.asciidoc +0 -24
  120. data/test/fixtures/include-file.jsx +0 -8
  121. data/test/fixtures/include-file.ml +0 -3
  122. data/test/fixtures/include-file.xml +0 -5
  123. data/test/fixtures/lists.adoc +0 -96
  124. data/test/fixtures/master.adoc +0 -5
  125. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  126. data/test/fixtures/other-chapters.adoc +0 -11
  127. data/test/fixtures/outer-include.adoc +0 -5
  128. data/test/fixtures/parent-include-restricted.adoc +0 -5
  129. data/test/fixtures/parent-include.adoc +0 -5
  130. data/test/fixtures/sample.asciidoc +0 -30
  131. data/test/fixtures/section-a.adoc +0 -4
  132. data/test/fixtures/stylesheets/custom.css +0 -3
  133. data/test/fixtures/subdir/index.adoc +0 -3
  134. data/test/fixtures/subdir/inner-include.adoc +0 -3
  135. data/test/fixtures/subdir/middle-include.adoc +0 -5
  136. data/test/fixtures/subs-docinfo.html +0 -2
  137. data/test/fixtures/subs.adoc +0 -6
  138. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  139. data/test/fixtures/tagged-class.rb +0 -23
  140. data/test/fixtures/tip.gif +0 -0
  141. data/test/fixtures/unclosed-tag.adoc +0 -3
  142. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  143. data/test/invoker_test.rb +0 -745
  144. data/test/links_test.rb +0 -855
  145. data/test/lists_test.rb +0 -5151
  146. data/test/logger_test.rb +0 -211
  147. data/test/manpage_test.rb +0 -660
  148. data/test/options_test.rb +0 -262
  149. data/test/paragraphs_test.rb +0 -562
  150. data/test/parser_test.rb +0 -742
  151. data/test/paths_test.rb +0 -395
  152. data/test/preamble_test.rb +0 -173
  153. data/test/reader_test.rb +0 -2161
  154. data/test/sections_test.rb +0 -3575
  155. data/test/substitutions_test.rb +0 -2066
  156. data/test/tables_test.rb +0 -2036
  157. data/test/test_helper.rb +0 -447
  158. data/test/text_test.rb +0 -309
@@ -1,1853 +0,0 @@
1
- # encoding: UTF-8
2
- unless defined? ASCIIDOCTOR_PROJECT_DIR
3
- $: << File.dirname(__FILE__); $:.uniq!
4
- require 'test_helper'
5
- end
6
-
7
- BUILT_IN_ELEMENTS = %w(admonition audio colist dlist document embedded example floating_title image inline_anchor inline_break inline_button inline_callout inline_footnote inline_image inline_indexterm inline_kbd inline_menu inline_quoted listing literal stem olist open page_break paragraph pass preamble quote section sidebar table thematic_break toc ulist verse video)
8
-
9
- context 'Document' do
10
-
11
- context 'Example document' do
12
- test 'document title' do
13
- doc = example_document(:asciidoc_index)
14
- assert_equal 'AsciiDoc Home Page', doc.doctitle
15
- assert_equal 'AsciiDoc Home Page', doc.name
16
- refute_nil doc.header
17
- assert_equal :section, doc.header.context
18
- assert_equal 'header', doc.header.sectname
19
- assert_equal 14, doc.blocks.size
20
- assert_equal :preamble, doc.blocks[0].context
21
- assert_equal :section, doc.blocks[1].context
22
-
23
- # verify compat-mode is set when atx-style doctitle is used
24
- result = doc.blocks[0].convert
25
- assert_xpath %q(//em[text()="Stuart Rackham"]), result, 1
26
- end
27
- end
28
-
29
- context 'Default settings' do
30
- test 'safe mode level set to SECURE by default' do
31
- doc = empty_document
32
- assert_equal Asciidoctor::SafeMode::SECURE, doc.safe
33
- end
34
-
35
- test 'safe mode level set using string' do
36
- doc = empty_document :safe => 'server'
37
- assert_equal Asciidoctor::SafeMode::SERVER, doc.safe
38
-
39
- doc = empty_document :safe => 'foo'
40
- assert_equal Asciidoctor::SafeMode::SECURE, doc.safe
41
- end
42
-
43
- test 'safe mode level set using symbol' do
44
- doc = empty_document :safe => :server
45
- assert_equal Asciidoctor::SafeMode::SERVER, doc.safe
46
-
47
- doc = empty_document :safe => :foo
48
- assert_equal Asciidoctor::SafeMode::SECURE, doc.safe
49
- end
50
-
51
- test 'safe mode level set using integer' do
52
- doc = empty_document :safe => 10
53
- assert_equal Asciidoctor::SafeMode::SERVER, doc.safe
54
-
55
- doc = empty_document :safe => 100
56
- assert_equal 100, doc.safe
57
- end
58
-
59
- test 'safe mode attributes are set on document' do
60
- doc = empty_document
61
- assert_equal Asciidoctor::SafeMode::SECURE, doc.attr('safe-mode-level')
62
- assert_equal 'secure', doc.attr('safe-mode-name')
63
- assert doc.attr?('safe-mode-secure')
64
- refute doc.attr?('safe-mode-unsafe')
65
- refute doc.attr?('safe-mode-safe')
66
- refute doc.attr?('safe-mode-server')
67
- end
68
-
69
- test 'safe mode level can be set in the constructor' do
70
- doc = Asciidoctor::Document.new [], :safe => Asciidoctor::SafeMode::SAFE
71
- assert_equal Asciidoctor::SafeMode::SAFE, doc.safe
72
- end
73
-
74
- test 'safe model level cannot be modified' do
75
- doc = empty_document
76
- begin
77
- doc.safe = Asciidoctor::SafeMode::UNSAFE
78
- flunk 'safe mode property of Asciidoctor::Document should not be writable!'
79
- rescue
80
- end
81
- end
82
-
83
- test 'toc and sectnums should be enabled by default for DocBook backend' do
84
- doc = document_from_string 'content', :backend => 'docbook', :parse => true
85
- assert doc.attr?('toc')
86
- assert doc.attr?('sectnums')
87
- result = doc.convert
88
- assert_match('<?asciidoc-toc?>', result)
89
- assert_match('<?asciidoc-numbered?>', result)
90
- end
91
-
92
- test 'maxdepth attribute should be set on asciidoc-toc and asciidoc-numbered processing instructions in DocBook backend' do
93
- doc = document_from_string 'content', :backend => 'docbook', :parse => true, :attributes => {'toclevels' => '1', 'sectnumlevels' => '1' }
94
- assert doc.attr?('toc')
95
- assert doc.attr?('sectnums')
96
- result = doc.convert
97
- assert_match('<?asciidoc-toc maxdepth="1"?>', result)
98
- assert_match('<?asciidoc-numbered maxdepth="1"?>', result)
99
- end
100
-
101
- test 'should be able to disable toc and sectnums in document header for DocBook backend' do
102
- input = <<-EOS
103
- = Document Title
104
- :toc!:
105
- :sectnums!:
106
- EOS
107
- doc = document_from_string input, :backend => 'docbook'
108
- refute doc.attr?('toc')
109
- refute doc.attr?('sectnums')
110
- end
111
-
112
- test 'noheader attribute should suppress info element when converting to DocBook' do
113
- input = <<-EOS
114
- = Document Title
115
- :noheader:
116
-
117
- content
118
- EOS
119
- result = convert_string input, :backend => 'docbook'
120
- assert_xpath '/article', result, 1
121
- assert_xpath '/article/info', result, 0
122
- end
123
-
124
- test 'should be able to disable section numbering using numbered attribute in document header for DocBook backend' do
125
- input = <<-EOS
126
- = Document Title
127
- :numbered!:
128
- EOS
129
- doc = document_from_string input, :backend => 'docbook'
130
- refute doc.attr?('sectnums')
131
- end
132
- end
133
-
134
- context 'Docinfo files' do
135
- test 'should include docinfo files for html backend' do
136
- sample_input_path = fixture_path('basic.asciidoc')
137
-
138
- cases = {
139
- 'docinfo' => { :head_script => 1, :meta => 0, :top_link => 0, :footer_script => 1 },
140
- 'docinfo=private' => { :head_script => 1, :meta => 0, :top_link => 0, :footer_script => 1 },
141
- 'docinfo1' => { :head_script => 0, :meta => 1, :top_link => 1, :footer_script => 0 },
142
- 'docinfo=shared' => { :head_script => 0, :meta => 1, :top_link => 1, :footer_script => 0 },
143
- 'docinfo2' => { :head_script => 1, :meta => 1, :top_link => 1, :footer_script => 1 },
144
- 'docinfo docinfo2' => { :head_script => 1, :meta => 1, :top_link => 1, :footer_script => 1 },
145
- 'docinfo=private,shared' => { :head_script => 1, :meta => 1, :top_link => 1, :footer_script => 1 },
146
- 'docinfo=private-head' => { :head_script => 1, :meta => 0, :top_link => 0, :footer_script => 0 },
147
- 'docinfo=shared-head' => { :head_script => 0, :meta => 1, :top_link => 0, :footer_script => 0 },
148
- 'docinfo=private-footer' => { :head_script => 0, :meta => 0, :top_link => 0, :footer_script => 1 },
149
- 'docinfo=shared-footer' => { :head_script => 0, :meta => 0, :top_link => 1, :footer_script => 0 },
150
- 'docinfo=private-head\ ,\ shared-footer' => { :head_script => 1, :meta => 0, :top_link => 1, :footer_script => 0 }
151
- }
152
-
153
- cases.each do |attr_val, markup|
154
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
155
- :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => %(linkcss copycss! #{attr_val})
156
- refute_empty output
157
- assert_css 'script[src="modernizr.js"]', output, markup[:head_script]
158
- assert_css 'meta[http-equiv="imagetoolbar"]', output, markup[:meta]
159
- assert_css 'body > a#top', output, markup[:top_link]
160
- assert_css 'body > script', output, markup[:footer_script]
161
- end
162
- end
163
-
164
- test 'should include docinfo footer even if nofooter attribute is set' do
165
- sample_input_path = fixture_path('basic.asciidoc')
166
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
167
- :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => '', 'nofooter' => ''}
168
- refute_empty output
169
- assert_css 'body > a#top', output, 1
170
- end
171
-
172
- test 'should include docinfo files for html backend with custom docinfodir' do
173
- sample_input_path = fixture_path('basic.asciidoc')
174
-
175
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
176
- :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => '', 'docinfodir' => 'custom-docinfodir'}
177
- refute_empty output
178
- assert_css 'script[src="bootstrap.js"]', output, 1
179
- assert_css 'meta[name="robots"]', output, 0
180
-
181
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
182
- :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => '', 'docinfodir' => 'custom-docinfodir'}
183
- refute_empty output
184
- assert_css 'script[src="bootstrap.js"]', output, 0
185
- assert_css 'meta[name="robots"]', output, 1
186
-
187
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
188
- :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => '', 'docinfodir' => './custom-docinfodir'}
189
- refute_empty output
190
- assert_css 'script[src="bootstrap.js"]', output, 1
191
- assert_css 'meta[name="robots"]', output, 1
192
-
193
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
194
- :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => '', 'docinfodir' => 'custom-docinfodir/subfolder'}
195
- refute_empty output
196
- assert_css 'script[src="bootstrap.js"]', output, 0
197
- assert_css 'meta[name="robots"]', output, 0
198
- end
199
-
200
- test 'should include docinfo files for docbook backend' do
201
- sample_input_path = fixture_path('basic.asciidoc')
202
-
203
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
204
- :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''}
205
- refute_empty output
206
- assert_css 'productname', output, 0
207
- assert_css 'copyright', output, 1
208
-
209
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
210
- :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''}
211
- refute_empty output
212
- assert_css 'productname', output, 1
213
- assert_xpath '//xmlns:productname[text()="Asciidoctor™"]', output, 1
214
- assert_css 'edition', output, 1
215
- assert_xpath '//xmlns:edition[text()="1.0"]', output, 1 # verifies substitutions are performed
216
- assert_css 'copyright', output, 0
217
-
218
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
219
- :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''}
220
- refute_empty output
221
- assert_css 'productname', output, 1
222
- assert_xpath '//xmlns:productname[text()="Asciidoctor™"]', output, 1
223
- assert_css 'edition', output, 1
224
- assert_xpath '//xmlns:edition[text()="1.0"]', output, 1 # verifies substitutions are performed
225
- assert_css 'copyright', output, 1
226
- end
227
-
228
- test 'should include docinfo footer files for html backend' do
229
- sample_input_path = fixture_path('basic.asciidoc')
230
-
231
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
232
- :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''}
233
- refute_empty output
234
- assert_css 'body script', output, 1
235
- assert_css 'a#top', output, 0
236
-
237
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
238
- :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''}
239
- refute_empty output
240
- assert_css 'body script', output, 0
241
- assert_css 'a#top', output, 1
242
-
243
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
244
- :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''}
245
- refute_empty output
246
- assert_css 'body script', output, 1
247
- assert_css 'a#top', output, 1
248
- end
249
-
250
- test 'should include docinfo footer files for docbook backend' do
251
- sample_input_path = fixture_path('basic.asciidoc')
252
-
253
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
254
- :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo' => ''}
255
- refute_empty output
256
- assert_css 'article > revhistory', output, 1
257
- assert_xpath '/xmlns:article/xmlns:revhistory/xmlns:revision/xmlns:revnumber[text()="1.0"]', output, 1 # verifies substitutions are performed
258
- assert_css 'glossary#_glossary', output, 0
259
-
260
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
261
- :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo1' => ''}
262
- refute_empty output
263
- assert_css 'article > revhistory', output, 0
264
- assert_css 'glossary#_glossary', output, 1
265
-
266
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
267
- :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''}
268
- refute_empty output
269
- assert_css 'article > revhistory', output, 1
270
- assert_xpath '/xmlns:article/xmlns:revhistory/xmlns:revision/xmlns:revnumber[text()="1.0"]', output, 1 # verifies substitutions are performed
271
- assert_css 'glossary#_glossary', output, 1
272
- end
273
-
274
- # WARNING this test manipulates runtime settings; should probably be run in forked process
275
- test 'should force encoding of docinfo files to UTF-8' do
276
- sample_input_path = fixture_path('basic.asciidoc')
277
-
278
- if RUBY_VERSION >= '1.9'
279
- default_external_old = Encoding.default_external
280
- force_encoding_old = Asciidoctor::FORCE_ENCODING
281
- verbose_old = $VERBOSE
282
- end
283
- begin
284
- if RUBY_VERSION >= '1.9'
285
- $VERBOSE = nil # disable warnings since we have to modify constants
286
- Encoding.default_external = 'US-ASCII'
287
- Asciidoctor::FORCE_ENCODING = true
288
- end
289
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
290
- :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER, :attributes => {'docinfo2' => ''}
291
- refute_empty output
292
- assert_css 'productname', output, 1
293
- assert_css 'edition', output, 1
294
- assert_xpath '//xmlns:edition[text()="1.0"]', output, 1 # verifies substitutions are performed
295
- assert_css 'copyright', output, 1
296
- ensure
297
- if RUBY_VERSION >= '1.9'
298
- Encoding.default_external = default_external_old
299
- Asciidoctor::FORCE_ENCODING = force_encoding_old
300
- $VERBOSE = verbose_old
301
- end
302
- end
303
- end
304
-
305
- test 'should not include docinfo files by default' do
306
- sample_input_path = fixture_path('basic.asciidoc')
307
-
308
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
309
- :header_footer => true, :safe => Asciidoctor::SafeMode::SERVER
310
- refute_empty output
311
- assert_css 'script[src="modernizr.js"]', output, 0
312
- assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
313
-
314
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
315
- :header_footer => true, :backend => 'docbook', :safe => Asciidoctor::SafeMode::SERVER
316
- refute_empty output
317
- assert_css 'productname', output, 0
318
- assert_css 'copyright', output, 0
319
- end
320
-
321
- test 'should not include docinfo files if safe mode is SECURE or greater' do
322
- sample_input_path = fixture_path('basic.asciidoc')
323
-
324
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
325
- :header_footer => true, :attributes => {'docinfo2' => ''}
326
- refute_empty output
327
- assert_css 'script[src="modernizr.js"]', output, 0
328
- assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
329
-
330
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
331
- :header_footer => true, :backend => 'docbook', :attributes => {'docinfo2' => ''}
332
- refute_empty output
333
- assert_css 'productname', output, 0
334
- assert_css 'copyright', output, 0
335
- end
336
-
337
- test 'should substitute attributes in docinfo files by default' do
338
- sample_input_path = fixture_path 'subs.adoc'
339
- using_memory_logger do |logger|
340
- output = Asciidoctor.convert_file sample_input_path,
341
- :to_file => false,
342
- :header_footer => true,
343
- :safe => :server,
344
- :attributes => { 'docinfo' => '', 'bootstrap-version' => nil, 'linkcss' => '', 'attribute-missing' => 'drop-line' }
345
- refute_empty output
346
- assert_css 'script', output, 0
347
- assert_xpath %(//meta[@name="copyright"][@content="(C) OpenDevise"]), output, 1
348
- assert_message logger, :WARN, 'dropping line containing reference to missing attribute: bootstrap-version'
349
- end
350
- end
351
-
352
- test 'should apply explicit substitutions to docinfo files' do
353
- sample_input_path = fixture_path 'subs.adoc'
354
- output = Asciidoctor.convert_file sample_input_path,
355
- :to_file => false,
356
- :header_footer => true,
357
- :safe => :server,
358
- :attributes => { 'docinfo' => '', 'docinfosubs' => 'attributes,replacements', 'linkcss' => '' }
359
- refute_empty output
360
- assert_css 'script[src="bootstrap.3.2.0.min.js"]', output, 1
361
- assert_xpath %(//meta[@name="copyright"][@content="#{decode_char 169} OpenDevise"]), output, 1
362
- end
363
- end
364
-
365
- context 'MathJax' do
366
- test 'should add MathJax script to HTML head if stem attribute is set' do
367
- output = convert_string '', :attributes => {'stem' => ''}
368
- assert_match('<script type="text/x-mathjax-config">', output)
369
- assert_match('inlineMath: [["\\\\(", "\\\\)"]]', output)
370
- assert_match('displayMath: [["\\\\[", "\\\\]"]]', output)
371
- assert_match('delimiters: [["\\\\$", "\\\\$"]]', output)
372
- end
373
- end
374
-
375
- context 'Converter' do
376
- test 'built-in HTML5 views are registered by default' do
377
- doc = document_from_string ''
378
- assert_equal 'html5', doc.attributes['backend']
379
- assert doc.attributes.has_key? 'backend-html5'
380
- assert_equal 'html', doc.attributes['basebackend']
381
- assert doc.attributes.has_key? 'basebackend-html'
382
- converter = doc.converter
383
- assert_kind_of Asciidoctor::Converter::Html5Converter, converter
384
- BUILT_IN_ELEMENTS.each do |element|
385
- assert_respond_to converter, element
386
- end
387
- end
388
-
389
- test 'built-in DocBook45 views are registered when backend is docbook45' do
390
- doc = document_from_string '', :attributes => {'backend' => 'docbook45'}
391
- converter = doc.converter
392
- assert_equal 'docbook45', doc.attributes['backend']
393
- assert doc.attributes.has_key? 'backend-docbook45'
394
- assert_equal 'docbook', doc.attributes['basebackend']
395
- assert doc.attributes.has_key? 'basebackend-docbook'
396
- converter = doc.converter
397
- assert_kind_of Asciidoctor::Converter::DocBook45Converter, converter
398
- BUILT_IN_ELEMENTS.each do |element|
399
- assert_respond_to converter, element
400
- end
401
- end
402
-
403
- test 'built-in DocBook5 views are registered when backend is docbook5' do
404
- doc = document_from_string '', :attributes => {'backend' => 'docbook5'}
405
- converter = doc.converter
406
- assert_equal 'docbook5', doc.attributes['backend']
407
- assert doc.attributes.has_key? 'backend-docbook5'
408
- assert_equal 'docbook', doc.attributes['basebackend']
409
- assert doc.attributes.has_key? 'basebackend-docbook'
410
- converter = doc.converter
411
- assert_kind_of Asciidoctor::Converter::DocBook5Converter, converter
412
- BUILT_IN_ELEMENTS.each do |element|
413
- assert_respond_to converter, element
414
- end
415
- end
416
-
417
- test 'should add favicon if favicon attribute is set' do
418
- {
419
- '' => %w(favicon.ico image/x-icon),
420
- '/favicon.ico' => %w(/favicon.ico image/x-icon),
421
- '/img/favicon.png' => %w(/img/favicon.png image/png)
422
- }.each {|val, (href, type)|
423
- result = convert_string %(= Untitled), :attributes => { 'favicon' => val }
424
- assert_css 'link[rel="icon"]', result, 1
425
- assert_css %(link[rel="icon"][href="#{href}"]), result, 1
426
- assert_css %(link[rel="icon"][type="#{type}"]), result, 1
427
- }
428
- end
429
- end
430
-
431
- context 'Structure' do
432
- test 'document with no doctitle' do
433
- doc = document_from_string('Snorf')
434
- assert_nil doc.doctitle
435
- assert_nil doc.name
436
- refute doc.has_header?
437
- assert_nil doc.header
438
- end
439
-
440
- test 'should enable compat mode for document with legacy doctitle' do
441
- input = <<-EOS
442
- Document Title
443
- ==============
444
-
445
- +content+
446
- EOS
447
-
448
- doc = document_from_string input
449
- assert(doc.attr? 'compat-mode')
450
- result = doc.convert
451
- assert_xpath '//code[text()="content"]', result, 1
452
- end
453
-
454
- test 'should not enable compat mode for document with legacy doctitle if compat mode disable by header' do
455
- input = <<-EOS
456
- Document Title
457
- ==============
458
- :compat-mode!:
459
-
460
- +content+
461
- EOS
462
-
463
- doc = document_from_string input
464
- assert_nil(doc.attr 'compat-mode')
465
- result = doc.convert
466
- assert_xpath '//code[text()="content"]', result, 0
467
- end
468
-
469
- test 'should not enable compat mode for document with legacy doctitle if compat mode is locked by API' do
470
- input = <<-EOS
471
- Document Title
472
- ==============
473
-
474
- +content+
475
- EOS
476
-
477
- doc = document_from_string input, :attributes => { 'compat-mode' => nil }
478
- assert(doc.attribute_locked? 'compat-mode')
479
- assert_nil(doc.attr 'compat-mode')
480
- result = doc.convert
481
- assert_xpath '//code[text()="content"]', result, 0
482
- end
483
-
484
- test 'title partition API with default separator' do
485
- title = Asciidoctor::Document::Title.new 'Main Title: And More: Subtitle'
486
- assert_equal 'Main Title: And More', title.main
487
- assert_equal 'Subtitle', title.subtitle
488
- end
489
-
490
- test 'title partition API with custom separator' do
491
- title = Asciidoctor::Document::Title.new 'Main Title:: And More:: Subtitle', :separator => '::'
492
- assert_equal 'Main Title:: And More', title.main
493
- assert_equal 'Subtitle', title.subtitle
494
- end
495
-
496
- test 'document with subtitle' do
497
- input = <<-EOS
498
- = Main Title: *Subtitle*
499
- Author Name
500
-
501
- content
502
- EOS
503
-
504
- doc = document_from_string input
505
- title = doc.doctitle :partition => true, :sanitize => true
506
- assert title.subtitle?
507
- assert title.sanitized?
508
- assert_equal 'Main Title', title.main
509
- assert_equal 'Subtitle', title.subtitle
510
- end
511
-
512
- test 'document with subtitle and custom separator' do
513
- input = <<-EOS
514
- [separator=::]
515
- = Main Title:: *Subtitle*
516
- Author Name
517
-
518
- content
519
- EOS
520
-
521
- doc = document_from_string input
522
- title = doc.doctitle :partition => true, :sanitize => true
523
- assert title.subtitle?
524
- assert title.sanitized?
525
- assert_equal 'Main Title', title.main
526
- assert_equal 'Subtitle', title.subtitle
527
- end
528
-
529
- test 'should not honor custom separator for doctitle if attribute is locked by API' do
530
- input = <<-EOS
531
- [separator=::]
532
- = Main Title - *Subtitle*
533
- Author Name
534
-
535
- content
536
- EOS
537
-
538
- doc = document_from_string input, :attributes => { 'title-separator' => ' -' }
539
- title = doc.doctitle :partition => true, :sanitize => true
540
- assert title.subtitle?
541
- assert title.sanitized?
542
- assert_equal 'Main Title', title.main
543
- assert_equal 'Subtitle', title.subtitle
544
- end
545
-
546
- test 'document with doctitle defined as attribute entry' do
547
- input = <<-EOS
548
- :doctitle: Document Title
549
-
550
- preamble
551
-
552
- == First Section
553
- EOS
554
- doc = document_from_string input
555
- assert_equal 'Document Title', doc.doctitle
556
- assert doc.has_header?
557
- assert_equal 'Document Title', doc.header.title
558
- assert_equal 'Document Title', doc.first_section.title
559
- end
560
-
561
- test 'document with doctitle defined as attribute entry followed by block with title' do
562
- input = <<-EOS
563
- :doctitle: Document Title
564
-
565
- .Block title
566
- Block content
567
- EOS
568
-
569
- doc = document_from_string input
570
- assert_equal 'Document Title', doc.doctitle
571
- assert doc.has_header?
572
- assert_equal 1, doc.blocks.size
573
- assert_equal :paragraph, doc.blocks[0].context
574
- assert_equal 'Block title', doc.blocks[0].title
575
- end
576
-
577
- test 'document with title attribute entry overrides doctitle' do
578
- input = <<-EOS
579
- = Document Title
580
- :title: Override
581
-
582
- {doctitle}
583
-
584
- == First Section
585
- EOS
586
- doc = document_from_string input
587
- assert_equal 'Override', doc.doctitle
588
- assert_equal 'Override', doc.title
589
- assert doc.has_header?
590
- assert_equal 'Document Title', doc.header.title
591
- assert_equal 'Document Title', doc.first_section.title
592
- assert_xpath '//*[@id="preamble"]//p[text()="Document Title"]', doc.convert, 1
593
- end
594
-
595
- test 'document with blank title attribute entry overrides doctitle' do
596
- input = <<-EOS
597
- = Document Title
598
- :title:
599
-
600
- {doctitle}
601
-
602
- == First Section
603
- EOS
604
- doc = document_from_string input
605
- assert_equal '', doc.doctitle
606
- assert_equal '', doc.title
607
- assert doc.has_header?
608
- assert_equal 'Document Title', doc.header.title
609
- assert_equal 'Document Title', doc.first_section.title
610
- assert_xpath '//*[@id="preamble"]//p[text()="Document Title"]', doc.convert, 1
611
- end
612
-
613
- test 'document with title attribute entry overrides doctitle attribute entry' do
614
- input = <<-EOS
615
- = Document Title
616
- :snapshot: {doctitle}
617
- :doctitle: doctitle
618
- :title: Override
619
-
620
- {snapshot}, {doctitle}
621
-
622
- == First Section
623
- EOS
624
- doc = document_from_string input
625
- assert_equal 'Override', doc.doctitle
626
- assert_equal 'Override', doc.title
627
- assert doc.has_header?
628
- assert_equal 'doctitle', doc.header.title
629
- assert_equal 'doctitle', doc.first_section.title
630
- assert_xpath '//*[@id="preamble"]//p[text()="Document Title, doctitle"]', doc.convert, 1
631
- end
632
-
633
- test 'document with doctitle attribute entry overrides header title and doctitle' do
634
- input = <<-EOS
635
- = Document Title
636
- :snapshot: {doctitle}
637
- :doctitle: Override
638
-
639
- {snapshot}, {doctitle}
640
-
641
- == First Section
642
- EOS
643
- doc = document_from_string input
644
- assert_equal 'Override', doc.doctitle
645
- assert_nil doc.attributes['title']
646
- assert doc.has_header?
647
- assert_equal 'Override', doc.header.title
648
- assert_equal 'Override', doc.first_section.title
649
- assert_xpath '//*[@id="preamble"]//p[text()="Document Title, Override"]', doc.convert, 1
650
- end
651
-
652
- test 'doctitle attribute entry above header overrides header title and doctitle' do
653
- input = <<-EOS
654
- :doctitle: Override
655
- = Document Title
656
-
657
- {doctitle}
658
-
659
- == First Section
660
- EOS
661
- doc = document_from_string input
662
- assert_equal 'Override', doc.doctitle
663
- assert_nil doc.attributes['title']
664
- assert doc.has_header?
665
- assert_equal 'Override', doc.header.title
666
- assert_equal 'Override', doc.first_section.title
667
- assert_xpath '//*[@id="preamble"]//p[text()="Override"]', doc.convert, 1
668
- end
669
-
670
- test 'should recognize document title when preceded by blank lines' do
671
- input = <<-EOS
672
- :doctype: book
673
-
674
- = Title
675
-
676
- preamble
677
-
678
- == Section 1
679
-
680
- text
681
- EOS
682
- output = convert_string input, :safe => Asciidoctor::SafeMode::SAFE
683
- assert_css '#header h1', output, 1
684
- assert_css '#content h1', output, 0
685
- end
686
-
687
- test 'document with multiline attribute entry but only one line should not crash' do
688
- input = ':foo: bar' + Asciidoctor::LINE_CONTINUATION
689
- doc = document_from_string input
690
- assert_equal 'bar', doc.attributes['foo']
691
- end
692
-
693
- test 'should sanitize contents of HTML title element' do
694
- input = <<-EOS
695
- = *Document* image:logo.png[] _Title_ image:another-logo.png[another logo]
696
-
697
- content
698
- EOS
699
-
700
- output = convert_string input
701
- assert_xpath '/html/head/title[text()="Document Title"]', output, 1
702
- nodes = xmlnodes_at_xpath('//*[@id="header"]/h1', output)
703
- assert_equal 1, nodes.size
704
- 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)
705
- end
706
-
707
- test 'should not choke on empty source' do
708
- doc = Asciidoctor::Document.new ''
709
- assert_empty doc.blocks
710
- assert_nil doc.doctitle
711
- refute doc.has_header?
712
- assert_nil doc.header
713
- end
714
-
715
- test 'should not choke on nil source' do
716
- doc = Asciidoctor::Document.new nil
717
- assert_empty doc.blocks
718
- assert_nil doc.doctitle
719
- refute doc.has_header?
720
- assert_nil doc.header
721
- end
722
-
723
- test 'with metadata' do
724
- input = <<-EOS
725
- = AsciiDoc
726
- Stuart Rackham <founder@asciidoc.org>
727
- v8.6.8, 2012-07-12: See changelog.
728
- :description: AsciiDoc user guide
729
- :keywords: asciidoc,documentation
730
- :copyright: Stuart Rackham
731
-
732
- == Version 8.6.8
733
-
734
- more info...
735
- EOS
736
- output = convert_string input
737
- assert_xpath '//meta[@name="author"][@content="Stuart Rackham"]', output, 1
738
- assert_xpath '//meta[@name="description"][@content="AsciiDoc user guide"]', output, 1
739
- assert_xpath '//meta[@name="keywords"][@content="asciidoc,documentation"]', output, 1
740
- assert_xpath '//meta[@name="copyright"][@content="Stuart Rackham"]', output, 1
741
- assert_xpath '//*[@id="header"]/*[@class="details"]/span[@id="author"][text() = "Stuart Rackham"]', output, 1
742
- assert_xpath '//*[@id="header"]/*[@class="details"]/span[@id="email"]/a[@href="mailto:founder@asciidoc.org"][text() = "founder@asciidoc.org"]', output, 1
743
- assert_xpath '//*[@id="header"]/*[@class="details"]/span[@id="revnumber"][text() = "version 8.6.8,"]', output, 1
744
- assert_xpath '//*[@id="header"]/*[@class="details"]/span[@id="revdate"][text() = "2012-07-12"]', output, 1
745
- assert_xpath '//*[@id="header"]/*[@class="details"]/span[@id="revremark"][text() = "See changelog."]', output, 1
746
- end
747
-
748
- test 'should parse revision line if date is empty' do
749
- input = <<-EOS
750
- = Document Title
751
- Author Name
752
- v1.0.0,:remark
753
-
754
- content
755
- EOS
756
-
757
- doc = document_from_string input
758
- assert_equal '1.0.0', doc.attributes['revnumber']
759
- assert_nil doc.attributes['revdate']
760
- assert_equal 'remark', doc.attributes['revremark']
761
- end
762
-
763
- test 'should include revision history if revdate and revnumber is set' do
764
- input = <<-EOS
765
- = Document Title
766
- Author Name
767
- :revdate: 2011-11-11
768
- :revnumber: 1.0
769
-
770
- content
771
- EOS
772
-
773
- output = convert_string input, :backend => 'docbook'
774
- assert_css 'revhistory', output, 1
775
- assert_css 'revhistory > revision', output, 1
776
- assert_css 'revhistory > revision > date', output, 1
777
- assert_css 'revhistory > revision > revnumber', output, 1
778
- end
779
-
780
- test 'should include revision history if revdate and revremark is set' do
781
- input = <<-EOS
782
- = Document Title
783
- Author Name
784
- :revdate: 2011-11-11
785
- :revremark: features!
786
-
787
- content
788
- EOS
789
-
790
- output = convert_string input, :backend => 'docbook'
791
- assert_css 'revhistory', output, 1
792
- assert_css 'revhistory > revision', output, 1
793
- assert_css 'revhistory > revision > date', output, 1
794
- assert_css 'revhistory > revision > revremark', output, 1
795
- end
796
-
797
- test 'should not include revision history if revdate is not set' do
798
- input = <<-EOS
799
- = Document Title
800
- Author Name
801
- :revnumber: 1.0
802
-
803
- content
804
- EOS
805
-
806
- output = convert_string input, :backend => 'docbook'
807
- assert_css 'revhistory', output, 0
808
- end
809
-
810
- test 'with metadata to DocBook45' do
811
- input = <<-EOS
812
- = AsciiDoc
813
- Stuart Rackham <founder@asciidoc.org>
814
- v8.6.8, 2012-07-12: See changelog.
815
-
816
- == Version 8.6.8
817
-
818
- more info...
819
- EOS
820
- output = convert_string input, :backend => 'docbook45'
821
- assert_xpath '/article/articleinfo', output, 1
822
- assert_xpath '/article/articleinfo/title[text() = "AsciiDoc"]', output, 1
823
- assert_xpath '/article/articleinfo/date[text() = "2012-07-12"]', output, 1
824
- assert_xpath '/article/articleinfo/author/firstname[text() = "Stuart"]', output, 1
825
- assert_xpath '/article/articleinfo/author/surname[text() = "Rackham"]', output, 1
826
- assert_xpath '/article/articleinfo/author/email[text() = "founder@asciidoc.org"]', output, 1
827
- assert_xpath '/article/articleinfo/revhistory', output, 1
828
- assert_xpath '/article/articleinfo/revhistory/revision', output, 1
829
- assert_xpath '/article/articleinfo/revhistory/revision/revnumber[text() = "8.6.8"]', output, 1
830
- assert_xpath '/article/articleinfo/revhistory/revision/date[text() = "2012-07-12"]', output, 1
831
- assert_xpath '/article/articleinfo/revhistory/revision/authorinitials[text() = "SR"]', output, 1
832
- assert_xpath '/article/articleinfo/revhistory/revision/revremark[text() = "See changelog."]', output, 1
833
- end
834
-
835
- test 'with metadata to DocBook5' do
836
- input = <<-EOS
837
- = AsciiDoc
838
- Stuart Rackham <founder@asciidoc.org>
839
-
840
- == Version 8.6.8
841
-
842
- more info...
843
- EOS
844
- output = convert_string input, :backend => 'docbook5'
845
- assert_xpath '/article/info', output, 1
846
- assert_xpath '/article/info/title[text() = "AsciiDoc"]', output, 1
847
- assert_xpath '/article/info/author/personname', output, 1
848
- assert_xpath '/article/info/author/personname/firstname[text() = "Stuart"]', output, 1
849
- assert_xpath '/article/info/author/personname/surname[text() = "Rackham"]', output, 1
850
- assert_xpath '/article/info/author/email[text() = "founder@asciidoc.org"]', output, 1
851
- end
852
-
853
- test 'with author defined using attribute entry to DocBook 4.5' do
854
- input = <<-EOS
855
- = Document Title
856
- :author: Doc Writer
857
- :email: thedoctor@asciidoc.org
858
-
859
- content
860
- EOS
861
-
862
- output = convert_string input, :backend => 'docbook45'
863
- assert_xpath '//articleinfo/author', output, 1
864
- assert_xpath '//articleinfo/author/firstname[text() = "Doc"]', output, 1
865
- assert_xpath '//articleinfo/author/surname[text() = "Writer"]', output, 1
866
- assert_xpath '//articleinfo/author/email[text() = "thedoctor@asciidoc.org"]', output, 1
867
- assert_xpath '//articleinfo/authorinitials[text() = "DW"]', output, 1
868
- end
869
-
870
- test 'should sanitize content of HTML meta authors tag' do
871
- input = <<-EOS
872
- = Document Title
873
- :author: pass:n[http://example.org/community/team.html[Ze *Product* team]]
874
-
875
- content
876
- EOS
877
-
878
- output = convert_string input
879
- assert_xpath '//meta[@name="author"][@content="Ze Product team"]', output, 1
880
- end
881
-
882
- test 'should not double escape ampersand in author attribute' do
883
- input = <<-EOS
884
- = Document Title
885
- R&D Lab
886
-
887
- {author}
888
- EOS
889
-
890
- output = convert_string input
891
- assert_includes output, 'R&amp;D Lab', 2
892
- end
893
-
894
- test 'should include multiple authors in HTML output' do
895
- input = <<-EOS
896
- = Document Title
897
- Doc Writer <thedoctor@asciidoc.org>; Junior Writer <junior@asciidoctor.org>
898
-
899
- content
900
- EOS
901
-
902
- output = convert_string input
903
- assert_xpath '//span[@id="author"]', output, 1
904
- assert_xpath '//span[@id="author"][text()="Doc Writer"]', output, 1
905
- assert_xpath '//span[@id="email"]', output, 1
906
- assert_xpath '//span[@id="email"]/a', output, 1
907
- assert_xpath '//span[@id="email"]/a[@href="mailto:thedoctor@asciidoc.org"][text()="thedoctor@asciidoc.org"]', output, 1
908
- assert_xpath '//span[@id="author2"]', output, 1
909
- assert_xpath '//span[@id="author2"][text()="Junior Writer"]', output, 1
910
- assert_xpath '//span[@id="email2"]', output, 1
911
- assert_xpath '//span[@id="email2"]/a', output, 1
912
- assert_xpath '//span[@id="email2"]/a[@href="mailto:junior@asciidoctor.org"][text()="junior@asciidoctor.org"]', output, 1
913
- end
914
-
915
- test 'should create authorgroup in DocBook when multiple authors' do
916
- input = <<-EOS
917
- = Document Title
918
- Doc Writer <thedoctor@asciidoc.org>; Junior Writer <junior@asciidoctor.org>
919
-
920
- content
921
- EOS
922
-
923
- output = convert_string input, :backend => 'docbook45'
924
- assert_xpath '//articleinfo/author', output, 0
925
- assert_xpath '//articleinfo/authorgroup', output, 1
926
- assert_xpath '//articleinfo/authorgroup/author', output, 2
927
- assert_xpath '//articleinfo/authorgroup/author[1]/firstname[text() = "Doc"]', output, 1
928
- assert_xpath '//articleinfo/authorgroup/author[2]/firstname[text() = "Junior"]', output, 1
929
- end
930
-
931
- test 'with author defined by indexed attribute name' do
932
- input = <<-EOS
933
- = Document Title
934
- :author_1: Doc Writer
935
-
936
- {author}
937
- EOS
938
-
939
- doc = document_from_string input
940
- assert_equal 'Doc Writer', (doc.attr 'author')
941
- assert_equal 'Doc Writer', (doc.attr 'author_1')
942
- end
943
-
944
- test 'with authors defined using attribute entry to DocBook' do
945
- input = <<-EOS
946
- = Document Title
947
- :authors: Doc Writer; Junior Writer
948
- :email_1: thedoctor@asciidoc.org
949
- :email_2: junior@asciidoc.org
950
-
951
- content
952
- EOS
953
-
954
- output = convert_string input, :backend => 'docbook45'
955
- assert_xpath '//articleinfo/author', output, 0
956
- assert_xpath '//articleinfo/authorgroup', output, 1
957
- assert_xpath '//articleinfo/authorgroup/author', output, 2
958
- assert_xpath '(//articleinfo/authorgroup/author)[1]/firstname[text() = "Doc"]', output, 1
959
- assert_xpath '(//articleinfo/authorgroup/author)[1]/email[text() = "thedoctor@asciidoc.org"]', output, 1
960
- assert_xpath '(//articleinfo/authorgroup/author)[2]/firstname[text() = "Junior"]', output, 1
961
- assert_xpath '(//articleinfo/authorgroup/author)[2]/email[text() = "junior@asciidoc.org"]', output, 1
962
- end
963
-
964
- test 'should populate copyright element in DocBook output if copyright attribute is defined' do
965
- input = <<-EOS
966
- = Jet Bike
967
- :copyright: ACME, Inc.
968
-
969
- Essential for catching road runners.
970
- EOS
971
- output = convert_string input, :backend => 'docbook5'
972
- assert_xpath '/article/info/copyright', output, 1
973
- assert_xpath '/article/info/copyright/holder[text()="ACME, Inc."]', output, 1
974
- end
975
-
976
- test 'should populate copyright element in DocBook output if copyright attribute is defined with year' do
977
- input = <<-EOS
978
- = Jet Bike
979
- :copyright: ACME, Inc. 1956
980
-
981
- Essential for catching road runners.
982
- EOS
983
- output = convert_string input, :backend => 'docbook5'
984
- assert_xpath '/article/info/copyright', output, 1
985
- assert_xpath '/article/info/copyright/holder[text()="ACME, Inc."]', output, 1
986
- assert_xpath '/article/info/copyright/year', output, 1
987
- assert_xpath '/article/info/copyright/year[text()="1956"]', output, 1
988
- end
989
-
990
- test 'should populate copyright element in DocBook output if copyright attribute is defined with year range' do
991
- input = <<-EOS
992
- = Jet Bike
993
- :copyright: ACME, Inc. 1956-2018
994
-
995
- Essential for catching road runners.
996
- EOS
997
- output = convert_string input, :backend => 'docbook5'
998
- assert_xpath '/article/info/copyright', output, 1
999
- assert_xpath '/article/info/copyright/holder[text()="ACME, Inc."]', output, 1
1000
- assert_xpath '/article/info/copyright/year', output, 1
1001
- assert_xpath '/article/info/copyright/year[text()="1956-2018"]', output, 1
1002
- end
1003
-
1004
- test 'with header footer' do
1005
- doc = document_from_string "= Title\n\nparagraph"
1006
- refute doc.attr?('embedded')
1007
- result = doc.convert
1008
- assert_xpath '/html', result, 1
1009
- assert_xpath '//*[@id="header"]', result, 1
1010
- assert_xpath '//*[@id="header"]/h1', result, 1
1011
- assert_xpath '//*[@id="footer"]', result, 1
1012
- assert_xpath '//*[@id="content"]', result, 1
1013
- end
1014
-
1015
- test 'does not output footer if nofooter is set' do
1016
- input = <<-EOS
1017
- :nofooter:
1018
-
1019
- content
1020
- EOS
1021
-
1022
- result = convert_string input
1023
- assert_xpath '//*[@id="footer"]', result, 0
1024
- end
1025
-
1026
- test 'can disable last updated in footer' do
1027
- doc = document_from_string "= Document Title\n\npreamble", :attributes => {'last-update-label!' => ''}
1028
- result = doc.convert
1029
- assert_xpath '//*[@id="footer-text"]', result, 1
1030
- assert_xpath '//*[@id="footer-text"][normalize-space(text())=""]', result, 1
1031
- end
1032
-
1033
- test 'no header footer' do
1034
- doc = document_from_string "= Document Title\n\ncontent", :header_footer => false
1035
- assert doc.attr?('embedded')
1036
- result = doc.convert
1037
- assert_xpath '/html', result, 0
1038
- assert_xpath '/h1', result, 0
1039
- assert_xpath '/*[@id="header"]', result, 0
1040
- assert_xpath '/*[@id="footer"]', result, 0
1041
- assert_xpath '/*[@class="paragraph"]', result, 1
1042
- end
1043
-
1044
- test 'enable title in embedded document by unassigning notitle attribute' do
1045
- input = <<-EOS
1046
- = Document Title
1047
-
1048
- content
1049
- EOS
1050
-
1051
- result = convert_string_to_embedded input, :attributes => {'notitle!' => ''}
1052
- assert_xpath '/html', result, 0
1053
- assert_xpath '/h1', result, 1
1054
- assert_xpath '/*[@id="header"]', result, 0
1055
- assert_xpath '/*[@id="footer"]', result, 0
1056
- assert_xpath '/*[@class="paragraph"]', result, 1
1057
- assert_xpath '(/*)[1]/self::h1', result, 1
1058
- assert_xpath '(/*)[2]/self::*[@class="paragraph"]', result, 1
1059
- end
1060
-
1061
- test 'enable title in embedded document by assigning showtitle attribute' do
1062
- input = <<-EOS
1063
- = Document Title
1064
-
1065
- content
1066
- EOS
1067
-
1068
- result = convert_string_to_embedded input, :attributes => {'showtitle' => ''}
1069
- assert_xpath '/html', result, 0
1070
- assert_xpath '/h1', result, 1
1071
- assert_xpath '/*[@id="header"]', result, 0
1072
- assert_xpath '/*[@id="footer"]', result, 0
1073
- assert_xpath '/*[@class="paragraph"]', result, 1
1074
- assert_xpath '(/*)[1]/self::h1', result, 1
1075
- assert_xpath '(/*)[2]/self::*[@class="paragraph"]', result, 1
1076
- end
1077
-
1078
- test 'parse header only' do
1079
- input = <<-EOS
1080
- = Document Title
1081
- Author Name
1082
- :foo: bar
1083
-
1084
- preamble
1085
- EOS
1086
-
1087
- doc = document_from_string input, :parse_header_only => true
1088
- assert_equal 'Document Title', doc.doctitle
1089
- assert_equal 'Author Name', doc.author
1090
- assert_equal 'bar', doc.attributes['foo']
1091
- # there would be at least 1 block had it parsed beyond the header
1092
- assert_equal 0, doc.blocks.size
1093
- end
1094
-
1095
- test 'outputs footnotes in footer' do
1096
- input = <<-EOS
1097
- A footnote footnote:[An example footnote.];
1098
- a second footnote with a reference ID footnoteref:[note2,Second footnote.];
1099
- finally a reference to the second footnote footnoteref:[note2].
1100
- EOS
1101
-
1102
- output = convert_string input
1103
- assert_css '#footnotes', output, 1
1104
- assert_css '#footnotes .footnote', output, 2
1105
- assert_css '#footnotes .footnote#_footnotedef_1', output, 1
1106
- assert_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
1107
- text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_1"]/text()', output
1108
- assert_equal '. An example footnote.', text.text.strip
1109
- assert_css '#footnotes .footnote#_footnotedef_2', output, 1
1110
- assert_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_2"]/a[@href="#_footnoteref_2"][text()="2"]', output, 1
1111
- text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_2"]/text()', output
1112
- assert_equal '. Second footnote.', text.text.strip
1113
- end
1114
-
1115
- test 'outputs footnotes block in embedded document by default' do
1116
- input = <<-EOS
1117
- Text that has supporting information{empty}footnote:[An example footnote.].
1118
- EOS
1119
-
1120
- output = convert_string_to_embedded input
1121
- assert_css '#footnotes', output, 1
1122
- assert_css '#footnotes .footnote', output, 1
1123
- assert_css '#footnotes .footnote#_footnotedef_1', output, 1
1124
- assert_xpath '/div[@id="footnotes"]/div[@id="_footnotedef_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
1125
- text = xmlnodes_at_xpath '/div[@id="footnotes"]/div[@id="_footnotedef_1"]/text()', output
1126
- assert_equal '. An example footnote.', text.text.strip
1127
- end
1128
-
1129
- test 'does not output footnotes block in embedded document if nofootnotes attribute is set' do
1130
- input = <<-EOS
1131
- Text that has supporting information{empty}footnote:[An example footnote.].
1132
- EOS
1133
-
1134
- output = convert_string_to_embedded input, :attributes => {'nofootnotes' => ''}
1135
- assert_css '#footnotes', output, 0
1136
- end
1137
- end
1138
-
1139
- context 'Catalog' do
1140
- test 'document catalog is aliased as references' do
1141
- input = <<-EOS
1142
- = Document Title
1143
-
1144
- == Section A
1145
-
1146
- content
1147
-
1148
- == Section B
1149
-
1150
- content{blank}footnote:[commentary]
1151
- EOS
1152
-
1153
- doc = document_from_string input
1154
- refute_nil doc.catalog
1155
- assert_equal [:footnotes, :ids, :images, :includes, :indexterms, :links, :refs, :callouts].to_set, doc.catalog.keys.to_set
1156
- assert_same doc.catalog, doc.references
1157
- assert_same doc.catalog[:footnotes], doc.references[:footnotes]
1158
- assert_same doc.catalog[:ids], doc.references[:ids]
1159
- assert_equal 'Section A', doc.references[:ids]['_section_a']
1160
- end
1161
-
1162
- test 'should catalog assets inside nested document' do
1163
- input = <<-EOS
1164
- image::outer.png[]
1165
-
1166
- |===
1167
- a|
1168
- image::inner.png[]
1169
- |===
1170
- EOS
1171
-
1172
- doc = document_from_string input, :catalog_assets => true
1173
- images = doc.catalog[:images]
1174
- refute_empty images
1175
- assert_equal 2, images.size
1176
- assert_equal images.map {|it| it.target }, ['outer.png', 'inner.png']
1177
- end
1178
- end
1179
-
1180
- context 'Backends and Doctypes' do
1181
- test 'html5 backend doctype article' do
1182
- result = convert_string("= Title\n\nparagraph", :attributes => {'backend' => 'html5'})
1183
- assert_xpath '/html', result, 1
1184
- assert_xpath '/html/body[@class="article"]', result, 1
1185
- assert_xpath '/html//*[@id="header"]/h1[text() = "Title"]', result, 1
1186
- assert_xpath '/html//*[@id="content"]//p[text() = "paragraph"]', result, 1
1187
- end
1188
-
1189
- test 'html5 backend doctype book' do
1190
- result = convert_string("= Title\n\nparagraph", :attributes => {'backend' => 'html5', 'doctype' => 'book'})
1191
- assert_xpath '/html', result, 1
1192
- assert_xpath '/html/body[@class="book"]', result, 1
1193
- assert_xpath '/html//*[@id="header"]/h1[text() = "Title"]', result, 1
1194
- assert_xpath '/html//*[@id="content"]//p[text() = "paragraph"]', result, 1
1195
- end
1196
-
1197
- test 'xhtml5 backend should map to html5 and set htmlsyntax to xml' do
1198
- input = <<-EOS
1199
- content
1200
- EOS
1201
- doc = document_from_string input, :backend => :xhtml5
1202
- assert_equal 'html5', doc.backend
1203
- assert_equal 'xml', (doc.attr 'htmlsyntax')
1204
- end
1205
-
1206
- test 'xhtml backend should map to html5 and set htmlsyntax to xml' do
1207
- input = <<-EOS
1208
- content
1209
- EOS
1210
- doc = document_from_string input, :backend => :xhtml
1211
- assert_equal 'html5', doc.backend
1212
- assert_equal 'xml', (doc.attr 'htmlsyntax')
1213
- end
1214
-
1215
- test 'honor htmlsyntax attribute passed via API if backend is html' do
1216
- input = <<-EOS
1217
- ---
1218
- EOS
1219
- doc = document_from_string input, :safe => :safe, :attributes => { 'htmlsyntax' => 'xml' }
1220
- assert_equal 'html5', doc.backend
1221
- assert_equal 'xml', (doc.attr 'htmlsyntax')
1222
- result = doc.convert :header_footer => false
1223
- assert_equal '<hr/>', result
1224
- end
1225
-
1226
- test 'honor htmlsyntax attribute in document header if followed by backend attribute' do
1227
- input = <<-EOS
1228
- :htmlsyntax: xml
1229
- :backend: html5
1230
-
1231
- ---
1232
- EOS
1233
- doc = document_from_string input, :safe => :safe
1234
- assert_equal 'html5', doc.backend
1235
- assert_equal 'xml', (doc.attr 'htmlsyntax')
1236
- result = doc.convert :header_footer => false
1237
- assert_equal '<hr/>', result
1238
- end
1239
-
1240
- test 'does not honor htmlsyntax attribute in document header if not followed by backend attribute' do
1241
- input = <<-EOS
1242
- :backend: html5
1243
- :htmlsyntax: xml
1244
-
1245
- ---
1246
- EOS
1247
- result = convert_string_to_embedded input, :safe => :safe
1248
- assert_equal '<hr>', result
1249
- end
1250
-
1251
- test 'should close all short tags when htmlsyntax is xml' do
1252
- input = <<-EOS
1253
- = Document Title
1254
- Author Name
1255
- v1.0, 2001-01-01
1256
- :icons:
1257
- :favicon:
1258
-
1259
- image:tiger.png[]
1260
-
1261
- image::tiger.png[]
1262
-
1263
- * [x] one
1264
- * [ ] two
1265
-
1266
- |===
1267
- |A |B
1268
- |===
1269
-
1270
- [horizontal, labelwidth="25%", itemwidth="75%"]
1271
- term:: description
1272
-
1273
- NOTE: note
1274
-
1275
- [quote,Author,Source]
1276
- ____
1277
- Quote me.
1278
- ____
1279
-
1280
- [verse,Author,Source]
1281
- ____
1282
- A tall tale.
1283
- ____
1284
-
1285
- [options="autoplay,loop"]
1286
- video::screencast.ogg[]
1287
-
1288
- video::12345[vimeo]
1289
-
1290
- [options="autoplay,loop"]
1291
- audio::podcast.ogg[]
1292
-
1293
- one +
1294
- two
1295
-
1296
- '''
1297
- EOS
1298
- result = convert_string input, :safe => :safe, :backend => :xhtml
1299
- begin
1300
- Nokogiri::XML::Document.parse(result) {|config|
1301
- config.options = Nokogiri::XML::ParseOptions::STRICT | Nokogiri::XML::ParseOptions::NONET
1302
- }
1303
- rescue => e
1304
- flunk "xhtml5 backend did not generate well-formed XML: #{e.message}\n#{result}"
1305
- end
1306
- end
1307
-
1308
- test 'xhtml backend should emit elements in proper namespace' do
1309
- input = <<-EOS
1310
- content
1311
- EOS
1312
- result = convert_string input, :safe => :safe, :backend => :xhtml, :keep_namespaces => true
1313
- assert_xpath '//*[not(namespace-uri() = "http://www.w3.org/1999/xhtml")]', result, 0
1314
- end
1315
-
1316
- test 'docbook45 backend doctype article' do
1317
- input = <<-EOS
1318
- = Title
1319
-
1320
- preamble
1321
-
1322
- == First Section
1323
-
1324
- section body
1325
- EOS
1326
- result = convert_string(input, :attributes => {'backend' => 'docbook45'})
1327
- assert_xpath '/article', result, 1
1328
- assert_xpath '/article/articleinfo/title[text() = "Title"]', result, 1
1329
- assert_xpath '/article/simpara[text() = "preamble"]', result, 1
1330
- assert_xpath '/article/section', result, 1
1331
- assert_xpath '/article/section[@id = "_first_section"]/title[text() = "First Section"]', result, 1
1332
- assert_xpath '/article/section[@id = "_first_section"]/simpara[text() = "section body"]', result, 1
1333
- end
1334
-
1335
- test 'docbook45 backend doctype article no title' do
1336
- result = convert_string('text', :attributes => {'backend' => 'docbook45'})
1337
- assert_xpath '/article', result, 1
1338
- assert_xpath '/article/articleinfo/date', result, 1
1339
- assert_xpath '/article/simpara[text() = "text"]', result, 1
1340
- end
1341
-
1342
- test 'docbook45 backend doctype article no xmlns' do
1343
- result = convert_string('text', :keep_namespaces => true, :attributes => {'backend' => 'docbook45', 'doctype' => 'article'})
1344
- refute_match(RE_XMLNS_ATTRIBUTE, result)
1345
- end
1346
-
1347
- test 'docbook45 backend doctype manpage' do
1348
- input = <<-EOS
1349
- = asciidoctor(1)
1350
-
1351
- == NAME
1352
-
1353
- asciidoctor - Process text
1354
-
1355
- == SYNOPSIS
1356
-
1357
- some text
1358
-
1359
- == First Section
1360
-
1361
- section body
1362
- EOS
1363
- result = convert_string(input, :attributes => {'backend' => 'docbook45', 'doctype' => 'manpage'})
1364
- assert_xpath '/refentry', result, 1
1365
- assert_xpath '/refentry/refentryinfo/title[text() = "asciidoctor(1)"]', result, 1
1366
- assert_xpath '/refentry/refmeta/refentrytitle[text() = "asciidoctor"]', result, 1
1367
- assert_xpath '/refentry/refmeta/manvolnum[text() = "1"]', result, 1
1368
- assert_xpath '/refentry/refnamediv/refname[text() = "asciidoctor"]', result, 1
1369
- assert_xpath '/refentry/refnamediv/refpurpose[text() = "Process text"]', result, 1
1370
- assert_xpath '/refentry/refsynopsisdiv', result, 1
1371
- assert_xpath '/refentry/refsynopsisdiv/simpara[text() = "some text"]', result, 1
1372
- assert_xpath '/refentry/refsection', result, 1
1373
- assert_xpath '/refentry/refsection[@id = "_first_section"]/title[text() = "First Section"]', result, 1
1374
- assert_xpath '/refentry/refsection[@id = "_first_section"]/simpara[text() = "section body"]', result, 1
1375
- end
1376
-
1377
- test 'docbook45 backend doctype book' do
1378
- input = <<-EOS
1379
- = Title
1380
-
1381
- preamble
1382
-
1383
- == First Chapter
1384
-
1385
- chapter body
1386
- EOS
1387
- result = convert_string(input, :attributes => {'backend' => 'docbook45', 'doctype' => 'book'})
1388
- assert_xpath '/book', result, 1
1389
- assert_xpath '/book/bookinfo/title[text() = "Title"]', result, 1
1390
- assert_xpath '/book/preface/simpara[text() = "preamble"]', result, 1
1391
- assert_xpath '/book/chapter', result, 1
1392
- assert_xpath '/book/chapter[@id = "_first_chapter"]/title[text() = "First Chapter"]', result, 1
1393
- assert_xpath '/book/chapter[@id = "_first_chapter"]/simpara[text() = "chapter body"]', result, 1
1394
- end
1395
-
1396
- test 'docbook45 backend doctype book no title' do
1397
- result = convert_string('text', :attributes => {'backend' => 'docbook45', 'doctype' => 'book'})
1398
- assert_xpath '/book', result, 1
1399
- assert_xpath '/book/bookinfo/date', result, 1
1400
- # NOTE simpara cannot be a direct child of book, so content must be treated as a preface
1401
- assert_xpath '/book/preface/simpara[text() = "text"]', result, 1
1402
- end
1403
-
1404
- test 'docbook45 backend doctype book no xmlns' do
1405
- result = convert_string('text', :keep_namespaces => true, :attributes => {'backend' => 'docbook45', 'doctype' => 'book'})
1406
- refute_match(RE_XMLNS_ATTRIBUTE, result)
1407
- end
1408
-
1409
- test 'docbook45 backend parses out subtitle' do
1410
- input = <<-EOS
1411
- = Document Title: Subtitle
1412
- :doctype: book
1413
-
1414
- text
1415
- EOS
1416
- result = convert_string input, :backend => 'docbook45'
1417
- assert_xpath '/book', result, 1
1418
- assert_xpath '/book/bookinfo/title[text() = "Document Title"]', result, 1
1419
- assert_xpath '/book/bookinfo/subtitle[text() = "Subtitle"]', result, 1
1420
- end
1421
-
1422
- test 'docbook5 backend doctype article' do
1423
- input = <<-EOS
1424
- = Title
1425
- Author Name
1426
-
1427
- preamble
1428
-
1429
- == First Section
1430
-
1431
- section body
1432
- EOS
1433
- result = convert_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5'})
1434
- assert_xpath '/xmlns:article', result, 1
1435
- doc = xmlnodes_at_xpath('/xmlns:article', result, 1)
1436
- assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
1437
- assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xl']
1438
- assert_xpath '/xmlns:article[@version="5.0"]', result, 1
1439
- assert_xpath '/xmlns:article/xmlns:info/xmlns:title[text() = "Title"]', result, 1
1440
- assert_xpath '/xmlns:article/xmlns:simpara[text() = "preamble"]', result, 1
1441
- assert_xpath '/xmlns:article/xmlns:section', result, 1
1442
- section = xmlnodes_at_xpath('/xmlns:article/xmlns:section', result, 1)
1443
- # nokogiri can't make up its mind
1444
- id_attr = section.attribute('id') || section.attribute('xml:id')
1445
- refute_nil id_attr
1446
- refute_nil id_attr.namespace
1447
- assert_equal 'xml', id_attr.namespace.prefix
1448
- assert_equal '_first_section', id_attr.value
1449
- end
1450
-
1451
- test 'docbook5 backend doctype manpage' do
1452
- input = <<-EOS
1453
- = asciidoctor(1)
1454
- :mansource: Asciidoctor
1455
- :manmanual: Asciidoctor Manual
1456
-
1457
- == NAME
1458
-
1459
- asciidoctor - Process text
1460
-
1461
- == SYNOPSIS
1462
-
1463
- some text
1464
-
1465
- == First Section
1466
-
1467
- section body
1468
- EOS
1469
- result = convert_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5', 'doctype' => 'manpage'})
1470
- assert_xpath '/xmlns:refentry', result, 1
1471
- doc = xmlnodes_at_xpath('/xmlns:refentry', result, 1)
1472
- assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
1473
- assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xl']
1474
- assert_xpath '/xmlns:refentry[@version="5.0"]', result, 1
1475
- assert_xpath '/xmlns:refentry/xmlns:info/xmlns:title[text() = "asciidoctor(1)"]', result, 1
1476
- assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:refentrytitle[text() = "asciidoctor"]', result, 1
1477
- assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:manvolnum[text() = "1"]', result, 1
1478
- assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="source"][text() = "Asciidoctor"]', result, 1
1479
- assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="manual"][text() = "Asciidoctor Manual"]', result, 1
1480
- assert_xpath '/xmlns:refentry/xmlns:refnamediv/xmlns:refname[text() = "asciidoctor"]', result, 1
1481
- assert_xpath '/xmlns:refentry/xmlns:refnamediv/xmlns:refpurpose[text() = "Process text"]', result, 1
1482
- assert_xpath '/xmlns:refentry/xmlns:refsynopsisdiv', result, 1
1483
- assert_xpath '/xmlns:refentry/xmlns:refsynopsisdiv/xmlns:simpara[text() = "some text"]', result, 1
1484
- assert_xpath '/xmlns:refentry/xmlns:refsection', result, 1
1485
- section = xmlnodes_at_xpath('/xmlns:refentry/xmlns:refsection', result, 1)
1486
- # nokogiri can't make up its mind
1487
- id_attr = section.attribute('id') || section.attribute('xml:id')
1488
- refute_nil id_attr
1489
- refute_nil id_attr.namespace
1490
- assert_equal 'xml', id_attr.namespace.prefix
1491
- assert_equal '_first_section', id_attr.value
1492
- end
1493
-
1494
- test 'should output non-breaking space for source and manual in docbook5 manpage output if absent from source' do
1495
- input = <<-EOS
1496
- = asciidoctor(1)
1497
-
1498
- == NAME
1499
-
1500
- asciidoctor - Process text
1501
-
1502
- == SYNOPSIS
1503
-
1504
- some text
1505
- EOS
1506
- result = convert_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5', 'doctype' => 'manpage'})
1507
- assert_xpath %(/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="source"][text() = "#{decode_char 160}"]), result, 1
1508
- assert_xpath %(/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="manual"][text() = "#{decode_char 160}"]), result, 1
1509
- end
1510
-
1511
- test 'docbook5 backend doctype book' do
1512
- input = <<-EOS
1513
- = Title
1514
- Author Name
1515
-
1516
- preamble
1517
-
1518
- == First Chapter
1519
-
1520
- chapter body
1521
- EOS
1522
- result = convert_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5', 'doctype' => 'book'})
1523
- assert_xpath '/xmlns:book', result, 1
1524
- doc = xmlnodes_at_xpath('/xmlns:book', result, 1)
1525
- assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
1526
- assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xl']
1527
- assert_xpath '/xmlns:book[@version="5.0"]', result, 1
1528
- assert_xpath '/xmlns:book/xmlns:info/xmlns:title[text() = "Title"]', result, 1
1529
- assert_xpath '/xmlns:book/xmlns:preface/xmlns:simpara[text() = "preamble"]', result, 1
1530
- assert_xpath '/xmlns:book/xmlns:chapter', result, 1
1531
- chapter = xmlnodes_at_xpath('/xmlns:book/xmlns:chapter', result, 1)
1532
- # nokogiri can't make up its mind
1533
- id_attr = chapter.attribute('id') || chapter.attribute('xml:id')
1534
- refute_nil id_attr
1535
- refute_nil id_attr.namespace
1536
- assert_equal 'xml', id_attr.namespace.prefix
1537
- assert_equal '_first_chapter', id_attr.value
1538
- end
1539
-
1540
- test 'adds refname to DocBook output for each name defined in NAME section of manpage' do
1541
- input = <<-EOS
1542
- = eve(1)
1543
- Andrew Stanton
1544
- v1.0.0
1545
- :doctype: manpage
1546
- :manmanual: EVE
1547
- :mansource: EVE
1548
-
1549
- == NAME
1550
-
1551
- eve, islifeform - analyzes an image to determine if it's a picture of a life form
1552
-
1553
- == SYNOPSIS
1554
-
1555
- *eve* ['OPTION']... 'FILE'...
1556
- EOS
1557
-
1558
- result = convert_string input, :backend => 'docbook5'
1559
- assert_xpath '/refentry/refnamediv/refname', result, 2
1560
- assert_xpath '(/refentry/refnamediv/refname)[1][text()="eve"]', result, 1
1561
- assert_xpath '(/refentry/refnamediv/refname)[2][text()="islifeform"]', result, 1
1562
- end
1563
-
1564
- test 'adds a front and back cover image to DocBook 5 when doctype is book' do
1565
- input = <<-EOS
1566
- = Title
1567
- :doctype: book
1568
- :imagesdir: images
1569
- :front-cover-image: image:front-cover.jpg[scaledwidth=210mm]
1570
- :back-cover-image: image:back-cover.jpg[scaledwidth=210mm]
1571
-
1572
- preamble
1573
-
1574
- == First Chapter
1575
-
1576
- chapter body
1577
- EOS
1578
-
1579
- result = convert_string input, :attributes => {'backend' => 'docbook5'}
1580
- assert_xpath '//info/cover[@role="front"]', result, 1
1581
- assert_xpath '//info/cover[@role="front"]//imagedata[@fileref="images/front-cover.jpg"]', result, 1
1582
- assert_xpath '//info/cover[@role="back"]', result, 1
1583
- assert_xpath '//info/cover[@role="back"]//imagedata[@fileref="images/back-cover.jpg"]', result, 1
1584
- end
1585
-
1586
- test 'should be able to set backend using :backend option key' do
1587
- doc = empty_document :backend => 'html5'
1588
- assert_equal 'html5', doc.attributes['backend']
1589
- end
1590
-
1591
- test ':backend option should override backend attribute' do
1592
- doc = empty_document :backend => 'html5', :attributes => {'backend' => 'docbook45'}
1593
- assert_equal 'html5', doc.attributes['backend']
1594
- end
1595
-
1596
- test 'should be able to set doctype using :doctype option key' do
1597
- doc = empty_document :doctype => 'book'
1598
- assert_equal 'book', doc.attributes['doctype']
1599
- end
1600
-
1601
- test ':doctype option should override doctype attribute' do
1602
- doc = empty_document :doctype => 'book', :attributes => {'doctype' => 'article'}
1603
- assert_equal 'book', doc.attributes['doctype']
1604
- end
1605
-
1606
- test 'do not override explicit author initials' do
1607
- input = <<-EOS
1608
- = AsciiDoc
1609
- Stuart Rackham <founder@asciidoc.org>
1610
- :Author Initials: SJR
1611
-
1612
- more info...
1613
- EOS
1614
- output = convert_string input, :attributes => {'backend' => 'docbook45'}
1615
- assert_xpath '/article/articleinfo/authorinitials[text()="SJR"]', output, 1
1616
- end
1617
-
1618
- test 'attribute entry can appear immediately after document title' do
1619
- input = <<-EOS
1620
- Reference Guide
1621
- ===============
1622
- :toc:
1623
-
1624
- preamble
1625
- EOS
1626
- doc = document_from_string input
1627
- assert doc.attr?('toc')
1628
- assert_equal '', doc.attr('toc')
1629
- end
1630
-
1631
- test 'attribute entry can appear before author line under document title' do
1632
- input = <<-EOS
1633
- Reference Guide
1634
- ===============
1635
- :toc:
1636
- Dan Allen
1637
-
1638
- preamble
1639
- EOS
1640
- doc = document_from_string input
1641
- assert doc.attr?('toc')
1642
- assert_equal '', doc.attr('toc')
1643
- assert_equal 'Dan Allen', doc.attr('author')
1644
- end
1645
-
1646
- test 'should parse mantitle and manvolnum from document title for manpage doctype' do
1647
- input = <<-EOS
1648
- = asciidoctor ( 1 )
1649
- :doctype: manpage
1650
-
1651
- == NAME
1652
-
1653
- asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
1654
- EOS
1655
-
1656
- doc = document_from_string input
1657
- assert_equal 'asciidoctor', doc.attr('mantitle')
1658
- assert_equal '1', doc.attr('manvolnum')
1659
- end
1660
-
1661
- test 'should perform attribute substitution on mantitle in manpage doctype' do
1662
- input = <<-EOS
1663
- = {app}(1)
1664
- :doctype: manpage
1665
- :app: Asciidoctor
1666
-
1667
- == NAME
1668
-
1669
- asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
1670
- EOS
1671
-
1672
- doc = document_from_string input
1673
- assert_equal 'asciidoctor', doc.attr('mantitle')
1674
- end
1675
-
1676
- test 'should consume name section as manname and manpurpose for manpage doctype' do
1677
- input = <<-EOS
1678
- = asciidoctor(1)
1679
- :doctype: manpage
1680
-
1681
- == NAME
1682
-
1683
- asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
1684
- EOS
1685
-
1686
- doc = document_from_string input
1687
- assert_equal 'asciidoctor', doc.attr('manname')
1688
- assert_equal 'converts AsciiDoc source files to HTML, DocBook and other formats', doc.attr('manpurpose')
1689
- assert_equal '_name', doc.attr('manname-id')
1690
- assert_equal 0, doc.blocks.size
1691
- end
1692
-
1693
- test 'should set docname and outfilesuffix from manname and manvolnum for manpage backend and doctype' do
1694
- input = <<-EOS
1695
- = asciidoctor(1)
1696
- :doctype: manpage
1697
-
1698
- == NAME
1699
-
1700
- asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
1701
- EOS
1702
-
1703
- doc = document_from_string input, :backend => 'manpage'
1704
- assert_equal 'asciidoctor', doc.attributes['docname']
1705
- assert_equal '.1', doc.attributes['outfilesuffix']
1706
- end
1707
-
1708
- test 'should mark synopsis as special section in manpage doctype' do
1709
- input = <<-EOS
1710
- = asciidoctor(1)
1711
- :doctype: manpage
1712
-
1713
- == NAME
1714
-
1715
- asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
1716
-
1717
- == SYNOPSIS
1718
-
1719
- *asciidoctor* ['OPTION']... 'FILE'..
1720
- EOS
1721
-
1722
- doc = document_from_string input
1723
- synopsis_section = doc.blocks.first
1724
- refute_nil synopsis_section
1725
- assert_equal :section, synopsis_section.context
1726
- assert synopsis_section.special
1727
- assert_equal 'synopsis', synopsis_section.sectname
1728
- end
1729
-
1730
- test 'should output special header block in HTML for manpage doctype' do
1731
- input = <<-EOS
1732
- = asciidoctor(1)
1733
- :doctype: manpage
1734
-
1735
- == NAME
1736
-
1737
- asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
1738
-
1739
- == SYNOPSIS
1740
-
1741
- *asciidoctor* ['OPTION']... 'FILE'..
1742
- EOS
1743
-
1744
- output = convert_string input
1745
- assert_css 'body.manpage', output, 1
1746
- assert_xpath '//body/*[@id="header"]/h1[text()="asciidoctor(1) Manual Page"]', output, 1
1747
- assert_xpath '//body/*[@id="header"]/h1/following-sibling::h2[text()="NAME"]', output, 1
1748
- assert_xpath '//h2[@id="_name"][text()="NAME"]', output, 1
1749
- assert_xpath '//h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]', output, 1
1750
- assert_xpath '//h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]/p[text()="asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats"]', output, 1
1751
- assert_xpath '//*[@id="content"]/*[@class="sect1"]/h2[text()="SYNOPSIS"]', output, 1
1752
- end
1753
-
1754
- test 'should output special header block in embeddable HTML for manpage doctype' do
1755
- input = <<-EOS
1756
- = asciidoctor(1)
1757
- :doctype: manpage
1758
- :showtitle:
1759
-
1760
- == NAME
1761
-
1762
- asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
1763
-
1764
- == SYNOPSIS
1765
-
1766
- *asciidoctor* ['OPTION']... 'FILE'..
1767
- EOS
1768
-
1769
- output = convert_string_to_embedded input
1770
- assert_xpath '/h1[text()="asciidoctor(1) Manual Page"]', output, 1
1771
- assert_xpath '/h1/following-sibling::h2[text()="NAME"]', output, 1
1772
- assert_xpath '/h2[@id="_name"][text()="NAME"]', output, 1
1773
- assert_xpath '/h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]', output, 1
1774
- assert_xpath '/h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]/p[text()="asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats"]', output, 1
1775
- end
1776
- end
1777
-
1778
- context 'Secure Asset Path' do
1779
- test 'allows us to specify a path relative to the current dir' do
1780
- doc = empty_document
1781
- legit_path = Dir.pwd + '/foo'
1782
- assert_equal legit_path, doc.normalize_asset_path(legit_path)
1783
- end
1784
-
1785
- test 'keeps naughty absolute paths from getting outside' do
1786
- naughty_path = "#{disk_root}etc/passwd"
1787
- using_memory_logger do |logger|
1788
- doc = empty_document
1789
- secure_path = doc.normalize_asset_path naughty_path
1790
- refute_equal naughty_path, secure_path
1791
- assert_equal ::File.join(doc.base_dir, 'etc/passwd'), secure_path
1792
- assert_message logger, :WARN, 'path is outside of jail; recovering automatically'
1793
- end
1794
- end
1795
-
1796
- test 'keeps naughty relative paths from getting outside' do
1797
- naughty_path = 'safe/ok/../../../../../etc/passwd'
1798
- using_memory_logger do
1799
- doc = empty_document
1800
- secure_path = doc.normalize_asset_path naughty_path
1801
- refute_equal naughty_path, secure_path
1802
- assert_match(/^#{doc.base_dir}/, secure_path)
1803
- end
1804
- end
1805
-
1806
- test 'should raise an exception when a converter cannot be resolved before conversion' do
1807
- input = <<-EOS
1808
- = Document Title
1809
-
1810
- text
1811
- EOS
1812
- exception = assert_raises NotImplementedError do
1813
- Asciidoctor.convert input, :backend => 'unknownBackend'
1814
- end
1815
- assert_includes exception.message, 'missing converter for backend \'unknownBackend\''
1816
- end
1817
-
1818
- test 'should raise an exception when a converter cannot be resolved while parsing' do
1819
- input = <<-EOS
1820
- = Document Title
1821
-
1822
- == A _Big_ Section
1823
-
1824
- text
1825
- EOS
1826
- exception = assert_raises NotImplementedError do
1827
- Asciidoctor.convert input, :backend => 'unknownBackend'
1828
- end
1829
- assert_includes exception.message, 'missing converter for backend \'unknownBackend\''
1830
- end
1831
- end
1832
-
1833
- context 'Timing report' do
1834
- test 'print_report does not lose precision' do
1835
- timings = Asciidoctor::Timings.new
1836
- log = timings.instance_variable_get(:@log)
1837
- log[:read] = 0.00001
1838
- log[:parse] = 0.00003
1839
- log[:convert] = 0.00005
1840
- timings.print_report(sink = StringIO.new)
1841
- expect = ['0.00004', '0.00005', '0.00009']
1842
- result = sink.string.split("\n").map {|l| l.sub(/.*:\s*([\d.]+)/, '\1') }
1843
- assert_equal expect, result
1844
- end
1845
-
1846
- test 'print_report should print 0 for untimed phases' do
1847
- Asciidoctor::Timings.new.print_report(sink = StringIO.new)
1848
- expect = [].fill('0.00000', 0..2)
1849
- result = sink.string.split("\n").map {|l| l.sub(/.*:\s*([\d.]+)/, '\1') }
1850
- assert_equal expect, result
1851
- end
1852
- end
1853
- end