#!/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 <'; '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