#! /usr/bin/env ruby # Author:: Nicolas Despr�s <nicolas.despres@lrde.epita.fr>. # Copyright:: Copyright (c) 2005 Uttk Team. All rights reserved. # License:: LGPL # $Id: /w/fey/uttk/trunk/misc/textile_compiler 22074 2006-02-21T13:47:00.947568Z pouillar $ require 'erb' require 'pathname' require 'optparse' module TextileCompiler DEFAULT_SEVERITY_LEVEL = :warning SEVERITY_LEVELS = { :fatal => 0, :error => 1, :warning => 2, :info => 3, :debug => 4 } def self.severity_level=(level) @@severity_level = level end def self.severity_level @@severity_level end def self.log(level, message) @@severity_level ||= DEFAULT_SEVERITY_LEVEL if SEVERITY_LEVELS[level] <= SEVERITY_LEVELS[@@severity_level] STDERR.puts "#{File.basename($0)}: #{level}: #{message}" end end def self.error(message) log(:error, message) end def self.fatal(message) log(:fatal, message) raise message end def self.warning(message) log(:warning, message) end def self.info(message) log(:info, message) end def self.debug(message) log(:debug, message) end class Compiler DEFAULT_OPTIONS = { :input_extension => '.rtextile', :output_extension => '.textile' } def initialize(commands, options={}) @command = commands @options = DEFAULT_OPTIONS @options.merge!(options) TextileCompiler.debug("current directory = `#{Pathname.pwd}'") end def compile(*pathnames) pathnames.each do |src_pathname| if src_pathname.extname == @options[:input_extension] base_pathname = src_pathname.to_s.sub(/#{src_pathname.extname}$/, '') dest_pathname = Pathname.new(base_pathname + @options[:output_extension]) dest_pathname.open('w') do |f| f.write ERB.new(src_pathname.read).result(@command.get_binding) end else TextileCompiler.warning("unknown file extension, ignore `#{src_pathname}'") end end end end # class Compiler class Textile def initialize @fixtures_directory = Pathname.new(".") end def get_binding binding end def comment(&block) end def command(command, options={}) args = options[:arguments] args ||= [] args = args.join(' ') cmd = "#{command} #{args}" cmd = "echo #{options[:input]} | #{cmd}" if options[:input] TextileCompiler.info("cmd `#{cmd}'") result = "|{background:#ddd}.<code>$ #{cmd}</code>|\n\n" TextileCompiler.debug("options[:directory] = `#{options[:directory]}'") directory = options[:directory] directory ||= "." directory = @fixtures_directory + Pathname.new(directory) unless directory.directory? and directory.executable? and directory.readable? TextileCompiler.error("bad directory `#{directory}' " + "(fixtures_directory = `#{@fixtures_directory}'") end TextileCompiler.debug("directory = `#{directory}'") full_cmd = "cd #{directory} && #{cmd}" full_cmd += " 2>&1" if options[:with_stderr] TextileCompiler.debug("run `#{full_cmd}'") unless options[:without_output] result += "<pre>\n" + `#{full_cmd}` + "\n</pre>" end status = $?.exitstatus if status != 0 TextileCompiler.warning("the command `#{full_cmd}' has exited with " + "status #{status}") end result end def fixtures_directory=(new_value) tmp = Pathname.new(new_value) if tmp.directory? and tmp.executable? and tmp.readable? @fixtures_directory = tmp else TextileCompiler.error("bad fixture directory `#{tmp}'") end end attr_reader :fixtures_directory end # class Textile end # class TextileCompiler ME_DIR, ME = Pathname.new($0).split options = TextileCompiler::Compiler::DEFAULT_OPTIONS opts = OptionParser.new do |opts| opts.banner = "Usage: #{ME} [options] <.rtextile files>..." opts.separator '' opts.summary_indent = ' ' opts.summary_width = 28 opts.on('--input-extension EXT', "Input extention (default: #{options[:input_extension]})") do |ext| options[:input_extenstion] = ext end opts.on('--output-extension EXT', "Output extention (default: #{options[:output_extension]})") do |ext| options[:output_extenstion] = ext end opts.on('-s', '--severity LEVEL', TextileCompiler::SEVERITY_LEVELS.keys, 'Log severity level (no argument for the list)') do |lvl| if lvl.nil? puts "Log severity level:" TextileCompiler::SEVERITY_LEVELS.keys.each { |l| puts " - #{l}" } exit else TextileCompiler.severity_level = lvl end end end opts.parse!(ARGV) ARGV.map! { |arg| Pathname.new(arg) } TextileCompiler::Compiler.new(TextileCompiler::Textile.new).compile(*ARGV)