def preprocess_include raw_target, raw_attributes
if (target = @document.sub_attributes raw_target, :attribute_missing => 'drop-line').empty?
advance
if @document.attributes.fetch('attribute-missing', Compliance.attribute_missing) == 'skip'
unshift %(Unresolved directive in #{@path} - include::#{raw_target}[#{raw_attributes}])
end
true
elsif include_processors? &&
(extension = @include_processor_extensions.find {|candidate| candidate.instance.handles? target })
advance
extension.process_method[@document, self, target, AttributeList.new(raw_attributes).parse]
true
elsif @document.safe >= SafeMode::SECURE
replace_next_line %(link:#{target}[])
true
elsif (abs_maxdepth = @maxdepth[:abs]) > 0 && @include_stack.size >= abs_maxdepth
warn %(asciidoctor: ERROR: #{line_info}: maximum include depth of #{@maxdepth[:rel]} exceeded)
false
elsif abs_maxdepth > 0
if ::RUBY_ENGINE_OPAL
target_type = :file
include_file = path = if @include_stack.empty?
::Dir.pwd == @document.base_dir ? target : (::File.join @dir, target)
else
::File.join @dir, target
end
elsif Helpers.uriish? target
unless @document.attributes.has_key? 'allow-uri-read'
replace_next_line %(link:#{target}[])
return true
end
target_type = :uri
include_file = path = target
if @document.attributes.has_key? 'cache-uri'
Helpers.require_library 'open-uri/cached', 'open-uri-cached' unless defined? ::OpenURI::Cache
elsif !::RUBY_ENGINE_OPAL
::OpenURI
end
else
target_type = :file
include_file = @document.normalize_system_path(target, @dir, nil, :target_name => 'include file')
unless ::File.file? include_file
warn %(asciidoctor: WARNING: #{line_info}: include file not found: #{include_file})
replace_next_line %(Unresolved directive in #{@path} - include::#{target}[#{raw_attributes}])
return true
end
path = PathResolver.new.relative_path include_file, @document.base_dir
end
inc_lines = nil
tags = nil
attributes = {}
if !raw_attributes.empty?
attributes = AttributeList.new(raw_attributes).parse
if attributes.has_key? 'lines'
inc_lines = []
attributes['lines'].split(DataDelimiterRx).each do |linedef|
if linedef.include?('..')
from, to = linedef.split('..').map(&:to_i)
if to == -1
inc_lines << from
inc_lines << 1.0/0.0
else
inc_lines.concat ::Range.new(from, to).to_a
end
else
inc_lines << linedef.to_i
end
end
inc_lines = inc_lines.sort.uniq
elsif attributes.has_key? 'tag'
tags = [attributes['tag']].to_set
elsif attributes.has_key? 'tags'
tags = attributes['tags'].split(DataDelimiterRx).to_set
end
end
if inc_lines
unless inc_lines.empty?
selected = []
inc_line_offset = 0
inc_lineno = 0
begin
open(include_file, 'r') do |f|
f.each_line do |l|
inc_lineno += 1
take = inc_lines[0]
if take.is_a?(::Float) && take.infinite?
selected.push l
inc_line_offset = inc_lineno if inc_line_offset == 0
else
if f.lineno == take
selected.push l
inc_line_offset = inc_lineno if inc_line_offset == 0
inc_lines.shift
end
break if inc_lines.empty?
end
end
end
rescue
warn %(asciidoctor: WARNING: #{line_info}: include #{target_type} not readable: #{include_file})
replace_next_line %(Unresolved directive in #{@path} - include::#{target}[#{raw_attributes}])
return true
end
advance
push_include selected, include_file, path, inc_line_offset, attributes
end
elsif tags
unless tags.empty?
selected = []
inc_line_offset = 0
inc_lineno = 0
active_tag = nil
tags_found = ::Set.new
begin
open(include_file, 'r') do |f|
f.each_line do |l|
inc_lineno += 1
l.force_encoding(::Encoding::UTF_8) if FORCE_ENCODING
l = l.rstrip
tl = l.chomp('-->').rstrip
if active_tag
if tl.end_with?(%(end::#{active_tag}[]))
active_tag = nil
else
selected.push l unless tl.end_with?('[]') && TagDirectiveRx =~ tl
inc_line_offset = inc_lineno if inc_line_offset == 0
end
else
tags.each do |tag|
if tl.end_with?(%(tag::#{tag}[]))
active_tag = tag
tags_found << tag
break
end
end if tl.end_with?('[]') && TagDirectiveRx =~ tl
end
end
end
rescue
warn %(asciidoctor: WARNING: #{line_info}: include #{target_type} not readable: #{include_file})
replace_next_line %(Unresolved directive in #{@path} - include::#{target}[#{raw_attributes}])
return true
end
unless (missing_tags = tags.to_a - tags_found.to_a).empty?
warn %(asciidoctor: WARNING: #{line_info}: tag#{missing_tags.size > 1 ? 's' : nil} '#{missing_tags * ','}' not found in include #{target_type}: #{include_file})
end
advance
push_include selected, include_file, path, inc_line_offset, attributes
end
else
begin
include_content = open(include_file, 'r') {|f| f.read }
advance
push_include include_content, include_file, path, 1, attributes
rescue
warn %(asciidoctor: WARNING: #{line_info}: include #{target_type} not readable: #{include_file})
replace_next_line %(Unresolved directive in #{@path} - include::#{target}[#{raw_attributes}])
return true
end
end
true
else
false
end
end