def load input, options = {}
options = options.dup
if (timings = options[:timings])
timings.start :read
end
attributes = options[:attributes] = if !(attrs = options[:attributes])
{}
elsif ::Hash === attrs || (::RUBY_ENGINE_JRUBY && ::Java::JavaUtil::Map === attrs)
attrs.dup
elsif ::Array === attrs
attrs.inject({}) do |accum, entry|
k, v = entry.split '=', 2
accum[k] = v || ''
accum
end
elsif ::String === attrs
capture_1 = '\1'
attrs = attrs.gsub(SpaceDelimiterRx, %(#{capture_1}#{NULL})).gsub(EscapedSpaceRx, capture_1)
attrs.split(NULL).inject({}) do |accum, entry|
k, v = entry.split '=', 2
accum[k] = v || ''
accum
end
elsif (attrs.respond_to? :keys) && (attrs.respond_to? :[])
original_attrs = attrs
attrs = {}
original_attrs.keys.each do |key|
attrs[key] = original_attrs[key]
end
attrs
else
raise ::ArgumentError, %(illegal type for attributes option: #{attrs.class.ancestors})
end
lines = nil
if ::File === input
input_path = ::File.expand_path input.path
input_mtime = input.mtime
lines = input.readlines
attributes['docfile'] = input_path
attributes['docdir'] = ::File.dirname input_path
attributes['docname'] = Helpers.basename input_path, true
docdate = (attributes['docdate'] ||= input_mtime.strftime('%Y-%m-%d'))
doctime = (attributes['doctime'] ||= input_mtime.strftime('%H:%M:%S %Z'))
attributes['docdatetime'] = %(#{docdate} #{doctime})
elsif input.respond_to? :readlines
begin
input.rewind
rescue
end
lines = input.readlines
elsif ::String === input
lines = input.lines.entries
elsif ::Array === input
lines = input.dup
else
raise ::ArgumentError, %(unsupported input type: #{input.class})
end
if timings
timings.record :read
timings.start :parse
end
if options[:parse] == false
doc = Document.new lines, options
else
doc = (Document.new lines, options).parse
end
timings.record :parse if timings
doc
rescue => ex
begin
context = %(asciidoctor: FAILED: #{attributes['docfile'] || '<stdin>'}: Failed to load AsciiDoc document)
if ex.respond_to? :exception
wrapped_ex = ex.exception %(#{context} - #{ex.message})
wrapped_ex.set_backtrace ex.backtrace
else
wrapped_ex = ex.class.new context, ex
wrapped_ex.stack_trace = ex.stack_trace
end
rescue
wrapped_ex = ex
end
raise wrapped_ex
end