Browse files

Added option parser to bin/rpeg-multimarkdown using micro-optparse

  • Loading branch information...
1 parent c3aaa84 commit 1ebab7798b004ba72210c110231feab3ffcdc197 @djungelvral committed Jun 6, 2011
Showing with 106 additions and 3 deletions.
  1. +4 −1 LICENSE
  2. +102 −2 bin/rpeg-multimarkdown
View
5 LICENSE
@@ -2,13 +2,16 @@ Ruby Markdown Extension, implemented using peg-markdown
Copyright (c) 2008 Ryan Tomayko
markdown in c, implemented using PEG grammar
Copyright (c) 2008 John MacFarlane
-
Additional MultiMarkdown files
Copyright (c) 2005-2011 Fletcher T. Penney
+Micro-optparse (included in bin/rpeg-multimarkdown)
+Copyright (c) 2011 Florian Pilz
Both peg-markdown and the rpeg-markdown license are released under both the GPL
and MIT licenses. You may pick the license that best fits your needs.
+Micro-optparse is released under the MIT license.
+
The GPL
This program is free software; you can redistribute it and/or modify
View
104 bin/rpeg-multimarkdown
@@ -8,6 +8,106 @@ rescue LoadError => boom
require 'multimarkdown'
end
+# Option parser -- http://florianpilz.github.com/micro-optparse/
+
+require 'ostruct'
+require 'optparse'
+
+class Parser
+ attr_accessor :banner, :version
+ def initialize
+ @options = []
+ @used_short = []
+ yield self if block_given?
+ end
+
+ def option(name, desc, settings = {})
+ @options << [name, desc, settings]
+ end
+
+ def short_from(name)
+ name.to_s.chars.each do |c|
+ next if @used_short.include?(c) || c == "_"
+ return c # returns from short_from method
+ end
+ end
+
+ def validate(options) # remove this method if you want fewer lines of code and don't need validations
+ options.each_pair do |key, value|
+ opt = @options.find_all{ |o| o[0] == key }.first
+ key = "--" << key.to_s.gsub("_", "-")
+ unless opt[2][:value_in_set].nil? || opt[2][:value_in_set].include?(value)
+ puts "Parameter for #{key} must be in [" << opt[2][:value_in_set].join(", ") << "]" ; exit(1)
+ end
+ unless opt[2][:value_matches].nil? || opt[2][:value_matches] =~ value
+ puts "Parameter for #{key} must match /" << opt[2][:value_matches].source << "/" ; exit(1)
+ end
+ unless opt[2][:value_satisfies].nil? || opt[2][:value_satisfies].call(value)
+ puts "Parameter for #{key} must satisfy given conditions (see description)" ; exit(1)
+ end
+ end
+ end
+
+ def process!(arguments = ARGV)
+ @result = (@default_values || {}).clone # reset or new
+ @optionparser ||= OptionParser.new do |p| # prepare only once
+ @options.each do |o|
+ @used_short << short = o[2][:short] || short_from(o[0])
+ @result[o[0]] = o[2][:default] || false # set default
+ klass = o[2][:default].class == Fixnum ? Integer : o[2][:default].class
+
+ if [TrueClass, FalseClass, NilClass].include?(klass) # boolean switch
+ p.on("-" << short, "--[no-]" << o[0].to_s.gsub("_", "-"), o[1]) {|x| @result[o[0]] = x}
+ else # argument with parameter
+ p.on("-" << short, "--" << o[0].to_s.gsub("_", "-") << " " << o[2][:default].to_s, klass, o[1]) {|x| @result[o[0]] = x}
+ end
+ end
+
+ p.banner = @banner unless @banner.nil?
+ p.on_tail("-h", "--help", "Show this message") {puts p ; exit}
+ short = @used_short.include?("v") ? "-V" : "-v"
+ p.on_tail(short, "--version", "Print version") {puts @version ; exit} unless @version.nil?
+ @default_values = @result.clone # save default values to reset @result in subsequent calls
+ end
+
+ begin
+ @optionparser.parse!(arguments)
+ rescue OptionParser::ParseError => e
+ puts e.message ; exit(1)
+ end
+
+ validate(@result) if self.respond_to?("validate")
+ @result
+ end
+end
+
+# Parse options
+options = Parser.new do |p|
+ p.banner = "Ruby interface to MultiMarkdown"
+ p.version = "rpeg-multimarkdown 0.1.0"
+ p.option :compatibility, "markdown compatibility mode", :default => false
+ p.option :filter_html, "filter out raw HTML (except styles)", :default => false
+ p.option :process_html, "process MultiMarkdown inside of raw HTML", :default => false
+ p.option :filter_styles, "filter out HTML styles", :default => false
+ p.option :output, "send output to FILE (default is stdout)", :default => ""
+ p.option :to, "convert to FORMAT (default is html)", :default => "html", :value_in_set => ["html","latex","memoir","beamer","odf","opml"]
+end.process!
+
+# Convert options to MultiMarkdown module's options
+mmopts = []
+mmopts << :compatibility if options[:compatibility]
+mmopts << :filter_html if options[:filter_html]
+mmopts << :filter_styles if options[:filter_styles]
+mmopts << :process_html if options[:process_html]
+
+# ARGV will now only contain input filename, if it contains anything
STDIN.reopen(ARGV[0], 'rb') if ARGV.any?
-multimarkdown = MultiMarkdown.new(STDIN.read)
-STDOUT.write(multimarkdown.to_html)
+multimarkdown = MultiMarkdown.new(STDIN.read,opts)
+STDOUT.reopen(options[:output], 'w') if options[:output]!=""
+case options[:to]
+when "html"
+ STDOUT.write(multimarkdown.to_html)
+else
+ puts "Output other than html not currently supported"
+ exit(1)
+end

0 comments on commit 1ebab77

Please sign in to comment.