asciidoctor 1.5.5 → 1.5.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +216 -1
- data/CONTRIBUTING.adoc +2 -2
- data/Gemfile +20 -1
- data/LICENSE.adoc +1 -1
- data/README-fr.adoc +4 -3
- data/README-jp.adoc +11 -10
- data/README-zh_CN.adoc +4 -3
- data/README.adoc +17 -202
- data/Rakefile +41 -25
- data/asciidoctor.gemspec +9 -10
- data/data/locale/attributes.adoc +216 -34
- data/data/stylesheets/asciidoctor-default.css +23 -16
- data/features/step_definitions.rb +15 -19
- data/features/xref.feature +584 -20
- data/lib/asciidoctor.rb +292 -278
- data/lib/asciidoctor/abstract_block.rb +155 -94
- data/lib/asciidoctor/abstract_node.rb +108 -94
- data/lib/asciidoctor/attribute_list.rb +30 -22
- data/lib/asciidoctor/block.rb +7 -7
- data/lib/asciidoctor/cli/invoker.rb +47 -34
- data/lib/asciidoctor/cli/options.rb +22 -11
- data/lib/asciidoctor/converter.rb +3 -3
- data/lib/asciidoctor/converter/base.rb +2 -2
- data/lib/asciidoctor/converter/composite.rb +1 -1
- data/lib/asciidoctor/converter/docbook45.rb +2 -2
- data/lib/asciidoctor/converter/docbook5.rb +132 -87
- data/lib/asciidoctor/converter/factory.rb +0 -1
- data/lib/asciidoctor/converter/html5.rb +116 -98
- data/lib/asciidoctor/converter/manpage.rb +51 -52
- data/lib/asciidoctor/converter/template.rb +47 -36
- data/lib/asciidoctor/core_ext.rb +8 -2
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +4 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +5 -0
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +1 -1
- data/lib/asciidoctor/core_ext/1.8.7/string/{limit.rb → limit_bytesize.rb} +7 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +1 -1
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +5 -5
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +3 -0
- data/lib/asciidoctor/core_ext/string/{limit.rb → limit_bytesize.rb} +2 -2
- data/lib/asciidoctor/document.rb +216 -213
- data/lib/asciidoctor/extensions.rb +318 -185
- data/lib/asciidoctor/helpers.rb +35 -35
- data/lib/asciidoctor/inline.rb +32 -1
- data/lib/asciidoctor/list.rb +22 -6
- data/lib/asciidoctor/parser.rb +1008 -1038
- data/lib/asciidoctor/path_resolver.rb +46 -50
- data/lib/asciidoctor/reader.rb +275 -251
- data/lib/asciidoctor/section.rb +86 -58
- data/lib/asciidoctor/stylesheets.rb +6 -6
- data/lib/asciidoctor/substitutors.rb +567 -649
- data/lib/asciidoctor/table.rb +163 -108
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +18 -16
- data/man/asciidoctor.adoc +15 -13
- data/test/attributes_test.rb +138 -22
- data/test/blocks_test.rb +377 -97
- data/test/converter_test.rb +13 -0
- data/test/document_test.rb +244 -34
- data/test/extensions_test.rb +409 -42
- data/test/fixtures/asciidoc_index.txt +521 -0
- data/test/fixtures/basic-docinfo-footer.html +6 -0
- data/test/fixtures/basic-docinfo-footer.xml +8 -0
- data/test/fixtures/basic-docinfo.html +1 -0
- data/test/fixtures/basic-docinfo.xml +4 -0
- data/test/fixtures/basic.asciidoc +5 -0
- data/test/fixtures/chapter-a.adoc +3 -0
- data/test/fixtures/child-include.adoc +5 -0
- data/test/fixtures/circle.svg +9 -0
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +1 -0
- data/test/fixtures/custom-docinfodir/docinfo.html +1 -0
- data/test/fixtures/docinfo-footer.html +1 -0
- data/test/fixtures/docinfo-footer.xml +9 -0
- data/test/fixtures/docinfo.html +1 -0
- data/test/fixtures/docinfo.xml +3 -0
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +13 -0
- data/test/fixtures/grandchild-include.adoc +3 -0
- data/test/fixtures/hello-asciidoctor.pdf +69 -0
- data/test/fixtures/include-file.asciidoc +24 -0
- data/test/fixtures/include-file.ml +3 -0
- data/test/fixtures/include-file.xml +5 -0
- data/test/fixtures/master.adoc +5 -0
- data/test/fixtures/mismatched-end-tag.adoc +7 -0
- data/test/fixtures/parent-include-restricted.adoc +5 -0
- data/test/fixtures/parent-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +26 -0
- data/test/fixtures/stylesheets/custom.css +3 -0
- data/test/fixtures/subs-docinfo.html +2 -0
- data/test/fixtures/subs.adoc +7 -0
- data/test/fixtures/tagged-class-enclosed.rb +26 -0
- data/test/fixtures/tagged-class.rb +23 -0
- data/test/fixtures/tip.gif +0 -0
- data/test/invoker_test.rb +82 -4
- data/test/links_test.rb +312 -37
- data/test/lists_test.rb +204 -25
- data/test/manpage_test.rb +191 -4
- data/test/options_test.rb +18 -1
- data/test/paragraphs_test.rb +32 -7
- data/test/parser_test.rb +150 -30
- data/test/paths_test.rb +47 -13
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +366 -126
- data/test/sections_test.rb +203 -56
- data/test/substitutions_test.rb +339 -131
- data/test/tables_test.rb +315 -15
- data/test/test_helper.rb +400 -0
- data/test/text_test.rb +5 -5
- metadata +110 -22
data/test/extensions_test.rb
CHANGED
@@ -3,7 +3,24 @@ unless defined? ASCIIDOCTOR_PROJECT_DIR
|
|
3
3
|
$: << File.dirname(__FILE__); $:.uniq!
|
4
4
|
require 'test_helper'
|
5
5
|
end
|
6
|
-
|
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
|
14
|
+
Asciidoctor::Extensions.groups
|
15
|
+
rescue; end
|
16
|
+
|
17
|
+
doc = empty_document
|
18
|
+
assert doc.extensions?, 'Extensions should be enabled after being autoloaded'
|
19
|
+
|
20
|
+
self.class.remove_tests self.class
|
21
|
+
end
|
22
|
+
self
|
23
|
+
end.new(nil).test_autoload
|
7
24
|
|
8
25
|
class SamplePreprocessor < Asciidoctor::Extensions::Preprocessor
|
9
26
|
def process doc, reader
|
@@ -17,8 +34,13 @@ end
|
|
17
34
|
class SampleDocinfoProcessor < Asciidoctor::Extensions::DocinfoProcessor
|
18
35
|
end
|
19
36
|
|
37
|
+
# NOTE intentionally using the deprecated name
|
20
38
|
class SampleTreeprocessor < Asciidoctor::Extensions::Treeprocessor
|
39
|
+
def process document
|
40
|
+
nil
|
41
|
+
end
|
21
42
|
end
|
43
|
+
SampleTreeProcessor = SampleTreeprocessor
|
22
44
|
|
23
45
|
class SamplePostprocessor < Asciidoctor::Extensions::Postprocessor
|
24
46
|
end
|
@@ -61,7 +83,7 @@ class BoilerplateTextIncludeProcessor < Asciidoctor::Extensions::IncludeProcesso
|
|
61
83
|
end
|
62
84
|
end
|
63
85
|
|
64
|
-
class
|
86
|
+
class ReplaceAuthorTreeProcessor < Asciidoctor::Extensions::TreeProcessor
|
65
87
|
def process document
|
66
88
|
document.attributes['firstname'] = 'Ghost'
|
67
89
|
document.attributes['author'] = 'Ghost Writer'
|
@@ -69,7 +91,7 @@ class ReplaceAuthorTreeprocessor < Asciidoctor::Extensions::Treeprocessor
|
|
69
91
|
end
|
70
92
|
end
|
71
93
|
|
72
|
-
class
|
94
|
+
class ReplaceTreeTreeProcessor < Asciidoctor::Extensions::TreeProcessor
|
73
95
|
def process document
|
74
96
|
if document.doctitle == 'Original Document'
|
75
97
|
Asciidoctor.load %(== Replacement Document\nReplacement Author\n\ncontent)
|
@@ -86,9 +108,9 @@ class StripAttributesPostprocessor < Asciidoctor::Extensions::Postprocessor
|
|
86
108
|
end
|
87
109
|
|
88
110
|
class UppercaseBlock < Asciidoctor::Extensions::BlockProcessor; use_dsl
|
89
|
-
|
90
|
-
|
91
|
-
|
111
|
+
named :yell
|
112
|
+
bound_to :paragraph
|
113
|
+
parses_content_as :simple
|
92
114
|
def process parent, reader, attributes
|
93
115
|
create_paragraph parent, reader.lines.map(&:upcase), attributes
|
94
116
|
end
|
@@ -96,23 +118,43 @@ end
|
|
96
118
|
|
97
119
|
class SnippetMacro < Asciidoctor::Extensions::BlockMacroProcessor
|
98
120
|
def process parent, target, attributes
|
99
|
-
create_pass_block parent, %(<script src="http://example.com/#{target}.js"></script>), {}, :content_model => :raw
|
121
|
+
create_pass_block parent, %(<script src="http://example.com/#{target}.js?_mode=#{attributes['mode']}"></script>), {}, :content_model => :raw
|
100
122
|
end
|
101
123
|
end
|
102
124
|
|
103
125
|
class TemperatureMacro < Asciidoctor::Extensions::InlineMacroProcessor; use_dsl
|
104
126
|
named :degrees
|
105
|
-
|
127
|
+
resolves_attributes '1:units', 'precision=1'
|
106
128
|
def process parent, target, attributes
|
107
129
|
units = attributes['units'] || (parent.document.attr 'temperature-unit', 'C')
|
130
|
+
precision = attributes['precision'].to_i
|
108
131
|
c = target.to_f
|
109
132
|
case units
|
110
133
|
when 'C'
|
111
|
-
%(#{c} °C)
|
134
|
+
%(#{round_with_precision c, precision} °C)
|
112
135
|
when 'F'
|
113
|
-
%(#{c * 1.8 + 32 } °F)
|
136
|
+
%(#{round_with_precision c * 1.8 + 32, precision} °F)
|
114
137
|
else
|
115
|
-
|
138
|
+
raise ::ArgumentError, %(Unknown temperature units: #{units})
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
if (::Numeric.instance_method :round).arity == 0
|
143
|
+
def round_with_precision value, precision = 0
|
144
|
+
if precision == 0
|
145
|
+
value.round
|
146
|
+
else
|
147
|
+
factor = 10 ** precision
|
148
|
+
if precision < 0
|
149
|
+
(value * factor).round.div factor
|
150
|
+
else
|
151
|
+
(value * factor).round.fdiv factor
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
else
|
156
|
+
def round_with_precision value, precision = 0
|
157
|
+
value.round precision
|
116
158
|
end
|
117
159
|
end
|
118
160
|
end
|
@@ -123,8 +165,7 @@ class MetaRobotsDocinfoProcessor < Asciidoctor::Extensions::DocinfoProcessor
|
|
123
165
|
end
|
124
166
|
end
|
125
167
|
|
126
|
-
class MetaAppDocinfoProcessor < Asciidoctor::Extensions::DocinfoProcessor
|
127
|
-
use_dsl
|
168
|
+
class MetaAppDocinfoProcessor < Asciidoctor::Extensions::DocinfoProcessor; use_dsl
|
128
169
|
at_location :head
|
129
170
|
|
130
171
|
def process document
|
@@ -197,43 +238,108 @@ context 'Extensions' do
|
|
197
238
|
end
|
198
239
|
end
|
199
240
|
|
241
|
+
test 'should unregister extension group by symbol name' do
|
242
|
+
begin
|
243
|
+
Asciidoctor::Extensions.register :sample, SampleExtensionGroup
|
244
|
+
refute_nil Asciidoctor::Extensions.groups
|
245
|
+
assert_equal 1, Asciidoctor::Extensions.groups.size
|
246
|
+
Asciidoctor::Extensions.unregister :sample
|
247
|
+
assert_equal 0, Asciidoctor::Extensions.groups.size
|
248
|
+
ensure
|
249
|
+
Asciidoctor::Extensions.unregister_all
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
test 'should unregister extension group by string name' do
|
254
|
+
begin
|
255
|
+
Asciidoctor::Extensions.register :sample, SampleExtensionGroup
|
256
|
+
refute_nil Asciidoctor::Extensions.groups
|
257
|
+
assert_equal 1, Asciidoctor::Extensions.groups.size
|
258
|
+
Asciidoctor::Extensions.unregister 'sample'
|
259
|
+
assert_equal 0, Asciidoctor::Extensions.groups.size
|
260
|
+
ensure
|
261
|
+
Asciidoctor::Extensions.unregister_all
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
test 'should unregister multiple extension groups by name' do
|
266
|
+
begin
|
267
|
+
Asciidoctor::Extensions.register :sample1, SampleExtensionGroup
|
268
|
+
Asciidoctor::Extensions.register :sample2, SampleExtensionGroup
|
269
|
+
refute_nil Asciidoctor::Extensions.groups
|
270
|
+
assert_equal 2, Asciidoctor::Extensions.groups.size
|
271
|
+
Asciidoctor::Extensions.unregister :sample1, :sample2
|
272
|
+
assert_equal 0, Asciidoctor::Extensions.groups.size
|
273
|
+
ensure
|
274
|
+
Asciidoctor::Extensions.unregister_all
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
200
278
|
test 'should get class for top-level class name' do
|
201
|
-
clazz = Asciidoctor::Extensions.class_for_name
|
279
|
+
clazz = Asciidoctor::Extensions.class_for_name 'String'
|
202
280
|
refute_nil clazz
|
203
|
-
assert_equal
|
281
|
+
assert_equal String, clazz
|
204
282
|
end
|
205
283
|
|
206
284
|
test 'should get class for class name in module' do
|
207
|
-
clazz = Asciidoctor::Extensions.class_for_name
|
285
|
+
clazz = Asciidoctor::Extensions.class_for_name 'Asciidoctor::Document'
|
208
286
|
refute_nil clazz
|
209
|
-
assert_equal Asciidoctor::
|
287
|
+
assert_equal Asciidoctor::Document, clazz
|
210
288
|
end
|
211
289
|
|
212
290
|
test 'should get class for class name resolved from root' do
|
213
|
-
clazz = Asciidoctor::Extensions.class_for_name
|
291
|
+
clazz = Asciidoctor::Extensions.class_for_name '::Asciidoctor::Document'
|
214
292
|
refute_nil clazz
|
215
|
-
assert_equal Asciidoctor::
|
293
|
+
assert_equal Asciidoctor::Document, clazz
|
216
294
|
end
|
217
295
|
|
218
296
|
test 'should raise exception if cannot find class for name' do
|
219
297
|
begin
|
220
|
-
Asciidoctor::Extensions.class_for_name
|
298
|
+
Asciidoctor::Extensions.class_for_name 'InvalidModule::InvalidClass'
|
221
299
|
flunk 'Expecting RuntimeError to be raised'
|
222
|
-
rescue
|
300
|
+
rescue NameError => e
|
223
301
|
assert_equal 'Could not resolve class for name: InvalidModule::InvalidClass', e.message
|
224
302
|
end
|
225
303
|
end
|
226
304
|
|
305
|
+
test 'should raise exception if name resolves to module' do
|
306
|
+
begin
|
307
|
+
Asciidoctor::Extensions.class_for_name 'Asciidoctor::Extensions'
|
308
|
+
flunk 'Expecting RuntimeError to be raised'
|
309
|
+
rescue NameError => e
|
310
|
+
assert_equal 'Could not resolve class for name: Asciidoctor::Extensions', e.message
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
227
314
|
test 'should resolve class if class is given' do
|
228
|
-
clazz = Asciidoctor::Extensions.resolve_class
|
315
|
+
clazz = Asciidoctor::Extensions.resolve_class Asciidoctor::Document
|
229
316
|
refute_nil clazz
|
230
|
-
assert_equal Asciidoctor::
|
317
|
+
assert_equal Asciidoctor::Document, clazz
|
231
318
|
end
|
232
319
|
|
233
320
|
test 'should resolve class if class from string' do
|
234
|
-
clazz = Asciidoctor::Extensions.resolve_class
|
321
|
+
clazz = Asciidoctor::Extensions.resolve_class 'Asciidoctor::Document'
|
235
322
|
refute_nil clazz
|
236
|
-
assert_equal Asciidoctor::
|
323
|
+
assert_equal Asciidoctor::Document, clazz
|
324
|
+
end
|
325
|
+
|
326
|
+
test 'should allow standalone registry to be created but not registered' do
|
327
|
+
registry = Asciidoctor::Extensions.create 'sample' do
|
328
|
+
block do
|
329
|
+
named :whisper
|
330
|
+
bound_to :paragraph
|
331
|
+
parses_content_as :simple
|
332
|
+
def process parent, reader, attributes
|
333
|
+
create_paragraph parent, reader.lines.map(&:downcase), attributes
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
assert_instance_of Asciidoctor::Extensions::Registry, registry
|
339
|
+
refute_nil registry.groups
|
340
|
+
assert_equal 1, registry.groups.size
|
341
|
+
assert_equal 'sample', registry.groups.keys.first
|
342
|
+
assert_equal 0, Asciidoctor::Extensions.groups.size
|
237
343
|
end
|
238
344
|
end
|
239
345
|
|
@@ -318,7 +424,8 @@ context 'Extensions' do
|
|
318
424
|
assert extensions.first.process_method.is_a? ::Method
|
319
425
|
end
|
320
426
|
|
321
|
-
|
427
|
+
# NOTE intentionally using the legacy names
|
428
|
+
test 'should instantiate tree processors' do
|
322
429
|
registry = Asciidoctor::Extensions::Registry.new
|
323
430
|
registry.treeprocessor SampleTreeprocessor
|
324
431
|
registry.activate Asciidoctor::Document.new
|
@@ -397,6 +504,30 @@ context 'Extensions' do
|
|
397
504
|
end
|
398
505
|
|
399
506
|
context 'Integration' do
|
507
|
+
test 'can provide extension registry as option' do
|
508
|
+
registry = Asciidoctor::Extensions.create do
|
509
|
+
tree_processor SampleTreeProcessor
|
510
|
+
end
|
511
|
+
|
512
|
+
doc = document_from_string %(= Document Title\n\ncontent), :extension_registry => registry
|
513
|
+
refute_nil doc.extensions
|
514
|
+
assert_equal 1, doc.extensions.groups.size
|
515
|
+
assert doc.extensions.tree_processors?
|
516
|
+
assert_equal 1, doc.extensions.tree_processors.size
|
517
|
+
assert_equal 0, Asciidoctor::Extensions.groups.size
|
518
|
+
end
|
519
|
+
|
520
|
+
test 'can provide extensions proc as option' do
|
521
|
+
doc = document_from_string %(= Document Title\n\ncontent), :extensions => proc {
|
522
|
+
tree_processor SampleTreeProcessor
|
523
|
+
}
|
524
|
+
refute_nil doc.extensions
|
525
|
+
assert_equal 1, doc.extensions.groups.size
|
526
|
+
assert doc.extensions.tree_processors?
|
527
|
+
assert_equal 1, doc.extensions.tree_processors.size
|
528
|
+
assert_equal 0, Asciidoctor::Extensions.groups.size
|
529
|
+
end
|
530
|
+
|
400
531
|
test 'should invoke preprocessors before parsing document' do
|
401
532
|
input = <<-EOS
|
402
533
|
junk line
|
@@ -457,13 +588,17 @@ last line
|
|
457
588
|
# Safe Mode is not required here
|
458
589
|
document = empty_document :base_dir => File.expand_path(File.dirname(__FILE__))
|
459
590
|
document.extensions.include_processor do
|
591
|
+
handles? do |target|
|
592
|
+
target == 'include-file.asciidoc'
|
593
|
+
end
|
594
|
+
|
460
595
|
process do |doc, reader, target, attributes|
|
461
596
|
# demonstrate that push_include normalizes endlines
|
462
597
|
content = ["include target:: #{target}\n", "\n", "middle line\n"]
|
463
598
|
reader.push_include content, target, target, 1, attributes
|
464
599
|
end
|
465
600
|
end
|
466
|
-
reader = Asciidoctor::PreprocessorReader.new document, input
|
601
|
+
reader = Asciidoctor::PreprocessorReader.new document, input, nil, :normalize => true
|
467
602
|
lines = []
|
468
603
|
lines << reader.read_line
|
469
604
|
lines << reader.read_line
|
@@ -473,12 +608,12 @@ last line
|
|
473
608
|
while reader.has_more_lines?
|
474
609
|
lines << reader.read_line
|
475
610
|
end
|
476
|
-
source = lines * ::Asciidoctor::
|
611
|
+
source = lines * ::Asciidoctor::LF
|
477
612
|
assert_match(/^include target:: include-file.asciidoc$/, source)
|
478
613
|
assert_match(/^middle line$/, source)
|
479
614
|
end
|
480
615
|
|
481
|
-
test 'should invoke
|
616
|
+
test 'should invoke tree processors after parsing document' do
|
482
617
|
input = <<-EOS
|
483
618
|
= Document Title
|
484
619
|
Doc Writer
|
@@ -488,7 +623,7 @@ content
|
|
488
623
|
|
489
624
|
begin
|
490
625
|
Asciidoctor::Extensions.register do
|
491
|
-
|
626
|
+
tree_processor ReplaceAuthorTreeProcessor
|
492
627
|
end
|
493
628
|
|
494
629
|
doc = document_from_string input
|
@@ -498,7 +633,7 @@ content
|
|
498
633
|
end
|
499
634
|
end
|
500
635
|
|
501
|
-
test 'should allow
|
636
|
+
test 'should allow tree processor to replace tree' do
|
502
637
|
input = <<-EOS
|
503
638
|
= Original Document
|
504
639
|
Doc Writer
|
@@ -508,7 +643,7 @@ content
|
|
508
643
|
|
509
644
|
begin
|
510
645
|
Asciidoctor::Extensions.register do
|
511
|
-
|
646
|
+
tree_processor ReplaceTreeTreeProcessor
|
512
647
|
end
|
513
648
|
|
514
649
|
doc = document_from_string input
|
@@ -518,6 +653,37 @@ content
|
|
518
653
|
end
|
519
654
|
end
|
520
655
|
|
656
|
+
test 'should honor block title assigned in tree processor' do
|
657
|
+
input = <<-EOS
|
658
|
+
= Document Title
|
659
|
+
:!example-caption:
|
660
|
+
|
661
|
+
.Old block title
|
662
|
+
====
|
663
|
+
example block content
|
664
|
+
====
|
665
|
+
EOS
|
666
|
+
|
667
|
+
old_title = nil
|
668
|
+
begin
|
669
|
+
Asciidoctor::Extensions.register do
|
670
|
+
tree_processor do
|
671
|
+
process do |doc|
|
672
|
+
ex = (doc.find_by :context => :example)[0]
|
673
|
+
old_title = ex.title
|
674
|
+
ex.title = 'New block title'
|
675
|
+
end
|
676
|
+
end
|
677
|
+
end
|
678
|
+
|
679
|
+
doc = document_from_string input
|
680
|
+
assert_equal 'Old block title', old_title
|
681
|
+
assert_equal 'New block title', (doc.find_by :context => :example)[0].title
|
682
|
+
ensure
|
683
|
+
Asciidoctor::Extensions.unregister_all
|
684
|
+
end
|
685
|
+
end
|
686
|
+
|
521
687
|
test 'should invoke postprocessors after rendering document' do
|
522
688
|
input = <<-EOS
|
523
689
|
* one
|
@@ -556,9 +722,36 @@ Hi there!
|
|
556
722
|
end
|
557
723
|
end
|
558
724
|
|
725
|
+
test 'should pass cloaked context in attributes passed to process method of custom block' do
|
726
|
+
input = <<-EOS
|
727
|
+
[custom]
|
728
|
+
****
|
729
|
+
sidebar
|
730
|
+
****
|
731
|
+
EOS
|
732
|
+
|
733
|
+
cloaked_context = nil
|
734
|
+
begin
|
735
|
+
Asciidoctor::Extensions.register do
|
736
|
+
block :custom do
|
737
|
+
on_context :sidebar
|
738
|
+
process do |doc, reader, attrs|
|
739
|
+
cloaked_context = attrs['cloaked-context']
|
740
|
+
nil
|
741
|
+
end
|
742
|
+
end
|
743
|
+
end
|
744
|
+
|
745
|
+
render_embedded_string input
|
746
|
+
assert_equal :sidebar, cloaked_context
|
747
|
+
ensure
|
748
|
+
Asciidoctor::Extensions.unregister_all
|
749
|
+
end
|
750
|
+
end
|
751
|
+
|
559
752
|
test 'should invoke processor for custom block macro' do
|
560
753
|
input = <<-EOS
|
561
|
-
snippet::12345[]
|
754
|
+
snippet::12345[mode=edit]
|
562
755
|
EOS
|
563
756
|
|
564
757
|
begin
|
@@ -567,7 +760,33 @@ snippet::12345[]
|
|
567
760
|
end
|
568
761
|
|
569
762
|
output = render_embedded_string input
|
570
|
-
assert output.include?('<script src="http://example.com/12345.js"></script>')
|
763
|
+
assert output.include?('<script src="http://example.com/12345.js?_mode=edit"></script>')
|
764
|
+
ensure
|
765
|
+
Asciidoctor::Extensions.unregister_all
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
test 'should match short form of block macro' do
|
770
|
+
input = <<-EOS
|
771
|
+
custom_toc::[]
|
772
|
+
EOS
|
773
|
+
|
774
|
+
resolved_target = nil
|
775
|
+
|
776
|
+
begin
|
777
|
+
Asciidoctor::Extensions.register do
|
778
|
+
block_macro do
|
779
|
+
named :custom_toc
|
780
|
+
process do |parent, target, attrs|
|
781
|
+
resolved_target = target
|
782
|
+
create_pass_block parent, '<!-- custom toc goes here -->', {}, :content_model => :raw
|
783
|
+
end
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
output = render_embedded_string input
|
788
|
+
assert_equal '<!-- custom toc goes here -->', output
|
789
|
+
assert_equal '', resolved_target
|
571
790
|
ensure
|
572
791
|
Asciidoctor::Extensions.unregister_all
|
573
792
|
end
|
@@ -576,14 +795,14 @@ snippet::12345[]
|
|
576
795
|
test 'should invoke processor for custom inline macro' do
|
577
796
|
begin
|
578
797
|
Asciidoctor::Extensions.register do
|
579
|
-
inline_macro TemperatureMacro, :
|
798
|
+
inline_macro TemperatureMacro, :deg
|
580
799
|
end
|
581
800
|
|
582
|
-
output = render_embedded_string 'Room temperature is
|
583
|
-
assert output.include?('Room temperature is 25
|
801
|
+
output = render_embedded_string 'Room temperature is deg:25[C,precision=0].', :attributes => { 'temperature-unit' => 'F' }
|
802
|
+
assert output.include?('Room temperature is 25 °C.')
|
584
803
|
|
585
|
-
output = render_embedded_string '
|
586
|
-
assert output.include?('
|
804
|
+
output = render_embedded_string 'Normal body temperature is deg:37[].', :attributes => { 'temperature-unit' => 'F' }
|
805
|
+
assert output.include?('Normal body temperature is 98.6 °F.')
|
587
806
|
ensure
|
588
807
|
Asciidoctor::Extensions.unregister_all
|
589
808
|
end
|
@@ -594,7 +813,8 @@ snippet::12345[]
|
|
594
813
|
Asciidoctor::Extensions.register do
|
595
814
|
inline_macro do
|
596
815
|
named :label
|
597
|
-
|
816
|
+
with_format :short
|
817
|
+
resolves_attributes false
|
598
818
|
process do |parent, target|
|
599
819
|
%(<label>#{target}</label>)
|
600
820
|
end
|
@@ -608,13 +828,114 @@ snippet::12345[]
|
|
608
828
|
end
|
609
829
|
end
|
610
830
|
|
831
|
+
test 'should assign captures correctly for inline macros' do
|
832
|
+
begin
|
833
|
+
Asciidoctor::Extensions.register do
|
834
|
+
inline_macro do
|
835
|
+
named :short_attributes
|
836
|
+
with_format :short
|
837
|
+
resolves_attributes '1:name'
|
838
|
+
process do |parent, target, attrs|
|
839
|
+
%(target=#{target.inspect}, attributes=#{attrs.sort_by {|k, _| k.to_s }.inspect})
|
840
|
+
end
|
841
|
+
end
|
842
|
+
|
843
|
+
inline_macro do
|
844
|
+
named :short_text
|
845
|
+
with_format :short
|
846
|
+
resolves_attributes false
|
847
|
+
process do |parent, target, attrs|
|
848
|
+
%(target=#{target.inspect}, attributes=#{attrs.sort_by {|k, _| k.to_s }.inspect})
|
849
|
+
end
|
850
|
+
end
|
851
|
+
|
852
|
+
inline_macro do
|
853
|
+
named :full_attributes
|
854
|
+
resolves_attributes '1:name' => nil
|
855
|
+
process do |parent, target, attrs|
|
856
|
+
%(target=#{target.inspect}, attributes=#{attrs.sort_by {|k, _| k.to_s }.inspect})
|
857
|
+
end
|
858
|
+
end
|
859
|
+
|
860
|
+
inline_macro do
|
861
|
+
named :full_text
|
862
|
+
resolves_attributes false
|
863
|
+
process do |parent, target, attrs|
|
864
|
+
%(target=#{target.inspect}, attributes=#{attrs.sort_by {|k, _| k.to_s }.inspect})
|
865
|
+
end
|
866
|
+
end
|
867
|
+
|
868
|
+
inline_macro do
|
869
|
+
named :@short_match
|
870
|
+
matching %r/@(\w+)/
|
871
|
+
resolves_attributes false
|
872
|
+
process do |parent, target, attrs|
|
873
|
+
%(target=#{target.inspect}, attributes=#{attrs.sort_by {|k, _| k.to_s }.inspect})
|
874
|
+
end
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
input = <<-EOS
|
879
|
+
[subs=normal]
|
880
|
+
++++
|
881
|
+
short_attributes:[]
|
882
|
+
short_attributes:[value,key=val]
|
883
|
+
short_text:[]
|
884
|
+
short_text:[[text\\]]
|
885
|
+
full_attributes:target[]
|
886
|
+
full_attributes:target[value,key=val]
|
887
|
+
full_text:target[]
|
888
|
+
full_text:target[[text\\]]
|
889
|
+
@target
|
890
|
+
++++
|
891
|
+
EOS
|
892
|
+
expected = <<-EOS.chomp
|
893
|
+
target="", attributes=[]
|
894
|
+
target="value,key=val", attributes=[[1, "value"], ["key", "val"], ["name", "value"]]
|
895
|
+
target="", attributes=[["text", ""]]
|
896
|
+
target="[text]", attributes=[["text", "[text]"]]
|
897
|
+
target="target", attributes=[]
|
898
|
+
target="target", attributes=[[1, "value"], ["key", "val"], ["name", "value"]]
|
899
|
+
target="target", attributes=[["text", ""]]
|
900
|
+
target="target", attributes=[["text", "[text]"]]
|
901
|
+
target="target", attributes=[]
|
902
|
+
EOS
|
903
|
+
output = render_embedded_string input
|
904
|
+
assert_equal expected, output
|
905
|
+
ensure
|
906
|
+
Asciidoctor::Extensions.unregister_all
|
907
|
+
end
|
908
|
+
end
|
909
|
+
|
910
|
+
test 'should invoke convert on return value if value is an inline node' do
|
911
|
+
begin
|
912
|
+
Asciidoctor::Extensions.register do
|
913
|
+
inline_macro do
|
914
|
+
named :mention
|
915
|
+
resolves_attributes false
|
916
|
+
process do |parent, target, attrs|
|
917
|
+
if (text = attrs['text']).empty?
|
918
|
+
text = %(@#{target})
|
919
|
+
end
|
920
|
+
create_anchor parent, text, :type => :link, :target => %(https://github.com/#{target})
|
921
|
+
end
|
922
|
+
end
|
923
|
+
end
|
924
|
+
|
925
|
+
output = render_embedded_string 'mention:mojavelinux[Dan]'
|
926
|
+
assert output.include?('<a href="https://github.com/mojavelinux">Dan</a>')
|
927
|
+
ensure
|
928
|
+
Asciidoctor::Extensions.unregister_all
|
929
|
+
end
|
930
|
+
end
|
931
|
+
|
611
932
|
test 'should not carry over attributes if block processor returns nil' do
|
612
933
|
begin
|
613
934
|
Asciidoctor::Extensions.register do
|
614
935
|
block do
|
615
936
|
named :skip
|
616
937
|
on_context :paragraph
|
617
|
-
|
938
|
+
parses_content_as :raw
|
618
939
|
process do |parent, reader, attrs|
|
619
940
|
nil
|
620
941
|
end
|
@@ -643,7 +964,7 @@ rendered
|
|
643
964
|
block do
|
644
965
|
named :foo
|
645
966
|
on_context :paragraph
|
646
|
-
|
967
|
+
parses_content_as :raw
|
647
968
|
process do |parent, reader, attrs|
|
648
969
|
original_attrs = attrs.dup
|
649
970
|
attrs.delete('title')
|
@@ -703,6 +1024,52 @@ content
|
|
703
1024
|
end
|
704
1025
|
end
|
705
1026
|
|
1027
|
+
test 'create_section should set up all section properties' do
|
1028
|
+
begin
|
1029
|
+
sect = nil
|
1030
|
+
Asciidoctor::Extensions.register do
|
1031
|
+
block_macro do
|
1032
|
+
named :sect
|
1033
|
+
process do |parent, target, attrs|
|
1034
|
+
opts = (level = attrs.delete 'level') ? { :level => level.to_i } : {}
|
1035
|
+
attrs['id'] = false if attrs['id'] == 'false'
|
1036
|
+
sect = create_section parent, 'Section Title', attrs, opts
|
1037
|
+
nil
|
1038
|
+
end
|
1039
|
+
end
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
input_tpl = <<-EOS
|
1043
|
+
= Document Title
|
1044
|
+
:doctype: book
|
1045
|
+
:sectnums:
|
1046
|
+
|
1047
|
+
sect::[%s]
|
1048
|
+
EOS
|
1049
|
+
|
1050
|
+
{
|
1051
|
+
'' => ['chapter', 1, false, true, '_section_title'],
|
1052
|
+
'level=0' => ['part', 0, false, false, '_section_title'],
|
1053
|
+
'level=0,style=appendix' => ['appendix', 1, true, true, '_section_title'],
|
1054
|
+
'style=appendix' => ['appendix', 1, true, true, '_section_title'],
|
1055
|
+
'style=glossary' => ['glossary', 1, true, false, '_section_title'],
|
1056
|
+
'style=abstract' => ['chapter', 1, false, true, '_section_title'],
|
1057
|
+
'id=section-title' => ['chapter', 1, false, true, 'section-title'],
|
1058
|
+
'id=false' => ['chapter', 1, false, true, nil]
|
1059
|
+
}.each do |attrlist, (expect_sectname, expect_level, expect_special, expect_numbered, expect_id)|
|
1060
|
+
input = input_tpl % attrlist
|
1061
|
+
document_from_string input, :safe => :server
|
1062
|
+
assert_equal expect_sectname, sect.sectname
|
1063
|
+
assert_equal expect_level, sect.level
|
1064
|
+
assert_equal expect_special, sect.special
|
1065
|
+
assert_equal expect_numbered, sect.numbered
|
1066
|
+
assert_equal expect_id, sect.id
|
1067
|
+
end
|
1068
|
+
ensure
|
1069
|
+
Asciidoctor::Extensions.unregister_all
|
1070
|
+
end
|
1071
|
+
end
|
1072
|
+
|
706
1073
|
test 'should add docinfo to document' do
|
707
1074
|
input = <<-EOS
|
708
1075
|
= Document Title
|