def self.load(input, options = {}, &block)
if (monitor = options.fetch(:monitor, false))
start = Time.now
end
attrs = (options[:attributes] ||= {})
if attrs.is_a? Hash
elsif attrs.is_a? Array
attrs = options[:attributes] = attrs.inject({}) do |accum, entry|
k, v = entry.split '=', 2
accum[k] = v || ''
accum
end
elsif attrs.is_a? String
attrs = attrs.gsub(REGEXP[:space_delim], "\\1\0").gsub(REGEXP[:escaped_space], '\1')
attrs = options[:attributes] = attrs.split("\0").inject({}) do |accum, entry|
k, v = entry.split '=', 2
accum[k] = v || ''
accum
end
else
raise ArgumentError, 'illegal type for attributes option'
end
lines = nil
if input.is_a? File
lines = input.readlines
input_mtime = input.mtime
input_path = File.expand_path(input.path)
attrs['docfile'] = input_path
attrs['docdir'] = File.dirname(input_path)
attrs['docname'] = File.basename(input_path, File.extname(input_path))
attrs['docdate'] = input_mtime.strftime('%Y-%m-%d')
attrs['doctime'] = input_mtime.strftime('%H:%M:%S %Z')
attrs['docdatetime'] = [attrs['docdate'], attrs['doctime']] * ' '
elsif input.respond_to?(:readlines)
input.rewind rescue nil
lines = input.readlines
elsif input.is_a?(String)
lines = input.lines.entries
elsif input.is_a?(Array)
lines = input.dup
else
raise "Unsupported input type: #{input.class}"
end
if monitor
read_time = Time.now - start
start = Time.now
end
doc = Document.new(lines, options, &block)
if monitor
parse_time = Time.now - start
monitor[:read] = read_time
monitor[:parse] = parse_time
monitor[:load] = read_time + parse_time
end
doc
end