asciidoctor 1.5.8 → 2.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +162 -17
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +12 -13
  5. data/README-fr.adoc +11 -12
  6. data/README-jp.adoc +11 -12
  7. data/README-zh_CN.adoc +12 -13
  8. data/README.adoc +6 -7
  9. data/asciidoctor.gemspec +19 -24
  10. data/bin/asciidoctor +5 -4
  11. data/data/reference/syntax.adoc +283 -0
  12. data/data/stylesheets/asciidoctor-default.css +56 -52
  13. data/data/stylesheets/coderay-asciidoctor.css +7 -9
  14. data/lib/asciidoctor.rb +171 -232
  15. data/lib/asciidoctor/abstract_block.rb +96 -105
  16. data/lib/asciidoctor/abstract_node.rb +118 -139
  17. data/lib/asciidoctor/attribute_list.rb +10 -14
  18. data/lib/asciidoctor/block.rb +20 -19
  19. data/lib/asciidoctor/callouts.rb +4 -2
  20. data/lib/asciidoctor/cli.rb +3 -2
  21. data/lib/asciidoctor/cli/invoker.rb +14 -21
  22. data/lib/asciidoctor/cli/options.rb +64 -54
  23. data/lib/asciidoctor/converter.rb +357 -185
  24. data/lib/asciidoctor/converter/composite.rb +40 -48
  25. data/lib/asciidoctor/converter/docbook5.rb +604 -640
  26. data/lib/asciidoctor/converter/html5.rb +949 -963
  27. data/lib/asciidoctor/converter/manpage.rb +569 -548
  28. data/lib/asciidoctor/converter/template.rb +231 -272
  29. data/lib/asciidoctor/core_ext.rb +5 -18
  30. data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
  31. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  32. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  33. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  34. data/lib/asciidoctor/document.rb +399 -377
  35. data/lib/asciidoctor/extensions.rb +72 -140
  36. data/lib/asciidoctor/helpers.rb +122 -83
  37. data/lib/asciidoctor/inline.rb +5 -1
  38. data/lib/asciidoctor/list.rb +13 -11
  39. data/lib/asciidoctor/logging.rb +17 -16
  40. data/lib/asciidoctor/parser.rb +390 -423
  41. data/lib/asciidoctor/path_resolver.rb +10 -5
  42. data/lib/asciidoctor/reader.rb +286 -263
  43. data/lib/asciidoctor/rouge_ext.rb +39 -0
  44. data/lib/asciidoctor/section.rb +9 -8
  45. data/lib/asciidoctor/stylesheets.rb +19 -37
  46. data/lib/asciidoctor/substitutors.rb +364 -509
  47. data/lib/asciidoctor/syntax_highlighter.rb +238 -0
  48. data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
  49. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
  50. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  51. data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
  52. data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
  53. data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
  54. data/lib/asciidoctor/table.rb +73 -66
  55. data/lib/asciidoctor/timings.rb +4 -2
  56. data/lib/asciidoctor/version.rb +2 -1
  57. data/lib/asciidoctor/writer.rb +30 -0
  58. data/man/asciidoctor.1 +19 -15
  59. data/man/asciidoctor.adoc +14 -12
  60. metadata +69 -216
  61. data/CONTRIBUTING.adoc +0 -185
  62. data/Gemfile +0 -60
  63. data/Rakefile +0 -129
  64. data/bin/asciidoctor-safe +0 -15
  65. data/features/open_block.feature +0 -92
  66. data/features/pass_block.feature +0 -66
  67. data/features/step_definitions.rb +0 -49
  68. data/features/text_formatting.feature +0 -57
  69. data/features/xref.feature +0 -1039
  70. data/lib/asciidoctor/converter/base.rb +0 -59
  71. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  72. data/lib/asciidoctor/converter/factory.rb +0 -226
  73. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  74. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  75. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  76. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  77. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  78. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  79. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  80. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  81. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  82. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  83. data/test/api_test.rb +0 -1240
  84. data/test/attribute_list_test.rb +0 -242
  85. data/test/attributes_test.rb +0 -1623
  86. data/test/blocks_test.rb +0 -3870
  87. data/test/converter_test.rb +0 -470
  88. data/test/document_test.rb +0 -1853
  89. data/test/extensions_test.rb +0 -1560
  90. data/test/fixtures/asciidoc_index.txt +0 -521
  91. data/test/fixtures/basic-docinfo-footer.html +0 -6
  92. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  93. data/test/fixtures/basic-docinfo.html +0 -1
  94. data/test/fixtures/basic-docinfo.xml +0 -4
  95. data/test/fixtures/basic.asciidoc +0 -5
  96. data/test/fixtures/chapter-a.adoc +0 -3
  97. data/test/fixtures/child-include.adoc +0 -5
  98. data/test/fixtures/circle.svg +0 -9
  99. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  100. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  101. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  102. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  103. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  104. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  105. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  106. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  107. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  108. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  109. data/test/fixtures/docinfo-footer.html +0 -1
  110. data/test/fixtures/docinfo-footer.xml +0 -9
  111. data/test/fixtures/docinfo.html +0 -1
  112. data/test/fixtures/docinfo.xml +0 -3
  113. data/test/fixtures/doctime-localtime.adoc +0 -2
  114. data/test/fixtures/dot.gif +0 -0
  115. data/test/fixtures/encoding.asciidoc +0 -13
  116. data/test/fixtures/file-with-missing-include.adoc +0 -1
  117. data/test/fixtures/grandchild-include.adoc +0 -3
  118. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  119. data/test/fixtures/include-file.asciidoc +0 -24
  120. data/test/fixtures/include-file.jsx +0 -8
  121. data/test/fixtures/include-file.ml +0 -3
  122. data/test/fixtures/include-file.xml +0 -5
  123. data/test/fixtures/lists.adoc +0 -96
  124. data/test/fixtures/master.adoc +0 -5
  125. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  126. data/test/fixtures/other-chapters.adoc +0 -11
  127. data/test/fixtures/outer-include.adoc +0 -5
  128. data/test/fixtures/parent-include-restricted.adoc +0 -5
  129. data/test/fixtures/parent-include.adoc +0 -5
  130. data/test/fixtures/sample.asciidoc +0 -30
  131. data/test/fixtures/section-a.adoc +0 -4
  132. data/test/fixtures/stylesheets/custom.css +0 -3
  133. data/test/fixtures/subdir/index.adoc +0 -3
  134. data/test/fixtures/subdir/inner-include.adoc +0 -3
  135. data/test/fixtures/subdir/middle-include.adoc +0 -5
  136. data/test/fixtures/subs-docinfo.html +0 -2
  137. data/test/fixtures/subs.adoc +0 -6
  138. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  139. data/test/fixtures/tagged-class.rb +0 -23
  140. data/test/fixtures/tip.gif +0 -0
  141. data/test/fixtures/unclosed-tag.adoc +0 -3
  142. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  143. data/test/invoker_test.rb +0 -745
  144. data/test/links_test.rb +0 -855
  145. data/test/lists_test.rb +0 -5151
  146. data/test/logger_test.rb +0 -211
  147. data/test/manpage_test.rb +0 -660
  148. data/test/options_test.rb +0 -262
  149. data/test/paragraphs_test.rb +0 -562
  150. data/test/parser_test.rb +0 -742
  151. data/test/paths_test.rb +0 -395
  152. data/test/preamble_test.rb +0 -173
  153. data/test/reader_test.rb +0 -2161
  154. data/test/sections_test.rb +0 -3575
  155. data/test/substitutions_test.rb +0 -2066
  156. data/test/tables_test.rb +0 -2036
  157. data/test/test_helper.rb +0 -447
  158. data/test/text_test.rb +0 -309
