asciidoctor 1.5.6.2 → 1.5.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +330 -143
- data/README-fr.adoc +441 -0
- data/README-jp.adoc +418 -0
- data/README-zh_CN.adoc +430 -0
- data/README.adoc +454 -0
- data/Rakefile +57 -0
- data/asciidoctor.gemspec +7 -1
- data/data/locale/attributes-ar.adoc +22 -0
- data/data/locale/attributes-bg.adoc +22 -0
- data/data/locale/attributes-ca.adoc +22 -0
- data/data/locale/attributes-cs.adoc +22 -0
- data/data/locale/attributes-da.adoc +22 -0
- data/data/locale/attributes-de.adoc +22 -0
- data/data/locale/attributes-en.adoc +23 -0
- data/data/locale/attributes-es.adoc +22 -0
- data/data/locale/attributes-fa.adoc +22 -0
- data/data/locale/attributes-fi.adoc +22 -0
- data/data/locale/attributes-fr.adoc +22 -0
- data/data/locale/attributes-hu.adoc +22 -0
- data/data/locale/attributes-id.adoc +22 -0
- data/data/locale/attributes-it.adoc +22 -0
- data/data/locale/attributes-ja.adoc +22 -0
- data/data/locale/attributes-kr.adoc +22 -0
- data/data/locale/attributes-nb.adoc +22 -0
- data/data/locale/attributes-nl.adoc +22 -0
- data/data/locale/attributes-nn.adoc +22 -0
- data/data/locale/attributes-pl.adoc +22 -0
- data/data/locale/attributes-pt.adoc +22 -0
- data/data/locale/attributes-pt_BR.adoc +22 -0
- data/data/locale/attributes-ro.adoc +22 -0
- data/data/locale/attributes-ru.adoc +22 -0
- data/data/locale/attributes-sr.adoc +22 -0
- data/data/locale/attributes-sr_Latn.adoc +22 -0
- data/data/locale/attributes-tr.adoc +22 -0
- data/data/locale/attributes-uk.adoc +22 -0
- data/data/locale/attributes-zh_CN.adoc +22 -0
- data/data/locale/attributes-zh_TW.adoc +22 -0
- data/data/locale/attributes.adoc +8 -649
- data/data/stylesheets/asciidoctor-default.css +77 -72
- data/features/xref.feature +366 -7
- data/lib/asciidoctor.rb +107 -93
- data/lib/asciidoctor/abstract_block.rb +247 -239
- data/lib/asciidoctor/abstract_node.rb +56 -58
- data/lib/asciidoctor/block.rb +3 -3
- data/lib/asciidoctor/callouts.rb +1 -1
- data/lib/asciidoctor/cli/invoker.rb +36 -9
- data/lib/asciidoctor/cli/options.rb +63 -25
- data/lib/asciidoctor/converter.rb +23 -13
- data/lib/asciidoctor/converter/base.rb +4 -0
- data/lib/asciidoctor/converter/docbook45.rb +16 -9
- data/lib/asciidoctor/converter/docbook5.rb +115 -97
- data/lib/asciidoctor/converter/factory.rb +29 -31
- data/lib/asciidoctor/converter/html5.rb +229 -192
- data/lib/asciidoctor/converter/manpage.rb +72 -50
- data/lib/asciidoctor/converter/template.rb +12 -12
- data/lib/asciidoctor/core_ext.rb +5 -1
- data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +6 -0
- data/lib/asciidoctor/document.rb +168 -77
- data/lib/asciidoctor/extensions.rb +79 -47
- data/lib/asciidoctor/helpers.rb +33 -11
- data/lib/asciidoctor/inline.rb +3 -2
- data/lib/asciidoctor/list.rb +2 -1
- data/lib/asciidoctor/logging.rb +122 -0
- data/lib/asciidoctor/parser.rb +406 -382
- data/lib/asciidoctor/path_resolver.rb +169 -162
- data/lib/asciidoctor/reader.rb +166 -121
- data/lib/asciidoctor/section.rb +45 -28
- data/lib/asciidoctor/stylesheets.rb +13 -5
- data/lib/asciidoctor/substitutors.rb +328 -254
- data/lib/asciidoctor/table.rb +105 -48
- data/lib/asciidoctor/timings.rb +34 -6
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +41 -23
- data/man/asciidoctor.adoc +14 -8
- data/test/api_test.rb +1004 -0
- data/test/attributes_test.rb +241 -50
- data/test/blocks_test.rb +549 -124
- data/test/converter_test.rb +170 -78
- data/test/document_test.rb +208 -767
- data/test/extensions_test.rb +188 -53
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +1 -1
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +1 -1
- data/test/fixtures/file-with-missing-include.adoc +1 -0
- data/test/fixtures/include-file.jsx +8 -0
- data/test/fixtures/lists.adoc +96 -0
- data/test/fixtures/other-chapters.adoc +11 -0
- data/test/fixtures/outer-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +5 -1
- data/test/fixtures/subdir/index.adoc +3 -0
- data/test/fixtures/subdir/inner-include.adoc +3 -0
- data/test/fixtures/subdir/middle-include.adoc +5 -0
- data/test/fixtures/tagged-class-enclosed.rb +0 -1
- data/test/fixtures/unclosed-tag.adoc +3 -0
- data/test/fixtures/unexpected-end-tag.adoc +4 -0
- data/test/invoker_test.rb +101 -40
- data/test/links_test.rb +266 -72
- data/test/lists_test.rb +243 -45
- data/test/logger_test.rb +211 -0
- data/test/manpage_test.rb +124 -6
- data/test/options_test.rb +46 -1
- data/test/paragraphs_test.rb +23 -10
- data/test/parser_test.rb +30 -1
- data/test/paths_test.rb +115 -33
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +337 -81
- data/test/sections_test.rb +656 -72
- data/test/substitutions_test.rb +182 -57
- data/test/tables_test.rb +324 -57
- data/test/test_helper.rb +77 -32
- data/test/text_test.rb +7 -7
- metadata +67 -3
data/test/converter_test.rb
CHANGED
@@ -9,59 +9,65 @@ context 'Converter' do
|
|
9
9
|
|
10
10
|
context 'View options' do
|
11
11
|
test 'should set Haml format to html5 for html5 backend' do
|
12
|
-
doc = Asciidoctor::Document.new [], :template_dir =>
|
13
|
-
|
12
|
+
doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
|
13
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
14
14
|
selected = doc.converter.find_converter('paragraph')
|
15
|
-
|
16
|
-
|
15
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
16
|
+
assert_kind_of Tilt::HamlTemplate, selected.templates['paragraph']
|
17
17
|
assert_equal :html5, selected.templates['paragraph'].options[:format]
|
18
18
|
end
|
19
19
|
|
20
20
|
test 'should set Haml format to xhtml for docbook backend' do
|
21
|
-
doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir =>
|
22
|
-
|
21
|
+
doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
|
22
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
23
23
|
selected = doc.converter.find_converter('paragraph')
|
24
|
-
|
25
|
-
|
24
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
25
|
+
assert_kind_of Tilt::HamlTemplate, selected.templates['paragraph']
|
26
26
|
assert_equal :xhtml, selected.templates['paragraph'].options[:format]
|
27
27
|
end
|
28
28
|
|
29
29
|
test 'should configure Slim to resolve includes in specified template dirs' do
|
30
|
-
template_dirs = [
|
31
|
-
File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'),
|
32
|
-
File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim-overrides'),
|
33
|
-
]
|
30
|
+
template_dirs = [(fixture_path 'custom-backends/slim'), (fixture_path 'custom-backends/slim-overrides')]
|
34
31
|
doc = Asciidoctor::Document.new [], :template_dirs => template_dirs, :template_cache => false
|
35
|
-
|
32
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
36
33
|
selected = doc.converter.find_converter('paragraph')
|
37
|
-
|
38
|
-
|
34
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
35
|
+
assert_kind_of Slim::Template, selected.templates['paragraph']
|
39
36
|
assert_equal template_dirs.reverse.map {|dir| File.expand_path dir }, selected.templates['paragraph'].options[:include_dirs]
|
40
37
|
end
|
41
38
|
|
39
|
+
test 'should coerce template_dirs option to an Array' do
|
40
|
+
template_dirs = fixture_path 'custom-backends/slim'
|
41
|
+
doc = Asciidoctor::Document.new [], :template_dirs => template_dirs, :template_cache => false
|
42
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
43
|
+
selected = doc.converter.find_converter('paragraph')
|
44
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
45
|
+
assert_kind_of Array, (selected.instance_variable_get :@template_dirs)
|
46
|
+
end
|
47
|
+
|
42
48
|
test 'should set Slim format to html for html5 backend' do
|
43
|
-
doc = Asciidoctor::Document.new [], :template_dir =>
|
44
|
-
|
49
|
+
doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false
|
50
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
45
51
|
selected = doc.converter.find_converter('paragraph')
|
46
|
-
|
47
|
-
|
52
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
53
|
+
assert_kind_of Slim::Template, selected.templates['paragraph']
|
48
54
|
assert_equal :html, selected.templates['paragraph'].options[:format]
|
49
55
|
end
|
50
56
|
|
51
57
|
test 'should set Slim format to nil for docbook backend' do
|
52
|
-
doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir =>
|
53
|
-
|
58
|
+
doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false
|
59
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
54
60
|
selected = doc.converter.find_converter('paragraph')
|
55
|
-
|
56
|
-
|
61
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
62
|
+
assert_kind_of Slim::Template, selected.templates['paragraph']
|
57
63
|
assert_nil selected.templates['paragraph'].options[:format]
|
58
64
|
end
|
59
65
|
|
60
66
|
test 'should set safe mode of Slim AsciiDoc engine to match document safe mode when Slim >= 3' do
|
61
|
-
doc = Asciidoctor::Document.new [], :template_dir =>
|
62
|
-
|
67
|
+
doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false, :safe => :unsafe
|
68
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
63
69
|
selected = doc.converter.find_converter('paragraph')
|
64
|
-
|
70
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
65
71
|
slim_asciidoc_opts = selected.instance_variable_get(:@engine_options)[:slim][:asciidoc]
|
66
72
|
if ::Slim::VERSION >= '3.0'
|
67
73
|
assert_equal({ :safe => Asciidoctor::SafeMode::UNSAFE }, slim_asciidoc_opts)
|
@@ -71,20 +77,20 @@ context 'Converter' do
|
|
71
77
|
end
|
72
78
|
|
73
79
|
test 'should support custom template engine options for known engine' do
|
74
|
-
doc = Asciidoctor::Document.new [], :template_dir =>
|
75
|
-
|
80
|
+
doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false, :template_engine_options => { :slim => { :pretty => true } }
|
81
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
76
82
|
selected = doc.converter.find_converter('paragraph')
|
77
|
-
|
78
|
-
|
83
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
84
|
+
assert_kind_of Slim::Template, selected.templates['paragraph']
|
79
85
|
assert_equal true, selected.templates['paragraph'].options[:pretty]
|
80
86
|
end
|
81
87
|
|
82
88
|
test 'should support custom template engine options' do
|
83
|
-
doc = Asciidoctor::Document.new [], :template_dir =>
|
84
|
-
|
89
|
+
doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false, :template_engine_options => { :slim => { :pretty => true } }
|
90
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
85
91
|
selected = doc.converter.find_converter('paragraph')
|
86
|
-
|
87
|
-
|
92
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
93
|
+
assert_kind_of Slim::Template, selected.templates['paragraph']
|
88
94
|
assert_equal false, selected.templates['paragraph'].options[:sort_attrs]
|
89
95
|
assert_equal true, selected.templates['paragraph'].options[:pretty]
|
90
96
|
end
|
@@ -92,43 +98,43 @@ context 'Converter' do
|
|
92
98
|
|
93
99
|
context 'Custom backends' do
|
94
100
|
test 'should load Haml templates for default backend' do
|
95
|
-
doc = Asciidoctor::Document.new [], :template_dir =>
|
96
|
-
|
101
|
+
doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
|
102
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
97
103
|
['paragraph', 'sidebar'].each do |node_name|
|
98
104
|
selected = doc.converter.find_converter node_name
|
99
|
-
|
100
|
-
|
105
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
106
|
+
assert_kind_of Tilt::HamlTemplate, selected.templates[node_name]
|
101
107
|
assert_equal %(block_#{node_name}.html.haml), File.basename(selected.templates[node_name].file)
|
102
108
|
end
|
103
109
|
end
|
104
110
|
|
105
111
|
test 'should set outfilesuffix according to backend info' do
|
106
112
|
doc = Asciidoctor.load 'content'
|
107
|
-
doc.
|
113
|
+
doc.convert
|
108
114
|
assert_equal '.html', doc.attributes['outfilesuffix']
|
109
115
|
|
110
|
-
doc = Asciidoctor.load 'content', :template_dir =>
|
111
|
-
doc.
|
116
|
+
doc = Asciidoctor.load 'content', :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
|
117
|
+
doc.convert
|
112
118
|
assert_equal '.html', doc.attributes['outfilesuffix']
|
113
119
|
end
|
114
120
|
|
115
121
|
test 'should not override outfilesuffix attribute if locked' do
|
116
122
|
doc = Asciidoctor.load 'content', :attributes => {'outfilesuffix' => '.foo'}
|
117
|
-
doc.
|
123
|
+
doc.convert
|
118
124
|
assert_equal '.foo', doc.attributes['outfilesuffix']
|
119
125
|
|
120
|
-
doc = Asciidoctor.load 'content', :template_dir =>
|
121
|
-
doc.
|
126
|
+
doc = Asciidoctor.load 'content', :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false, :attributes => {'outfilesuffix' => '.foo'}
|
127
|
+
doc.convert
|
122
128
|
assert_equal '.foo', doc.attributes['outfilesuffix']
|
123
129
|
end
|
124
130
|
|
125
131
|
test 'should load Haml templates for docbook45 backend' do
|
126
|
-
doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir =>
|
127
|
-
|
132
|
+
doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
|
133
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
128
134
|
['paragraph'].each do |node_name|
|
129
135
|
selected = doc.converter.find_converter node_name
|
130
|
-
|
131
|
-
|
136
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
137
|
+
assert_kind_of Tilt::HamlTemplate, selected.templates[node_name]
|
132
138
|
assert_equal %(block_#{node_name}.xml.haml), File.basename(selected.templates[node_name].file)
|
133
139
|
end
|
134
140
|
end
|
@@ -148,7 +154,7 @@ Sidebar content
|
|
148
154
|
****
|
149
155
|
EOS
|
150
156
|
|
151
|
-
output = render_embedded_string input, :template_dir =>
|
157
|
+
output = render_embedded_string input, :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
|
152
158
|
assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p', output, 1
|
153
159
|
assert_xpath '//aside', output, 1
|
154
160
|
assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p/following-sibling::aside', output, 1
|
@@ -161,12 +167,12 @@ Sidebar content
|
|
161
167
|
# clear out any cache, just to be sure
|
162
168
|
Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
|
163
169
|
|
164
|
-
template_dir =
|
170
|
+
template_dir = fixture_path 'custom-backends/haml'
|
165
171
|
doc = Asciidoctor::Document.new [], :template_dir => template_dir
|
166
172
|
doc.converter
|
167
173
|
caches = Asciidoctor::Converter::TemplateConverter.caches
|
168
174
|
if defined? ::ThreadSafe::Cache
|
169
|
-
|
175
|
+
assert_kind_of ::ThreadSafe::Cache, caches[:templates]
|
170
176
|
refute_empty caches[:templates]
|
171
177
|
paragraph_template_before = caches[:templates].values.find {|t| File.basename(t.file) == 'block_paragraph.html.haml' }
|
172
178
|
refute_nil paragraph_template_before
|
@@ -194,7 +200,7 @@ Sidebar content
|
|
194
200
|
end
|
195
201
|
|
196
202
|
test 'should use custom cache to cache templates' do
|
197
|
-
template_dir =
|
203
|
+
template_dir = fixture_path 'custom-backends/haml'
|
198
204
|
Asciidoctor::PathResolver.new.system_path(File.join(template_dir, 'html5', 'block_paragraph.html.haml'), nil)
|
199
205
|
caches = { :scans => {}, :templates => {} }
|
200
206
|
doc = Asciidoctor::Document.new [], :template_dir => template_dir, :template_cache => caches
|
@@ -203,7 +209,7 @@ Sidebar content
|
|
203
209
|
refute_empty caches[:templates]
|
204
210
|
paragraph_template = caches[:templates].values.find {|t| File.basename(t.file) == 'block_paragraph.html.haml' }
|
205
211
|
refute_nil paragraph_template
|
206
|
-
|
212
|
+
assert_kind_of ::Tilt::HamlTemplate, paragraph_template
|
207
213
|
end
|
208
214
|
|
209
215
|
test 'should be able to disable template cache' do
|
@@ -211,8 +217,7 @@ Sidebar content
|
|
211
217
|
# clear out any cache, just to be sure
|
212
218
|
Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
|
213
219
|
|
214
|
-
doc = Asciidoctor::Document.new [], :template_dir =>
|
215
|
-
:template_cache => false
|
220
|
+
doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/haml'), :template_cache => false
|
216
221
|
doc.converter
|
217
222
|
caches = Asciidoctor::Converter::TemplateConverter.caches
|
218
223
|
assert caches.empty? || caches[:scans].empty?
|
@@ -224,51 +229,51 @@ Sidebar content
|
|
224
229
|
end
|
225
230
|
|
226
231
|
test 'should load ERB templates using ERBTemplate if eruby is not set' do
|
227
|
-
doc = Asciidoctor::Document.new [], :template_dir =>
|
228
|
-
|
232
|
+
doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/erb'), :template_cache => false
|
233
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
229
234
|
['paragraph'].each do |node_name|
|
230
235
|
selected = doc.converter.find_converter node_name
|
231
|
-
|
236
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
232
237
|
template = selected.templates[node_name]
|
233
|
-
|
234
|
-
|
235
|
-
|
238
|
+
assert_kind_of Tilt::ERBTemplate, template
|
239
|
+
refute_kind_of Tilt::ErubisTemplate, template
|
240
|
+
assert_kind_of ::ERB, template.instance_variable_get('@engine')
|
236
241
|
assert_equal %(block_#{node_name}.html.erb), File.basename(selected.templates[node_name].file)
|
237
242
|
end
|
238
243
|
end
|
239
244
|
|
240
245
|
test 'should load ERB templates using ErubisTemplate if eruby is set to erubis' do
|
241
|
-
doc = Asciidoctor::Document.new [], :template_dir =>
|
242
|
-
|
246
|
+
doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/erb'), :template_cache => false, :eruby => 'erubis'
|
247
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
243
248
|
['paragraph'].each do |node_name|
|
244
249
|
selected = doc.converter.find_converter node_name
|
245
|
-
|
250
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
246
251
|
template = selected.templates[node_name]
|
247
|
-
|
248
|
-
|
249
|
-
|
252
|
+
assert_kind_of Tilt::ERBTemplate, template
|
253
|
+
assert_kind_of Tilt::ErubisTemplate, template
|
254
|
+
assert_kind_of ::Erubis::FastEruby, template.instance_variable_get('@engine')
|
250
255
|
assert_equal %(block_#{node_name}.html.erb), File.basename(selected.templates[node_name].file)
|
251
256
|
end
|
252
257
|
end
|
253
258
|
|
254
259
|
test 'should load Slim templates for default backend' do
|
255
|
-
doc = Asciidoctor::Document.new [], :template_dir =>
|
256
|
-
|
260
|
+
doc = Asciidoctor::Document.new [], :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false
|
261
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
257
262
|
['paragraph', 'sidebar'].each do |node_name|
|
258
263
|
selected = doc.converter.find_converter node_name
|
259
|
-
|
260
|
-
|
264
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
265
|
+
assert_kind_of Slim::Template, selected.templates[node_name]
|
261
266
|
assert_equal %(block_#{node_name}.html.slim), File.basename(selected.templates[node_name].file)
|
262
267
|
end
|
263
268
|
end
|
264
269
|
|
265
270
|
test 'should load Slim templates for docbook45 backend' do
|
266
|
-
doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir =>
|
267
|
-
|
271
|
+
doc = Asciidoctor::Document.new [], :backend => 'docbook45', :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false
|
272
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
268
273
|
['paragraph'].each do |node_name|
|
269
274
|
selected = doc.converter.find_converter node_name
|
270
|
-
|
271
|
-
|
275
|
+
assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
|
276
|
+
assert_kind_of Slim::Template, selected.templates[node_name]
|
272
277
|
assert_equal %(block_#{node_name}.xml.slim), File.basename(selected.templates[node_name].file)
|
273
278
|
end
|
274
279
|
end
|
@@ -288,7 +293,7 @@ Sidebar content
|
|
288
293
|
****
|
289
294
|
EOS
|
290
295
|
|
291
|
-
output = render_embedded_string input, :template_dir =>
|
296
|
+
output = render_embedded_string input, :template_dir => (fixture_path 'custom-backends/slim'), :template_cache => false
|
292
297
|
assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p', output, 1
|
293
298
|
assert_xpath '//aside', output, 1
|
294
299
|
assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p/following-sibling::aside', output, 1
|
@@ -350,6 +355,93 @@ content
|
|
350
355
|
end
|
351
356
|
end
|
352
357
|
|
358
|
+
test 'should map handles? method on converter to respond_to? by default' do
|
359
|
+
class CustomConverterC
|
360
|
+
include Asciidoctor::Converter
|
361
|
+
def paragraph node
|
362
|
+
'paragraph'
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
converter = CustomConverterC.new 'myhtml'
|
367
|
+
assert_respond_to converter, :handles?
|
368
|
+
assert converter.handles?(:paragraph)
|
369
|
+
end
|
370
|
+
|
371
|
+
test 'should not configure converter to support templates by default' do
|
372
|
+
input = <<-EOS
|
373
|
+
paragraph
|
374
|
+
EOS
|
375
|
+
|
376
|
+
begin
|
377
|
+
Asciidoctor::Converter::Factory.unregister_all
|
378
|
+
class CustomConverterD
|
379
|
+
include Asciidoctor::Converter
|
380
|
+
register_for 'myhtml'
|
381
|
+
def convert node, transform = nil, opts = {}
|
382
|
+
transform ||= node.node_name
|
383
|
+
send transform, node
|
384
|
+
end
|
385
|
+
|
386
|
+
def document node
|
387
|
+
['<!DOCTYPE html>', '<html>', '<body>', node.content, '</body>', '</html>'] * %(\n)
|
388
|
+
end
|
389
|
+
|
390
|
+
def paragraph node
|
391
|
+
['<div class="paragraph">', %(<p>#{node.content}</p>), '</div>'] * %(\n)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
doc = document_from_string input, :backend => 'myhtml', :template_dir => (fixture_path 'custom-backends/slim/html5'), :template_cache => false
|
396
|
+
assert_kind_of CustomConverterD, doc.converter
|
397
|
+
refute doc.converter.supports_templates?
|
398
|
+
output = doc.convert
|
399
|
+
assert_xpath '//*[@class="paragraph"]/p[text()="paragraph"]', output, 1
|
400
|
+
ensure
|
401
|
+
Asciidoctor::Converter::Factory.unregister_all
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
test 'should wrap converter in composite converter with template converter if it declares that it supports templates' do
|
406
|
+
input = <<-EOS
|
407
|
+
paragraph
|
408
|
+
EOS
|
409
|
+
|
410
|
+
begin
|
411
|
+
Asciidoctor::Converter::Factory.unregister_all
|
412
|
+
class CustomConverterE
|
413
|
+
include Asciidoctor::Converter
|
414
|
+
register_for 'myhtml'
|
415
|
+
|
416
|
+
def initialize *args
|
417
|
+
super
|
418
|
+
supports_templates
|
419
|
+
end
|
420
|
+
|
421
|
+
def convert node, transform = nil, opts = {}
|
422
|
+
transform ||= node.node_name
|
423
|
+
send transform, node
|
424
|
+
end
|
425
|
+
|
426
|
+
def document node
|
427
|
+
['<!DOCTYPE html>', '<html>', '<body>', node.content, '</body>', '</html>'] * %(\n)
|
428
|
+
end
|
429
|
+
|
430
|
+
def paragraph node
|
431
|
+
['<div class="paragraph">', %(<p>#{node.content}</p>), '</div>'] * %(\n)
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
doc = document_from_string input, :backend => 'myhtml', :template_dir => (fixture_path 'custom-backends/slim/html5'), :template_cache => false
|
436
|
+
assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
|
437
|
+
output = doc.convert
|
438
|
+
assert_xpath '//*[@class="paragraph"]/p[text()="paragraph"]', output, 0
|
439
|
+
assert_xpath '//body/p[text()="paragraph"]', output, 1
|
440
|
+
ensure
|
441
|
+
Asciidoctor::Converter::Factory.unregister_all
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
353
445
|
test 'should fall back to catch all converter' do
|
354
446
|
input = <<-EOS
|
355
447
|
content
|
@@ -358,7 +450,7 @@ content
|
|
358
450
|
begin
|
359
451
|
Asciidoctor::Converter::Factory.unregister_all
|
360
452
|
|
361
|
-
class
|
453
|
+
class CustomConverterF
|
362
454
|
include Asciidoctor::Converter
|
363
455
|
register_for '*'
|
364
456
|
def convert node, name = nil
|
@@ -367,7 +459,7 @@ content
|
|
367
459
|
end
|
368
460
|
|
369
461
|
converters = Asciidoctor::Converter::Factory.converters
|
370
|
-
assert converters['*'] ==
|
462
|
+
assert converters['*'] == CustomConverterF
|
371
463
|
output = render_string input, :backend => 'foobaz'
|
372
464
|
assert 'foobaz content', output
|
373
465
|
ensure
|
data/test/document_test.rb
CHANGED
@@ -131,718 +131,6 @@ content
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
-
context 'Load APIs' do
|
135
|
-
test 'should load input file' do
|
136
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
137
|
-
doc = File.open(sample_input_path) {|file| Asciidoctor.load file, :safe => Asciidoctor::SafeMode::SAFE }
|
138
|
-
assert_equal 'Document Title', doc.doctitle
|
139
|
-
assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
|
140
|
-
assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
|
141
|
-
assert_equal '.asciidoc', doc.attr('docfilesuffix')
|
142
|
-
end
|
143
|
-
|
144
|
-
test 'should load input file from filename' do
|
145
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
146
|
-
doc = Asciidoctor.load_file(sample_input_path, :safe => Asciidoctor::SafeMode::SAFE)
|
147
|
-
assert_equal 'Document Title', doc.doctitle
|
148
|
-
assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
|
149
|
-
assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
|
150
|
-
assert_equal '.asciidoc', doc.attr('docfilesuffix')
|
151
|
-
end
|
152
|
-
|
153
|
-
test 'should not load invalid file' do
|
154
|
-
sample_input_path = fixture_path('hello-asciidoctor.pdf')
|
155
|
-
exception = assert_raises ArgumentError do
|
156
|
-
Asciidoctor.load_file(sample_input_path, :safe => Asciidoctor::SafeMode::SAFE)
|
157
|
-
end
|
158
|
-
assert_match(/Failed to load AsciiDoc document/, exception.message)
|
159
|
-
# verify we have the correct backtrace (should be in at least first 5 lines)
|
160
|
-
assert_match((RUBY_ENGINE == 'rbx' ? /parser\.rb/ : /helpers\.rb/), exception.backtrace[0..4].join("\n"))
|
161
|
-
end if RUBY_MIN_VERSION_1_9
|
162
|
-
|
163
|
-
test 'should load input IO' do
|
164
|
-
input = StringIO.new(<<-EOS)
|
165
|
-
Document Title
|
166
|
-
==============
|
167
|
-
|
168
|
-
preamble
|
169
|
-
EOS
|
170
|
-
doc = Asciidoctor.load(input, :safe => Asciidoctor::SafeMode::SAFE)
|
171
|
-
assert_equal 'Document Title', doc.doctitle
|
172
|
-
refute doc.attr?('docfile')
|
173
|
-
assert_equal doc.base_dir, doc.attr('docdir')
|
174
|
-
end
|
175
|
-
|
176
|
-
test 'should load input string' do
|
177
|
-
input = <<-EOS
|
178
|
-
Document Title
|
179
|
-
==============
|
180
|
-
|
181
|
-
preamble
|
182
|
-
EOS
|
183
|
-
doc = Asciidoctor.load(input, :safe => Asciidoctor::SafeMode::SAFE)
|
184
|
-
assert_equal 'Document Title', doc.doctitle
|
185
|
-
refute doc.attr?('docfile')
|
186
|
-
assert_equal doc.base_dir, doc.attr('docdir')
|
187
|
-
end
|
188
|
-
|
189
|
-
test 'should load input string array' do
|
190
|
-
input = <<-EOS
|
191
|
-
Document Title
|
192
|
-
==============
|
193
|
-
|
194
|
-
preamble
|
195
|
-
EOS
|
196
|
-
doc = Asciidoctor.load(input.lines.entries, :safe => Asciidoctor::SafeMode::SAFE)
|
197
|
-
assert_equal 'Document Title', doc.doctitle
|
198
|
-
refute doc.attr?('docfile')
|
199
|
-
assert_equal doc.base_dir, doc.attr('docdir')
|
200
|
-
end
|
201
|
-
|
202
|
-
test 'should accept attributes as array' do
|
203
|
-
# NOTE there's a tab character before idseparator
|
204
|
-
doc = Asciidoctor.load('text', :attributes => %w(toc sectnums source-highlighter=coderay idprefix idseparator=-))
|
205
|
-
assert_kind_of Hash, doc.attributes
|
206
|
-
assert doc.attr?('toc')
|
207
|
-
assert_equal '', doc.attr('toc')
|
208
|
-
assert doc.attr?('sectnums')
|
209
|
-
assert_equal '', doc.attr('sectnums')
|
210
|
-
assert doc.attr?('source-highlighter')
|
211
|
-
assert_equal 'coderay', doc.attr('source-highlighter')
|
212
|
-
assert doc.attr?('idprefix')
|
213
|
-
assert_equal '', doc.attr('idprefix')
|
214
|
-
assert doc.attr?('idseparator')
|
215
|
-
assert_equal '-', doc.attr('idseparator')
|
216
|
-
end
|
217
|
-
|
218
|
-
test 'should accept attributes as empty array' do
|
219
|
-
doc = Asciidoctor.load('text', :attributes => [])
|
220
|
-
assert_kind_of Hash, doc.attributes
|
221
|
-
end
|
222
|
-
|
223
|
-
test 'should accept attributes as string' do
|
224
|
-
doc = Asciidoctor.load('text', :attributes => 'toc sectnums
|
225
|
-
source-highlighter=coderay
|
226
|
-
idprefix
|
227
|
-
idseparator=-')
|
228
|
-
assert_kind_of Hash, doc.attributes
|
229
|
-
assert doc.attr?('toc')
|
230
|
-
assert_equal '', doc.attr('toc')
|
231
|
-
assert doc.attr?('sectnums')
|
232
|
-
assert_equal '', doc.attr('sectnums')
|
233
|
-
assert doc.attr?('source-highlighter')
|
234
|
-
assert_equal 'coderay', doc.attr('source-highlighter')
|
235
|
-
assert doc.attr?('idprefix')
|
236
|
-
assert_equal '', doc.attr('idprefix')
|
237
|
-
assert doc.attr?('idseparator')
|
238
|
-
assert_equal '-', doc.attr('idseparator')
|
239
|
-
end
|
240
|
-
|
241
|
-
test 'should accept values containing spaces in attributes string' do
|
242
|
-
doc = Asciidoctor.load('text', :attributes => %(idprefix idseparator=- note-caption=Note\\ to\\\tself toc))
|
243
|
-
assert_kind_of Hash, doc.attributes
|
244
|
-
assert doc.attr?('idprefix')
|
245
|
-
assert_equal '', doc.attr('idprefix')
|
246
|
-
assert doc.attr?('idseparator')
|
247
|
-
assert_equal '-', doc.attr('idseparator')
|
248
|
-
assert doc.attr?('note-caption')
|
249
|
-
assert_equal "Note to\tself", doc.attr('note-caption')
|
250
|
-
end
|
251
|
-
|
252
|
-
test 'should accept attributes as empty string' do
|
253
|
-
doc = Asciidoctor.load('text', :attributes => '')
|
254
|
-
assert_kind_of Hash, doc.attributes
|
255
|
-
end
|
256
|
-
|
257
|
-
test 'should accept attributes as nil' do
|
258
|
-
doc = Asciidoctor.load('text', :attributes => nil)
|
259
|
-
assert_kind_of Hash, doc.attributes
|
260
|
-
end
|
261
|
-
|
262
|
-
test 'should accept attributes if hash like' do
|
263
|
-
class Hashish
|
264
|
-
def initialize
|
265
|
-
@table = {'toc' => ''}
|
266
|
-
end
|
267
|
-
|
268
|
-
def keys
|
269
|
-
@table.keys
|
270
|
-
end
|
271
|
-
|
272
|
-
def [](key)
|
273
|
-
@table[key]
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
doc = Asciidoctor.load('text', :attributes => Hashish.new)
|
278
|
-
assert_kind_of Hash, doc.attributes
|
279
|
-
assert doc.attributes.has_key?('toc')
|
280
|
-
end
|
281
|
-
|
282
|
-
test 'should output timestamps by default' do
|
283
|
-
doc = document_from_string 'text', :backend => :html5, :attributes => nil
|
284
|
-
result = doc.convert
|
285
|
-
assert doc.attr?('docdate')
|
286
|
-
refute doc.attr? 'reproducible'
|
287
|
-
assert_xpath '//div[@id="footer-text" and contains(string(.//text()), "Last updated")]', result, 1
|
288
|
-
end
|
289
|
-
|
290
|
-
test 'should not output timestamps if reproducible attribute is set in HTML 5' do
|
291
|
-
doc = document_from_string 'text', :backend => :html5, :attributes => { 'reproducible' => '' }
|
292
|
-
result = doc.convert
|
293
|
-
assert doc.attr?('docdate')
|
294
|
-
assert doc.attr?('reproducible')
|
295
|
-
assert_xpath '//div[@id="footer-text" and contains(string(.//text()), "Last updated")]', result, 0
|
296
|
-
end
|
297
|
-
|
298
|
-
test 'should not output timestamps if reproducible attribute is set in DocBook' do
|
299
|
-
doc = document_from_string 'text', :backend => :docbook, :attributes => { 'reproducible' => '' }
|
300
|
-
result = doc.convert
|
301
|
-
assert doc.attr?('docdate')
|
302
|
-
assert doc.attr?('reproducible')
|
303
|
-
assert_xpath '/article/info/date', result, 0
|
304
|
-
end
|
305
|
-
|
306
|
-
test 'should not modify options argument' do
|
307
|
-
options = {
|
308
|
-
:safe => Asciidoctor::SafeMode::SAFE
|
309
|
-
}
|
310
|
-
options.freeze
|
311
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
312
|
-
begin
|
313
|
-
Asciidoctor.load_file sample_input_path, options
|
314
|
-
rescue
|
315
|
-
flunk %(options argument should not be modified)
|
316
|
-
end
|
317
|
-
end
|
318
|
-
|
319
|
-
test 'should not modify attributes Hash argument' do
|
320
|
-
attributes = {}
|
321
|
-
attributes.freeze
|
322
|
-
options = {
|
323
|
-
:safe => Asciidoctor::SafeMode::SAFE,
|
324
|
-
:attributes => attributes
|
325
|
-
}
|
326
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
327
|
-
begin
|
328
|
-
Asciidoctor.load_file sample_input_path, options
|
329
|
-
rescue
|
330
|
-
flunk %(attributes argument should not be modified)
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
test 'should track file and line information with blocks if sourcemap option is set' do
|
335
|
-
doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :sourcemap => true
|
336
|
-
|
337
|
-
section_1 = doc.sections[0]
|
338
|
-
assert_equal 'Section A', section_1.title
|
339
|
-
refute_nil section_1.source_location
|
340
|
-
assert_equal 'sample.asciidoc', section_1.file
|
341
|
-
assert_equal 10, section_1.lineno
|
342
|
-
|
343
|
-
section_2 = doc.sections[1]
|
344
|
-
assert_equal 'Section B', section_2.title
|
345
|
-
refute_nil section_2.source_location
|
346
|
-
assert_equal 'sample.asciidoc', section_2.file
|
347
|
-
assert_equal 18, section_2.lineno
|
348
|
-
|
349
|
-
last_block = section_2.blocks[-1]
|
350
|
-
assert_equal :ulist, last_block.context
|
351
|
-
refute_nil last_block.source_location
|
352
|
-
assert_equal 'sample.asciidoc', last_block.file
|
353
|
-
assert_equal 23, last_block.lineno
|
354
|
-
|
355
|
-
doc = Asciidoctor.load_file fixture_path('master.adoc'), :sourcemap => true, :safe => :safe
|
356
|
-
|
357
|
-
section_1 = doc.sections[0]
|
358
|
-
assert_equal 'Chapter A', section_1.title
|
359
|
-
refute_nil section_1.source_location
|
360
|
-
assert_equal fixture_path('chapter-a.adoc'), section_1.file
|
361
|
-
assert_equal 1, section_1.lineno
|
362
|
-
end
|
363
|
-
|
364
|
-
test 'should assign correct source location if section occurs on last line of input' do
|
365
|
-
input = <<-EOS
|
366
|
-
= Document Title
|
367
|
-
|
368
|
-
== Section A
|
369
|
-
|
370
|
-
content
|
371
|
-
|
372
|
-
== Section B
|
373
|
-
EOS
|
374
|
-
|
375
|
-
doc = document_from_string input, :sourcemap => true
|
376
|
-
assert_equal [1, 3, 7], (doc.find_by :context => :section).map(&:lineno)
|
377
|
-
end
|
378
|
-
|
379
|
-
test 'should allow sourcemap option on document to be modified' do
|
380
|
-
doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :parse => false
|
381
|
-
doc.sourcemap = true
|
382
|
-
doc = doc.parse
|
383
|
-
|
384
|
-
section_1 = doc.sections[0]
|
385
|
-
assert_equal 'Section A', section_1.title
|
386
|
-
refute_nil section_1.source_location
|
387
|
-
assert_equal 'sample.asciidoc', section_1.file
|
388
|
-
assert_equal 10, section_1.lineno
|
389
|
-
end
|
390
|
-
|
391
|
-
test 'find_by should return Array of blocks anywhere in document tree that match criteria' do
|
392
|
-
input = <<-EOS
|
393
|
-
= Document Title
|
394
|
-
|
395
|
-
preamble
|
396
|
-
|
397
|
-
== Section A
|
398
|
-
|
399
|
-
paragraph
|
400
|
-
|
401
|
-
--
|
402
|
-
Exhibit A::
|
403
|
-
+
|
404
|
-
[#tiger.animal]
|
405
|
-
image::tiger.png[Tiger]
|
406
|
-
--
|
407
|
-
|
408
|
-
image::shoe.png[Shoe]
|
409
|
-
|
410
|
-
== Section B
|
411
|
-
|
412
|
-
paragraph
|
413
|
-
EOS
|
414
|
-
|
415
|
-
doc = Asciidoctor.load input
|
416
|
-
result = doc.find_by :context => :image
|
417
|
-
assert_equal 2, result.size
|
418
|
-
assert_equal :image, result[0].context
|
419
|
-
assert_equal 'tiger.png', result[0].attr('target')
|
420
|
-
assert_equal :image, result[1].context
|
421
|
-
assert_equal 'shoe.png', result[1].attr('target')
|
422
|
-
end
|
423
|
-
|
424
|
-
test 'find_by should return an empty Array if no matches are found' do
|
425
|
-
input = <<-EOS
|
426
|
-
paragraph
|
427
|
-
EOS
|
428
|
-
doc = Asciidoctor.load input
|
429
|
-
result = doc.find_by :context => :section
|
430
|
-
refute_nil result
|
431
|
-
assert_equal 0, result.size
|
432
|
-
end
|
433
|
-
|
434
|
-
test 'find_by should return Array of blocks that match style criteria' do
|
435
|
-
input = <<-EOS
|
436
|
-
[square]
|
437
|
-
* one
|
438
|
-
* two
|
439
|
-
* three
|
440
|
-
|
441
|
-
---
|
442
|
-
|
443
|
-
* apples
|
444
|
-
* bananas
|
445
|
-
* pears
|
446
|
-
EOS
|
447
|
-
|
448
|
-
doc = Asciidoctor.load input
|
449
|
-
result = doc.find_by :context => :ulist, :style => 'square'
|
450
|
-
assert_equal 1, result.size
|
451
|
-
assert_equal :ulist, result[0].context
|
452
|
-
end
|
453
|
-
|
454
|
-
test 'find_by should return Array of blocks that match role criteria' do
|
455
|
-
input = <<-EOS
|
456
|
-
[#tiger.animal]
|
457
|
-
image::tiger.png[Tiger]
|
458
|
-
|
459
|
-
image::shoe.png[Shoe]
|
460
|
-
EOS
|
461
|
-
|
462
|
-
doc = Asciidoctor.load input
|
463
|
-
result = doc.find_by :context => :image, :role => 'animal'
|
464
|
-
assert_equal 1, result.size
|
465
|
-
assert_equal :image, result[0].context
|
466
|
-
assert_equal 'tiger.png', result[0].attr('target')
|
467
|
-
end
|
468
|
-
|
469
|
-
test 'find_by should return the document title section if context selector is :section' do
|
470
|
-
input = <<-EOS
|
471
|
-
= Document Title
|
472
|
-
|
473
|
-
preamble
|
474
|
-
|
475
|
-
== Section One
|
476
|
-
|
477
|
-
content
|
478
|
-
EOS
|
479
|
-
doc = Asciidoctor.load input
|
480
|
-
result = doc.find_by :context => :section
|
481
|
-
refute_nil result
|
482
|
-
assert_equal 2, result.size
|
483
|
-
assert_equal :section, result[0].context
|
484
|
-
assert_equal 'Document Title', result[0].title
|
485
|
-
end
|
486
|
-
|
487
|
-
test 'find_by should only return results for which the block argument yields true' do
|
488
|
-
input = <<-EOS
|
489
|
-
== Section
|
490
|
-
|
491
|
-
content
|
492
|
-
|
493
|
-
=== Subsection
|
494
|
-
|
495
|
-
content
|
496
|
-
EOS
|
497
|
-
doc = Asciidoctor.load input
|
498
|
-
result = doc.find_by(:context => :section) {|sect| sect.level == 1 }
|
499
|
-
refute_nil result
|
500
|
-
assert_equal 1, result.size
|
501
|
-
assert_equal :section, result[0].context
|
502
|
-
assert_equal 'Section', result[0].title
|
503
|
-
end
|
504
|
-
|
505
|
-
test 'find_by should only return one result when matching by id' do
|
506
|
-
input = <<-EOS
|
507
|
-
== Section
|
508
|
-
|
509
|
-
content
|
510
|
-
|
511
|
-
[#subsection]
|
512
|
-
=== Subsection
|
513
|
-
|
514
|
-
content
|
515
|
-
EOS
|
516
|
-
doc = Asciidoctor.load input
|
517
|
-
result = doc.find_by(:context => :section, :id => 'subsection')
|
518
|
-
refute_nil result
|
519
|
-
assert_equal 1, result.size
|
520
|
-
assert_equal :section, result[0].context
|
521
|
-
assert_equal 'Subsection', result[0].title
|
522
|
-
end
|
523
|
-
|
524
|
-
test 'find_by should return an empty Array if the id criteria matches but the block argument yields false' do
|
525
|
-
input = <<-EOS
|
526
|
-
== Section
|
527
|
-
|
528
|
-
content
|
529
|
-
|
530
|
-
[#subsection]
|
531
|
-
=== Subsection
|
532
|
-
|
533
|
-
content
|
534
|
-
EOS
|
535
|
-
doc = Asciidoctor.load input
|
536
|
-
result = doc.find_by(:context => :section, :id => 'subsection') {|sect| false }
|
537
|
-
refute_nil result
|
538
|
-
assert_equal 0, result.size
|
539
|
-
end
|
540
|
-
|
541
|
-
test 'find_by should not crash if dlist entry does not have description' do
|
542
|
-
input = <<-EOS
|
543
|
-
term without description::
|
544
|
-
EOS
|
545
|
-
doc = Asciidoctor.load input
|
546
|
-
result = doc.find_by
|
547
|
-
refute_nil result
|
548
|
-
assert_equal 3, result.size
|
549
|
-
assert_kind_of Asciidoctor::Document, result[0]
|
550
|
-
assert_kind_of Asciidoctor::List, result[1]
|
551
|
-
assert_kind_of Asciidoctor::ListItem, result[2]
|
552
|
-
end
|
553
|
-
end
|
554
|
-
|
555
|
-
context 'Convert APIs' do
|
556
|
-
test 'should convert source document to string when to_file is false' do
|
557
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
558
|
-
|
559
|
-
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
|
560
|
-
refute_empty output
|
561
|
-
assert_xpath '/html', output, 1
|
562
|
-
assert_xpath '/html/head', output, 1
|
563
|
-
assert_xpath '/html/body', output, 1
|
564
|
-
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
|
565
|
-
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
|
566
|
-
end
|
567
|
-
|
568
|
-
test 'lines in output should be separated by line feed' do
|
569
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
570
|
-
|
571
|
-
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
|
572
|
-
refute_empty output
|
573
|
-
lines = output.split("\n")
|
574
|
-
assert_equal lines.size, output.split(/\r\n|\r|\n/).size
|
575
|
-
raw_lengths = lines.map(&:length)
|
576
|
-
trimmed_lengths = lines.map {|line| line.rstrip.length }
|
577
|
-
assert_equal raw_lengths, trimmed_lengths
|
578
|
-
end
|
579
|
-
|
580
|
-
test 'should accept attributes as array' do
|
581
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
582
|
-
output = Asciidoctor.convert_file sample_input_path, :attributes => %w(sectnums idprefix idseparator=-), :to_file => false
|
583
|
-
assert_css '#section-a', output, 1
|
584
|
-
end
|
585
|
-
|
586
|
-
test 'should accept attributes as string' do
|
587
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
588
|
-
output = Asciidoctor.convert_file sample_input_path, :attributes => 'sectnums idprefix idseparator=-', :to_file => false
|
589
|
-
assert_css '#section-a', output, 1
|
590
|
-
end
|
591
|
-
|
592
|
-
test 'should link to default stylesheet by default when safe mode is SECURE or greater' do
|
593
|
-
sample_input_path = fixture_path('basic.asciidoc')
|
594
|
-
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
|
595
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
|
596
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
|
597
|
-
end
|
598
|
-
|
599
|
-
test 'should embed default stylesheet by default if SafeMode is less than SECURE' do
|
600
|
-
input = <<-EOS
|
601
|
-
= Document Title
|
602
|
-
|
603
|
-
text
|
604
|
-
EOS
|
605
|
-
|
606
|
-
output = Asciidoctor.render(input, :safe => Asciidoctor::SafeMode::SERVER, :header_footer => true)
|
607
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
|
608
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
|
609
|
-
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
610
|
-
styles = stylenode.content
|
611
|
-
refute_nil styles
|
612
|
-
refute_empty styles.strip
|
613
|
-
end
|
614
|
-
|
615
|
-
test 'should link to default stylesheet by default even if linkcss is unset in document' do
|
616
|
-
input = <<-EOS
|
617
|
-
= Document Title
|
618
|
-
:linkcss!:
|
619
|
-
|
620
|
-
text
|
621
|
-
EOS
|
622
|
-
|
623
|
-
output = Asciidoctor.render(input, :header_footer => true)
|
624
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
|
625
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
|
626
|
-
end
|
627
|
-
|
628
|
-
test 'should link to default stylesheet by default if linkcss is unset' do
|
629
|
-
input = <<-EOS
|
630
|
-
= Document Title
|
631
|
-
|
632
|
-
text
|
633
|
-
EOS
|
634
|
-
|
635
|
-
output = Asciidoctor.render(input, :header_footer => true, :attributes => {'linkcss!' => ''})
|
636
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
|
637
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
|
638
|
-
end
|
639
|
-
|
640
|
-
test 'should embed default stylesheet if safe mode is less than secure and linkcss is unset' do
|
641
|
-
sample_input_path = fixture_path('basic.asciidoc')
|
642
|
-
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false,
|
643
|
-
:safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss!' => ''}
|
644
|
-
assert_css 'html:root > head > style', output, 1
|
645
|
-
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
646
|
-
styles = stylenode.content
|
647
|
-
refute_nil styles
|
648
|
-
refute_empty styles.strip
|
649
|
-
end
|
650
|
-
|
651
|
-
test 'should not link to stylesheet if stylesheet is unset' do
|
652
|
-
input = <<-EOS
|
653
|
-
= Document Title
|
654
|
-
|
655
|
-
text
|
656
|
-
EOS
|
657
|
-
|
658
|
-
output = Asciidoctor.render(input, :header_footer => true, :attributes => {'stylesheet!' => ''})
|
659
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 0
|
660
|
-
assert_css 'html:root > head > link[rel="stylesheet"]', output, 0
|
661
|
-
end
|
662
|
-
|
663
|
-
test 'should link to custom stylesheet if specified in stylesheet attribute' do
|
664
|
-
input = <<-EOS
|
665
|
-
= Document Title
|
666
|
-
|
667
|
-
text
|
668
|
-
EOS
|
669
|
-
|
670
|
-
output = Asciidoctor.render(input, :header_footer => true, :attributes => {'stylesheet' => './custom.css'})
|
671
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 0
|
672
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href="./custom.css"]', output, 1
|
673
|
-
|
674
|
-
output = Asciidoctor.render(input, :header_footer => true, :attributes => {'stylesheet' => 'file:///home/username/custom.css'})
|
675
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href="file:///home/username/custom.css"]', output, 1
|
676
|
-
end
|
677
|
-
|
678
|
-
test 'should resolve custom stylesheet relative to stylesdir' do
|
679
|
-
input = <<-EOS
|
680
|
-
= Document Title
|
681
|
-
|
682
|
-
text
|
683
|
-
EOS
|
684
|
-
|
685
|
-
output = Asciidoctor.render(input, :header_footer => true, :attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets'})
|
686
|
-
assert_css 'html:root > head > link[rel="stylesheet"][href="./stylesheets/custom.css"]', output, 1
|
687
|
-
end
|
688
|
-
|
689
|
-
test 'should resolve custom stylesheet to embed relative to stylesdir' do
|
690
|
-
sample_input_path = fixture_path('basic.asciidoc')
|
691
|
-
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :safe => Asciidoctor::SafeMode::SAFE, :to_file => false,
|
692
|
-
:attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets', 'linkcss!' => ''}
|
693
|
-
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
694
|
-
styles = stylenode.content
|
695
|
-
refute_nil styles
|
696
|
-
refute_empty styles.strip
|
697
|
-
end
|
698
|
-
|
699
|
-
test 'should convert source file and write result to adjacent file by default' do
|
700
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
701
|
-
sample_output_path = fixture_path('sample.html')
|
702
|
-
begin
|
703
|
-
Asciidoctor.convert_file sample_input_path
|
704
|
-
assert File.exist?(sample_output_path)
|
705
|
-
output = IO.read(sample_output_path)
|
706
|
-
refute_empty output
|
707
|
-
assert_xpath '/html', output, 1
|
708
|
-
assert_xpath '/html/head', output, 1
|
709
|
-
assert_xpath '/html/body', output, 1
|
710
|
-
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
|
711
|
-
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
|
712
|
-
ensure
|
713
|
-
FileUtils.rm(sample_output_path)
|
714
|
-
end
|
715
|
-
end
|
716
|
-
|
717
|
-
test 'should convert source file and write to specified file' do
|
718
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
719
|
-
sample_output_path = fixture_path('result.html')
|
720
|
-
begin
|
721
|
-
Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path
|
722
|
-
assert File.exist?(sample_output_path)
|
723
|
-
output = IO.read(sample_output_path)
|
724
|
-
refute_empty output
|
725
|
-
assert_xpath '/html', output, 1
|
726
|
-
assert_xpath '/html/head', output, 1
|
727
|
-
assert_xpath '/html/body', output, 1
|
728
|
-
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
|
729
|
-
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
|
730
|
-
ensure
|
731
|
-
FileUtils.rm(sample_output_path)
|
732
|
-
end
|
733
|
-
end
|
734
|
-
|
735
|
-
test 'should convert source file and write to specified file in base_dir' do
|
736
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
737
|
-
sample_output_path = fixture_path('result.html')
|
738
|
-
fixture_dir = fixture_path('')
|
739
|
-
begin
|
740
|
-
Asciidoctor.convert_file sample_input_path, :to_file => 'result.html', :base_dir => fixture_dir
|
741
|
-
assert File.exist?(sample_output_path)
|
742
|
-
output = IO.read(sample_output_path)
|
743
|
-
refute_empty output
|
744
|
-
assert_xpath '/html', output, 1
|
745
|
-
assert_xpath '/html/head', output, 1
|
746
|
-
assert_xpath '/html/body', output, 1
|
747
|
-
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
|
748
|
-
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
|
749
|
-
rescue => e
|
750
|
-
flunk e.message
|
751
|
-
ensure
|
752
|
-
FileUtils.rm(sample_output_path, :force => true)
|
753
|
-
end
|
754
|
-
end
|
755
|
-
|
756
|
-
test 'in_place option is ignored when to_file is specified' do
|
757
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
758
|
-
sample_output_path = fixture_path('result.html')
|
759
|
-
begin
|
760
|
-
Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path, :in_place => true
|
761
|
-
assert File.exist?(sample_output_path)
|
762
|
-
ensure
|
763
|
-
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
|
764
|
-
end
|
765
|
-
end
|
766
|
-
|
767
|
-
test 'in_place option is ignored when to_dir is specified' do
|
768
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
769
|
-
sample_output_path = fixture_path('sample.html')
|
770
|
-
begin
|
771
|
-
Asciidoctor.convert_file sample_input_path, :to_dir => File.dirname(sample_output_path), :in_place => true
|
772
|
-
assert File.exist?(sample_output_path)
|
773
|
-
ensure
|
774
|
-
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
|
775
|
-
end
|
776
|
-
end
|
777
|
-
|
778
|
-
test 'output should be relative to to_dir option' do
|
779
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
780
|
-
output_dir = File.join(File.dirname(sample_input_path), 'test_output')
|
781
|
-
Dir.mkdir output_dir if !File.exist? output_dir
|
782
|
-
sample_output_path = File.join(output_dir, 'sample.html')
|
783
|
-
begin
|
784
|
-
Asciidoctor.convert_file sample_input_path, :to_dir => output_dir
|
785
|
-
assert File.exist? sample_output_path
|
786
|
-
ensure
|
787
|
-
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
|
788
|
-
FileUtils.rmdir output_dir
|
789
|
-
end
|
790
|
-
end
|
791
|
-
|
792
|
-
test 'missing directories should be created if mkdirs is enabled' do
|
793
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
794
|
-
output_dir = File.join(File.join(File.dirname(sample_input_path), 'test_output'), 'subdir')
|
795
|
-
sample_output_path = File.join(output_dir, 'sample.html')
|
796
|
-
begin
|
797
|
-
Asciidoctor.convert_file sample_input_path, :to_dir => output_dir, :mkdirs => true
|
798
|
-
assert File.exist? sample_output_path
|
799
|
-
ensure
|
800
|
-
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
|
801
|
-
FileUtils.rmdir output_dir
|
802
|
-
FileUtils.rmdir File.dirname(output_dir)
|
803
|
-
end
|
804
|
-
end
|
805
|
-
|
806
|
-
# TODO need similar test for when to_dir is specified
|
807
|
-
test 'should raise exception if an attempt is made to overwrite input file' do
|
808
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
809
|
-
|
810
|
-
assert_raises IOError do
|
811
|
-
Asciidoctor.convert_file sample_input_path, :attributes => { 'outfilesuffix' => '.asciidoc' }
|
812
|
-
end
|
813
|
-
end
|
814
|
-
|
815
|
-
test 'to_file should be relative to to_dir when both given' do
|
816
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
817
|
-
base_dir = File.dirname(sample_input_path)
|
818
|
-
sample_rel_output_path = File.join('test_output', 'result.html')
|
819
|
-
output_dir = File.dirname(File.join(base_dir, sample_rel_output_path))
|
820
|
-
Dir.mkdir output_dir if !File.exist? output_dir
|
821
|
-
sample_output_path = File.join(base_dir, sample_rel_output_path)
|
822
|
-
begin
|
823
|
-
Asciidoctor.convert_file sample_input_path, :to_dir => base_dir, :to_file => sample_rel_output_path
|
824
|
-
assert File.exist? sample_output_path
|
825
|
-
ensure
|
826
|
-
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
|
827
|
-
FileUtils.rmdir output_dir
|
828
|
-
end
|
829
|
-
end
|
830
|
-
|
831
|
-
test 'should not modify options argument' do
|
832
|
-
options = {
|
833
|
-
:safe => Asciidoctor::SafeMode::SAFE,
|
834
|
-
:to_file => false
|
835
|
-
}
|
836
|
-
options.freeze
|
837
|
-
sample_input_path = fixture_path('sample.asciidoc')
|
838
|
-
begin
|
839
|
-
Asciidoctor.convert_file sample_input_path, options
|
840
|
-
rescue
|
841
|
-
flunk %(options argument should not be modified)
|
842
|
-
end
|
843
|
-
end
|
844
|
-
end
|
845
|
-
|
846
134
|
context 'Docinfo files' do
|
847
135
|
test 'should include docinfo files for html backend' do
|
848
136
|
sample_input_path = fixture_path('basic.asciidoc')
|
@@ -1048,18 +336,17 @@ text
|
|
1048
336
|
|
1049
337
|
test 'should substitute attributes in docinfo files by default' do
|
1050
338
|
sample_input_path = fixture_path 'subs.adoc'
|
1051
|
-
|
339
|
+
using_memory_logger do |logger|
|
1052
340
|
output = Asciidoctor.convert_file sample_input_path,
|
1053
341
|
:to_file => false,
|
1054
342
|
:header_footer => true,
|
1055
343
|
:safe => :server,
|
1056
344
|
:attributes => { 'docinfo' => '', 'bootstrap-version' => nil, 'linkcss' => '', 'attribute-missing' => 'drop-line' }
|
1057
|
-
|
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'
|
1058
349
|
end
|
1059
|
-
refute_empty output
|
1060
|
-
assert_css 'script', output, 0
|
1061
|
-
assert_xpath %(//meta[@name="copyright"][@content="(C) OpenDevise"]), output, 1
|
1062
|
-
assert_includes warnings, 'dropping line containing reference to missing attribute'
|
1063
350
|
end
|
1064
351
|
|
1065
352
|
test 'should apply explicit substitutions to docinfo files' do
|
@@ -1134,9 +421,9 @@ text
|
|
1134
421
|
'/img/favicon.png' => %w(/img/favicon.png image/png)
|
1135
422
|
}.each {|val, (href, type)|
|
1136
423
|
result = render_string %(= Untitled), :attributes => { 'favicon' => val }
|
1137
|
-
assert_css 'link[rel="
|
1138
|
-
assert_css %(link[rel="
|
1139
|
-
assert_css %(link[rel="
|
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
|
1140
427
|
}
|
1141
428
|
end
|
1142
429
|
end
|
@@ -1302,7 +589,25 @@ Block content
|
|
1302
589
|
assert doc.has_header?
|
1303
590
|
assert_equal 'Document Title', doc.header.title
|
1304
591
|
assert_equal 'Document Title', doc.first_section.title
|
1305
|
-
assert_xpath '//*[@id="preamble"]//p[text()="Document Title"]', doc.
|
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
|
1306
611
|
end
|
1307
612
|
|
1308
613
|
test 'document with title attribute entry overrides doctitle attribute entry' do
|
@@ -1322,7 +627,7 @@ Block content
|
|
1322
627
|
assert doc.has_header?
|
1323
628
|
assert_equal 'doctitle', doc.header.title
|
1324
629
|
assert_equal 'doctitle', doc.first_section.title
|
1325
|
-
assert_xpath '//*[@id="preamble"]//p[text()="Document Title, doctitle"]', doc.
|
630
|
+
assert_xpath '//*[@id="preamble"]//p[text()="Document Title, doctitle"]', doc.convert, 1
|
1326
631
|
end
|
1327
632
|
|
1328
633
|
test 'document with doctitle attribute entry overrides header title and doctitle' do
|
@@ -1337,11 +642,11 @@ Block content
|
|
1337
642
|
EOS
|
1338
643
|
doc = document_from_string input
|
1339
644
|
assert_equal 'Override', doc.doctitle
|
1340
|
-
assert_nil doc.title
|
645
|
+
assert_nil doc.attributes['title']
|
1341
646
|
assert doc.has_header?
|
1342
647
|
assert_equal 'Override', doc.header.title
|
1343
648
|
assert_equal 'Override', doc.first_section.title
|
1344
|
-
assert_xpath '//*[@id="preamble"]//p[text()="Document Title, Override"]', doc.
|
649
|
+
assert_xpath '//*[@id="preamble"]//p[text()="Document Title, Override"]', doc.convert, 1
|
1345
650
|
end
|
1346
651
|
|
1347
652
|
test 'doctitle attribute entry above header overrides header title and doctitle' do
|
@@ -1355,11 +660,11 @@ Block content
|
|
1355
660
|
EOS
|
1356
661
|
doc = document_from_string input
|
1357
662
|
assert_equal 'Override', doc.doctitle
|
1358
|
-
assert_nil doc.title
|
663
|
+
assert_nil doc.attributes['title']
|
1359
664
|
assert doc.has_header?
|
1360
665
|
assert_equal 'Override', doc.header.title
|
1361
666
|
assert_equal 'Override', doc.first_section.title
|
1362
|
-
assert_xpath '//*[@id="preamble"]//p[text()="Override"]', doc.
|
667
|
+
assert_xpath '//*[@id="preamble"]//p[text()="Override"]', doc.convert, 1
|
1363
668
|
end
|
1364
669
|
|
1365
670
|
test 'should recognize document title when preceded by blank lines' do
|
@@ -1568,6 +873,18 @@ content
|
|
1568
873
|
assert_xpath '//meta[@name="author"][@content="Ze Product team"]', output, 1
|
1569
874
|
end
|
1570
875
|
|
876
|
+
test 'should not double escape ampersand in author attribute' do
|
877
|
+
input = <<-EOS
|
878
|
+
= Document Title
|
879
|
+
R&D Lab
|
880
|
+
|
881
|
+
{author}
|
882
|
+
EOS
|
883
|
+
|
884
|
+
output = render_string input
|
885
|
+
assert_includes output, 'R&D Lab', 2
|
886
|
+
end
|
887
|
+
|
1571
888
|
test 'should include multiple authors in HTML output' do
|
1572
889
|
input = <<-EOS
|
1573
890
|
= Document Title
|
@@ -1605,6 +922,19 @@ content
|
|
1605
922
|
assert_xpath '//articleinfo/authorgroup/author[2]/firstname[text() = "Junior"]', output, 1
|
1606
923
|
end
|
1607
924
|
|
925
|
+
test 'with author defined by indexed attribute name' do
|
926
|
+
input = <<-EOS
|
927
|
+
= Document Title
|
928
|
+
:author_1: Doc Writer
|
929
|
+
|
930
|
+
{author}
|
931
|
+
EOS
|
932
|
+
|
933
|
+
doc = document_from_string input
|
934
|
+
assert_equal 'Doc Writer', (doc.attr 'author')
|
935
|
+
assert_equal 'Doc Writer', (doc.attr 'author_1')
|
936
|
+
end
|
937
|
+
|
1608
938
|
test 'with authors defined using attribute entry to DocBook' do
|
1609
939
|
input = <<-EOS
|
1610
940
|
= Document Title
|
@@ -1625,10 +955,50 @@ content
|
|
1625
955
|
assert_xpath '(//articleinfo/authorgroup/author)[2]/email[text() = "junior@asciidoc.org"]', output, 1
|
1626
956
|
end
|
1627
957
|
|
958
|
+
test 'should populate copyright element in DocBook output if copyright attribute is defined' do
|
959
|
+
input = <<-EOS
|
960
|
+
= Jet Bike
|
961
|
+
:copyright: ACME, Inc.
|
962
|
+
|
963
|
+
Essential for catching road runners.
|
964
|
+
EOS
|
965
|
+
output = render_string input, :backend => 'docbook5'
|
966
|
+
assert_xpath '/article/info/copyright', output, 1
|
967
|
+
assert_xpath '/article/info/copyright/holder[text()="ACME, Inc."]', output, 1
|
968
|
+
end
|
969
|
+
|
970
|
+
test 'should populate copyright element in DocBook output if copyright attribute is defined with year' do
|
971
|
+
input = <<-EOS
|
972
|
+
= Jet Bike
|
973
|
+
:copyright: ACME, Inc. 1956
|
974
|
+
|
975
|
+
Essential for catching road runners.
|
976
|
+
EOS
|
977
|
+
output = render_string input, :backend => 'docbook5'
|
978
|
+
assert_xpath '/article/info/copyright', output, 1
|
979
|
+
assert_xpath '/article/info/copyright/holder[text()="ACME, Inc."]', output, 1
|
980
|
+
assert_xpath '/article/info/copyright/year', output, 1
|
981
|
+
assert_xpath '/article/info/copyright/year[text()="1956"]', output, 1
|
982
|
+
end
|
983
|
+
|
984
|
+
test 'should populate copyright element in DocBook output if copyright attribute is defined with year range' do
|
985
|
+
input = <<-EOS
|
986
|
+
= Jet Bike
|
987
|
+
:copyright: ACME, Inc. 1956-2018
|
988
|
+
|
989
|
+
Essential for catching road runners.
|
990
|
+
EOS
|
991
|
+
output = render_string input, :backend => 'docbook5'
|
992
|
+
assert_xpath '/article/info/copyright', output, 1
|
993
|
+
assert_xpath '/article/info/copyright/holder[text()="ACME, Inc."]', output, 1
|
994
|
+
assert_xpath '/article/info/copyright/year', output, 1
|
995
|
+
assert_xpath '/article/info/copyright/year[text()="1956-2018"]', output, 1
|
996
|
+
end
|
997
|
+
|
1628
998
|
test 'with header footer' do
|
1629
999
|
doc = document_from_string "= Title\n\nparagraph"
|
1630
1000
|
refute doc.attr?('embedded')
|
1631
|
-
result = doc.
|
1001
|
+
result = doc.convert
|
1632
1002
|
assert_xpath '/html', result, 1
|
1633
1003
|
assert_xpath '//*[@id="header"]', result, 1
|
1634
1004
|
assert_xpath '//*[@id="header"]/h1', result, 1
|
@@ -1649,7 +1019,7 @@ content
|
|
1649
1019
|
|
1650
1020
|
test 'can disable last updated in footer' do
|
1651
1021
|
doc = document_from_string "= Document Title\n\npreamble", :attributes => {'last-update-label!' => ''}
|
1652
|
-
result = doc.
|
1022
|
+
result = doc.convert
|
1653
1023
|
assert_xpath '//*[@id="footer-text"]', result, 1
|
1654
1024
|
assert_xpath '//*[@id="footer-text"][normalize-space(text())=""]', result, 1
|
1655
1025
|
end
|
@@ -1657,7 +1027,7 @@ content
|
|
1657
1027
|
test 'no header footer' do
|
1658
1028
|
doc = document_from_string "= Document Title\n\ncontent", :header_footer => false
|
1659
1029
|
assert doc.attr?('embedded')
|
1660
|
-
result = doc.
|
1030
|
+
result = doc.convert
|
1661
1031
|
assert_xpath '/html', result, 0
|
1662
1032
|
assert_xpath '/h1', result, 0
|
1663
1033
|
assert_xpath '/*[@id="header"]', result, 0
|
@@ -1726,13 +1096,13 @@ finally a reference to the second footnote footnoteref:[note2].
|
|
1726
1096
|
output = render_string input
|
1727
1097
|
assert_css '#footnotes', output, 1
|
1728
1098
|
assert_css '#footnotes .footnote', output, 2
|
1729
|
-
assert_css '#footnotes .footnote#
|
1730
|
-
assert_xpath '//div[@id="footnotes"]/div[@id="
|
1731
|
-
text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="
|
1099
|
+
assert_css '#footnotes .footnote#_footnotedef_1', output, 1
|
1100
|
+
assert_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
|
1101
|
+
text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_1"]/text()', output
|
1732
1102
|
assert_equal '. An example footnote.', text.text.strip
|
1733
|
-
assert_css '#footnotes .footnote#
|
1734
|
-
assert_xpath '//div[@id="footnotes"]/div[@id="
|
1735
|
-
text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="
|
1103
|
+
assert_css '#footnotes .footnote#_footnotedef_2', output, 1
|
1104
|
+
assert_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_2"]/a[@href="#_footnoteref_2"][text()="2"]', output, 1
|
1105
|
+
text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnotedef_2"]/text()', output
|
1736
1106
|
assert_equal '. Second footnote.', text.text.strip
|
1737
1107
|
end
|
1738
1108
|
|
@@ -1744,9 +1114,9 @@ Text that has supporting information{empty}footnote:[An example footnote.].
|
|
1744
1114
|
output = render_embedded_string input
|
1745
1115
|
assert_css '#footnotes', output, 1
|
1746
1116
|
assert_css '#footnotes .footnote', output, 1
|
1747
|
-
assert_css '#footnotes .footnote#
|
1748
|
-
assert_xpath '/div[@id="footnotes"]/div[@id="
|
1749
|
-
text = xmlnodes_at_xpath '/div[@id="footnotes"]/div[@id="
|
1117
|
+
assert_css '#footnotes .footnote#_footnotedef_1', output, 1
|
1118
|
+
assert_xpath '/div[@id="footnotes"]/div[@id="_footnotedef_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
|
1119
|
+
text = xmlnodes_at_xpath '/div[@id="footnotes"]/div[@id="_footnotedef_1"]/text()', output
|
1750
1120
|
assert_equal '. An example footnote.', text.text.strip
|
1751
1121
|
end
|
1752
1122
|
|
@@ -1776,12 +1146,29 @@ content{blank}footnote:[commentary]
|
|
1776
1146
|
|
1777
1147
|
doc = document_from_string input
|
1778
1148
|
refute_nil doc.catalog
|
1779
|
-
assert_equal [:footnotes, :ids, :images, :includes, :indexterms, :links, :refs].to_set, doc.catalog.keys.to_set
|
1149
|
+
assert_equal [:footnotes, :ids, :images, :includes, :indexterms, :links, :refs, :callouts].to_set, doc.catalog.keys.to_set
|
1780
1150
|
assert_same doc.catalog, doc.references
|
1781
1151
|
assert_same doc.catalog[:footnotes], doc.references[:footnotes]
|
1782
1152
|
assert_same doc.catalog[:ids], doc.references[:ids]
|
1783
1153
|
assert_equal 'Section A', doc.references[:ids]['_section_a']
|
1784
1154
|
end
|
1155
|
+
|
1156
|
+
test 'should catalog assets inside nested document' do
|
1157
|
+
input = <<-EOS
|
1158
|
+
image::outer.png[]
|
1159
|
+
|
1160
|
+
|===
|
1161
|
+
a|
|
1162
|
+
image::inner.png[]
|
1163
|
+
|===
|
1164
|
+
EOS
|
1165
|
+
|
1166
|
+
doc = document_from_string input, :catalog_assets => true
|
1167
|
+
images = doc.catalog[:images]
|
1168
|
+
refute_empty images
|
1169
|
+
assert_equal 2, images.size
|
1170
|
+
assert_equal images, ['outer.png', 'inner.png']
|
1171
|
+
end
|
1785
1172
|
end
|
1786
1173
|
|
1787
1174
|
context 'Backends and Doctypes' do
|
@@ -1861,6 +1248,7 @@ content
|
|
1861
1248
|
Author Name
|
1862
1249
|
v1.0, 2001-01-01
|
1863
1250
|
:icons:
|
1251
|
+
:favicon:
|
1864
1252
|
|
1865
1253
|
image:tiger.png[]
|
1866
1254
|
|
@@ -2057,6 +1445,8 @@ section body
|
|
2057
1445
|
test 'docbook5 backend doctype manpage' do
|
2058
1446
|
input = <<-EOS
|
2059
1447
|
= asciidoctor(1)
|
1448
|
+
:mansource: Asciidoctor
|
1449
|
+
:manmanual: Asciidoctor Manual
|
2060
1450
|
|
2061
1451
|
== NAME
|
2062
1452
|
|
@@ -2079,6 +1469,8 @@ section body
|
|
2079
1469
|
assert_xpath '/xmlns:refentry/xmlns:info/xmlns:title[text() = "asciidoctor(1)"]', result, 1
|
2080
1470
|
assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:refentrytitle[text() = "asciidoctor"]', result, 1
|
2081
1471
|
assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:manvolnum[text() = "1"]', result, 1
|
1472
|
+
assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="source"][text() = "Asciidoctor"]', result, 1
|
1473
|
+
assert_xpath '/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="manual"][text() = "Asciidoctor Manual"]', result, 1
|
2082
1474
|
assert_xpath '/xmlns:refentry/xmlns:refnamediv/xmlns:refname[text() = "asciidoctor"]', result, 1
|
2083
1475
|
assert_xpath '/xmlns:refentry/xmlns:refnamediv/xmlns:refpurpose[text() = "Process text"]', result, 1
|
2084
1476
|
assert_xpath '/xmlns:refentry/xmlns:refsynopsisdiv', result, 1
|
@@ -2093,6 +1485,23 @@ section body
|
|
2093
1485
|
assert_equal '_first_section', id_attr.value
|
2094
1486
|
end
|
2095
1487
|
|
1488
|
+
test 'should output non-breaking space for source and manual in docbook5 manpage output if absent from source' do
|
1489
|
+
input = <<-EOS
|
1490
|
+
= asciidoctor(1)
|
1491
|
+
|
1492
|
+
== NAME
|
1493
|
+
|
1494
|
+
asciidoctor - Process text
|
1495
|
+
|
1496
|
+
== SYNOPSIS
|
1497
|
+
|
1498
|
+
some text
|
1499
|
+
EOS
|
1500
|
+
result = render_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5', 'doctype' => 'manpage'})
|
1501
|
+
assert_xpath %(/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="source"][text() = "#{decode_char 160}"]), result, 1
|
1502
|
+
assert_xpath %(/xmlns:refentry/xmlns:refmeta/xmlns:refmiscinfo[@class="manual"][text() = "#{decode_char 160}"]), result, 1
|
1503
|
+
end
|
1504
|
+
|
2096
1505
|
test 'docbook5 backend doctype book' do
|
2097
1506
|
input = <<-EOS
|
2098
1507
|
= Title
|
@@ -2122,6 +1531,30 @@ chapter body
|
|
2122
1531
|
assert_equal '_first_chapter', id_attr.value
|
2123
1532
|
end
|
2124
1533
|
|
1534
|
+
test 'adds refname to DocBook output for each name defined in NAME section of manpage' do
|
1535
|
+
input = <<-EOS
|
1536
|
+
= eve(1)
|
1537
|
+
Andrew Stanton
|
1538
|
+
v1.0.0
|
1539
|
+
:doctype: manpage
|
1540
|
+
:manmanual: EVE
|
1541
|
+
:mansource: EVE
|
1542
|
+
|
1543
|
+
== NAME
|
1544
|
+
|
1545
|
+
eve, islifeform - analyzes an image to determine if it's a picture of a life form
|
1546
|
+
|
1547
|
+
== SYNOPSIS
|
1548
|
+
|
1549
|
+
*eve* ['OPTION']... 'FILE'...
|
1550
|
+
EOS
|
1551
|
+
|
1552
|
+
result = render_string input, :backend => 'docbook5'
|
1553
|
+
assert_xpath '/refentry/refnamediv/refname', result, 2
|
1554
|
+
assert_xpath '(/refentry/refnamediv/refname)[1][text()="eve"]', result, 1
|
1555
|
+
assert_xpath '(/refentry/refnamediv/refname)[2][text()="islifeform"]', result, 1
|
1556
|
+
end
|
1557
|
+
|
2125
1558
|
test 'adds a front and back cover image to DocBook 5 when doctype is book' do
|
2126
1559
|
input = <<-EOS
|
2127
1560
|
= Title
|
@@ -2214,24 +1647,24 @@ preamble
|
|
2214
1647
|
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
2215
1648
|
EOS
|
2216
1649
|
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
1650
|
+
doc = document_from_string input
|
1651
|
+
assert_equal 'asciidoctor', doc.attr('mantitle')
|
1652
|
+
assert_equal '1', doc.attr('manvolnum')
|
2220
1653
|
end
|
2221
1654
|
|
2222
1655
|
test 'should perform attribute substitution on mantitle in manpage doctype' do
|
2223
1656
|
input = <<-EOS
|
2224
1657
|
= {app}(1)
|
2225
1658
|
:doctype: manpage
|
2226
|
-
:app:
|
1659
|
+
:app: Asciidoctor
|
2227
1660
|
|
2228
1661
|
== NAME
|
2229
1662
|
|
2230
1663
|
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
2231
1664
|
EOS
|
2232
1665
|
|
2233
|
-
|
2234
|
-
|
1666
|
+
doc = document_from_string input
|
1667
|
+
assert_equal 'asciidoctor', doc.attr('mantitle')
|
2235
1668
|
end
|
2236
1669
|
|
2237
1670
|
test 'should consume name section as manname and manpurpose for manpage doctype' do
|
@@ -2244,10 +1677,11 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
|
2244
1677
|
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
2245
1678
|
EOS
|
2246
1679
|
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
2250
|
-
|
1680
|
+
doc = document_from_string input
|
1681
|
+
assert_equal 'asciidoctor', doc.attr('manname')
|
1682
|
+
assert_equal 'converts AsciiDoc source files to HTML, DocBook and other formats', doc.attr('manpurpose')
|
1683
|
+
assert_equal '_name', doc.attr('manname-id')
|
1684
|
+
assert_equal 0, doc.blocks.size
|
2251
1685
|
end
|
2252
1686
|
|
2253
1687
|
test 'should set docname and outfilesuffix from manname and manvolnum for manpage backend and doctype' do
|
@@ -2260,9 +1694,9 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
|
2260
1694
|
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
2261
1695
|
EOS
|
2262
1696
|
|
2263
|
-
|
2264
|
-
|
2265
|
-
|
1697
|
+
doc = document_from_string input, :backend => 'manpage'
|
1698
|
+
assert_equal 'asciidoctor', doc.attributes['docname']
|
1699
|
+
assert_equal '.1', doc.attributes['outfilesuffix']
|
2266
1700
|
end
|
2267
1701
|
|
2268
1702
|
test 'should mark synopsis as special section in manpage doctype' do
|
@@ -2279,12 +1713,12 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
|
2279
1713
|
*asciidoctor* ['OPTION']... 'FILE'..
|
2280
1714
|
EOS
|
2281
1715
|
|
2282
|
-
|
2283
|
-
|
2284
|
-
|
2285
|
-
|
2286
|
-
|
2287
|
-
|
1716
|
+
doc = document_from_string input
|
1717
|
+
synopsis_section = doc.blocks.first
|
1718
|
+
refute_nil synopsis_section
|
1719
|
+
assert_equal :section, synopsis_section.context
|
1720
|
+
assert synopsis_section.special
|
1721
|
+
assert_equal 'synopsis', synopsis_section.sectname
|
2288
1722
|
end
|
2289
1723
|
|
2290
1724
|
test 'should output special header block in HTML for manpage doctype' do
|
@@ -2305,6 +1739,7 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
|
2305
1739
|
assert_css 'body.manpage', output, 1
|
2306
1740
|
assert_xpath '//body/*[@id="header"]/h1[text()="asciidoctor(1) Manual Page"]', output, 1
|
2307
1741
|
assert_xpath '//body/*[@id="header"]/h1/following-sibling::h2[text()="NAME"]', output, 1
|
1742
|
+
assert_xpath '//h2[@id="_name"][text()="NAME"]', output, 1
|
2308
1743
|
assert_xpath '//h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]', output, 1
|
2309
1744
|
assert_xpath '//h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]/p[text()="asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats"]', output, 1
|
2310
1745
|
assert_xpath '//*[@id="content"]/*[@class="sect1"]/h2[text()="SYNOPSIS"]', output, 1
|
@@ -2328,6 +1763,7 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
|
2328
1763
|
output = render_embedded_string input
|
2329
1764
|
assert_xpath '/h1[text()="asciidoctor(1) Manual Page"]', output, 1
|
2330
1765
|
assert_xpath '/h1/following-sibling::h2[text()="NAME"]', output, 1
|
1766
|
+
assert_xpath '/h2[@id="_name"][text()="NAME"]', output, 1
|
2331
1767
|
assert_xpath '/h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]', output, 1
|
2332
1768
|
assert_xpath '/h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]/p[text()="asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats"]', output, 1
|
2333
1769
|
end
|
@@ -2342,18 +1778,23 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
|
2342
1778
|
|
2343
1779
|
test 'keeps naughty absolute paths from getting outside' do
|
2344
1780
|
naughty_path = "#{disk_root}etc/passwd"
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
1781
|
+
using_memory_logger do |logger|
|
1782
|
+
doc = empty_document
|
1783
|
+
secure_path = doc.normalize_asset_path naughty_path
|
1784
|
+
refute_equal naughty_path, secure_path
|
1785
|
+
assert_equal (::File.join doc.base_dir, 'etc/passwd'), secure_path
|
1786
|
+
assert_message logger, :WARN, 'path is outside of jail; recovering automatically'
|
1787
|
+
end
|
2349
1788
|
end
|
2350
1789
|
|
2351
1790
|
test 'keeps naughty relative paths from getting outside' do
|
2352
1791
|
naughty_path = 'safe/ok/../../../../../etc/passwd'
|
2353
|
-
|
2354
|
-
|
2355
|
-
|
2356
|
-
|
1792
|
+
using_memory_logger do
|
1793
|
+
doc = empty_document
|
1794
|
+
secure_path = doc.normalize_asset_path naughty_path
|
1795
|
+
refute_equal naughty_path, secure_path
|
1796
|
+
assert_match(/^#{doc.base_dir}/, secure_path)
|
1797
|
+
end
|
2357
1798
|
end
|
2358
1799
|
|
2359
1800
|
test 'should raise an exception when a converter cannot be resolved before conversion' do
|