ANSI Codes
Ansi::Code module makes it very easy to use ANSI codes. These are esspecially nice for beautifying shell output.
Ansi::Code.red + "Hello" + Ansi::Code.blue + "World" => "\e[31mHello\e[34mWorld" Ansi::Code.red{ "Hello" } + Ansi::Code.blue{ "World" } => "\e[31mHello\e[0m\e[34mWorld\e[0m"
IMPORTANT! Do not mixin Ansi::Code, instead use {ANSI::Mixin}.
See {ANSI::Code::CHART} for list of all supported codes.
List of primary colors.
# File lib/ansi/code.rb, line 55 def self.colors %w{black red green yellow blue magenta cyan white} end
List of primary styles.
# File lib/ansi/code.rb, line 50 def self.styles %w{bold dark italic underline underscore blink rapid reverse negative concealed strike} end
styles.each do |style| module_eval " def #{style}(string=nil) if string return string unless $ansi #warn "use ANSI block notation for future versions" return "\#{#{style.upcase}}\#{string}\#{ENDCODE}" end if block_given? return yield unless $ansi return "\#{#{style.upcase}}\#{yield}\#{ENDCODE}" end #{style.upcase} end ", __FILE__, __LINE__ end # Dynamically create color methods. colors.each do |color| module_eval " def #{color}(string=nil) if string return string unless $ansi #warn "use ANSI block notation for future versions" return "\#{#{color.upcase}}\#{string}\#{ENDCODE}" end if block_given? return yield unless $ansi return "\#{#{color.upcase}}\#{yield}\#{ENDCODE}" end #{color.upcase} end def on_#{color}(string=nil) if string return string unless $ansi #warn "use ANSI block notation for future versions" return "\#{ON_#{color.upcase}}\#{string}\#{ENDCODE}" end if block_given? return yield unless $ansi return "\#{ON_#{color.upcase}}\#{yield}\#{ENDCODE}" end ON_#{color.upcase} end ", __FILE__, __LINE__ end
# Return ANSI code given a list of symbolic names.
# File lib/ansi/code.rb, line 113 def [](*codes) code(*codes) end
Apply ANSI codes to a first argument or block value.
@example
ansi("Valentine", :red, :on_white)
@example
ansi(:red, :on_white){ "Valentine" }
@return [String]
String wrapped ANSI code.
# File lib/ansi/code.rb, line 227 def ansi(*codes) #:yield: if block_given? string = yield.to_s else string = codes.shift.to_s end return string unless $ansi c = code(*codes) c + string.gsub(ENDCODE, ENDCODE + c) + ENDCODE end
Look-up code from chart, or if Integer simply pass through. Also resolves :random and :on_random.
@param codes [Array<Symbol,Integer]
Symbols or integers to covnert to ANSI code.
@return [String] ANSI code
# File lib/ansi/code.rb, line 291 def code(*codes) list = [] codes.each do |code| list << case code when Integer code when Array rgb(*code) when :random random when :on_random random(true) else CHART[code.to_sym] end end "\e[" + (list * ";") + "m" end
Like move
but returns to original positon after yielding the
block.
# File lib/ansi/code.rb, line 173 def display(line, column=0) #:yield: result = "\e[s" result << "\e[#{line.to_i};#{column.to_i}H" if block_given? result << yield result << "\e[u" #elsif string # result << string # result << "\e[u" end result end
Move cursor down a specificed number of spaces.
# File lib/ansi/code.rb, line 197 def down(spaces=1) "\e[#{spaces.to_i}B" end
Creates an xterm-256 color from a CSS-style color string.
# File lib/ansi/code.rb, line 331 def hex(string, background=false) string.tr!('#','') x = (string.size == 6 ? 2 : 1) r, g, b = [0,1,2].map{ |i| string[i*x,2].to_i(16) } rgb(r, g, b, background) end
Move cursor left a specificed number of spaces.
# File lib/ansi/code.rb, line 202 def left(spaces=1) "\e[#{spaces.to_i}D" end
Use method missing to dispatch ANSI code methods.
# File lib/ansi/code.rb, line 142 def method_missing(code, *args, &blk) esc = nil if CHART.key?(code) esc = "\e[#{CHART[code]}m" elsif SPECIAL_CHART.key?(code) esc = SPECIAL_CHART[code] end if esc if string = args.first return string unless $ansi #warn "use ANSI block notation for future versions" return "#{esc}#{string}#{ENDCODE}" end if block_given? return yield unless $ansi return "#{esc}#{yield}#{ENDCODE}" end esc else super(code, *args, &blk) end end
Move cursor to line and column.
# File lib/ansi/code.rb, line 187 def move(line, column=0) "\e[#{line.to_i};#{column.to_i}H" end
Creates an xterm-256 color from rgb value.
@param background [Boolean]
Use `true` for background color, otherwise foreground color.
# File lib/ansi/code.rb, line 326 def rgb(red, green, blue, background=false) "#{background ? 48 : 38};5;#{rgb_value(red, green, blue)}" end
Move cursor right a specificed number of spaces.
# File lib/ansi/code.rb, line 207 def right(spaces=1) "\e[#{spaces.to_i}C" end
Remove ANSI codes from string or block value.
@param [String] string
String from which to remove ANSI codes.
@return [String]
String wrapped ANSI code.
# File lib/ansi/code.rb, line 251 def unansi(string=nil) #:yield: if block_given? string = yield.to_s else string = string.to_s end string.gsub(PATTERN, '') end
Alias for unansi.
@deprecated
May change in future definition.
Move cursor up a specificed number of spaces.
# File lib/ansi/code.rb, line 192 def up(spaces=1) "\e[#{spaces.to_i}A" end
Gets closest xterm-256 color.
# File lib/ansi/code.rb, line 341 def rgb_256(r, g, b) r, g, b = [r, g, b].map{ |c| rgb_valid(c); (6 * (c.to_f / 256.0)).to_i } v = (r * 36 + g * 6 + b + 16).abs raise ArgumentError, "RGB value outside 0-255 range" if v > 255 v end