asciidoctor 1.5.6.1 → 1.5.6.2
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 +5 -5
- data/CHANGELOG.adoc +36 -2
- data/CONTRIBUTING.adoc +15 -1
- data/Gemfile +9 -1
- data/{LICENSE.adoc → LICENSE} +3 -4
- data/Rakefile +0 -83
- data/asciidoctor.gemspec +3 -5
- data/lib/asciidoctor.rb +1 -1
- data/lib/asciidoctor/abstract_node.rb +145 -145
- data/lib/asciidoctor/document.rb +12 -16
- data/lib/asciidoctor/extensions.rb +13 -0
- data/lib/asciidoctor/path_resolver.rb +53 -24
- data/lib/asciidoctor/reader.rb +95 -88
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +5 -5
- data/man/asciidoctor.adoc +2 -2
- data/test/extensions_test.rb +55 -1
- data/test/links_test.rb +15 -0
- data/test/sections_test.rb +4 -4
- data/test/substitutions_test.rb +2 -2
- data/test/test_helper.rb +4 -4
- metadata +7 -39
- data/README-fr.adoc +0 -423
- data/README-jp.adoc +0 -408
- data/README-zh_CN.adoc +0 -427
- data/README.adoc +0 -422
data/lib/asciidoctor/document.rb
CHANGED
@@ -319,18 +319,16 @@ class Document < AbstractBlock
|
|
319
319
|
# legacy support for numbered attribute
|
320
320
|
attr_overrides['sectnums'] = attr_overrides.delete 'numbered' if attr_overrides.key? 'numbered'
|
321
321
|
|
322
|
-
#
|
323
|
-
#
|
324
|
-
#
|
325
|
-
if options[:base_dir]
|
326
|
-
@base_dir = attr_overrides['docdir'] = ::File.expand_path
|
322
|
+
# If the base_dir option is specified, it overrides docdir and is used as the root for relative
|
323
|
+
# paths. Otherwise, the base_dir is the directory of the source file (docdir), if set, otherwise
|
324
|
+
# the current directory.
|
325
|
+
if (base_dir_val = options[:base_dir])
|
326
|
+
@base_dir = (attr_overrides['docdir'] = ::File.expand_path base_dir_val)
|
327
|
+
elsif attr_overrides['docdir']
|
328
|
+
@base_dir = attr_overrides['docdir']
|
327
329
|
else
|
328
|
-
|
329
|
-
|
330
|
-
else
|
331
|
-
#warn 'asciidoctor: WARNING: setting base_dir is recommended when working with string documents' unless nested?
|
332
|
-
@base_dir = attr_overrides['docdir'] = ::File.expand_path(::Dir.pwd)
|
333
|
-
end
|
330
|
+
#warn 'asciidoctor: WARNING: setting base_dir is recommended when working with string documents' unless nested?
|
331
|
+
@base_dir = attr_overrides['docdir'] = ::Dir.pwd
|
334
332
|
end
|
335
333
|
|
336
334
|
# allow common attributes backend and doctype to be set using options hash, coerce values to string
|
@@ -1195,12 +1193,10 @@ class Document < AbstractBlock
|
|
1195
1193
|
if @docinfo_processor_extensions.key?(location)
|
1196
1194
|
# false means we already performed a lookup and didn't find any
|
1197
1195
|
@docinfo_processor_extensions[location] != false
|
1196
|
+
elsif @extensions && @document.extensions.docinfo_processors?(location)
|
1197
|
+
!!(@docinfo_processor_extensions[location] = @document.extensions.docinfo_processors(location))
|
1198
1198
|
else
|
1199
|
-
|
1200
|
-
!!(@docinfo_processor_extensions[location] = @document.extensions.docinfo_processors(location))
|
1201
|
-
else
|
1202
|
-
@docinfo_processor_extensions[location] = false
|
1203
|
-
end
|
1199
|
+
@docinfo_processor_extensions[location] = false
|
1204
1200
|
end
|
1205
1201
|
end
|
1206
1202
|
|
@@ -147,7 +147,20 @@ module Extensions
|
|
147
147
|
Block.new parent, context, { :source => source, :attributes => attrs }.merge(opts)
|
148
148
|
end
|
149
149
|
|
150
|
+
# Public: Creates an image block node and links it to the specified parent.
|
151
|
+
#
|
152
|
+
# parent - The parent Block (Block, Section, or Document) of this new image block.
|
153
|
+
# attrs - A Hash of attributes to control how the image block is built.
|
154
|
+
# Use the target attribute to set the source of the image.
|
155
|
+
# Use the alt attribute to specify an alternate text for the image.
|
156
|
+
# opts - An optional Hash of options (default: {})
|
157
|
+
#
|
158
|
+
# Returns a [Block] node with all properties properly initialized.
|
150
159
|
def create_image_block parent, attrs, opts = {}
|
160
|
+
unless (target = attrs['target'])
|
161
|
+
raise ::ArgumentError, 'Unable to create an image block, target attribute is required'
|
162
|
+
end
|
163
|
+
attrs['alt'] ||= (attrs['default-alt'] = Helpers.basename(target, true).tr('_-', ' '))
|
151
164
|
create_block parent, :image, nil, attrs, opts
|
152
165
|
end
|
153
166
|
|
@@ -124,32 +124,49 @@ class PathResolver
|
|
124
124
|
def initialize file_separator = nil, working_dir = nil
|
125
125
|
@file_separator = file_separator ? file_separator : (::File::ALT_SEPARATOR || ::File::SEPARATOR)
|
126
126
|
if working_dir
|
127
|
-
@working_dir = (
|
127
|
+
@working_dir = (root? working_dir) ? working_dir : (::File.expand_path working_dir)
|
128
128
|
else
|
129
129
|
@working_dir = ::File.expand_path ::Dir.pwd
|
130
130
|
end
|
131
131
|
@_partition_path_sys, @_partition_path_web = {}, {}
|
132
132
|
end
|
133
133
|
|
134
|
-
# Public: Check
|
135
|
-
# This operation considers posix paths, windows paths, and file URLs.
|
134
|
+
# Public: Check whether the specified path is an absolute path.
|
136
135
|
#
|
137
|
-
#
|
138
|
-
#
|
136
|
+
# This operation considers both posix paths and Windows paths. It does not
|
137
|
+
# consider URIs.
|
138
|
+
#
|
139
|
+
# Unix absolute paths and UNC paths both start with slash. Windows roots can
|
140
|
+
# start with a drive letter.
|
139
141
|
#
|
140
142
|
# path - the String path to check
|
141
143
|
#
|
142
144
|
# returns a Boolean indicating whether the path is an absolute root path
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
145
|
+
def absolute_path? path
|
146
|
+
(path.start_with? SLASH) || (@file_separator == BACKSLASH && (WindowsRootRx.match? path))
|
147
|
+
end
|
148
|
+
|
149
|
+
# Public: Check if the specified path is an absolute root path (or, in the
|
150
|
+
# browser environment, an absolute URI as well)
|
151
|
+
#
|
152
|
+
# This operation considers both posix paths and Windows paths. If the JavaScript IO
|
153
|
+
# module is xmlhttprequest, this operation also considers absolute URIs.
|
154
|
+
#
|
155
|
+
# Unix absolute paths and UNC paths start with slash. Windows roots can
|
156
|
+
# start with a drive letter. When the IO module is xmlhttprequest (Opal
|
157
|
+
# runtime only), an absolute (qualified) URI (starts with file://, http://,
|
158
|
+
# or https://) is also considered to be an absolute path.
|
159
|
+
#
|
160
|
+
# path - the String path to check
|
161
|
+
#
|
162
|
+
# returns a Boolean indicating whether the path is an absolute root path (or
|
163
|
+
# an absolute URI when the JavaScript IO module is xmlhttprequest)
|
164
|
+
if RUBY_ENGINE == 'opal' && ::JAVASCRIPT_IO_MODULE == 'xmlhttprequest'
|
165
|
+
def root? path
|
166
|
+
(absolute_path? path) || (path.start_with? 'file://', 'http://', 'https://')
|
148
167
|
end
|
149
168
|
else
|
150
|
-
|
151
|
-
(path.start_with? SLASH) || (@file_separator == BACKSLASH && (WindowsRootRx.match? path))
|
152
|
-
end
|
169
|
+
alias root? absolute_path?
|
153
170
|
end
|
154
171
|
|
155
172
|
# Public: Determine if the path is a UNC (root) path
|
@@ -157,7 +174,7 @@ class PathResolver
|
|
157
174
|
# path - the String path to check
|
158
175
|
#
|
159
176
|
# returns a Boolean indicating whether the path is a UNC path
|
160
|
-
def
|
177
|
+
def unc? path
|
161
178
|
path.start_with? DOUBLE_SLASH
|
162
179
|
end
|
163
180
|
|
@@ -166,10 +183,22 @@ class PathResolver
|
|
166
183
|
# path - the String path to check
|
167
184
|
#
|
168
185
|
# returns a Boolean indicating whether the path is an absolute (root) web path
|
169
|
-
def
|
186
|
+
def web_root? path
|
170
187
|
path.start_with? SLASH
|
171
188
|
end
|
172
189
|
|
190
|
+
# Public: Determine whether path descends from base.
|
191
|
+
#
|
192
|
+
# If path equals base, or base is a parent of path, return true.
|
193
|
+
#
|
194
|
+
# path - The String path to check. Can be relative.
|
195
|
+
# base - The String base path to check against. Can be relative.
|
196
|
+
#
|
197
|
+
# returns If path descends from base, return the offset, otherwise false.
|
198
|
+
def descends_from? path, base
|
199
|
+
base == path ? 0 : ((path.start_with? base + '/') ? base.length + 1 : false)
|
200
|
+
end
|
201
|
+
|
173
202
|
# Public: Normalize path by converting any backslashes to forward slashes
|
174
203
|
#
|
175
204
|
# path - the String path to normalize
|
@@ -224,7 +253,7 @@ class PathResolver
|
|
224
253
|
|
225
254
|
root = if web
|
226
255
|
# ex. /sample/path
|
227
|
-
if
|
256
|
+
if web_root? posix_path
|
228
257
|
SLASH
|
229
258
|
# ex. ./sample/path
|
230
259
|
elsif posix_path.start_with? DOT_SLASH
|
@@ -234,9 +263,9 @@ class PathResolver
|
|
234
263
|
nil
|
235
264
|
end
|
236
265
|
else
|
237
|
-
if
|
266
|
+
if root? posix_path
|
238
267
|
# ex. //sample/path
|
239
|
-
if
|
268
|
+
if unc? posix_path
|
240
269
|
DOUBLE_SLASH
|
241
270
|
# ex. /sample/path
|
242
271
|
elsif posix_path.start_with? SLASH
|
@@ -308,7 +337,7 @@ class PathResolver
|
|
308
337
|
# that the resolved path be contained within the jail, if provided
|
309
338
|
def system_path target, start = nil, jail = nil, opts = {}
|
310
339
|
if jail
|
311
|
-
unless
|
340
|
+
unless root? jail
|
312
341
|
raise ::SecurityError, %(Jail is not an absolute path: #{jail})
|
313
342
|
end
|
314
343
|
jail = posixify jail
|
@@ -323,7 +352,7 @@ class PathResolver
|
|
323
352
|
if target_segments.empty?
|
324
353
|
if start.nil_or_empty?
|
325
354
|
return jail ? jail : @working_dir
|
326
|
-
elsif
|
355
|
+
elsif root? start
|
327
356
|
unless jail
|
328
357
|
return expand_path start
|
329
358
|
end
|
@@ -343,7 +372,7 @@ class PathResolver
|
|
343
372
|
|
344
373
|
if start.nil_or_empty?
|
345
374
|
start = jail ? jail : @working_dir
|
346
|
-
elsif
|
375
|
+
elsif root? start
|
347
376
|
start = posixify start
|
348
377
|
else
|
349
378
|
start = system_path start, jail, jail, opts
|
@@ -412,7 +441,7 @@ class PathResolver
|
|
412
441
|
start = posixify start
|
413
442
|
uri_prefix = nil
|
414
443
|
|
415
|
-
unless start.nil_or_empty? || (
|
444
|
+
unless start.nil_or_empty? || (web_root? target)
|
416
445
|
target = (start.end_with? SLASH) ? %(#{start}#{target}) : %(#{start}#{SLASH}#{target})
|
417
446
|
if (uri_prefix = Helpers.uri_prefix target)
|
418
447
|
target = target[uri_prefix.length..-1]
|
@@ -420,7 +449,7 @@ class PathResolver
|
|
420
449
|
end
|
421
450
|
|
422
451
|
# use this logic instead if we want to normalize target if it contains a URI
|
423
|
-
#unless
|
452
|
+
#unless web_root? target
|
424
453
|
# if preserve_uri_target && (uri_prefix = Helpers.uri_prefix target)
|
425
454
|
# target = target[uri_prefix.length..-1]
|
426
455
|
# elsif !start.nil_or_empty?
|
@@ -466,7 +495,7 @@ class PathResolver
|
|
466
495
|
#
|
467
496
|
# Return the [String] relative path of the filename calculated from the base directory.
|
468
497
|
def relative_path filename, base_directory
|
469
|
-
if (
|
498
|
+
if (root? filename) && (filename.start_with? base_directory)
|
470
499
|
filename.slice base_directory.length + 1, filename.length
|
471
500
|
else
|
472
501
|
filename
|
data/lib/asciidoctor/reader.rb
CHANGED
@@ -89,12 +89,10 @@ class Reader
|
|
89
89
|
else
|
90
90
|
data.split LF, -1
|
91
91
|
end
|
92
|
+
elsif opts[:normalize]
|
93
|
+
Helpers.normalize_lines_array data
|
92
94
|
else
|
93
|
-
|
94
|
-
Helpers.normalize_lines_array data
|
95
|
-
else
|
96
|
-
data.dup
|
97
|
-
end
|
95
|
+
data.dup
|
98
96
|
end
|
99
97
|
end
|
100
98
|
|
@@ -296,11 +294,11 @@ class Reader
|
|
296
294
|
#
|
297
295
|
# replacement - The String line to put in place of the next line (i.e., the line at the cursor).
|
298
296
|
#
|
299
|
-
# Returns
|
297
|
+
# Returns true.
|
300
298
|
def replace_next_line replacement
|
301
299
|
shift
|
302
300
|
unshift replacement
|
303
|
-
|
301
|
+
true
|
304
302
|
end
|
305
303
|
# deprecated
|
306
304
|
alias replace_line replace_next_line
|
@@ -816,76 +814,46 @@ class PreprocessorReader < Reader
|
|
816
814
|
#
|
817
815
|
# If none of the above apply, emit the include directive line verbatim.
|
818
816
|
#
|
819
|
-
# target
|
820
|
-
#
|
817
|
+
# target - The unsubstituted String name of the target document to include as specified in the
|
818
|
+
# target slot of the include directive.
|
819
|
+
# attrlist - An attribute list String, which is the text between the square brackets of the
|
820
|
+
# include directive.
|
821
821
|
#
|
822
|
-
# Returns a Boolean indicating whether the line under the cursor
|
823
|
-
|
824
|
-
|
825
|
-
|
822
|
+
# Returns a [Boolean] indicating whether the line under the cursor was changed. To skip over the
|
823
|
+
# directive, call shift and return true.
|
824
|
+
def preprocess_include_directive target, attrlist
|
825
|
+
if ((expanded_target = target).include? ATTR_REF_HEAD) &&
|
826
|
+
(expanded_target = @document.sub_attributes target, :attribute_missing => 'drop-line').empty?
|
826
827
|
shift
|
827
828
|
if @document.attributes.fetch('attribute-missing', Compliance.attribute_missing) == 'skip'
|
828
|
-
unshift %(Unresolved directive in #{@path} - include::#{
|
829
|
+
unshift %(Unresolved directive in #{@path} - include::#{target}[#{attrlist}])
|
829
830
|
end
|
830
831
|
true
|
831
|
-
elsif include_processors? && (ext = @include_processor_extensions.find {|candidate| candidate.instance.handles?
|
832
|
+
elsif include_processors? && (ext = @include_processor_extensions.find {|candidate| candidate.instance.handles? expanded_target })
|
832
833
|
shift
|
833
834
|
# FIXME parse attributes only if requested by extension
|
834
|
-
ext.process_method[@document, self,
|
835
|
+
ext.process_method[@document, self, expanded_target, AttributeList.new(attrlist).parse]
|
835
836
|
true
|
836
837
|
# if running in SafeMode::SECURE or greater, don't process this directive
|
837
838
|
# however, be friendly and at least make it a link to the source document
|
838
839
|
elsif @document.safe >= SafeMode::SECURE
|
839
840
|
# FIXME we don't want to use a link macro if we are in a verbatim context
|
840
|
-
replace_next_line %(link:#{
|
841
|
-
true
|
841
|
+
replace_next_line %(link:#{expanded_target}[])
|
842
842
|
elsif (abs_maxdepth = @maxdepth[:abs]) > 0
|
843
843
|
if @include_stack.size >= abs_maxdepth
|
844
844
|
warn %(asciidoctor: ERROR: #{line_info}: maximum include depth of #{@maxdepth[:rel]} exceeded)
|
845
|
-
return
|
845
|
+
return
|
846
846
|
end
|
847
|
-
if ::RUBY_ENGINE_OPAL && ::JAVASCRIPT_IO_MODULE == 'xmlhttprequest'
|
848
|
-
# NOTE resolves uri relative to currently loaded document
|
849
|
-
# NOTE we defer checking if file exists and catch the 404 error if it does not
|
850
|
-
target_type = :file
|
851
|
-
inc_path = relpath = @include_stack.empty? && ::Dir.pwd == @document.base_dir ? target : (::File.join @dir, target)
|
852
|
-
elsif Helpers.uriish? target
|
853
|
-
unless @document.attributes.key? 'allow-uri-read'
|
854
|
-
replace_next_line %(link:#{target}[])
|
855
|
-
return true
|
856
|
-
end
|
857
847
|
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
# caching requires the open-uri-cached gem to be installed
|
862
|
-
# processing will be automatically aborted if these libraries can't be opened
|
863
|
-
Helpers.require_library 'open-uri/cached', 'open-uri-cached' unless defined? ::OpenURI::Cache
|
864
|
-
elsif !::RUBY_ENGINE_OPAL
|
865
|
-
# autoload open-uri
|
866
|
-
::OpenURI
|
867
|
-
end
|
868
|
-
else
|
869
|
-
target_type = :file
|
870
|
-
# include file is resolved relative to dir of current include, or base_dir if within original docfile
|
871
|
-
inc_path = @document.normalize_system_path target, @dir, nil, :target_name => 'include file'
|
872
|
-
unless ::File.file? inc_path
|
873
|
-
warn %(asciidoctor: WARNING: #{line_info}: include file not found: #{inc_path})
|
874
|
-
replace_next_line %(Unresolved directive in #{@path} - include::#{target}[#{raw_attributes}])
|
875
|
-
return true
|
876
|
-
end
|
877
|
-
# NOTE relpath is the path relative to the root document (or base_dir, if set)
|
878
|
-
# QUESTION should we move relative_path method to Document
|
879
|
-
relpath = (@path_resolver ||= PathResolver.new).relative_path inc_path, @document.base_dir
|
880
|
-
end
|
848
|
+
parsed_attributes = attrlist.empty? ? {} : (AttributeList.new attrlist).parse
|
849
|
+
inc_path, target_type, relpath = resolve_include_path expanded_target, attrlist, parsed_attributes
|
850
|
+
return inc_path unless target_type
|
881
851
|
|
882
|
-
inc_linenos
|
883
|
-
unless
|
884
|
-
|
885
|
-
attributes = AttributeList.new(raw_attributes).parse
|
886
|
-
if attributes.key? 'lines'
|
852
|
+
inc_linenos = inc_tags = nil
|
853
|
+
unless parsed_attributes.empty?
|
854
|
+
if parsed_attributes.key? 'lines'
|
887
855
|
inc_linenos = []
|
888
|
-
|
856
|
+
parsed_attributes['lines'].split(DataDelimiterRx).each do |linedef|
|
889
857
|
if linedef.include?('..')
|
890
858
|
from, to = linedef.split('..', 2).map {|it| it.to_i }
|
891
859
|
if to == -1
|
@@ -899,17 +867,17 @@ class PreprocessorReader < Reader
|
|
899
867
|
end
|
900
868
|
end
|
901
869
|
inc_linenos = inc_linenos.empty? ? nil : inc_linenos.sort.uniq
|
902
|
-
elsif
|
903
|
-
unless (tag =
|
870
|
+
elsif parsed_attributes.key? 'tag'
|
871
|
+
unless (tag = parsed_attributes['tag']).empty?
|
904
872
|
if tag.start_with? '!'
|
905
873
|
inc_tags = { (tag.slice 1, tag.length) => false } unless tag == '!'
|
906
874
|
else
|
907
875
|
inc_tags = { tag => true }
|
908
876
|
end
|
909
877
|
end
|
910
|
-
elsif
|
878
|
+
elsif parsed_attributes.key? 'tags'
|
911
879
|
inc_tags = {}
|
912
|
-
|
880
|
+
parsed_attributes['tags'].split(DataDelimiterRx).each do |tagdef|
|
913
881
|
if tagdef.start_with? '!'
|
914
882
|
inc_tags[tagdef.slice 1, tagdef.length] = false unless tagdef == '!'
|
915
883
|
else
|
@@ -944,12 +912,11 @@ class PreprocessorReader < Reader
|
|
944
912
|
end
|
945
913
|
rescue
|
946
914
|
warn %(asciidoctor: WARNING: #{line_info}: include #{target_type} not readable: #{inc_path})
|
947
|
-
replace_next_line %(Unresolved directive in #{@path} - include::#{
|
948
|
-
return true
|
915
|
+
return replace_next_line %(Unresolved directive in #{@path} - include::#{expanded_target}[#{attrlist}])
|
949
916
|
end
|
950
917
|
shift
|
951
918
|
# FIXME not accounting for skipped lines in reader line numbering
|
952
|
-
push_include inc_lines, inc_path, relpath, inc_offset,
|
919
|
+
push_include inc_lines, inc_path, relpath, inc_offset, parsed_attributes if inc_offset
|
953
920
|
elsif inc_tags
|
954
921
|
inc_lines, inc_offset, inc_lineno, tag_stack, tags_used, active_tag = [], nil, 0, [], ::Set.new, nil
|
955
922
|
if inc_tags.key? '**'
|
@@ -982,9 +949,9 @@ class PreprocessorReader < Reader
|
|
982
949
|
elsif inc_tags.key? this_tag
|
983
950
|
if (idx = tag_stack.rindex {|key, _| key == this_tag })
|
984
951
|
idx == 0 ? tag_stack.shift : (tag_stack.delete_at idx)
|
985
|
-
warn %(asciidoctor: WARNING: #{
|
952
|
+
warn %(asciidoctor: WARNING: #{expanded_target}: line #{inc_lineno}: mismatched end tag in include: expected #{active_tag}, found #{this_tag})
|
986
953
|
else
|
987
|
-
warn %(asciidoctor: WARNING: #{
|
954
|
+
warn %(asciidoctor: WARNING: #{expanded_target}: line #{inc_lineno}: unexpected end tag in include: #{this_tag})
|
988
955
|
end
|
989
956
|
end
|
990
957
|
elsif inc_tags.key?(this_tag = $2)
|
@@ -1004,25 +971,23 @@ class PreprocessorReader < Reader
|
|
1004
971
|
end
|
1005
972
|
rescue
|
1006
973
|
warn %(asciidoctor: WARNING: #{line_info}: include #{target_type} not readable: #{inc_path})
|
1007
|
-
replace_next_line %(Unresolved directive in #{@path} - include::#{
|
1008
|
-
return true
|
974
|
+
return replace_next_line %(Unresolved directive in #{@path} - include::#{expanded_target}[#{attrlist}])
|
1009
975
|
end
|
1010
976
|
unless (missing_tags = inc_tags.keys.to_a - tags_used.to_a).empty?
|
1011
977
|
warn %(asciidoctor: WARNING: #{line_info}: tag#{missing_tags.size > 1 ? 's' : nil} '#{missing_tags * ','}' not found in include #{target_type}: #{inc_path})
|
1012
978
|
end
|
1013
979
|
shift
|
1014
980
|
# FIXME not accounting for skipped lines in reader line numbering
|
1015
|
-
push_include inc_lines, inc_path, relpath, inc_offset,
|
981
|
+
push_include inc_lines, inc_path, relpath, inc_offset, parsed_attributes if inc_offset
|
1016
982
|
else
|
1017
983
|
begin
|
1018
984
|
# NOTE read content first so that we only advance cursor if IO operation succeeds
|
1019
985
|
inc_content = target_type == :file ? (::IO.read inc_path) : open(inc_path, 'r') {|f| f.read }
|
1020
986
|
shift
|
1021
|
-
push_include inc_content, inc_path, relpath, 1,
|
987
|
+
push_include inc_content, inc_path, relpath, 1, parsed_attributes
|
1022
988
|
rescue
|
1023
989
|
warn %(asciidoctor: WARNING: #{line_info}: include #{target_type} not readable: #{inc_path})
|
1024
|
-
replace_next_line %(Unresolved directive in #{@path} - include::#{
|
1025
|
-
return true
|
990
|
+
return replace_next_line %(Unresolved directive in #{@path} - include::#{expanded_target}[#{attrlist}])
|
1026
991
|
end
|
1027
992
|
end
|
1028
993
|
true
|
@@ -1031,6 +996,50 @@ class PreprocessorReader < Reader
|
|
1031
996
|
end
|
1032
997
|
end
|
1033
998
|
|
999
|
+
# Internal: Resolve the target of an include directive.
|
1000
|
+
#
|
1001
|
+
# An internal method to resolve the target of an include directive. This method must return an
|
1002
|
+
# Array containing the resolved (absolute) path of the target, the target type (:file or :uri),
|
1003
|
+
# and the path of the target relative to the outermost document. Alternately, the method may
|
1004
|
+
# return a boolean to halt processing of the include directive line and to indicate whether the
|
1005
|
+
# cursor should be advanced beyond this line (true) or the line should be reprocessed (false).
|
1006
|
+
#
|
1007
|
+
# This method is overridden in Asciidoctor.js to resolve the target of an include in the browser
|
1008
|
+
# environment.
|
1009
|
+
#
|
1010
|
+
# target - A String containing the unresolved include target.
|
1011
|
+
# (Attribute references in target value have already been resolved).
|
1012
|
+
# attrlist - An attribute list String (i.e., the text between the square brackets).
|
1013
|
+
# attributes - A Hash of attributes parsed from attrlist.
|
1014
|
+
#
|
1015
|
+
# Returns An Array containing the resolved (absolute) include path, the target type, and the path
|
1016
|
+
# relative to the outermost document. May also return a boolean to halt processing of the include.
|
1017
|
+
def resolve_include_path target, attrlist, attributes
|
1018
|
+
if Helpers.uriish? target
|
1019
|
+
return replace_next_line %(link:#{target}[#{attrlist}]) unless @document.attributes.key? 'allow-uri-read'
|
1020
|
+
if @document.attributes.key? 'cache-uri'
|
1021
|
+
# caching requires the open-uri-cached gem to be installed
|
1022
|
+
# processing will be automatically aborted if these libraries can't be opened
|
1023
|
+
Helpers.require_library 'open-uri/cached', 'open-uri-cached' unless defined? ::OpenURI::Cache
|
1024
|
+
elsif !::RUBY_ENGINE_OPAL
|
1025
|
+
# autoload open-uri
|
1026
|
+
::OpenURI
|
1027
|
+
end
|
1028
|
+
[target, :uri, target]
|
1029
|
+
else
|
1030
|
+
# include file is resolved relative to dir of current include, or base_dir if within original docfile
|
1031
|
+
inc_path = @document.normalize_system_path target, @dir, nil, :target_name => 'include file'
|
1032
|
+
unless ::File.file? inc_path
|
1033
|
+
warn %(asciidoctor: WARNING: #{line_info}: include file not found: #{inc_path})
|
1034
|
+
return replace_next_line %(Unresolved directive in #{@path} - include::#{target}[#{attrlist}])
|
1035
|
+
end
|
1036
|
+
# NOTE relpath is the path relative to the root document (or base_dir, if set)
|
1037
|
+
# QUESTION should we move relative_path method to Document
|
1038
|
+
relpath = (@path_resolver ||= PathResolver.new).relative_path inc_path, @document.base_dir
|
1039
|
+
[inc_path, :file, relpath]
|
1040
|
+
end
|
1041
|
+
end
|
1042
|
+
|
1034
1043
|
# Public: Push source onto the front of the reader and switch the context
|
1035
1044
|
# based on the file, document-relative path and line information given.
|
1036
1045
|
#
|
@@ -1205,22 +1214,20 @@ class PreprocessorReader < Reader
|
|
1205
1214
|
|
1206
1215
|
if quoted
|
1207
1216
|
val
|
1217
|
+
elsif val.empty?
|
1218
|
+
nil
|
1219
|
+
elsif val == 'true'
|
1220
|
+
true
|
1221
|
+
elsif val == 'false'
|
1222
|
+
false
|
1223
|
+
elsif val.rstrip.empty?
|
1224
|
+
' '
|
1225
|
+
elsif val.include? '.'
|
1226
|
+
val.to_f
|
1208
1227
|
else
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
true
|
1213
|
-
elsif val == 'false'
|
1214
|
-
false
|
1215
|
-
elsif val.rstrip.empty?
|
1216
|
-
' '
|
1217
|
-
elsif val.include? '.'
|
1218
|
-
val.to_f
|
1219
|
-
else
|
1220
|
-
# fallback to coercing to integer, since we
|
1221
|
-
# require string values to be explicitly quoted
|
1222
|
-
val.to_i
|
1223
|
-
end
|
1228
|
+
# fallback to coercing to integer, since we
|
1229
|
+
# require string values to be explicitly quoted
|
1230
|
+
val.to_i
|
1224
1231
|
end
|
1225
1232
|
end
|
1226
1233
|
|