Skip to content
Permalink
master
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
executable file 185 lines (167 sloc) 4.94 KB
#!/usr/bin/env ruby
require 'yaml'
# guess output_format from ARGV
def get_output_format()
output_file = nil
ARGV.each_with_index do |a, i|
if a == "-o" || a == "--output"
output_file = ARGV[i+1]
elsif a.start_with? "--output="
output_file = a[9..-1]
end
end
output_format = nil
ARGV.each_with_index do |a, i|
if a == "-t" || a == "--to"
output_format = ARGV[i+1]
elsif a.start_with? "--to="
output_format = a[5..-1]
end
end
if output_format.nil?
if !output_file.nil? && output_file.include?(".")
output_format = output_file.split(".").last
if ["pdf", "tex"].include? output_format
output_format = "latex"
end
end
end
return output_format
end
def get_pandoc_opts()
opts = %x(pandoc --bash-completion).scan(/opts\=\"([^"]*)/).first.first
# strip the two preceding dashes and ignore one-letter variants
opts.split(' ').map do |o|
if o[0..1] == "--"
o[2..-1]
end
end
end
# convert a meta-hash to an arguments-array
def get_args(meta)
pandoc_opts = get_pandoc_opts()
args = []
meta.each do |key, val|
# check whether `key` is an option that can be
# used with the installed pandoc version
if pandoc_opts.include? key
opt = key
else
# since RMarkdown YAML uses e.g. `toc_depth` instead of `toc-depth`
# try that as well:
key = key.gsub('_', '-')
if pandoc_opts.include? key
opt = key
end
end
if opt && val != false
if val.is_a? Hash
val.each do |k, v|
args.push "--" ++ opt
args.push k ++ "=" ++ v
end
elsif val.is_a? Array
val.each do |v|
args.push "--" ++ opt
args.push v
end
else
args.push "--" ++ opt
if not (val.nil? || val.is_a?(TrueClass))
# try to only include a value for an option that takes one
args.push val.to_s
end
end
end
end
if more_args = meta['pandoc_args']
args.concat more_args
end
return args
end
def output_key_name()
"output"
end
def data_dir_name()
if ENV['APPDATA']
# Windows
File.join ENV['APPDATA'], "panrun"
else
# POSIX
File.join Dir.home, ".panrun"
end
end
# try to load default YAML from other files and merge it with local YAML
def get_meta_from_other_file(meta, type=nil)
if not type.is_a?(String)
type = "default"
end
data_dir = data_dir_name()
file_name = if [".", "..", "/", "\\"].include? type[0]
if File.file? type
type
else
abort "Could not find file #{type}"
end
else
# look in ~/.panrun/
name = File.join(data_dir, type + ".yaml")
if File.file? name
name
else
nil
end
end
file_meta, args = if file_name && m = YAML.load_file(file_name)
[ m[output_key_name] || {}, ["--metadata-file", file_name] ]
else
[{}, []]
end
file_meta.each do |format, _|
meta[format] = file_meta[format].merge( meta[format] || {} )
end
return [meta, args]
end
# determine input file
input_file = ARGV[0]
if input_file.nil? || input_file[0] == "-"
abort "Usage: panrun input.md [pandoc-options]\n\n"\
"Looking for default.yaml etc. in #{data_dir_name}\n"\
"For more info, see https://github.com/mb21/panrun"
end
# load and merge various metadata
yaml = YAML.load_file(input_file)
doc_meta = yaml[output_key_name] || {}
meta, file_arg = get_meta_from_other_file doc_meta, yaml["type"]
# determine output format
output_format = get_output_format()
if output_format.nil?
if meta.is_a?(Hash) && meta.first
# fallback to the first output key (hashes are ordered in ruby)
output_format = meta.first[0]
meta_val = meta.first[1]
if not meta_val["to"] || meta_val["output"]
STDERR.puts "panrun: [WARNING] defaulting to the YAML for output format '#{output_format}',\n"\
" but pandoc may not default to the same format.\n"\
" It is recommended to add a `to:` or `output:` field to your YAML."
end
else
abort "Could not find any output format in YAML."
end
end
# lookup format in meta, else try various rmarkdown formats
meta_out = if meta[output_format]
meta[output_format]
elsif meta[output_format + "_document"]
meta[output_format + "_document"]
elsif output_format == "latex" && meta["pdf_document"]
meta["pdf_document"]
elsif meta[output_format + "_presentation"]
meta[output_format + "_presentation"]
else
abort "Could not find YAML key for detected output format '#{output_format}'."
end
args = get_args(meta_out)
args = ["pandoc", input_file] + args + file_arg + ARGV[1..-1]
STDERR.puts "panrun calling: " + args.join(' ')
exec *args