asciidoctor 1.5.2 → 1.5.3
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 +107 -1
- data/LICENSE.adoc +1 -1
- data/README.adoc +155 -230
- data/Rakefile +2 -1
- data/bin/asciidoctor +5 -1
- data/data/stylesheets/asciidoctor-default.css +37 -29
- data/data/stylesheets/coderay-asciidoctor.css +3 -3
- data/features/text_formatting.feature +2 -0
- data/lib/asciidoctor.rb +46 -21
- data/lib/asciidoctor/abstract_block.rb +14 -8
- data/lib/asciidoctor/abstract_node.rb +77 -24
- data/lib/asciidoctor/attribute_list.rb +1 -1
- data/lib/asciidoctor/block.rb +2 -3
- data/lib/asciidoctor/cli/options.rb +14 -15
- data/lib/asciidoctor/converter/docbook45.rb +8 -8
- data/lib/asciidoctor/converter/docbook5.rb +25 -17
- data/lib/asciidoctor/converter/factory.rb +6 -1
- data/lib/asciidoctor/converter/html5.rb +159 -117
- data/lib/asciidoctor/converter/manpage.rb +671 -0
- data/lib/asciidoctor/converter/template.rb +24 -17
- data/lib/asciidoctor/document.rb +89 -47
- data/lib/asciidoctor/extensions.rb +22 -21
- data/lib/asciidoctor/helpers.rb +73 -16
- data/lib/asciidoctor/list.rb +26 -5
- data/lib/asciidoctor/parser.rb +179 -122
- data/lib/asciidoctor/path_resolver.rb +6 -10
- data/lib/asciidoctor/reader.rb +37 -34
- data/lib/asciidoctor/stylesheets.rb +16 -10
- data/lib/asciidoctor/substitutors.rb +98 -21
- data/lib/asciidoctor/table.rb +21 -17
- data/lib/asciidoctor/timings.rb +3 -3
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +155 -89
- data/man/asciidoctor.adoc +19 -11
- data/test/attributes_test.rb +86 -0
- data/test/blocks_test.rb +203 -15
- data/test/converter_test.rb +15 -2
- data/test/document_test.rb +290 -36
- data/test/extensions_test.rb +22 -3
- data/test/fixtures/circle.svg +8 -0
- data/test/fixtures/subs-docinfo.html +2 -0
- data/test/fixtures/subs.adoc +7 -0
- data/test/invoker_test.rb +25 -0
- data/test/links_test.rb +17 -0
- data/test/lists_test.rb +173 -0
- data/test/options_test.rb +2 -2
- data/test/paragraphs_test.rb +2 -2
- data/test/parser_test.rb +56 -13
- data/test/reader_test.rb +35 -3
- data/test/sections_test.rb +59 -0
- data/test/substitutions_test.rb +53 -14
- data/test/tables_test.rb +158 -2
- data/test/test_helper.rb +7 -2
- metadata +22 -11
- data/benchmark/benchmark.rb +0 -129
- data/benchmark/sample-data/mdbasics.adoc +0 -334
- data/lib/asciidoctor/opal_ext.rb +0 -26
- data/lib/asciidoctor/opal_ext/comparable.rb +0 -38
- data/lib/asciidoctor/opal_ext/dir.rb +0 -13
- data/lib/asciidoctor/opal_ext/error.rb +0 -2
- data/lib/asciidoctor/opal_ext/file.rb +0 -145
@@ -22,7 +22,7 @@ module Asciidoctor
|
|
22
22
|
# As an optimization, scan results and templates are cached for the lifetime
|
23
23
|
# of the Ruby process. If the {https://rubygems.org/gems/thread_safe
|
24
24
|
# thread_safe} gem is installed, these caches are guaranteed to be thread
|
25
|
-
# safe. If this gem is not present, a warning is issued.
|
25
|
+
# safe. If this gem is not present, they are not and a warning is issued.
|
26
26
|
class Converter::TemplateConverter < Converter::Base
|
27
27
|
DEFAULT_ENGINE_OPTIONS = {
|
28
28
|
:erb => { :trim => '<' },
|
@@ -37,9 +37,9 @@ module Asciidoctor
|
|
37
37
|
require 'thread_safe' unless defined? ::ThreadSafe
|
38
38
|
@caches = { :scans => ::ThreadSafe::Cache.new, :templates => ::ThreadSafe::Cache.new }
|
39
39
|
rescue ::LoadError
|
40
|
-
@caches = {}
|
41
|
-
# FIXME perhaps only warn if the cache option is enabled?
|
42
|
-
warn 'asciidoctor: WARNING: gem \'thread_safe\' is not installed. This gem recommended when using custom backend templates.'
|
40
|
+
@caches = { :scans => {}, :templates => {} }
|
41
|
+
# FIXME perhaps only warn if the cache option is enabled (meaning not disabled)?
|
42
|
+
warn 'asciidoctor: WARNING: gem \'thread_safe\' is not installed. This gem is recommended when using custom backend templates.'
|
43
43
|
end
|
44
44
|
|
45
45
|
def self.caches
|
@@ -52,28 +52,33 @@ module Asciidoctor
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def initialize backend, template_dirs, opts = {}
|
55
|
+
Helpers.require_library 'tilt' unless defined? ::Tilt
|
55
56
|
@backend = backend
|
56
57
|
@templates = {}
|
57
58
|
@template_dirs = template_dirs
|
58
59
|
@eruby = opts[:eruby]
|
60
|
+
@safe = opts[:safe]
|
59
61
|
@engine = opts[:template_engine]
|
60
62
|
@engine_options = DEFAULT_ENGINE_OPTIONS.inject({}) do |accum, (engine, default_opts)|
|
61
63
|
accum[engine] = default_opts.dup
|
62
64
|
accum
|
63
65
|
end
|
66
|
+
if opts[:htmlsyntax] == 'html'
|
67
|
+
@engine_options[:haml][:format] = :html5
|
68
|
+
@engine_options[:slim][:format] = :html
|
69
|
+
end
|
64
70
|
if (overrides = opts[:template_engine_options])
|
65
71
|
overrides.each do |engine, override_opts|
|
66
72
|
(@engine_options[engine] ||= {}).update override_opts
|
67
73
|
end
|
68
74
|
end
|
69
|
-
@engine_options[:haml][:format] = @engine_options[:slim][:format] = :html5 if opts[:htmlsyntax] == 'html'
|
70
75
|
case opts[:template_cache]
|
71
76
|
when true
|
72
77
|
@caches = self.class.caches
|
73
78
|
when ::Hash
|
74
79
|
@caches = opts[:template_cache]
|
75
80
|
else
|
76
|
-
@caches = {}
|
81
|
+
@caches = {} # the empty Hash effectively disables caching
|
77
82
|
end
|
78
83
|
scan
|
79
84
|
#create_handlers
|
@@ -97,7 +102,8 @@ module Asciidoctor
|
|
97
102
|
engine = @engine
|
98
103
|
@template_dirs.each do |template_dir|
|
99
104
|
# FIXME need to think about safe mode restrictions here
|
100
|
-
template_dir = path_resolver.system_path template_dir, nil
|
105
|
+
next unless ::File.directory?(template_dir = (path_resolver.system_path template_dir, nil))
|
106
|
+
|
101
107
|
# NOTE last matching template wins for template name if no engine is given
|
102
108
|
file_pattern = '*'
|
103
109
|
if engine
|
@@ -177,11 +183,8 @@ module Asciidoctor
|
|
177
183
|
raise %(Could not find a custom template to handle transform: #{template_name})
|
178
184
|
end
|
179
185
|
|
180
|
-
# Slim doesn't include helpers in the template's execution scope
|
181
|
-
|
182
|
-
if (defined? ::Slim::Helpers) && (template.is_a? ::Slim::Template)
|
183
|
-
node.extend ::Slim::Helpers
|
184
|
-
end
|
186
|
+
# Slim doesn't include helpers in the template's execution scope (like HAML), so do it ourselves
|
187
|
+
node.extend ::Slim::Helpers if (defined? ::Slim::Helpers) && (::Slim::Template === template)
|
185
188
|
|
186
189
|
# NOTE opts become locals in the template
|
187
190
|
if template_name == 'document'
|
@@ -247,12 +250,16 @@ module Asciidoctor
|
|
247
250
|
template_class = ::Tilt
|
248
251
|
extra_engine_options = {}
|
249
252
|
if ext_name == 'slim'
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
253
|
+
unless defined? ::Slim
|
254
|
+
# slim doesn't get loaded by Tilt, so we have to load it explicitly
|
255
|
+
Helpers.require_library 'slim'
|
256
|
+
if @safe && ::Slim::VERSION >= '3.0'
|
257
|
+
slim_asciidoc_opts = (@engine_options[:slim][:asciidoc] ||= {})
|
258
|
+
slim_asciidoc_opts[:safe] ||= @safe
|
259
|
+
end
|
255
260
|
end
|
261
|
+
# load include plugin when using Slim >= 2.1
|
262
|
+
require 'slim/include' unless (defined? ::Slim::Include) || ::Slim::VERSION < '2.1'
|
256
263
|
elsif ext_name == 'erb'
|
257
264
|
template_class, extra_engine_options = (eruby_loaded ||= load_eruby(@eruby))
|
258
265
|
end
|
data/lib/asciidoctor/document.rb
CHANGED
@@ -38,20 +38,22 @@ class Document < AbstractBlock
|
|
38
38
|
# Public Parsed and stores a partitioned title (i.e., title & subtitle).
|
39
39
|
class Title
|
40
40
|
attr_reader :main
|
41
|
+
alias :title :main
|
41
42
|
attr_reader :subtitle
|
42
43
|
attr_reader :combined
|
43
44
|
|
44
45
|
def initialize val, opts = {}
|
45
|
-
# TODO separate sanitization by type (:cdata for HTML/XML, :
|
46
|
+
# TODO separate sanitization by type (:cdata for HTML/XML, :plain_text for non-SGML, false for none)
|
46
47
|
if (@sanitized = opts[:sanitize]) && val.include?('<')
|
47
48
|
val = val.gsub(XmlSanitizeRx, '').tr_s(' ', ' ').strip
|
48
49
|
end
|
49
|
-
if (
|
50
|
-
@main, _, @subtitle = val.rpartition ': '
|
51
|
-
else
|
50
|
+
if (sep = opts[:separator] || ':').empty? || !val.include?(sep = %(#{sep} ))
|
52
51
|
@main = val
|
53
52
|
@subtitle = nil
|
53
|
+
else
|
54
|
+
@main, _, @subtitle = val.rpartition sep
|
54
55
|
end
|
56
|
+
@combined = val
|
55
57
|
end
|
56
58
|
|
57
59
|
def sanitized?
|
@@ -137,6 +139,9 @@ class Document < AbstractBlock
|
|
137
139
|
# Public: Get the Hash of resolved options used to initialize this Document
|
138
140
|
attr_reader :options
|
139
141
|
|
142
|
+
# Public: Get the outfilesuffix defined at the end of the header.
|
143
|
+
attr_reader :outfilesuffix
|
144
|
+
|
140
145
|
# Public: Get a reference to the parent Document of this nested document.
|
141
146
|
attr_reader :parent_document
|
142
147
|
|
@@ -246,7 +251,7 @@ class Document < AbstractBlock
|
|
246
251
|
options.freeze
|
247
252
|
|
248
253
|
attrs = @attributes
|
249
|
-
attrs['encoding'] = 'UTF-8'
|
254
|
+
#attrs['encoding'] = 'UTF-8'
|
250
255
|
attrs['sectids'] = ''
|
251
256
|
attrs['notitle'] = '' unless header_footer
|
252
257
|
attrs['toc-placement'] = 'auto'
|
@@ -378,13 +383,16 @@ class Document < AbstractBlock
|
|
378
383
|
# Eagerly parse (for now) since a subdocument is not a publicly accessible object
|
379
384
|
Parser.parse @reader, self
|
380
385
|
|
381
|
-
# should we call
|
382
|
-
|
386
|
+
# should we call some sort of post-parse function?
|
387
|
+
restore_attributes
|
383
388
|
@parsed = true
|
384
389
|
else
|
385
390
|
# setup default backend and doctype
|
386
|
-
attrs['backend'] ||= DEFAULT_BACKEND
|
387
|
-
|
391
|
+
if (attrs['backend'] ||= DEFAULT_BACKEND) == 'manpage'
|
392
|
+
attrs['doctype'] = attr_overrides['doctype'] = 'manpage'
|
393
|
+
else
|
394
|
+
attrs['doctype'] ||= DEFAULT_DOCTYPE
|
395
|
+
end
|
388
396
|
update_backend_attributes attrs['backend'], true
|
389
397
|
|
390
398
|
#attrs['indir'] = attrs['docdir']
|
@@ -460,8 +468,8 @@ class Document < AbstractBlock
|
|
460
468
|
# Now parse the lines in the reader into blocks
|
461
469
|
Parser.parse @reader, doc, :header_only => !!@options[:parse_header_only]
|
462
470
|
|
463
|
-
# should we call
|
464
|
-
|
471
|
+
# should we call sort of post-parse function?
|
472
|
+
restore_attributes
|
465
473
|
|
466
474
|
if exts && exts.treeprocessors?
|
467
475
|
exts.treeprocessors.each do |ext|
|
@@ -529,13 +537,15 @@ class Document < AbstractBlock
|
|
529
537
|
end
|
530
538
|
end
|
531
539
|
|
532
|
-
def register(type, value)
|
540
|
+
def register(type, value, force = false)
|
533
541
|
case type
|
534
542
|
when :ids
|
535
|
-
|
536
|
-
|
543
|
+
id, reftext = [*value]
|
544
|
+
reftext ||= '[' + id + ']'
|
545
|
+
if force
|
546
|
+
@references[:ids][id] = reftext
|
537
547
|
else
|
538
|
-
@references[:ids][
|
548
|
+
@references[:ids][id] ||= reftext
|
539
549
|
end
|
540
550
|
when :footnotes, :indexterms
|
541
551
|
@references[type] << value
|
@@ -614,6 +624,8 @@ class Document < AbstractBlock
|
|
614
624
|
# If the :partition attribute is specified, the value is parsed into an Document::Title object.
|
615
625
|
# If the :sanitize attribute is specified, XML elements are removed from the value.
|
616
626
|
#
|
627
|
+
# TODO separate sanitization by type (:cdata for HTML/XML, :plain_text for non-SGML, false for none)
|
628
|
+
#
|
617
629
|
# Returns the resolved title as a [Title] if the :partition option is passed or a [String] if not
|
618
630
|
# or nil if no value can be resolved.
|
619
631
|
def doctitle opts = {}
|
@@ -627,8 +639,8 @@ class Document < AbstractBlock
|
|
627
639
|
return
|
628
640
|
end
|
629
641
|
|
630
|
-
if opts[:partition]
|
631
|
-
Title.new val, opts
|
642
|
+
if (separator = opts[:partition])
|
643
|
+
Title.new val, opts.merge({ :separator => (separator == true ? @attributes['title-separator'] : separator) })
|
632
644
|
elsif opts[:sanitize] && val.include?('<')
|
633
645
|
val.gsub(XmlSanitizeRx, '').tr_s(' ', ' ').strip
|
634
646
|
else
|
@@ -763,7 +775,10 @@ class Document < AbstractBlock
|
|
763
775
|
@compat_mode = false
|
764
776
|
end
|
765
777
|
|
766
|
-
|
778
|
+
# NOTE pin the outfilesuffix after the header is parsed
|
779
|
+
@outfilesuffix = attrs['outfilesuffix']
|
780
|
+
|
781
|
+
@header_attributes = attrs.dup
|
767
782
|
|
768
783
|
# unfreeze "flexible" attributes
|
769
784
|
unless nested?
|
@@ -777,12 +792,11 @@ class Document < AbstractBlock
|
|
777
792
|
end
|
778
793
|
end
|
779
794
|
|
780
|
-
# Internal: Restore the attributes to the previously saved state
|
781
|
-
#--
|
782
|
-
# QUESTION should we restore attributes after parse?
|
795
|
+
# Internal: Restore the attributes to the previously saved state (attributes in header)
|
783
796
|
def restore_attributes
|
797
|
+
@callouts.rewind
|
784
798
|
# QUESTION shouldn't this be a dup in case we convert again?
|
785
|
-
@attributes = @
|
799
|
+
@attributes = @header_attributes
|
786
800
|
end
|
787
801
|
|
788
802
|
# Internal: Delete any attributes stored for playback
|
@@ -823,7 +837,7 @@ class Document < AbstractBlock
|
|
823
837
|
else
|
824
838
|
case name
|
825
839
|
when 'backend'
|
826
|
-
update_backend_attributes apply_attribute_value_subs(value)
|
840
|
+
update_backend_attributes apply_attribute_value_subs(value), !!@attributes_modified.delete?('htmlsyntax')
|
827
841
|
when 'doctype'
|
828
842
|
update_doctype_attributes apply_attribute_value_subs(value)
|
829
843
|
else
|
@@ -897,7 +911,7 @@ class Document < AbstractBlock
|
|
897
911
|
attrs['htmlsyntax'] = 'xml'
|
898
912
|
new_backend = new_backend[1..-1]
|
899
913
|
elsif new_backend.start_with? 'html'
|
900
|
-
attrs['htmlsyntax'] = 'html'
|
914
|
+
attrs['htmlsyntax'] = 'html' unless attrs['htmlsyntax'] == 'xml'
|
901
915
|
end
|
902
916
|
if (resolved_name = BACKEND_ALIASES[new_backend])
|
903
917
|
new_backend = resolved_name
|
@@ -986,6 +1000,7 @@ class Document < AbstractBlock
|
|
986
1000
|
converter_opts[:template_engine] = @options[:template_engine]
|
987
1001
|
converter_opts[:template_engine_options] = @options[:template_engine_options]
|
988
1002
|
converter_opts[:eruby] = @options[:eruby]
|
1003
|
+
converter_opts[:safe] = @safe
|
989
1004
|
end
|
990
1005
|
if (converter = @options[:converter])
|
991
1006
|
converter_factory = Converter::Factory.new ::Hash[backend, converter]
|
@@ -1002,9 +1017,10 @@ class Document < AbstractBlock
|
|
1002
1017
|
# loaded by the Converter. If a :template_dir is not specified,
|
1003
1018
|
# or a template is missing, the converter will fall back to
|
1004
1019
|
# using the appropriate built-in template.
|
1020
|
+
#--
|
1021
|
+
# QUESTION should we dup @header_attributes before converting?
|
1005
1022
|
def convert opts = {}
|
1006
1023
|
parse unless @parsed
|
1007
|
-
restore_attributes
|
1008
1024
|
unless @safe >= SafeMode::SERVER || opts.empty?
|
1009
1025
|
# QUESTION should we store these on the Document object?
|
1010
1026
|
@attributes.delete 'outfile' unless (@attributes['outfile'] = opts['outfile'])
|
@@ -1021,7 +1037,7 @@ class Document < AbstractBlock
|
|
1021
1037
|
if (block = @blocks[0]) && block.content_model != :compound
|
1022
1038
|
output = block.content
|
1023
1039
|
else
|
1024
|
-
output =
|
1040
|
+
output = nil
|
1025
1041
|
end
|
1026
1042
|
else
|
1027
1043
|
transform = ((opts.key? :header_footer) ? opts[:header_footer] : @options[:header_footer]) ? 'document' : 'embedded'
|
@@ -1051,9 +1067,11 @@ class Document < AbstractBlock
|
|
1051
1067
|
@converter.write output, target
|
1052
1068
|
else
|
1053
1069
|
if target.respond_to? :write
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1070
|
+
unless output.nil_or_empty?
|
1071
|
+
target.write output.chomp
|
1072
|
+
# ensure there's a trailing endline
|
1073
|
+
target.write EOL
|
1074
|
+
end
|
1057
1075
|
else
|
1058
1076
|
::File.open(target, 'w') {|f| f.write output }
|
1059
1077
|
end
|
@@ -1097,34 +1115,49 @@ class Document < AbstractBlock
|
|
1097
1115
|
# will be determined based on the basebackend. (default: nil)
|
1098
1116
|
#
|
1099
1117
|
# returns The contents of the docinfo file(s)
|
1100
|
-
def docinfo(location = :
|
1118
|
+
def docinfo(location = :head, ext = nil)
|
1101
1119
|
if safe >= SafeMode::SECURE
|
1102
1120
|
''
|
1103
1121
|
else
|
1104
1122
|
qualifier = (location == :footer ? '-footer' : nil)
|
1105
|
-
ext = @
|
1123
|
+
ext = @outfilesuffix unless ext
|
1106
1124
|
docinfodir = @attributes['docinfodir']
|
1107
1125
|
|
1108
1126
|
content = nil
|
1109
1127
|
|
1110
|
-
docinfo = @attributes
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
if (content = read_asset(docinfo_path, :normalize => true))
|
1118
|
-
content = sub_attributes(content)
|
1128
|
+
if (docinfo = @attributes['docinfo']).nil_or_empty?
|
1129
|
+
if @attributes.key? 'docinfo2'
|
1130
|
+
docinfo = ['private', 'shared']
|
1131
|
+
elsif @attributes.key? 'docinfo1'
|
1132
|
+
docinfo = ['shared']
|
1133
|
+
else
|
1134
|
+
docinfo = docinfo ? ['private'] : nil
|
1119
1135
|
end
|
1136
|
+
else
|
1137
|
+
docinfo = docinfo.split(',').map(&:strip)
|
1120
1138
|
end
|
1121
1139
|
|
1122
|
-
if
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
content =
|
1140
|
+
if docinfo
|
1141
|
+
docinfo_filename = %(docinfo#{qualifier}#{ext})
|
1142
|
+
unless (docinfo & ['shared', %(shared-#{location})]).empty?
|
1143
|
+
docinfo_path = normalize_system_path(docinfo_filename, docinfodir)
|
1144
|
+
# NOTE normalizing the lines is essential if we're performing substitutions
|
1145
|
+
if (content = read_asset(docinfo_path, :normalize => true))
|
1146
|
+
if (docinfosubs ||= resolve_docinfo_subs)
|
1147
|
+
content = (docinfosubs == :attributes) ? sub_attributes(content) : apply_subs(content, docinfosubs)
|
1148
|
+
end
|
1149
|
+
end
|
1150
|
+
end
|
1151
|
+
|
1152
|
+
unless @attributes['docname'].nil_or_empty? || (docinfo & ['private', %(private-#{location})]).empty?
|
1153
|
+
docinfo_path = normalize_system_path(%(#{@attributes['docname']}-#{docinfo_filename}), docinfodir)
|
1154
|
+
# NOTE normalizing the lines is essential if we're performing substitutions
|
1155
|
+
if (content2 = read_asset(docinfo_path, :normalize => true))
|
1156
|
+
if (docinfosubs ||= resolve_docinfo_subs)
|
1157
|
+
content2 = (docinfosubs == :attributes) ? sub_attributes(content2) : apply_subs(content2, docinfosubs)
|
1158
|
+
end
|
1159
|
+
content = content ? %(#{content}#{EOL}#{content2}) : content2
|
1160
|
+
end
|
1128
1161
|
end
|
1129
1162
|
end
|
1130
1163
|
|
@@ -1139,7 +1172,16 @@ class Document < AbstractBlock
|
|
1139
1172
|
end
|
1140
1173
|
end
|
1141
1174
|
|
1142
|
-
def
|
1175
|
+
def resolve_docinfo_subs
|
1176
|
+
if @attributes.key? 'docinfosubs'
|
1177
|
+
subs = resolve_subs @attributes['docinfosubs'], :block, nil, 'docinfo'
|
1178
|
+
subs.empty? ? nil : subs
|
1179
|
+
else
|
1180
|
+
:attributes
|
1181
|
+
end
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
def docinfo_processors?(location = :head)
|
1143
1185
|
if @docinfo_processor_extensions.key?(location)
|
1144
1186
|
# false means we already performed a lookup and didn't find any
|
1145
1187
|
@docinfo_processor_extensions[location] != false
|
@@ -110,7 +110,7 @@ module Extensions
|
|
110
110
|
#--
|
111
111
|
# QUESTION is parse_content the right method name? should we wrap in open block automatically?
|
112
112
|
def parse_content parent, content, attributes = {}
|
113
|
-
reader = (content.is_a? Reader) ?
|
113
|
+
reader = (content.is_a? Reader) ? content : (Reader.new content)
|
114
114
|
while reader.has_more_lines?
|
115
115
|
block = Parser.next_block reader, parent, attributes
|
116
116
|
parent << block if block
|
@@ -258,7 +258,7 @@ module Extensions
|
|
258
258
|
|
259
259
|
def initialize config = {}
|
260
260
|
super config
|
261
|
-
@config[:location] ||= :
|
261
|
+
@config[:location] ||= :head
|
262
262
|
end
|
263
263
|
|
264
264
|
def process document
|
@@ -423,8 +423,9 @@ module Extensions
|
|
423
423
|
# for example, FormalInlineMacro, ShortInlineMacro (no target) and other patterns
|
424
424
|
# FIXME for inline passthrough, we need to have some way to specify the text as a passthrough
|
425
425
|
class InlineMacroProcessor < MacroProcessor
|
426
|
-
|
427
|
-
|
426
|
+
# Lookup the regexp option, resolving it first if necessary.
|
427
|
+
# Once this method is called, the regexp is considered frozen.
|
428
|
+
def regexp
|
428
429
|
@config[:regexp] ||= (resolve_regexp @name, @config[:format])
|
429
430
|
end
|
430
431
|
|
@@ -796,7 +797,7 @@ module Extensions
|
|
796
797
|
|
797
798
|
# Public: Checks whether any {DocinfoProcessor} extensions have been registered.
|
798
799
|
#
|
799
|
-
# location - A Symbol for selecting docinfo extensions at a given location (:
|
800
|
+
# location - A Symbol for selecting docinfo extensions at a given location (:head or :footer) (default: nil)
|
800
801
|
#
|
801
802
|
# Returns a [Boolean] indicating whether any DocinfoProcessor extensions are registered.
|
802
803
|
def docinfo_processors? location = nil
|
@@ -814,7 +815,7 @@ module Extensions
|
|
814
815
|
# Public: Retrieves the {Extension} proxy objects for all the
|
815
816
|
# DocinfoProcessor instances stored in this registry.
|
816
817
|
#
|
817
|
-
# location - A Symbol for selecting docinfo extensions at a given location (:
|
818
|
+
# location - A Symbol for selecting docinfo extensions at a given location (:head or :footer) (default: nil)
|
818
819
|
#
|
819
820
|
# Returns an [Array] of Extension proxy objects.
|
820
821
|
def docinfo_processors location = nil
|
@@ -877,7 +878,7 @@ module Extensions
|
|
877
878
|
# end
|
878
879
|
#
|
879
880
|
# # as a method block with an explicit block name
|
880
|
-
#
|
881
|
+
# block :shout do
|
881
882
|
# process |parent, reader, attrs|
|
882
883
|
# ...
|
883
884
|
# end
|
@@ -940,22 +941,22 @@ module Extensions
|
|
940
941
|
# Examples
|
941
942
|
#
|
942
943
|
# # as a BlockMacroProcessor subclass
|
943
|
-
#
|
944
|
+
# block_macro GistBlockMacro
|
944
945
|
#
|
945
946
|
# # as a BlockMacroProcessor subclass with an explicit macro name
|
946
|
-
#
|
947
|
+
# block_macro GistBlockMacro, :gist
|
947
948
|
#
|
948
949
|
# # as an instance of a BlockMacroProcessor subclass
|
949
|
-
#
|
950
|
+
# block_macro GistBlockMacro.new
|
950
951
|
#
|
951
952
|
# # as an instance of a BlockMacroProcessor subclass with an explicit macro name
|
952
|
-
#
|
953
|
+
# block_macro GistBlockMacro.new, :gist
|
953
954
|
#
|
954
955
|
# # as a name of a BlockMacroProcessor subclass
|
955
|
-
#
|
956
|
+
# block_macro 'GistBlockMacro'
|
956
957
|
#
|
957
958
|
# # as a name of a BlockMacroProcessor subclass with an explicit macro name
|
958
|
-
#
|
959
|
+
# block_macro 'GistBlockMacro', :gist
|
959
960
|
#
|
960
961
|
# # as a method block
|
961
962
|
# block_macro do
|
@@ -966,7 +967,7 @@ module Extensions
|
|
966
967
|
# end
|
967
968
|
#
|
968
969
|
# # as a method block with an explicit macro name
|
969
|
-
#
|
970
|
+
# block_macro :gist do
|
970
971
|
# process |parent, target, attrs|
|
971
972
|
# ...
|
972
973
|
# end
|
@@ -1029,22 +1030,22 @@ module Extensions
|
|
1029
1030
|
# Examples
|
1030
1031
|
#
|
1031
1032
|
# # as an InlineMacroProcessor subclass
|
1032
|
-
#
|
1033
|
+
# inline_macro ChromeInlineMacro
|
1033
1034
|
#
|
1034
1035
|
# # as an InlineMacroProcessor subclass with an explicit macro name
|
1035
|
-
#
|
1036
|
+
# inline_macro ChromeInineMacro, :chrome
|
1036
1037
|
#
|
1037
1038
|
# # as an instance of an InlineMacroProcessor subclass
|
1038
|
-
#
|
1039
|
+
# inline_macro ChromeInlineMacro.new
|
1039
1040
|
#
|
1040
1041
|
# # as an instance of an InlineMacroProcessor subclass with an explicit macro name
|
1041
|
-
#
|
1042
|
+
# inline_macro ChromeInlineMacro.new, :chrome
|
1042
1043
|
#
|
1043
1044
|
# # as a name of an InlineMacroProcessor subclass
|
1044
|
-
#
|
1045
|
+
# inline_macro 'ChromeInlineMacro'
|
1045
1046
|
#
|
1046
1047
|
# # as a name of an InlineMacroProcessor subclass with an explicit macro name
|
1047
|
-
#
|
1048
|
+
# inline_macro 'ChromeInineMacro', :chrome
|
1048
1049
|
#
|
1049
1050
|
# # as a method block
|
1050
1051
|
# inline_macro do
|
@@ -1055,7 +1056,7 @@ module Extensions
|
|
1055
1056
|
# end
|
1056
1057
|
#
|
1057
1058
|
# # as a method block with an explicit macro name
|
1058
|
-
#
|
1059
|
+
# inline_macro :chrome do
|
1059
1060
|
# process |parent, target, attrs|
|
1060
1061
|
# ...
|
1061
1062
|
# end
|