Skip to content

Instantly share code, notes, and snippets.

@xwmx
Created May 12, 2010 20:52
Show Gist options
  • Save xwmx/399110 to your computer and use it in GitHub Desktop.
Save xwmx/399110 to your computer and use it in GitHub Desktop.
require 'open3'
class RbST
@@executable_path = File.expand_path(File.join(File.dirname(__FILE__), "rst2parts"))
@@executables = {
:html => File.join(@@executable_path, "rst2html.py"),
:latex => File.join(@@executable_path, "rst2latex.py")
}
# Takes a string or file path plus any additional options and converts the input.
def self.convert(*args)
new(*args).convert
end
# Print LaTeX-Specific Options, General Docutils Options and reStructuredText Parser Options.
def self.latex_options
new.print_options(:latex)
end
# Print HTML-Specific Options, General Docutils Options and reStructuredText Parser Options.
def self.html_options
new.print_options(:html)
end
# Specify custom executables to use instead of the default rst2latex.py and
# rst2html.py scripts. Takes a hash with two possible keys, :html and :latex,
# which should contain a full path to the alternative executable.
def self.executables=(exec_paths = {})
if exec_paths.empty? || (exec_paths.keys & [:html, :latex]).empty?
raise ArgumentError, "Custom executable format must be :html or :latex"
end
@@executables = @@executables.merge(exec_paths)
end
# Return the executable hash.
def self.executables; @@executables end
# Takes a string or file path plus any additional options and creates a new converter object.
def initialize(*args)
target = args.shift
@target = File.exists?(target) ? File.read(target) : target rescue target
@options = args
end
def convert # :nodoc:
@output_format ||= :html
execute "python #{@@executables[@output_format]}" + convert_options
end
alias_method :to_s, :convert
# Converts the object's input to HTML.
def to_html(*args)
@output_format = :html
@options += args
convert
end
# Converts the object's input to LaTeX.
def to_latex(*args)
@output_format = :latex
@options += args
convert
end
# Formats and prints the options from the docutils help in the way they'd be specified in RbST: strings, symbols and hashes.
def print_options(format)
help = execute("python #{@@executables[format]} --help")
# non-hyphenated long options to symbols
help.gsub!(/(\-\-)([A-Za-z0-9]+)([=|\s])/, ':\2\3')
# hyphenated long options to quoted strings
help.gsub!(/(\-\-)([\w|\-]+)(\n)?[^$|^=|\]]?/, '\'\2\'\3')
# equal to hashrocket
help.gsub!(/\=/, ' => ')
# hort options to symbols
help.gsub!(/([^\w])\-(\w)([^\w])/, '\1:\2\1')
# short options with args get a hashrocket
help.gsub!(/(:\w) </, '\1 => <')
puts help
end
protected
def execute(command)
output = ''
Open3::popen3(command) do |stdin, stdout, stderr|
stdin.puts @target
stdin.close
output = stdout.read.strip
end
output
end
def convert_options
@options.inject('') do |string, opt|
string + if opt.respond_to?(:each_pair)
convert_opts_with_args(opt)
else
opt.to_s.length == 1 ? " -#{opt}" : " --#{opt.to_s.gsub(/_/, '-')}"
end
end
end
def convert_opts_with_args(opt)
opt.inject('') do |string, (flag, val)|
flag = flag.to_s.gsub(/_/, '-')
string + (flag.length == 1 ? " -#{flag} #{val}" : " --#{flag}=#{val}")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment