185 lines
5.5 KiB
Ruby
Executable File

#!/usr/bin/env ruby
# Tiny eRuby --- ERB2
# Copyright (c) 1999-2000,2002 Masatoshi SEKI
# You can redistribute it and/or modify it under the same terms as Ruby.
require 'erb'
class ERB
module Main
def ARGV.switch
return nil if self.empty?
arg = self.shift
return nil if arg == '--'
case arg
when /\A-(.)(.*)/
if $1 == '-'
arg, @maybe_arg = arg.split(/=/, 2)
return arg
end
raise 'unknown switch "-"' if $2[0] == ?- and $1 != 'T'
if $2.size > 0
self.unshift "-#{$2}"
@maybe_arg = $2
else
@maybe_arg = nil
end
"-#{$1}"
when /\A(\w+)=/
arg
else
self.unshift arg
nil
end
end
def ARGV.req_arg
(@maybe_arg || self.shift || raise('missing argument')).tap {
@maybe_arg = nil
}
end
def trim_mode_opt(trim_mode, disable_percent)
return trim_mode if disable_percent
case trim_mode
when 0
return '%'
when 1
return '%>'
when 2
return '%<>'
when '-'
return '%-'
end
end
module_function :trim_mode_opt
def run(factory=ERB)
trim_mode = 0
disable_percent = false
variables = {}
begin
while switch = ARGV.switch
case switch
when '-x' # ruby source
output = true
when '-n' # line number
number = true
when '-v' # verbose
$VERBOSE = true
when '--version' # version
STDERR.puts factory.version
exit
when '-d', '--debug' # debug
$DEBUG = true
when '-r' # require
require ARGV.req_arg
when '-T' # trim mode
arg = ARGV.req_arg
if arg == '-'
trim_mode = arg
next
end
raise "invalid trim mode #{arg.dump}" unless arg =~ /\A[0-2]\z/
trim_mode = arg.to_i
when '-E', '--encoding'
arg = ARGV.req_arg
set_encoding(*arg.split(/:/, 2))
when '-U'
set_encoding(Encoding::UTF_8, Encoding::UTF_8)
when '-P'
disable_percent = true
when '--help'
raise ''
when /\A-/
raise "Unknown switch: #{switch.dump}"
else
var, val = *switch.split('=', 2)
(variables ||= {})[var] = val
end
end
rescue # usage
message = $!.to_s
STDERR.puts message unless message.empty?
STDERR.puts 'Usage:'
STDERR.puts " #{File.basename($0)} [options] [filepaths]"
STDERR.puts <<EOU
Options:
-d --debug Set $DEBUG to enable debugging.
-E ex[:in] --encoding ex[:in]
Set default external and internal encodings.
-h --help Print this text and exit.
-n Print generated Ruby source code with line numbers;
ignored if given without option -x.
-P Disable execution tag shorthand (for lines beginning with '%').
-r library Load the named library.
-T trim_mode Specify trim_mode:
'0' means '%'; '1' means '%>'; '2' means '<>'; '-' means '%-'.
-U Set default encoding to UTF-8.
-v Set $VERBOSE to enable debugging,
--version Print ERB version string and exit.
-x Print generated Ruby source code.
-- Treat all following words as filepaths (not options).
name=value Set the variable named name to the given string value.
Filepaths:
The erb program reads the text from all files at the filepaths as a single ERB template:
plain text, possibly with embedded ERB tags;
filepaths may be repeated.
The pseudo-filepath '-' (hyphen character) specifies the standard input.
If no filepaths are given, the sole input is the standard input.
See details and examples at https://docs.ruby-lang.org/en/master/erb_executable_md.html
EOU
exit 1
end
$<.set_encoding(Encoding::UTF_8, nil)
src = $<.read
filename = $FILENAME
exit 2 unless src
trim = trim_mode_opt(trim_mode, disable_percent)
erb = factory.new(src, trim_mode: trim)
erb.filename = filename
if output
if number
erb.src.each_line.with_index do |line, l|
puts "%3d %s"%[l+1, line]
end
else
puts erb.src
end
else
bind = TOPLEVEL_BINDING
if variables
enc = erb.encoding
for var, val in variables do
val = val.encode(enc) if val
bind.local_variable_set(var, val)
end
end
erb.run(bind)
end
end
module_function :run
def set_encoding(extern, intern = nil)
verbose, $VERBOSE = $VERBOSE, nil
Encoding.default_external = extern unless extern.nil? || extern == ""
Encoding.default_internal = intern unless intern.nil? || intern == ""
[$stdin, $stdout, $stderr].each do |io|
io.set_encoding(extern, intern)
end
ensure
$VERBOSE = verbose
end
module_function :set_encoding
class << self; private :set_encoding; end
end
end
ERB::Main.run