module Lol

Constants

STRIP_ANSI

Public Class Methods

cat(fd, opts={}) click to toggle source
# File lib/lolcat/lol.rb, line 32
def self.cat(fd, opts={})
  print "\e[?25l" if opts[:animate]
  fd.each do |line|
    opts[:os] += 1
    println(line, opts)
  end
  ensure
  print "\e[?25h" if opts[:animate]
end
cat!() click to toggle source
# File lib/lolcat/cat.rb, line 50
  def self.cat!
    p = Trollop::Parser.new do
      version "lolcat #{Lolcat::VERSION} (c)2011 moe@busyloop.net"
      banner <<HEADER

Usage: lolcat [OPTION]... [FILE]...

Concatenate FILE(s), or standard input, to standard output.
With no FILE, or when FILE is -, read standard input.

HEADER
      banner ''
      opt :spread, "Rainbow spread", :short => 'p', :default => 3.0
      opt :freq, "Rainbow frequency", :short => 'F', :default => 0.1
      opt :seed, "Rainbow seed, 0 = random", :short => 'S', :default => 0
      opt :animate, "Enable psychedelics", :short => 'a', :default => false
      opt :duration, "Animation duration", :short => 'd', :default => 12
      opt :speed, "Animation speed", :short => 's', :default => 20.0
      opt :force, "Force color even when stdout is not a tty", :short => 'f', :default => false
      opt :version,  "Print version and exit", :short => 'v'
      opt :help,  "Show this message", :short => 'h'
      banner <<FOOTER

Examples:
  lolcat f - g      Output f's contents, then stdin, then g's contents.
  lolcat            Copy standard input to standard output.
  fortune | lolcat  Display a rainbow cookie.

Report lolcat bugs to <http://www.github.org/busyloop/lolcat/issues>
lolcat home page: <http://www.github.org/busyloop/lolcat/>
Report lolcat translation bugs to <http://speaklolcat.com/>

FOOTER
    end

    opts = Trollop::with_standard_exception_handling p do
      begin
        o = p.parse ARGV
      rescue Trollop::HelpNeeded
        buf = StringIO.new
        p.educate buf
        buf.rewind
        halp! buf.read, {}
        buf.close
      end
      o
    end

    p.die :spread, "must be > 0" if opts[:spread] < 0.1
    p.die :duration, "must be > 0" if opts[:duration] < 0.1
    p.die :speed, "must be > 0.1" if opts[:speed] < 0.1

    opts[:os] = opts[:seed]
    opts[:os] = rand(256) if opts[:os] == 0

    begin
      files = ARGV.empty? ? [:stdin] : ARGV[0..-1]
      files.each do |file|
        fd = ARGF if file == '-' or file == :stdin
        begin
          fd = File.open file unless fd == ARGF

          if $stdout.tty? or opts[:force]
            Lol.cat fd, opts
          else
            until fd.eof? do
              $stdout.write(fd.read(8192))
            end
          end
        rescue Errno::ENOENT
          puts "lolcat: #{file}: No such file or directory"
          exit 1
        rescue Errno::EACCES
          puts "lolcat: #{file}: Permission denied"
          exit 1
        rescue Errno::EISDIR
          puts "lolcat: #{file}: Is a directory"
          exit 1
        rescue Errno::EPIPE
          exit 1
        end
      end
    rescue Interrupt
    end
  end
halp!(text, opts={}) click to toggle source
# File lib/lolcat/cat.rb, line 26
def self.halp!(text, opts={})
  opts = { 
    :animate => false,
    :duration => 12,
    :os => 0,
    :speed => 20,
    :spread => 8.0,
    :freq => 0.3
  }.merge opts

  begin
    i = 20
    o = rand(256)
    text.split("\n").each do |line|
      i -= 1
      opts[:os] = o+i
      Lol.println line, opts
    end
    puts "\n"
  rescue Interrupt
  end
  exit 1
end
println(str, defaults={}, opts={}) click to toggle source
# File lib/lolcat/lol.rb, line 42
def self.println(str, defaults={}, opts={})
  opts.merge!(defaults)
  str.chomp!
  str.gsub! STRIP_ANSI, '' if !str.nil? and ($stdout.tty? or opts[:force])
  opts[:animate] ? println_ani(str, opts) : println_plain(str, opts)
  puts
end
rainbow(freq, i) click to toggle source
# File lib/lolcat/lol.rb, line 25
def self.rainbow(freq, i)
   red   = Math.sin(freq*i + 0) * 127 + 128
   green = Math.sin(freq*i + 2*Math::PI/3) * 127 + 128
   blue  = Math.sin(freq*i + 4*Math::PI/3) * 127 + 128
   "#%02X%02X%02X" % [ red, green, blue ]
end

Private Class Methods

println_ani(str, opts={}) click to toggle source
# File lib/lolcat/lol.rb, line 59
def self.println_ani(str, opts={})
  return if str.empty?
  (1..opts[:duration]).each do |i|
    print "\e[#{str.length}D"
    opts[:os] += opts[:spread]
    println_plain(str, opts)
    sleep 1.0/opts[:speed]
  end
end
println_plain(str, defaults={}, opts={}) click to toggle source
# File lib/lolcat/lol.rb, line 52
def self.println_plain(str, defaults={}, opts={})
  opts.merge!(defaults)
  str.chomp.chars.each_with_index do |c,i|
    print Paint[c, rainbow(opts[:freq], opts[:os]+i/opts[:spread])]
  end
end