def convert input, options = {}
options = options.dup
options.delete(:parse)
to_file = options.delete(:to_file)
to_dir = options.delete(:to_dir)
mkdirs = options.delete(:mkdirs) || false
timings = options[:timings]
case to_file
when true, nil
write_to_same_dir = !to_dir && ::File === input
stream_output = false
write_to_target = to_dir
to_file = nil
when false
write_to_same_dir = false
stream_output = false
write_to_target = false
to_file = nil
when '/dev/null'
return self.load input, options
else
write_to_same_dir = false
write_to_target = (stream_output = to_file.respond_to? :write) ? false : to_file
end
unless options.key? :header_footer
options[:header_footer] = true if write_to_same_dir || write_to_target
end
if write_to_same_dir
input_path = ::File.expand_path input.path
options[:to_dir] = (outdir = ::File.dirname input_path)
elsif write_to_target
if to_dir
if to_file
options[:to_dir] = ::File.expand_path ::File.join to_dir, to_file, '..'
else
options[:to_dir] = ::File.expand_path to_dir
end
elsif to_file
options[:to_dir] = ::File.expand_path to_file, '..'
end
else
options[:to_dir] = nil
end
doc = self.load input, options
if write_to_same_dir
outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
if outfile == input_path
raise ::IOError, %(input file and output file cannot be the same: #{outfile})
end
elsif write_to_target
working_dir = (options.key? :base_dir) ? (::File.expand_path options[:base_dir]) : (::File.expand_path ::Dir.pwd)
jail = doc.safe >= SafeMode::SAFE ? working_dir : nil
if to_dir
outdir = doc.normalize_system_path(to_dir, working_dir, jail, :target_name => 'to_dir', :recover => false)
if to_file
outfile = doc.normalize_system_path(to_file, outdir, nil, :target_name => 'to_dir', :recover => false)
outdir = ::File.dirname outfile
else
outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
end
elsif to_file
outfile = doc.normalize_system_path(to_file, working_dir, jail, :target_name => 'to_dir', :recover => false)
outdir = ::File.dirname outfile
end
if ::File === input && outfile == (::File.expand_path input.path)
raise ::IOError, %(input file and output file cannot be the same: #{outfile})
end
unless ::File.directory? outdir
if mkdirs
Helpers.mkdir_p outdir
else
raise ::IOError, %(target directory does not exist: #{to_dir})
end
end
else
outfile = to_file
outdir = nil
end
timings.start :convert if timings
opts = outfile && !stream_output ? { 'outfile' => outfile, 'outdir' => outdir } : {}
output = doc.convert opts
timings.record :convert if timings
if outfile
timings.start :write if timings
doc.write output, outfile
timings.record :write if timings
if !stream_output && doc.safe < SafeMode::SECURE && (doc.attr? 'linkcss') &&
(doc.attr? 'copycss') && (doc.attr? 'basebackend-html') &&
!((stylesdir = (doc.attr 'stylesdir')) && (Helpers.uriish? stylesdir))
copy_asciidoctor_stylesheet = false
copy_user_stylesheet = false
if (stylesheet = (doc.attr 'stylesheet'))
if DEFAULT_STYLESHEET_KEYS.include? stylesheet
copy_asciidoctor_stylesheet = true
elsif !(Helpers.uriish? stylesheet)
copy_user_stylesheet = true
end
end
copy_coderay_stylesheet = (doc.attr? 'source-highlighter', 'coderay') && (doc.attr 'coderay-css', 'class') == 'class'
copy_pygments_stylesheet = (doc.attr? 'source-highlighter', 'pygments') && (doc.attr 'pygments-css', 'class') == 'class'
if copy_asciidoctor_stylesheet || copy_user_stylesheet || copy_coderay_stylesheet || copy_pygments_stylesheet
stylesoutdir = doc.normalize_system_path(stylesdir, outdir, doc.safe >= SafeMode::SAFE ? outdir : nil)
Helpers.mkdir_p stylesoutdir if mkdirs
if copy_asciidoctor_stylesheet
Stylesheets.instance.write_primary_stylesheet stylesoutdir
elsif copy_user_stylesheet
if (stylesheet_src = (doc.attr 'copycss')).empty?
stylesheet_src = doc.normalize_system_path stylesheet
else
stylesheet_src = doc.normalize_system_path stylesheet_src
end
stylesheet_dest = doc.normalize_system_path stylesheet, stylesoutdir, (doc.safe >= SafeMode::SAFE ? outdir : nil)
if stylesheet_src != stylesheet_dest && (stylesheet_data = doc.read_asset stylesheet_src,
:warn_on_failure => !(::File.file? stylesheet_dest), :label => 'stylesheet')
::IO.write stylesheet_dest, stylesheet_data
end
end
if copy_coderay_stylesheet
Stylesheets.instance.write_coderay_stylesheet stylesoutdir
elsif copy_pygments_stylesheet
Stylesheets.instance.write_pygments_stylesheet stylesoutdir, (doc.attr 'pygments-style')
end
end
end
doc
else
output
end
end