class Tefil::TextFilterBase

Module that provide a framework for text filters.

Provide basic functions for a command like below:

Input:
  - Without indicating filenames like "command.rb",
    input data is eaten from STDIN.
  - With indicating filenames like "command.rb *.txt",
    input data is eaten from indicated files in order.
    When the file which is in the filenames does not exist,
    output report to STDERR.

Output:
  - Without indicating "--overwrite" option,
    output to STDOUT even from many files.
  - With indicating "--overwrite" option,
    - With indicating input files,
      overwrite each file.
    - Without indicating input files,
      output to STDOUT in one stream.

If indicated file(s) not found, this program notify on stderr and does not throw an exception.

Public Class Methods

new(options = {}) click to toggle source
# File lib/tefil/textfilterbase.rb, line 36
def initialize(options = {})
  @overwrite = options[:overwrite]
  @smart_filename = options[:smart_filename]
end

Public Instance Methods

filter(filenames) click to toggle source

line ごとのファイル名表示はここでは提供せず、したければ process_stream で作る。 grep の行数表示のように、複雑な表示をすることもありうる。

# File lib/tefil/textfilterbase.rb, line 57
def filter(filenames)
  @num_files = filenames.size
  input_io = $stdin
  output_io = $stdout
  if filenames.size == 0 
    process_stream( input_io, output_io)
  else
    filenames.each do |filename|
      @filename = filename
      input_io = File.open(filename, "r")
      output_io = Tempfile.new("tefil", "/tmp") if @overwrite
      smart_filename(output_io)
      begin
        process_stream(input_io, output_io)
      rescue ArgumentError, Errno::EISDIR
        $stderr.puts $!
        next
      rescue Errno::EPIPE
      end

      if @overwrite
        output_io.open
        File.open(filename, "w") do |overwrite_io|
          output_io.each { |line| overwrite_io.puts(line) }
        end
      end
    end
  end
end

Private Instance Methods

process_stream(in_io, out_io) click to toggle source

Process a file. An argument 'in_io' indicates an io (file handle) for input. Another argument 'out_io' indicates an io (file handle) for output. This method must be redefined in a subclass or be overridden. If not redefined, raise an exception Tefil::NotRedefinedMethodError.

# File lib/tefil/textfilterbase.rb, line 105
def process_stream(in_io, out_io)
  raise NotRedefinedMethodError
end
process_string(in_str) click to toggle source
# File lib/tefil/textfilterbase.rb, line 109
def process_string(in_str)
  in_io = StringIO.open in_str
  out_io = StringIO.new
  process_stream(in_io, out_io)
  out_io.rewind
  out_io.read
end
smart_filename(output_io) click to toggle source

@smart_filename が真, かつ @overwrite が 偽, かつ filter メソッドに渡されたファイル数が複数のときには 処理中のファイル名を output_io に出力する。

# File lib/tefil/textfilterbase.rb, line 93
def smart_filename(output_io)
  if @smart_filename && (! @overwrite) && (@num_files >= 2)
    output_io.puts("#{@filename}:")
  end
end