111 lines
2.9 KiB
Ruby
Executable File
111 lines
2.9 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
require 'ostruct'
|
|
require 'optparse'
|
|
require 'tilt'
|
|
|
|
usage = <<USAGE
|
|
Usage: tilt <options> <file>
|
|
Process template <file> and write output to stdout. With no <file> or
|
|
when <file> is '-', read template from stdin and use the --type option
|
|
to determine the template's type.
|
|
|
|
Options
|
|
-l, --list List template engines + file patterns and exit
|
|
-t, --type=<pattern> Use this template engine; required if no <file>
|
|
-y, --layout=<file> Use <file> as a layout template
|
|
|
|
-D<name>=<value> Define variable <name> as <value>
|
|
-o, --vars=<ruby> Evaluate <ruby> to Hash and use for variables
|
|
|
|
-h, --help Show this help message
|
|
|
|
Convert markdown to HTML:
|
|
$ tilt foo.markdown > foo.html
|
|
|
|
Process ERB template:
|
|
$ echo "Answer: <%= 2 + 2 %>" | tilt -t erb
|
|
Answer: 4
|
|
|
|
Define variables:
|
|
$ echo "Answer: <%= 2 + n %>" | tilt --locals="{:n=>40, :x=>0}"
|
|
Answer: 42
|
|
$ echo "Answer: <%= 2 + n %>" | tilt -Dn=40 -Dx=0
|
|
Answer: 42
|
|
USAGE
|
|
|
|
script_name = File.basename($0)
|
|
pattern = nil
|
|
layout = nil
|
|
locals = {}
|
|
|
|
ARGV.options do |o|
|
|
o.program_name = script_name
|
|
|
|
# list all available template engines
|
|
o.on("-l", "--list") do
|
|
groups = {}
|
|
Tilt.mappings.each do |pattern,engine|
|
|
key = engine.name.split('::').last.sub(/Template$/, '')
|
|
(groups[key] ||= []) << pattern
|
|
end
|
|
groups.sort { |(k1,v1),(k2,v2)| k1 <=> k2 }.each do |engine,files|
|
|
printf "%-15s %s\n", engine, files.sort.join(', ')
|
|
end
|
|
exit
|
|
end
|
|
|
|
# the template type / pattern
|
|
o.on("-t", "--type=PATTERN", String) do |val|
|
|
abort "unknown template type: #{val}" if Tilt[val].nil?
|
|
pattern = val
|
|
end
|
|
|
|
# pass template output into the specified layout template
|
|
o.on("-y", "--layout=FILE", String) do |file|
|
|
paths = [file, "~/.tilt/#{file}", "/etc/tilt/#{file}"]
|
|
layout = paths.
|
|
map { |p| File.expand_path(p) }.
|
|
find { |p| File.exist?(p) }
|
|
abort "no such layout: #{file}" if layout.nil?
|
|
end
|
|
|
|
# define a local variable
|
|
o.on("-D", "--define=PAIR", String) do |pair|
|
|
key, value = pair.split(/[=:]/, 2)
|
|
locals[key.to_sym] = value
|
|
end
|
|
|
|
# define local variables using a Ruby hash
|
|
o.on("--vars=RUBY") do |ruby|
|
|
hash = eval(ruby)
|
|
abort "vars must be a Hash, not #{hash.inspect}" if !hash.is_a?(Hash)
|
|
hash.each { |key, value| locals[key.to_sym] = value }
|
|
end
|
|
|
|
o.on_tail("-h", "--help") { puts usage; exit }
|
|
|
|
o.parse!
|
|
end
|
|
|
|
file = ARGV.first || '-'
|
|
pattern = file if pattern.nil?
|
|
abort "template type not given. see: #{$0} --help" if ['-', ''].include?(pattern)
|
|
|
|
engine = Tilt[pattern]
|
|
abort "template engine not found for: #{pattern}" if engine.nil?
|
|
|
|
template =
|
|
engine.new(file) {
|
|
if file == '-'
|
|
$stdin.read
|
|
else
|
|
File.read(file)
|
|
end
|
|
}
|
|
output = template.render(self, locals)
|
|
|
|
# process layout
|
|
output = Tilt.new(layout).render(self, locals) { output } if layout
|
|
|
|
$stdout.write(output)
|