@@ -1,1560 +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
- class ExtensionsInitTest < Minitest::Test
8
- def test_autoload
9
- doc = empty_document
10
- refute doc.extensions?, 'Extensions should not be enabled by default'
11
-
12
- begin
13
- # NOTE trigger extensions to autoload by registering empty group
14
- Asciidoctor::Extensions.register do
15
- end
16
- rescue; end
17
-
18
- doc = empty_document
19
- assert doc.extensions?, 'Extensions should be enabled after being autoloaded'
20
-
21
- self.class.remove_tests self.class
22
- ensure
23
- Asciidoctor::Extensions.unregister_all
24
- end
25
- self
26
- end.new(nil).test_autoload
27
-
28
- class SamplePreprocessor < Asciidoctor::Extensions::Preprocessor
29
- def process doc, reader
30
- nil
31
- end
32
- end
33
-
34
- class SampleIncludeProcessor < Asciidoctor::Extensions::IncludeProcessor
35
- end
36
-
37
- class SampleDocinfoProcessor < Asciidoctor::Extensions::DocinfoProcessor
38
- end
39
-
40
- # NOTE intentionally using the deprecated name
41
- class SampleTreeprocessor < Asciidoctor::Extensions::Treeprocessor
42
- def process document
43
- nil
44
- end
45
- end
46
- SampleTreeProcessor = SampleTreeprocessor
47
-
48
- class SamplePostprocessor < Asciidoctor::Extensions::Postprocessor
49
- end
50
-
51
- class SampleBlock < Asciidoctor::Extensions::BlockProcessor
52
- end
53
-
54
- class SampleBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
55
- end
56
-
57
- class SampleInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
58
- end
59
-
60
- class ScrubHeaderPreprocessor < Asciidoctor::Extensions::Preprocessor
61
- def process doc, reader
62
- lines = reader.lines
63
- skipped = []
64
- while !lines.empty? && !lines.first.start_with?('=')
65
- skipped << lines.shift
66
- reader.advance
67
- end
68
- doc.set_attr 'skipped', (skipped * "\n")
69
- reader
70
- end
71
- end
72
-
73
- class BoilerplateTextIncludeProcessor < Asciidoctor::Extensions::IncludeProcessor
74
- def handles? target
75
- target.end_with? '.txt'
76
- end
77
-
78
- def process document, reader, target, attributes
79
- case target
80
- when 'lorem-ipsum.txt'
81
- content = ["Lorem ipsum dolor sit amet...\n"]
82
- reader.push_include content, target, target, 1, attributes
83
- else
84
- nil
85
- end
86
- end
87
- end
88
-
89
- class ReplaceAuthorTreeProcessor < Asciidoctor::Extensions::TreeProcessor
90
- def process document
91
- document.attributes['firstname'] = 'Ghost'
92
- document.attributes['author'] = 'Ghost Writer'
93
- document
94
- end
95
- end
96
-
97
- class ReplaceTreeTreeProcessor < Asciidoctor::Extensions::TreeProcessor
98
- def process document
99
- if document.doctitle == 'Original Document'
100
- Asciidoctor.load %(== Replacement Document\nReplacement Author\n\ncontent)
101
- else
102
- document
103
- end
104
- end
105
- end
106
-
107
- class SelfSigningTreeProcessor < Asciidoctor::Extensions::TreeProcessor
108
- def process document
109
- document << (create_paragraph document, self.class.name, {})
110
- nil
111
- end
112
- end
113
-
114
- class StripAttributesPostprocessor < Asciidoctor::Extensions::Postprocessor
115
- def process document, output
116
- output.gsub(/<(\w+).*?>/m, "<\\1>")
117
- end
118
- end
119
-
120
- class UppercaseBlock < Asciidoctor::Extensions::BlockProcessor; use_dsl
121
- named :yell
122
- bound_to :paragraph
123
- parses_content_as :simple
124
- def process parent, reader, attributes
125
- create_paragraph parent, reader.lines.map(&:upcase), attributes
126
- end
127
- end
128
-
129
- class SnippetMacro < Asciidoctor::Extensions::BlockMacroProcessor
130
- def process parent, target, attributes
131
- create_pass_block parent, %(<script src="http://example.com/#{target}.js?_mode=#{attributes['mode']}"></script>), {}, :content_model => :raw
132
- end
133
- end
134
-
135
- class TemperatureMacro < Asciidoctor::Extensions::InlineMacroProcessor; use_dsl
136
- named :degrees
137
- resolves_attributes '1:units', 'precision=1'
138
- def process parent, target, attributes
139
- units = attributes['units'] || (parent.document.attr 'temperature-unit', 'C')
140
- precision = attributes['precision'].to_i
141
- c = target.to_f
142
- case units
143
- when 'C'
144
- %(#{round_with_precision c, precision} &#176;C)
145
- when 'F'
146
- %(#{round_with_precision c * 1.8 + 32, precision} &#176;F)
147
- else
148
- raise ::ArgumentError, %(Unknown temperature units: #{units})
149
- end
150
- end
151
-
152
- if (::Numeric.instance_method :round).arity == 0
153
- def round_with_precision value, precision = 0
154
- if precision == 0
155
- value.round
156
- else
157
- factor = 10 ** precision
158
- if precision < 0
159
- (value * factor).round.div factor
160
- else
161
- (value * factor).round.fdiv factor
162
- end
163
- end
164
- end
165
- else
166
- def round_with_precision value, precision = 0
167
- value.round precision
168
- end
169
- end
170
- end
171
-
172
- class MetaRobotsDocinfoProcessor < Asciidoctor::Extensions::DocinfoProcessor
173
- def process document
174
- '<meta name="robots" content="index,follow">'
175
- end
176
- end
177
-
178
- class MetaAppDocinfoProcessor < Asciidoctor::Extensions::DocinfoProcessor; use_dsl
179
- at_location :head
180
-
181
- def process document
182
- '<meta name="application-name" content="Asciidoctor App">'
183
- end
184
- end
185
-
186
- class SampleExtensionGroup < Asciidoctor::Extensions::Group
187
- def activate registry
188
- registry.document.attributes['activate-method-called'] = ''
189
- registry.preprocessor SamplePreprocessor
190
- end
191
- end
192
-
193
- def create_cat_in_sink_block_macro
194
- Asciidoctor::Extensions.create do
195
- block_macro do
196
- named :cat_in_sink
197
- process do |parent, target, attrs|
198
- image_attrs = {}
199
- unless target.nil_or_empty?
200
- image_attrs['target'] = %(cat-in-sink-day-#{target}.png)
201
- end
202
- if (title = attrs.delete 'title')
203
- image_attrs['title'] = title
204
- end
205
- if (alt = attrs.delete 1)
206
- image_attrs['alt'] = alt
207
- end
208
- create_image_block parent, image_attrs
209
- end
210
- end
211
- end
212
- end
213
-
214
- context 'Extensions' do
215
- context 'Register' do
216
- test 'should not activate registry if no extension groups are registered' do
217
- assert defined? Asciidoctor::Extensions
218
- doc = empty_document
219
- refute doc.extensions?, 'Extensions should not be enabled if not groups are registered'
220
- end
221
-
222
- test 'should register extension group class' do
223
- begin
224
- Asciidoctor::Extensions.register :sample, SampleExtensionGroup
225
- refute_nil Asciidoctor::Extensions.groups
226
- assert_equal 1, Asciidoctor::Extensions.groups.size
227
- assert_equal SampleExtensionGroup, Asciidoctor::Extensions.groups[:sample]
228
- ensure
229
- Asciidoctor::Extensions.unregister_all
230
- end
231
- end
232
-
233
- test 'should self register extension group class' do
234
- begin
235
- SampleExtensionGroup.register :sample
236
- refute_nil Asciidoctor::Extensions.groups
237
- assert_equal 1, Asciidoctor::Extensions.groups.size
238
- assert_equal SampleExtensionGroup, Asciidoctor::Extensions.groups[:sample]
239
- ensure
240
- Asciidoctor::Extensions.unregister_all
241
- end
242
- end
243
-
244
- test 'should register extension group from class name' do
245
- begin
246
- Asciidoctor::Extensions.register :sample, 'SampleExtensionGroup'
247
- refute_nil Asciidoctor::Extensions.groups
248
- assert_equal 1, Asciidoctor::Extensions.groups.size
249
- assert_equal SampleExtensionGroup, Asciidoctor::Extensions.groups[:sample]
250
- ensure
251
- Asciidoctor::Extensions.unregister_all
252
- end
253
- end
254
-
255
- test 'should register extension group from instance' do
256
- begin
257
- Asciidoctor::Extensions.register :sample, SampleExtensionGroup.new
258
- refute_nil Asciidoctor::Extensions.groups
259
- assert_equal 1, Asciidoctor::Extensions.groups.size
260
- assert_kind_of SampleExtensionGroup, Asciidoctor::Extensions.groups[:sample]
261
- ensure
262
- Asciidoctor::Extensions.unregister_all
263
- end
264
- end
265
-
266
- test 'should register extension block' do
267
- begin
268
- Asciidoctor::Extensions.register :sample do
269
- end
270
- refute_nil Asciidoctor::Extensions.groups
271
- assert_equal 1, Asciidoctor::Extensions.groups.size
272
- assert_kind_of Proc, Asciidoctor::Extensions.groups[:sample]
273
- ensure
274
- Asciidoctor::Extensions.unregister_all
275
- end
276
- end
277
-
278
- test 'should coerce group name to symbol when registering' do
279
- begin
280
- Asciidoctor::Extensions.register 'sample', SampleExtensionGroup
281
- refute_nil Asciidoctor::Extensions.groups
282
- assert_equal 1, Asciidoctor::Extensions.groups.size
283
- assert_equal SampleExtensionGroup, Asciidoctor::Extensions.groups[:sample]
284
- ensure
285
- Asciidoctor::Extensions.unregister_all
286
- end
287
- end
288
-
289
- test 'should unregister extension group by symbol name' do
290
- begin
291
- Asciidoctor::Extensions.register :sample, SampleExtensionGroup
292
- refute_nil Asciidoctor::Extensions.groups
293
- assert_equal 1, Asciidoctor::Extensions.groups.size
294
- Asciidoctor::Extensions.unregister :sample
295
- assert_equal 0, Asciidoctor::Extensions.groups.size
296
- ensure
297
- Asciidoctor::Extensions.unregister_all
298
- end
299
- end
300
-
301
- test 'should unregister extension group by string name' do
302
- begin
303
- Asciidoctor::Extensions.register :sample, SampleExtensionGroup
304
- refute_nil Asciidoctor::Extensions.groups
305
- assert_equal 1, Asciidoctor::Extensions.groups.size
306
- Asciidoctor::Extensions.unregister 'sample'
307
- assert_equal 0, Asciidoctor::Extensions.groups.size
308
- ensure
309
- Asciidoctor::Extensions.unregister_all
310
- end
311
- end
312
-
313
- test 'should unregister multiple extension groups by name' do
314
- begin
315
- Asciidoctor::Extensions.register :sample1, SampleExtensionGroup
316
- Asciidoctor::Extensions.register :sample2, SampleExtensionGroup
317
- refute_nil Asciidoctor::Extensions.groups
318
- assert_equal 2, Asciidoctor::Extensions.groups.size
319
- Asciidoctor::Extensions.unregister :sample1, :sample2
320
- assert_equal 0, Asciidoctor::Extensions.groups.size
321
- ensure
322
- Asciidoctor::Extensions.unregister_all
323
- end
324
- end
325
-
326
- test 'should get class for top-level class name' do
327
- clazz = Asciidoctor::Extensions.class_for_name 'String'
328
- refute_nil clazz
329
- assert_equal String, clazz
330
- end
331
-
332
- test 'should get class for class name in module' do
333
- clazz = Asciidoctor::Extensions.class_for_name 'Asciidoctor::Document'
334
- refute_nil clazz
335
- assert_equal Asciidoctor::Document, clazz
336
- end
337
-
338
- test 'should get class for class name resolved from root' do
339
- clazz = Asciidoctor::Extensions.class_for_name '::Asciidoctor::Document'
340
- refute_nil clazz
341
- assert_equal Asciidoctor::Document, clazz
342
- end
343
-
344
- test 'should raise exception if cannot find class for name' do
345
- begin
346
- Asciidoctor::Extensions.class_for_name 'InvalidModule::InvalidClass'
347
- flunk 'Expecting RuntimeError to be raised'
348
- rescue NameError => e
349
- assert_equal 'Could not resolve class for name: InvalidModule::InvalidClass', e.message
350
- end
351
- end
352
-
353
- test 'should raise exception if constant name is invalid' do
354
- begin
355
- Asciidoctor::Extensions.class_for_name 'foobar'
356
- flunk 'Expecting RuntimeError to be raised'
357
- rescue NameError => e
358
- assert_equal 'Could not resolve class for name: foobar', e.message
359
- end
360
- end
361
-
362
- test 'should raise exception if class not found in scope' do
363
- begin
364
- Asciidoctor::Extensions.class_for_name 'Asciidoctor::Extensions::String'
365
- flunk 'Expecting RuntimeError to be raised'
366
- rescue NameError => e
367
- assert_equal 'Could not resolve class for name: Asciidoctor::Extensions::String', e.message
368
- end
369
- end
370
-
371
- test 'should raise exception if name resolves to module' do
372
- begin
373
- Asciidoctor::Extensions.class_for_name 'Asciidoctor::Extensions'
374
- flunk 'Expecting RuntimeError to be raised'
375
- rescue NameError => e
376
- assert_equal 'Could not resolve class for name: Asciidoctor::Extensions', e.message
377
- end
378
- end
379
-
380
- test 'should resolve class if class is given' do
381
- clazz = Asciidoctor::Extensions.resolve_class Asciidoctor::Document
382
- refute_nil clazz
383
- assert_equal Asciidoctor::Document, clazz
384
- end
385
-
386
- test 'should resolve class if class from string' do
387
- clazz = Asciidoctor::Extensions.resolve_class 'Asciidoctor::Document'
388
- refute_nil clazz
389
- assert_equal Asciidoctor::Document, clazz
390
- end
391
-
392
- test 'should not resolve class if not in scope' do
393
- begin
394
- Asciidoctor::Extensions.resolve_class 'Asciidoctor::Extensions::String'
395
- flunk 'Expecting RuntimeError to be raised'
396
- rescue NameError => e
397
- assert_equal 'Could not resolve class for name: Asciidoctor::Extensions::String', e.message
398
- end
399
- end
400
-
401
- test 'should raise NameError if extension class cannot be resolved from string' do
402
- begin
403
- Asciidoctor::Extensions.register do
404
- block 'foobar'
405
- end
406
- empty_document
407
- flunk 'Expecting RuntimeError to be raised'
408
- rescue NameError => e
409
- assert_equal 'Could not resolve class for name: foobar', e.message
410
- ensure
411
- Asciidoctor::Extensions.unregister_all
412
- end
413
- end
414
-
415
- test 'should allow standalone registry to be created but not registered' do
416
- registry = Asciidoctor::Extensions.create 'sample' do
417
- block do
418
- named :whisper
419
- bound_to :paragraph
420
- parses_content_as :simple
421
- def process parent, reader, attributes
422
- create_paragraph parent, reader.lines.map(&:downcase), attributes
423
- end
424
- end
425
- end
426
-
427
- assert_instance_of Asciidoctor::Extensions::Registry, registry
428
- refute_nil registry.groups
429
- assert_equal 1, registry.groups.size
430
- assert_equal 'sample', registry.groups.keys.first
431
- assert_equal 0, Asciidoctor::Extensions.groups.size
432
- end
433
- end
434
-
435
- context 'Activate' do
436
- test 'should call activate on extension group class' do
437
- begin
438
- doc = Asciidoctor::Document.new
439
- Asciidoctor::Extensions.register :sample, SampleExtensionGroup
440
- registry = Asciidoctor::Extensions::Registry.new
441
- registry.activate doc
442
- assert doc.attr? 'activate-method-called'
443
- assert registry.preprocessors?
444
- ensure
445
- Asciidoctor::Extensions.unregister_all
446
- end
447
- end
448
-
449
- test 'should invoke extension block' do
450
- begin
451
- doc = Asciidoctor::Document.new
452
- Asciidoctor::Extensions.register do
453
- @document.attributes['block-called'] = ''
454
- preprocessor SamplePreprocessor
455
- end
456
- registry = Asciidoctor::Extensions::Registry.new
457
- registry.activate doc
458
- assert doc.attr? 'block-called'
459
- assert registry.preprocessors?
460
- ensure
461
- Asciidoctor::Extensions.unregister_all
462
- end
463
- end
464
-
465
- test 'should create registry in Document if extensions are loaded' do
466
- begin
467
- SampleExtensionGroup.register
468
- doc = Asciidoctor::Document.new
469
- assert doc.extensions?
470
- assert_kind_of Asciidoctor::Extensions::Registry, doc.extensions
471
- ensure
472
- Asciidoctor::Extensions.unregister_all
473
- end
474
-
475
- end
476
- end
477
-
478
- context 'Instantiate' do
479
- test 'should instantiate preprocessors' do
480
- registry = Asciidoctor::Extensions::Registry.new
481
- registry.preprocessor SamplePreprocessor
482
- registry.activate Asciidoctor::Document.new
483
- assert registry.preprocessors?
484
- extensions = registry.preprocessors
485
- assert_equal 1, extensions.size
486
- assert_kind_of Asciidoctor::Extensions::ProcessorExtension, extensions.first
487
- assert_kind_of SamplePreprocessor, extensions.first.instance
488
- assert_kind_of Method, extensions.first.process_method
489
- end
490
-
491
- test 'should instantiate include processors' do
492
- registry = Asciidoctor::Extensions::Registry.new
493
- registry.include_processor SampleIncludeProcessor
494
- registry.activate Asciidoctor::Document.new
495
- assert registry.include_processors?
496
- extensions = registry.include_processors
497
- assert_equal 1, extensions.size
498
- assert_kind_of Asciidoctor::Extensions::ProcessorExtension, extensions.first
499
- assert_kind_of SampleIncludeProcessor, extensions.first.instance
500
- assert_kind_of Method, extensions.first.process_method
501
- end
502
-
503
- test 'should instantiate docinfo processors' do
504
- registry = Asciidoctor::Extensions::Registry.new
505
- registry.docinfo_processor SampleDocinfoProcessor
506
- registry.activate Asciidoctor::Document.new
507
- assert registry.docinfo_processors?
508
- assert registry.docinfo_processors?(:head)
509
- extensions = registry.docinfo_processors
510
- assert_equal 1, extensions.size
511
- assert_kind_of Asciidoctor::Extensions::ProcessorExtension, extensions.first
512
- assert_kind_of SampleDocinfoProcessor, extensions.first.instance
513
- assert_kind_of Method, extensions.first.process_method
514
- end
515
-
516
- # NOTE intentionally using the legacy names
517
- test 'should instantiate tree processors' do
518
- registry = Asciidoctor::Extensions::Registry.new
519
- registry.treeprocessor SampleTreeprocessor
520
- registry.activate Asciidoctor::Document.new
521
- assert registry.treeprocessors?
522
- extensions = registry.treeprocessors
523
- assert_equal 1, extensions.size
524
- assert_kind_of Asciidoctor::Extensions::ProcessorExtension, extensions.first
525
- assert_kind_of SampleTreeprocessor, extensions.first.instance
526
- assert_kind_of Method, extensions.first.process_method
527
- end
528
-
529
- test 'should instantiate postprocessors' do
530
- registry = Asciidoctor::Extensions::Registry.new
531
- registry.postprocessor SamplePostprocessor
532
- registry.activate Asciidoctor::Document.new
533
- assert registry.postprocessors?
534
- extensions = registry.postprocessors
535
- assert_equal 1, extensions.size
536
- assert_kind_of Asciidoctor::Extensions::ProcessorExtension, extensions.first
537
- assert_kind_of SamplePostprocessor, extensions.first.instance
538
- assert_kind_of Method, extensions.first.process_method
539
- end
540
-
541
- test 'should instantiate block processor' do
542
- registry = Asciidoctor::Extensions::Registry.new
543
- registry.block SampleBlock, :sample
544
- registry.activate Asciidoctor::Document.new
545
- assert registry.blocks?
546
- assert registry.registered_for_block? :sample, :paragraph
547
- extension = registry.find_block_extension :sample
548
- assert_kind_of Asciidoctor::Extensions::ProcessorExtension, extension
549
- assert_kind_of SampleBlock, extension.instance
550
- assert_kind_of Method, extension.process_method
551
- end
552
-
553
- test 'should not match block processor for unsupported context' do
554
- registry = Asciidoctor::Extensions::Registry.new
555
- registry.block SampleBlock, :sample
556
- registry.activate Asciidoctor::Document.new
557
- refute registry.registered_for_block? :sample, :sidebar
558
- end
559
-
560
- test 'should instantiate block macro processor' do
561
- registry = Asciidoctor::Extensions::Registry.new
562
- registry.block_macro SampleBlockMacro, 'sample'
563
- registry.activate Asciidoctor::Document.new
564
- assert registry.block_macros?
565
- assert registry.registered_for_block_macro? 'sample'
566
- extension = registry.find_block_macro_extension 'sample'
567
- assert_kind_of Asciidoctor::Extensions::ProcessorExtension, extension
568
- assert_kind_of SampleBlockMacro, extension.instance
569
- assert_kind_of Method, extension.process_method
570
- end
571
-
572
- test 'should instantiate inline macro processor' do
573
- registry = Asciidoctor::Extensions::Registry.new
574
- registry.inline_macro SampleInlineMacro, 'sample'
575
- registry.activate Asciidoctor::Document.new
576
- assert registry.inline_macros?
577
- assert registry.registered_for_inline_macro? 'sample'
578
- extension = registry.find_inline_macro_extension 'sample'
579
- assert_kind_of Asciidoctor::Extensions::ProcessorExtension, extension
580
- assert_kind_of SampleInlineMacro, extension.instance
581
- assert_kind_of Method, extension.process_method
582
- end
583
-
584
- test 'should allow processors to be registered by a string name' do
585
- registry = Asciidoctor::Extensions::Registry.new
586
- registry.preprocessor 'SamplePreprocessor'
587
- registry.activate Asciidoctor::Document.new
588
- assert registry.preprocessors?
589
- extensions = registry.preprocessors
590
- assert_equal 1, extensions.size
591
- assert_kind_of Asciidoctor::Extensions::ProcessorExtension, extensions.first
592
- end
593
- end
594
-
595
- context 'Integration' do
596
- test 'can provide extension registry as an option' do
597
- registry = Asciidoctor::Extensions.create do
598
- tree_processor SampleTreeProcessor
599
- end
600
-
601
- doc = document_from_string %(= Document Title\n\ncontent), :extension_registry => registry
602
- refute_nil doc.extensions
603
- assert_equal 1, doc.extensions.groups.size
604
- assert doc.extensions.tree_processors?
605
- assert_equal 1, doc.extensions.tree_processors.size
606
- assert_equal 0, Asciidoctor::Extensions.groups.size
607
- end
608
-
609
- # NOTE I'm not convinced we want to continue to support this use case
610
- test 'can provide extension registry created without any groups as option' do
611
- registry = Asciidoctor::Extensions.create
612
- registry.tree_processor SampleTreeProcessor
613
-
614
- doc = document_from_string %(= Document Title\n\ncontent), :extension_registry => registry
615
- refute_nil doc.extensions
616
- assert_equal 0, doc.extensions.groups.size
617
- assert doc.extensions.tree_processors?
618
- assert_equal 1, doc.extensions.tree_processors.size
619
- assert_equal 0, Asciidoctor::Extensions.groups.size
620
- end
621
-
622
- test 'can provide extensions proc as option' do
623
- doc = document_from_string %(= Document Title\n\ncontent), :extensions => proc {
624
- tree_processor SampleTreeProcessor
625
- }
626
- refute_nil doc.extensions
627
- assert_equal 1, doc.extensions.groups.size
628
- assert doc.extensions.tree_processors?
629
- assert_equal 1, doc.extensions.tree_processors.size
630
- assert_equal 0, Asciidoctor::Extensions.groups.size
631
- end
632
-
633
- test 'should invoke preprocessors before parsing document' do
634
- input = <<-EOS
635
- junk line
636
-
637
- = Document Title
638
-
639
- sample content
640
- EOS
641
-
642
- begin
643
- Asciidoctor::Extensions.register do
644
- preprocessor ScrubHeaderPreprocessor
645
- end
646
-
647
- doc = document_from_string input
648
- assert doc.attr? 'skipped'
649
- assert_equal 'junk line', (doc.attr 'skipped').strip
650
- assert doc.has_header?
651
- assert_equal 'Document Title', doc.doctitle
652
- ensure
653
- Asciidoctor::Extensions.unregister_all
654
- end
655
- end
656
-
657
- test 'should invoke include processor to process include macro' do
658
- input = <<-EOS
659
- before
660
-
661
- include::lorem-ipsum.txt[]
662
-
663
- after
664
- EOS
665
-
666
- begin
667
- Asciidoctor::Extensions.register do
668
- include_processor BoilerplateTextIncludeProcessor
669
- end
670
-
671
- result = convert_string input, :safe => :server
672
- assert_css '.paragraph > p', result, 3
673
- assert_includes result, 'before'
674
- assert_includes result, 'Lorem ipsum'
675
- assert_includes result, 'after'
676
- ensure
677
- Asciidoctor::Extensions.unregister_all
678
- end
679
- end
680
-
681
- test 'should call include processor to process include directive' do
682
- input = <<-EOS
683
- first line
684
-
685
- include::include-file.asciidoc[]
686
-
687
- last line
688
- EOS
689
-
690
- registry = Asciidoctor::Extensions.create do
691
- include_processor do
692
- handles? do |target|
693
- target == 'include-file.asciidoc'
694
- end
695
-
696
- process do |doc, reader, target, attributes|
697
- # demonstrate that push_include normalizes endlines
698
- content = ["include target:: #{target}\n", "\n", "middle line\n"]
699
- reader.push_include content, target, target, 1, attributes
700
- end
701
- end
702
- end
703
- # Safe Mode is not required here
704
- document = empty_document :base_dir => testdir, :extension_registry => registry
705
- reader = Asciidoctor::PreprocessorReader.new document, input, nil, :normalize => true
706
- lines = []
707
- lines << reader.read_line
708
- lines << reader.read_line
709
- lines << reader.read_line
710
- assert_equal 'include target:: include-file.asciidoc', lines.last
711
- assert_equal 'include-file.asciidoc: line 2', reader.line_info
712
- while reader.has_more_lines?
713
- lines << reader.read_line
714
- end
715
- source = lines * ::Asciidoctor::LF
716
- assert_match(/^include target:: include-file.asciidoc$/, source)
717
- assert_match(/^middle line$/, source)
718
- end
719
-
720
- test 'should invoke tree processors after parsing document' do
721
- input = <<-EOS
722
- = Document Title
723
- Doc Writer
724
-
725
- content
726
- EOS
727
-
728
- begin
729
- Asciidoctor::Extensions.register do
730
- tree_processor ReplaceAuthorTreeProcessor
731
- end
732
-
733
- doc = document_from_string input
734
- assert_equal 'Ghost Writer', doc.author
735
- ensure
736
- Asciidoctor::Extensions.unregister_all
737
- end
738
- end
739
-
740
- test 'should set source_location on document before invoking tree processors' do
741
- begin
742
- Asciidoctor::Extensions.register do
743
- tree_processor do
744
- process do |doc|
745
- para = create_paragraph doc.blocks.last.parent, %(file: #{doc.file}, lineno: #{doc.lineno}), {}
746
- doc << para
747
- end
748
- end
749
- end
750
-
751
- sample_doc = fixture_path 'sample.asciidoc'
752
- doc = Asciidoctor.load_file sample_doc, :sourcemap => true
753
- assert_includes doc.convert, 'file: sample.asciidoc, lineno: 1'
754
- ensure
755
- Asciidoctor::Extensions.unregister_all
756
- end
757
- end
758
-
759
- test 'should allow tree processor to replace tree' do
760
- input = <<-EOS
761
- = Original Document
762
- Doc Writer
763
-
764
- content
765
- EOS
766
-
767
- begin
768
- Asciidoctor::Extensions.register do
769
- tree_processor ReplaceTreeTreeProcessor
770
- end
771
-
772
- doc = document_from_string input
773
- assert_equal 'Replacement Document', doc.doctitle
774
- ensure
775
- Asciidoctor::Extensions.unregister_all
776
- end
777
- end
778
-
779
- test 'should honor block title assigned in tree processor' do
780
- input = <<-EOS
781
- = Document Title
782
- :!example-caption:
783
-
784
- .Old block title
785
- ====
786
- example block content
787
- ====
788
- EOS
789
-
790
- old_title = nil
791
- begin
792
- Asciidoctor::Extensions.register do
793
- tree_processor do
794
- process do |doc|
795
- ex = (doc.find_by :context => :example)[0]
796
- old_title = ex.title
797
- ex.title = 'New block title'
798
- end
799
- end
800
- end
801
-
802
- doc = document_from_string input
803
- assert_equal 'Old block title', old_title
804
- assert_equal 'New block title', (doc.find_by :context => :example)[0].title
805
- ensure
806
- Asciidoctor::Extensions.unregister_all
807
- end
808
- end
809
-
810
- test 'should be able to register preferred tree processor' do
811
- begin
812
- Asciidoctor::Extensions.register do
813
- tree_processor do
814
- process do |doc|
815
- doc << (create_paragraph doc, 'd', {})
816
- nil
817
- end
818
- end
819
-
820
- tree_processor do
821
- prefer
822
- process do |doc|
823
- doc << (create_paragraph doc, 'c', {})
824
- nil
825
- end
826
- end
827
-
828
- prefer :tree_processor do
829
- process do |doc|
830
- doc << (create_paragraph doc, 'b', {})
831
- nil
832
- end
833
- end
834
-
835
- prefer tree_processor {
836
- process do |doc|
837
- doc << (create_paragraph doc, 'a', {})
838
- nil
839
- end
840
- }
841
-
842
- prefer :tree_processor, SelfSigningTreeProcessor
843
- end
844
-
845
- (doc = empty_document).convert
846
- assert_equal %w(SelfSigningTreeProcessor a b c d), doc.blocks.map {|b| b.lines[0] }
847
- ensure
848
- Asciidoctor::Extensions.unregister_all
849
- end
850
- end
851
-
852
- test 'should invoke postprocessors after converting document' do
853
- input = <<-EOS
854
- * one
855
- * two
856
- * three
857
- EOS
858
-
859
- begin
860
- Asciidoctor::Extensions.register do
861
- postprocessor StripAttributesPostprocessor
862
- end
863
-
864
- output = convert_string input
865
- refute_match(/<div class="ulist">/, output)
866
- ensure
867
- Asciidoctor::Extensions.unregister_all
868
- end
869
- end
870
-
871
- test 'should invoke processor for custom block' do
872
- input = <<-EOS
873
- [yell]
874
- Hi there!
875
- EOS
876
-
877
- begin
878
- Asciidoctor::Extensions.register do
879
- block UppercaseBlock
880
- end
881
-
882
- output = convert_string_to_embedded input
883
- assert_xpath '//p', output, 1
884
- assert_xpath '//p[text()="HI THERE!"]', output, 1
885
- ensure
886
- Asciidoctor::Extensions.unregister_all
887
- end
888
- end
889
-
890
- test 'should invoke processor for custom block in an AsciiDoc table cell' do
891
- input = <<-EOS
892
- |===
893
- a|
894
- [yell]
895
- Hi there!
896
- |===
897
- EOS
898
-
899
- begin
900
- Asciidoctor::Extensions.register do
901
- block UppercaseBlock
902
- end
903
-
904
- output = convert_string_to_embedded input
905
- assert_xpath '/table//p', output, 1
906
- assert_xpath '/table//p[text()="HI THERE!"]', output, 1
907
- ensure
908
- Asciidoctor::Extensions.unregister_all
909
- end
910
- end
911
-
912
- test 'should pass cloaked context in attributes passed to process method of custom block' do
913
- input = <<-EOS
914
- [custom]
915
- ****
916
- sidebar
917
- ****
918
- EOS
919
-
920
- cloaked_context = nil
921
- begin
922
- Asciidoctor::Extensions.register do
923
- block :custom do
924
- on_context :sidebar
925
- process do |doc, reader, attrs|
926
- cloaked_context = attrs['cloaked-context']
927
- nil
928
- end
929
- end
930
- end
931
-
932
- convert_string_to_embedded input
933
- assert_equal :sidebar, cloaked_context
934
- ensure
935
- Asciidoctor::Extensions.unregister_all
936
- end
937
- end
938
-
939
- test 'should invoke processor for custom block macro' do
940
- input = <<-EOS
941
- snippet::12345[mode=edit]
942
- EOS
943
-
944
- begin
945
- Asciidoctor::Extensions.register do
946
- block_macro SnippetMacro, :snippet
947
- end
948
-
949
- output = convert_string_to_embedded input
950
- assert_includes output, '<script src="http://example.com/12345.js?_mode=edit"></script>'
951
- ensure
952
- Asciidoctor::Extensions.unregister_all
953
- end
954
- end
955
-
956
- test 'should substitute attributes in target of custom block macro' do
957
- input = <<-EOS
958
- snippet::{gist-id}[mode=edit]
959
- EOS
960
-
961
- begin
962
- Asciidoctor::Extensions.register do
963
- block_macro SnippetMacro, :snippet
964
- end
965
-
966
- output = convert_string_to_embedded input, :attributes => { 'gist-id' => '12345' }
967
- assert_includes output, '<script src="http://example.com/12345.js?_mode=edit"></script>'
968
- ensure
969
- Asciidoctor::Extensions.unregister_all
970
- end
971
- end
972
-
973
- test 'should drop block macro line if target references missing attribute and attribute-missing is drop-line' do
974
- input = <<-EOS
975
- [.rolename]
976
- snippet::{gist-ns}12345[mode=edit]
977
-
978
- following paragraph
979
- EOS
980
-
981
- begin
982
- Asciidoctor::Extensions.register do
983
- block_macro SnippetMacro, :snippet
984
- end
985
-
986
- doc, output = nil, nil
987
- using_memory_logger do |logger|
988
- doc = document_from_string input, :attributes => { 'attribute-missing' => 'drop-line' }
989
- assert_equal 1, doc.blocks.size
990
- assert_equal :paragraph, doc.blocks[0].context
991
- output = doc.convert
992
- assert_message logger, :WARN, 'dropping line containing reference to missing attribute: gist-ns'
993
- end
994
- assert_css '.paragraph', output, 1
995
- assert_css '.rolename', output, 0
996
- ensure
997
- Asciidoctor::Extensions.unregister_all
998
- end
999
- end
1000
-
1001
- test 'should invoke processor for custom block macro in an AsciiDoc table cell' do
1002
- input = <<-EOS
1003
- |===
1004
- a|message::hi[]
1005
- |===
1006
- EOS
1007
-
1008
- begin
1009
- Asciidoctor::Extensions.register do
1010
- block_macro :message do
1011
- process do |parent, target, attrs|
1012
- create_paragraph parent, target.upcase, {}
1013
- end
1014
- end
1015
- end
1016
-
1017
- output = convert_string_to_embedded input
1018
- assert_xpath '/table//p[text()="HI"]', output, 1
1019
- ensure
1020
- Asciidoctor::Extensions.unregister_all
1021
- end
1022
- end
1023
-
1024
- test 'should match short form of block macro' do
1025
- input = <<-EOS
1026
- custom-toc::[]
1027
- EOS
1028
-
1029
- resolved_target = nil
1030
-
1031
- begin
1032
- Asciidoctor::Extensions.register do
1033
- block_macro do
1034
- named 'custom-toc'
1035
- process do |parent, target, attrs|
1036
- resolved_target = target
1037
- create_pass_block parent, '<!-- custom toc goes here -->', {}, :content_model => :raw
1038
- end
1039
- end
1040
- end
1041
-
1042
- output = convert_string_to_embedded input
1043
- assert_equal '<!-- custom toc goes here -->', output
1044
- assert_equal '', resolved_target
1045
- ensure
1046
- Asciidoctor::Extensions.unregister_all
1047
- end
1048
- end
1049
-
1050
- test 'should fail to convert if name of block macro is illegal' do
1051
- input = 'illegal name::target[]'
1052
-
1053
- begin
1054
- Asciidoctor::Extensions.register do
1055
- block_macro do
1056
- named 'illegal name'
1057
- process do |parent, target, attrs|
1058
- nil
1059
- end
1060
- end
1061
- end
1062
-
1063
- assert_raises ArgumentError do
1064
- convert_string_to_embedded input
1065
- end
1066
- ensure
1067
- Asciidoctor::Extensions.unregister_all
1068
- end
1069
- end
1070
-
1071
- test 'should be able to set header attribute in block macro processor' do
1072
- begin
1073
- Asciidoctor::Extensions.register do
1074
- block_macro do
1075
- named :attribute
1076
- resolves_attributes '1:value'
1077
- process do |parent, target, attrs|
1078
- parent.document.set_attr target, attrs['value']
1079
- nil
1080
- end
1081
- end
1082
- block_macro do
1083
- named :header_attribute
1084
- resolves_attributes '1:value'
1085
- process do |parent, target, attrs|
1086
- parent.document.set_header_attribute target, attrs['value']
1087
- nil
1088
- end
1089
- end
1090
- end
1091
- input = <<-EOS
1092
- attribute::yin[yang]
1093
-
1094
- header_attribute::foo[bar]
1095
- EOS
1096
- doc = document_from_string input
1097
- assert_nil doc.attr 'yin'
1098
- assert_equal 'bar', (doc.attr 'foo')
1099
- ensure
1100
- Asciidoctor::Extensions.unregister_all
1101
- end
1102
- end
1103
-
1104
- test 'should invoke processor for custom inline macro' do
1105
- begin
1106
- Asciidoctor::Extensions.register do
1107
- inline_macro TemperatureMacro, :deg
1108
- end
1109
-
1110
- output = convert_string_to_embedded 'Room temperature is deg:25[C,precision=0].', :attributes => { 'temperature-unit' => 'F' }
1111
- assert_includes output, 'Room temperature is 25 &#176;C.'
1112
-
1113
- output = convert_string_to_embedded 'Normal body temperature is deg:37[].', :attributes => { 'temperature-unit' => 'F' }
1114
- assert_includes output, 'Normal body temperature is 98.6 &#176;F.'
1115
- ensure
1116
- Asciidoctor::Extensions.unregister_all
1117
- end
1118
- end
1119
-
1120
- test 'should resolve regexp for inline macro lazily' do
1121
- begin
1122
- Asciidoctor::Extensions.register do
1123
- inline_macro do
1124
- named :label
1125
- with_format :short
1126
- resolves_attributes false
1127
- process do |parent, target|
1128
- %(<label>#{target}</label>)
1129
- end
1130
- end
1131
- end
1132
-
1133
- output = convert_string_to_embedded 'label:[Checkbox]'
1134
- assert_includes output, '<label>Checkbox</label>'
1135
- ensure
1136
- Asciidoctor::Extensions.unregister_all
1137
- end
1138
- end
1139
-
1140
- test 'should assign captures correctly for inline macros' do
1141
- begin
1142
- Asciidoctor::Extensions.register do
1143
- inline_macro do
1144
- named :short_attributes
1145
- with_format :short
1146
- resolves_attributes '1:name'
1147
- process do |parent, target, attrs|
1148
- %(target=#{target.inspect}, attributes=#{attrs.sort_by {|k, _| k.to_s }.inspect})
1149
- end
1150
- end
1151
-
1152
- inline_macro do
1153
- named :short_text
1154
- with_format :short
1155
- resolves_attributes false
1156
- process do |parent, target, attrs|
1157
- %(target=#{target.inspect}, attributes=#{attrs.sort_by {|k, _| k.to_s }.inspect})
1158
- end
1159
- end
1160
-
1161
- inline_macro do
1162
- named :'full-attributes'
1163
- resolves_attributes '1:name' => nil
1164
- process do |parent, target, attrs|
1165
- %(target=#{target.inspect}, attributes=#{attrs.sort_by {|k, _| k.to_s }.inspect})
1166
- end
1167
- end
1168
-
1169
- inline_macro do
1170
- named :'full-text'
1171
- resolves_attributes false
1172
- process do |parent, target, attrs|
1173
- %(target=#{target.inspect}, attributes=#{attrs.sort_by {|k, _| k.to_s }.inspect})
1174
- end
1175
- end
1176
-
1177
- inline_macro do
1178
- named :@short_match
1179
- matching %r/@(\w+)/
1180
- resolves_attributes false
1181
- process do |parent, target, attrs|
1182
- %(target=#{target.inspect}, attributes=#{attrs.sort_by {|k, _| k.to_s }.inspect})
1183
- end
1184
- end
1185
- end
1186
-
1187
- input = <<-EOS
1188
- [subs=normal]
1189
- ++++
1190
- short_attributes:[]
1191
- short_attributes:[value,key=val]
1192
- short_text:[]
1193
- short_text:[[text\\]]
1194
- full-attributes:target[]
1195
- full-attributes:target[value,key=val]
1196
- full-text:target[]
1197
- full-text:target[[text\\]]
1198
- @target
1199
- ++++
1200
- EOS
1201
- expected = <<-EOS.chomp
1202
- target="", attributes=[]
1203
- target="value,key=val", attributes=[[1, "value"], ["key", "val"], ["name", "value"]]
1204
- target="", attributes=[["text", ""]]
1205
- target="[text]", attributes=[["text", "[text]"]]
1206
- target="target", attributes=[]
1207
- target="target", attributes=[[1, "value"], ["key", "val"], ["name", "value"]]
1208
- target="target", attributes=[["text", ""]]
1209
- target="target", attributes=[["text", "[text]"]]
1210
- target="target", attributes=[]
1211
- EOS
1212
- output = convert_string_to_embedded input
1213
- assert_equal expected, output
1214
- ensure
1215
- Asciidoctor::Extensions.unregister_all
1216
- end
1217
- end
1218
-
1219
- test 'should invoke convert on return value if value is an inline node' do
1220
- begin
1221
- Asciidoctor::Extensions.register do
1222
- inline_macro do
1223
- named :mention
1224
- resolves_attributes false
1225
- process do |parent, target, attrs|
1226
- if (text = attrs['text']).empty?
1227
- text = %(@#{target})
1228
- end
1229
- create_anchor parent, text, :type => :link, :target => %(https://github.com/#{target})
1230
- end
1231
- end
1232
- end
1233
-
1234
- output = convert_string_to_embedded 'mention:mojavelinux[Dan]'
1235
- assert_includes output, '<a href="https://github.com/mojavelinux">Dan</a>'
1236
- ensure
1237
- Asciidoctor::Extensions.unregister_all
1238
- end
1239
- end
1240
-
1241
- test 'should not carry over attributes if block processor returns nil' do
1242
- begin
1243
- Asciidoctor::Extensions.register do
1244
- block do
1245
- named 'skip-me'
1246
- on_context :paragraph
1247
- parses_content_as :raw
1248
- process do |parent, reader, attrs|
1249
- nil
1250
- end
1251
- end
1252
- end
1253
- input = <<-EOS
1254
- .unused title
1255
- [skip-me]
1256
- not shown
1257
-
1258
- --
1259
- shown
1260
- --
1261
- EOS
1262
- doc = document_from_string input
1263
- assert_equal 1, doc.blocks.size
1264
- assert_nil doc.blocks[0].attributes['title']
1265
- ensure
1266
- Asciidoctor::Extensions.unregister_all
1267
- end
1268
- end
1269
-
1270
- test 'should not invoke process method or carry over attributes if block processor declares skip content model' do
1271
- begin
1272
- process_method_called = false
1273
- Asciidoctor::Extensions.register do
1274
- block do
1275
- named :ignore
1276
- on_context :paragraph
1277
- parses_content_as :skip
1278
- process do |parent, reader, attrs|
1279
- process_method_called = true
1280
- nil
1281
- end
1282
- end
1283
- end
1284
- input = <<-EOS
1285
- .unused title
1286
- [ignore]
1287
- not shown
1288
-
1289
- --
1290
- shown
1291
- --
1292
- EOS
1293
- doc = document_from_string input
1294
- refute process_method_called
1295
- assert_equal 1, doc.blocks.size
1296
- assert_nil doc.blocks[0].attributes['title']
1297
- ensure
1298
- Asciidoctor::Extensions.unregister_all
1299
- end
1300
- end
1301
-
1302
- test 'should pass attributes by value to block processor' do
1303
- begin
1304
- Asciidoctor::Extensions.register do
1305
- block do
1306
- named :foo
1307
- on_context :paragraph
1308
- parses_content_as :raw
1309
- process do |parent, reader, attrs|
1310
- original_attrs = attrs.dup
1311
- attrs.delete('title')
1312
- create_paragraph parent, reader.read_lines, original_attrs.merge('id' => 'value')
1313
- end
1314
- end
1315
- end
1316
- input = <<-EOS
1317
- .title
1318
- [foo]
1319
- content
1320
- EOS
1321
- doc = document_from_string input
1322
- assert_equal 1, doc.blocks.size
1323
- assert_equal 'title', doc.blocks[0].attributes['title']
1324
- assert_equal 'value', doc.blocks[0].id
1325
- ensure
1326
- Asciidoctor::Extensions.unregister_all
1327
- end
1328
- end
1329
-
1330
- test 'parse_content should not share attributes between parsed blocks' do
1331
- begin
1332
- Asciidoctor::Extensions.register do
1333
- block do
1334
- named :wrap
1335
- on_context :open
1336
- process do |parent, reader, attrs|
1337
- wrap = create_open_block parent, nil, attrs
1338
- parse_content wrap, reader.read_lines
1339
- end
1340
- end
1341
- end
1342
- input = <<-EOS
1343
- [wrap]
1344
- --
1345
- [foo=bar]
1346
- ====
1347
- content
1348
- ====
1349
-
1350
- [baz=qux]
1351
- ====
1352
- content
1353
- ====
1354
- --
1355
- EOS
1356
- doc = document_from_string input
1357
- assert_equal 1, doc.blocks.size
1358
- wrap = doc.blocks[0]
1359
- assert_equal 2, wrap.blocks.size
1360
- assert_equal 2, wrap.blocks[0].attributes.size
1361
- assert_equal 2, wrap.blocks[1].attributes.size
1362
- assert_nil wrap.blocks[1].attributes['foo']
1363
- ensure
1364
- Asciidoctor::Extensions.unregister_all
1365
- end
1366
- end
1367
-
1368
- test 'create_section should set up all section properties' do
1369
- begin
1370
- sect = nil
1371
- Asciidoctor::Extensions.register do
1372
- block_macro do
1373
- named :sect
1374
- process do |parent, target, attrs|
1375
- opts = (level = attrs.delete 'level') ? { :level => level.to_i } : {}
1376
- attrs['id'] = false if attrs['id'] == 'false'
1377
- parent = parent.parent if parent.context == :preamble
1378
- sect = create_section parent, 'Section Title', attrs, opts
1379
- nil
1380
- end
1381
- end
1382
- end
1383
-
1384
- input_tpl = <<-EOS
1385
- = Document Title
1386
- :doctype: book
1387
- :sectnums:
1388
-
1389
- sect::[%s]
1390
- EOS
1391
-
1392
- {
1393
- '' => ['chapter', 1, false, true, '_section_title'],
1394
- 'level=0' => ['part', 0, false, false, '_section_title'],
1395
- 'level=0,alt' => ['part', 0, false, true, '_section_title', { 'partnums' => '' }],
1396
- 'level=0,style=appendix' => ['appendix', 1, true, true, '_section_title'],
1397
- 'style=appendix' => ['appendix', 1, true, true, '_section_title'],
1398
- 'style=glossary' => ['glossary', 1, true, false, '_section_title'],
1399
- 'style=glossary,alt' => ['glossary', 1, true, :chapter, '_section_title', { 'sectnums' => 'all' }],
1400
- 'style=abstract' => ['chapter', 1, false, true, '_section_title'],
1401
- 'id=section-title' => ['chapter', 1, false, true, 'section-title'],
1402
- 'id=false' => ['chapter', 1, false, true, nil]
1403
- }.each do |attrlist, (expect_sectname, expect_level, expect_special, expect_numbered, expect_id, extra_attrs)|
1404
- input = input_tpl % attrlist
1405
- document_from_string input, :safe => :server, :attributes => extra_attrs
1406
- assert_equal expect_sectname, sect.sectname
1407
- assert_equal expect_level, sect.level
1408
- assert_equal expect_special, sect.special
1409
- assert_equal expect_numbered, sect.numbered
1410
- if expect_id
1411
- assert_equal expect_id, sect.id
1412
- else
1413
- assert_nil sect.id
1414
- end
1415
- end
1416
- ensure
1417
- Asciidoctor::Extensions.unregister_all
1418
- end
1419
- end
1420
-
1421
- test 'should add docinfo to document' do
1422
- input = <<-EOS
1423
- = Document Title
1424
-
1425
- sample content
1426
- EOS
1427
-
1428
- begin
1429
- Asciidoctor::Extensions.register do
1430
- docinfo_processor MetaRobotsDocinfoProcessor
1431
- end
1432
-
1433
- doc = document_from_string input, :safe => :server
1434
- assert_equal '<meta name="robots" content="index,follow">', doc.docinfo
1435
- ensure
1436
- Asciidoctor::Extensions.unregister_all
1437
- end
1438
- end
1439
-
1440
- test 'should add multiple docinfo to document' do
1441
- input = <<-EOS
1442
- = Document Title
1443
-
1444
- sample content
1445
- EOS
1446
-
1447
- begin
1448
- Asciidoctor::Extensions.register do
1449
- docinfo_processor MetaAppDocinfoProcessor
1450
- docinfo_processor MetaRobotsDocinfoProcessor, :position => :>>
1451
- docinfo_processor do
1452
- at_location :footer
1453
- process do |doc|
1454
- '<script><!-- analytics code --></script>'
1455
- end
1456
- end
1457
- end
1458
-
1459
- doc = document_from_string input, :safe => :server
1460
- assert_equal '<meta name="robots" content="index,follow">
1461
- <meta name="application-name" content="Asciidoctor App">', doc.docinfo
1462
- assert_equal '<script><!-- analytics code --></script>', doc.docinfo(:footer)
1463
- ensure
1464
- Asciidoctor::Extensions.unregister_all
1465
- end
1466
- end
1467
-
1468
- test 'should append docinfo to document' do
1469
- begin
1470
- Asciidoctor::Extensions.register do
1471
- docinfo_processor MetaRobotsDocinfoProcessor
1472
- end
1473
- sample_input_path = fixture_path('basic.asciidoc')
1474
-
1475
- output = Asciidoctor.convert_file sample_input_path, :to_file => false,
1476
- :header_footer => true,
1477
- :safe => Asciidoctor::SafeMode::SERVER,
1478
- :attributes => {'docinfo' => ''}
1479
- refute_empty output
1480
- assert_css 'script[src="modernizr.js"]', output, 1
1481
- assert_css 'meta[name="robots"]', output, 1
1482
- assert_css 'meta[http-equiv="imagetoolbar"]', output, 0
1483
- ensure
1484
- Asciidoctor::Extensions.unregister_all
1485
- end
1486
- end
1487
-
1488
- test 'should return extension instance after registering' do
1489
- begin
1490
- exts = []
1491
- Asciidoctor::Extensions.register do
1492
- exts.push preprocessor SamplePreprocessor
1493
- exts.push include_processor SampleIncludeProcessor
1494
- exts.push tree_processor SampleTreeProcessor
1495
- exts.push docinfo_processor SampleDocinfoProcessor
1496
- exts.push postprocessor SamplePostprocessor
1497
- end
1498
- empty_document
1499
- exts.each do |ext|
1500
- assert_kind_of Asciidoctor::Extensions::ProcessorExtension, ext
1501
- end
1502
- ensure
1503
- Asciidoctor::Extensions.unregister_all
1504
- end
1505
- end
1506
-
1507
- test 'should raise an exception if mandatory target attribute is not provided for image block' do
1508
- input = <<-EOS
1509
- cat_in_sink::[]
1510
- EOS
1511
- exception = assert_raises ArgumentError do
1512
- convert_string_to_embedded input, :extension_registry => create_cat_in_sink_block_macro
1513
- end
1514
- assert_match(/target attribute is required/, exception.message)
1515
- end
1516
-
1517
- test 'should assign alt attribute to image block if alt is not provided' do
1518
- input = <<-EOS
1519
- cat_in_sink::25[]
1520
- EOS
1521
- doc = document_from_string input, :header_footer => false, :extension_registry => create_cat_in_sink_block_macro
1522
- image = doc.blocks[0]
1523
- assert_equal 'cat in sink day 25', (image.attr 'alt')
1524
- assert_equal 'cat in sink day 25', (image.attr 'default-alt')
1525
- output = doc.convert
1526
- assert_includes output, '<img src="cat-in-sink-day-25.png" alt="cat in sink day 25">'
1527
- end
1528
-
1529
- test 'should create an image block if mandatory attributes are provided' do
1530
- input = <<-EOS
1531
- cat_in_sink::30[cat in sink (yes)]
1532
- EOS
1533
- doc = document_from_string input, :header_footer => false, :extension_registry => create_cat_in_sink_block_macro
1534
- image = doc.blocks[0]
1535
- assert_equal 'cat in sink (yes)', (image.attr 'alt')
1536
- refute(image.attr? 'default-alt')
1537
- output = doc.convert
1538
- assert_includes output, '<img src="cat-in-sink-day-30.png" alt="cat in sink (yes)">'
1539
- end
1540
-
1541
- test 'should not assign caption on image block if title is not set on custom block macro' do
1542
- input = <<-EOS
1543
- cat_in_sink::30[]
1544
- EOS
1545
- doc = document_from_string input, :header_footer => false, :extension_registry => create_cat_in_sink_block_macro
1546
- output = doc.convert
1547
- assert_xpath '/*[@class="imageblock"]/*[@class="title"]', output, 0
1548
- end
1549
-
1550
- test 'should assign caption on image block if title is set on custom block macro' do
1551
- input = <<-EOS
1552
- .Cat in Sink?
1553
- cat_in_sink::30[]
1554
- EOS
1555
- doc = document_from_string input, :header_footer => false, :extension_registry => create_cat_in_sink_block_macro
1556
- output = doc.convert
1557
- assert_xpath '/*[@class="imageblock"]/*[@class="title"][text()="Figure 1. Cat in Sink?"]', output, 1
1558
- end
1559
- end
1560
- end