require 'open3' require 'json' module Pandoc def self.prog @prog ||= 'pandoc' end def self.prog=(val) @prog = val end def self.load(fmt, input) cmd = Pandoc::prog + " -t json" unless fmt.nil? cmd += " -f " + fmt end str = input if str.respond_to? :read str = str.read end json = '' errors = '' Open3::popen3(cmd) do |stdin, stdout, stderr| stdin.puts(str) stdin.close json = stdout.read errors = stderr.read end unless errors.empty? raise errors end return Pandoc::AST::new(json) end class AST def initialize(json) @js = JSON::parse(json) end def [](key) Pandoc::AST::js2sane(@js["meta"][key]) end def js @js end def to(format) cmd = Pandoc::prog + " -f json -t " + format.to_s output = '' errors = '' Open3::popen3(cmd) do |stdin, stdout, stderr| stdin.puts @js.to_json stdin.close output = stdout.read errors = stderr.read end unless errors.empty? raise errors end return output end def self.js2sane(js) if js.nil? return js end case js["t"] when "MetaMap" Hash[js["c"].map{|k,v| [k, js2sane(v)]}] when "MetaList" js["c"].map{|c| js2sane(c)} when "MetaBool" js["c"] when "MetaString" js["c"] when "MetaInlines" js["c"].map{|c| js2sane(c)}.join() when "MetaBlocks" js["c"].map{|c| js2sane(c)}.join("\n") when "Str" js["c"] when "Space" " " when "RawInline" js["c"][1] when "RawBlock" js["c"][1] when "Para" js["c"].map{|c| js2sane(c)}.join() else throw js["t"] end end end end