asciidoctor 1.5.8 → 2.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +11 -0
  3. data/CHANGELOG.adoc +628 -45
  4. data/LICENSE +2 -1
  5. data/README-de.adoc +28 -38
  6. data/README-fr.adoc +30 -43
  7. data/README-jp.adoc +255 -201
  8. data/README-zh_CN.adoc +40 -44
  9. data/README.adoc +170 -143
  10. data/asciidoctor.gemspec +22 -34
  11. data/bin/asciidoctor +5 -4
  12. data/data/locale/attributes-ar.adoc +4 -3
  13. data/data/locale/attributes-be.adoc +23 -0
  14. data/data/locale/attributes-bg.adoc +4 -3
  15. data/data/locale/attributes-ca.adoc +6 -5
  16. data/data/locale/attributes-cs.adoc +4 -3
  17. data/data/locale/attributes-da.adoc +6 -5
  18. data/data/locale/attributes-de.adoc +6 -5
  19. data/data/locale/attributes-en.adoc +4 -4
  20. data/data/locale/attributes-es.adoc +6 -5
  21. data/data/locale/attributes-fa.adoc +4 -3
  22. data/data/locale/attributes-fi.adoc +4 -3
  23. data/data/locale/attributes-fr.adoc +8 -7
  24. data/data/locale/attributes-hu.adoc +4 -3
  25. data/data/locale/attributes-id.adoc +4 -3
  26. data/data/locale/attributes-it.adoc +6 -5
  27. data/data/locale/attributes-ja.adoc +4 -3
  28. data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
  29. data/data/locale/attributes-nb.adoc +4 -3
  30. data/data/locale/attributes-nl.adoc +6 -5
  31. data/data/locale/attributes-nn.adoc +4 -3
  32. data/data/locale/attributes-pl.adoc +8 -7
  33. data/data/locale/attributes-pt.adoc +6 -5
  34. data/data/locale/attributes-pt_BR.adoc +6 -5
  35. data/data/locale/attributes-ro.adoc +4 -3
  36. data/data/locale/attributes-ru.adoc +6 -5
  37. data/data/locale/attributes-sr.adoc +4 -4
  38. data/data/locale/attributes-sr_Latn.adoc +4 -4
  39. data/data/locale/attributes-sv.adoc +4 -4
  40. data/data/locale/attributes-th.adoc +23 -0
  41. data/data/locale/attributes-tr.adoc +4 -3
  42. data/data/locale/attributes-uk.adoc +6 -5
  43. data/data/locale/attributes-vi.adoc +23 -0
  44. data/data/locale/attributes-zh_CN.adoc +4 -3
  45. data/data/locale/attributes-zh_TW.adoc +4 -3
  46. data/data/reference/syntax.adoc +296 -0
  47. data/data/stylesheets/asciidoctor-default.css +120 -114
  48. data/data/stylesheets/coderay-asciidoctor.css +15 -17
  49. data/lib/asciidoctor/abstract_block.rb +146 -140
  50. data/lib/asciidoctor/abstract_node.rb +152 -170
  51. data/lib/asciidoctor/attribute_list.rb +77 -89
  52. data/lib/asciidoctor/block.rb +29 -28
  53. data/lib/asciidoctor/callouts.rb +4 -2
  54. data/lib/asciidoctor/cli/invoker.rb +20 -24
  55. data/lib/asciidoctor/cli/options.rb +107 -96
  56. data/lib/asciidoctor/cli.rb +3 -2
  57. data/lib/asciidoctor/convert.rb +199 -0
  58. data/lib/asciidoctor/converter/composite.rb +40 -48
  59. data/lib/asciidoctor/converter/docbook5.rb +627 -644
  60. data/lib/asciidoctor/converter/html5.rb +1053 -951
  61. data/lib/asciidoctor/converter/manpage.rb +581 -532
  62. data/lib/asciidoctor/converter/template.rb +232 -271
  63. data/lib/asciidoctor/converter.rb +370 -185
  64. data/lib/asciidoctor/core_ext/float/truncate.rb +20 -0
  65. data/lib/asciidoctor/core_ext/hash/merge.rb +8 -0
  66. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  67. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  68. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  69. data/lib/asciidoctor/core_ext.rb +8 -17
  70. data/lib/asciidoctor/document.rb +503 -461
  71. data/lib/asciidoctor/extensions.rb +127 -174
  72. data/lib/asciidoctor/helpers.rb +184 -107
  73. data/lib/asciidoctor/inline.rb +9 -12
  74. data/lib/asciidoctor/list.rb +11 -29
  75. data/lib/asciidoctor/load.rb +119 -0
  76. data/lib/asciidoctor/logging.rb +22 -17
  77. data/lib/asciidoctor/parser.rb +673 -719
  78. data/lib/asciidoctor/path_resolver.rb +48 -33
  79. data/lib/asciidoctor/reader.rb +383 -338
  80. data/lib/asciidoctor/rouge_ext.rb +39 -0
  81. data/lib/asciidoctor/rx.rb +723 -0
  82. data/lib/asciidoctor/section.rb +17 -16
  83. data/lib/asciidoctor/stylesheets.rb +19 -37
  84. data/lib/asciidoctor/substitutors.rb +926 -1022
  85. data/lib/asciidoctor/syntax_highlighter/coderay.rb +88 -0
  86. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +34 -0
  87. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  88. data/lib/asciidoctor/syntax_highlighter/prettify.rb +30 -0
  89. data/lib/asciidoctor/syntax_highlighter/pygments.rb +157 -0
  90. data/lib/asciidoctor/syntax_highlighter/rouge.rb +143 -0
  91. data/lib/asciidoctor/syntax_highlighter.rb +253 -0
  92. data/lib/asciidoctor/table.rb +152 -114
  93. data/lib/asciidoctor/timings.rb +7 -5
  94. data/lib/asciidoctor/version.rb +2 -1
  95. data/lib/asciidoctor/writer.rb +30 -0
  96. data/lib/asciidoctor.rb +266 -1340
  97. data/man/asciidoctor.1 +49 -47
  98. data/man/asciidoctor.adoc +54 -45
  99. metadata +50 -245
  100. data/CONTRIBUTING.adoc +0 -185
  101. data/Gemfile +0 -60
  102. data/Rakefile +0 -129
  103. data/bin/asciidoctor-safe +0 -15
  104. data/features/open_block.feature +0 -92
  105. data/features/pass_block.feature +0 -66
  106. data/features/step_definitions.rb +0 -49
  107. data/features/text_formatting.feature +0 -57
  108. data/features/xref.feature +0 -1039
  109. data/lib/asciidoctor/converter/base.rb +0 -59
  110. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  111. data/lib/asciidoctor/converter/factory.rb +0 -226
  112. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  113. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  114. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  115. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  116. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  117. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  118. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  119. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  120. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  121. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  122. data/test/api_test.rb +0 -1240
  123. data/test/attribute_list_test.rb +0 -242
  124. data/test/attributes_test.rb +0 -1623
  125. data/test/blocks_test.rb +0 -3870
  126. data/test/converter_test.rb +0 -470
  127. data/test/document_test.rb +0 -1853
  128. data/test/extensions_test.rb +0 -1560
  129. data/test/fixtures/asciidoc_index.txt +0 -521
  130. data/test/fixtures/basic-docinfo-footer.html +0 -6
  131. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  132. data/test/fixtures/basic-docinfo.html +0 -1
  133. data/test/fixtures/basic-docinfo.xml +0 -4
  134. data/test/fixtures/basic.asciidoc +0 -5
  135. data/test/fixtures/chapter-a.adoc +0 -3
  136. data/test/fixtures/child-include.adoc +0 -5
  137. data/test/fixtures/circle.svg +0 -9
  138. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  139. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  140. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  141. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  142. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  143. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  144. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  145. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  146. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  147. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  148. data/test/fixtures/docinfo-footer.html +0 -1
  149. data/test/fixtures/docinfo-footer.xml +0 -9
  150. data/test/fixtures/docinfo.html +0 -1
  151. data/test/fixtures/docinfo.xml +0 -3
  152. data/test/fixtures/doctime-localtime.adoc +0 -2
  153. data/test/fixtures/dot.gif +0 -0
  154. data/test/fixtures/encoding.asciidoc +0 -13
  155. data/test/fixtures/file-with-missing-include.adoc +0 -1
  156. data/test/fixtures/grandchild-include.adoc +0 -3
  157. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  158. data/test/fixtures/include-file.asciidoc +0 -24
  159. data/test/fixtures/include-file.jsx +0 -8
  160. data/test/fixtures/include-file.ml +0 -3
  161. data/test/fixtures/include-file.xml +0 -5
  162. data/test/fixtures/lists.adoc +0 -96
  163. data/test/fixtures/master.adoc +0 -5
  164. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  165. data/test/fixtures/other-chapters.adoc +0 -11
  166. data/test/fixtures/outer-include.adoc +0 -5
  167. data/test/fixtures/parent-include-restricted.adoc +0 -5
  168. data/test/fixtures/parent-include.adoc +0 -5
  169. data/test/fixtures/sample.asciidoc +0 -30
  170. data/test/fixtures/section-a.adoc +0 -4
  171. data/test/fixtures/stylesheets/custom.css +0 -3
  172. data/test/fixtures/subdir/index.adoc +0 -3
  173. data/test/fixtures/subdir/inner-include.adoc +0 -3
  174. data/test/fixtures/subdir/middle-include.adoc +0 -5
  175. data/test/fixtures/subs-docinfo.html +0 -2
  176. data/test/fixtures/subs.adoc +0 -6
  177. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  178. data/test/fixtures/tagged-class.rb +0 -23
  179. data/test/fixtures/tip.gif +0 -0
  180. data/test/fixtures/unclosed-tag.adoc +0 -3
  181. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  182. data/test/invoker_test.rb +0 -745
  183. data/test/links_test.rb +0 -855
  184. data/test/lists_test.rb +0 -5151
  185. data/test/logger_test.rb +0 -211
  186. data/test/manpage_test.rb +0 -660
  187. data/test/options_test.rb +0 -262
  188. data/test/paragraphs_test.rb +0 -562
  189. data/test/parser_test.rb +0 -742
  190. data/test/paths_test.rb +0 -395
  191. data/test/preamble_test.rb +0 -173
  192. data/test/reader_test.rb +0 -2161
  193. data/test/sections_test.rb +0 -3575
  194. data/test/substitutions_test.rb +0 -2066
  195. data/test/tables_test.rb +0 -2036
  196. data/test/test_helper.rb +0 -447
  197. 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