Module: ANSI::Code

Extended by:
Code
Includes:
Constants
Included in:
ANSI, Code
Defined in:
lib/ansi/code.rb

Overview

ANSI Codes

Ansi::Code module makes it very easy to use ANSI codes. These are especially 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 Mixin.

See CHART for list of all supported codes.

Constant Summary collapse

PATTERN =

Regexp for matching most ANSI codes.

/\e\[(\d+)m/
ENDCODE =

ANSI clear code.

"\e[0m"

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(code, *args, &blk) ⇒ Object

Use method missing to dispatch ANSI code methods.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/ansi/code.rb', line 89

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

Class Method Details

.colorsObject

List of primary colors.



55
56
57
# File 'lib/ansi/code.rb', line 55

def self.colors
  %w{black red green yellow blue magenta cyan white}
end

.stylesObject

List of primary styles.



50
51
52
# File 'lib/ansi/code.rb', line 50

def self.styles
  %w{bold dark italic underline underscore blink rapid reverse negative concealed strike}
end

Instance Method Details

#[](*codes) ⇒ Object

Return ANSI code given a list of symbolic names.



60
61
62
# File 'lib/ansi/code.rb', line 60

def [](*codes)
  code(*codes)
end

#ansi(*codes) ⇒ String Also known as: style, color

Apply ANSI codes to a first argument or block value.

Examples:

ansi("Valentine", :red, :on_white)
ansi(:red, :on_white){ "Valentine" }

Returns:

  • (String)

    String wrapped ANSI code.



176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/ansi/code.rb', line 176

def ansi(*codes) #:yield:
  if block_given?
    string = yield.to_s
  else
    # first argument must be the string
    string = codes.shift.to_s
  end

  return string unless $ansi

  c = code(*codes)

  c + string.gsub(ENDCODE, ENDCODE + c) + ENDCODE
end

#code(*codes) ⇒ String

Look-up code from chart, or if Integer simply pass through. Also resolves :random and :on_random.

Parameters:

  • codes (Array<Symbol,Integer] Symbols or integers to convert to ANSI code.)

    odes [Array<Symbol,Integer] Symbols or integers to convert to ANSI code.

Returns:



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/ansi/code.rb', line 241

def code(*codes)
  list = []
  codes.each do |code|
    list << \
      case code
      when Integer
        code
      when Array
        rgb_code(*code)
      when :random, 'random'
        random
      when :on_random, 'on_random'
        random(true)
      when String
        # TODO: code =~ /\d\d\d\d\d\d/ ?
        if code.start_with?('#')
          hex_code(code)
        else
          CHART[code.to_sym]
        end
      else
        CHART[code.to_sym]
      end
  end
  "\e[" + (list * ";") + "m"
end

#display(line, column = 0) ⇒ Object

Like move but returns to original position after yielding the block.



120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/ansi/code.rb', line 120

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

#down(spaces = 1) ⇒ Object

Move cursor down a specified number of spaces.



144
145
146
# File 'lib/ansi/code.rb', line 144

def down(spaces=1)
  "\e[#{spaces.to_i}B"
end

#hex_code(string, background = false) ⇒ Object

Creates an xterm-256 color code from a CSS-style color string.

Parameters:

  • string (String)

    Hex string in CSS style, .e.g. ‘#5FA0C2`.

  • background (Boolean) (defaults to: false)

    Use ‘true` for background color, otherwise foreground color.



325
326
327
328
329
330
# File 'lib/ansi/code.rb', line 325

def hex_code(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_code(r, g, b, background)
end

#left(spaces = 1) ⇒ Object Also known as: back

Move cursor left a specified number of spaces.



149
150
151
# File 'lib/ansi/code.rb', line 149

def left(spaces=1)
  "\e[#{spaces.to_i}D"
end

#move(line, column = 0) ⇒ Object

Move cursor to line and column.



134
135
136
# File 'lib/ansi/code.rb', line 134

def move(line, column=0)
  "\e[#{line.to_i};#{column.to_i}H"
end

#random(background = false) ⇒ Integer

Provides a random primary ANSI color.

Parameters:

  • background (Boolean) (defaults to: false)

    Use ‘true` for background color, otherwise foreground color.

Returns:

  • (Integer)

    ANSI color number



274
275
276
# File 'lib/ansi/code.rb', line 274

def random(background=false)
  (background ? 40 : 30) + rand(8)
end

#rgb(*args) ⇒ Object

Creates an XTerm 256 color escape code from RGB value(s). The RGB value can be three arguments red, green and blue respectively each from 0 to 255, or the RGB value can be a single CSS-style hex string.

Parameters:

  • background (Boolean)

    Use ‘true` for background color, otherwise foreground color.



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/ansi/code.rb', line 286

def rgb(*args)
  case args.size
  when 1, 2
    hex, background = *args
    esc = "\e[" + hex_code(hex, background) + "m"
  when 3, 4
    red, green, blue, background = *args
    esc = "\e[" + rgb_code(red, green, blue, background) + "m"
  else
    raise ArgumentError
  end

  if block_given?
    return yield.to_s unless $ansi
    return "#{esc}#{yield}#{ENDCODE}"
  else
    return esc
  end
end

#rgb_256(r, g, b) ⇒ Object

Given red, green and blue values between 0 and 255, this method returns the closest XTerm 256 color value.

Raises:

  • (ArgumentError)


335
336
337
338
339
340
341
342
# File 'lib/ansi/code.rb', line 335

def rgb_256(r, g, b)
  # TODO: what was rgb_valid for?
  #r, g, b = [r, g, b].map{ |c| rgb_valid(c); (6 * (c.to_f / 256.0)).to_i }
  r, g, b = [r, g, b].map{ |c| (6 * (c.to_f / 256.0)).to_i }
  v = (r * 36 + g * 6 + b + 16).abs
  raise ArgumentError, "RGB value is outside 0-255 range -- #{v}" if v > 255
  v
end

#rgb_code(red, green, blue, background = false) ⇒ Object

Creates an xterm-256 color from rgb value.

Parameters:

  • background (Boolean) (defaults to: false)

    Use ‘true` for background color, otherwise foreground color.



313
314
315
# File 'lib/ansi/code.rb', line 313

def rgb_code(red, green, blue, background=false)
  "#{background ? 48 : 38};5;#{rgb_256(red, green, blue)}"
end

#right(spaces = 1) ⇒ Object Also known as: forward

Move cursor right a specified number of spaces.



155
156
157
# File 'lib/ansi/code.rb', line 155

def right(spaces=1)
  "\e[#{spaces.to_i}C"
end

#unansi(string = nil) ⇒ String Also known as: unstyle, uncolor

Remove ANSI codes from string or block value.

Parameters:

  • string (String) (defaults to: nil)

    String from which to remove ANSI codes.

Returns:

  • (String)

    String wrapped ANSI code.



201
202
203
204
205
206
207
208
# File 'lib/ansi/code.rb', line 201

def unansi(string=nil) #:yield:
  if block_given?
    string = yield.to_s
  else
    string = string.to_s
  end
  string.gsub(PATTERN, '')
end

#up(spaces = 1) ⇒ Object

Move cursor up a specified number of spaces.



139
140
141
# File 'lib/ansi/code.rb', line 139

def up(spaces=1)
  "\e[#{spaces.to_i}A"
end