Module: Planter::Color

Extended by:
Color
Included in:
Planter, Color
Defined in:
lib/planter/color.rb

Overview

Cribbed from https://github.com/flori/term-ansicolor Terminal output color functions.

Constant Summary collapse

ESCAPE_REGEX =

Regexp to match excape sequences

/(?<=\[)(?:(?:(?:[349]|10)[0-9]|[0-9])?;?)+(?=m)/
ATTRIBUTES =

All available color names. Available as methods and string extensions.

Examples:

Use a color as a method. Color reset will be added to end of string.

Color.yellow('This text is yellow') => "\e[33mThis text is yellow\e[0m"

Use a color as a string extension. Color reset added automatically.

'This text is green'.green => "\e[1;32mThis text is green\e[0m"

Send a text string as a color

Color.send('red') => "\e[31m"
[
  [:clear, 0], # String#clear is already used to empty string in Ruby 1.9
  [:reset, 0], # synonym for :clear
  [:bold, 1],
  [:dark, 2],
  [:italic, 3], # not widely implemented
  [:underline, 4],
  [:underscore, 4], # synonym for :underline
  [:blink, 5],
  [:rapid_blink, 6], # not widely implemented
  [:negative, 7], # no reverse because of String#reverse
  [:concealed, 8],
  [:strikethrough, 9], # not widely implemented
  [:strike, 9], # not widely implemented
  [:black, 30],
  [:red, 31],
  [:green, 32],
  [:yellow, 33],
  [:blue, 34],
  [:magenta, 35],
  [:purple, 35],
  [:cyan, 36],
  [:white, 37],
  [:bgblack, 40],
  [:bgred, 41],
  [:bggreen, 42],
  [:bgyellow, 43],
  [:bgblue, 44],
  [:bgmagenta, 45],
  [:bgpurple, 45],
  [:bgcyan, 46],
  [:bgwhite, 47],
  [:boldblack, 90],
  [:boldred, 91],
  [:boldgreen, 92],
  [:boldyellow, 93],
  [:boldblue, 94],
  [:boldmagenta, 95],
  [:boldpurple, 95],
  [:boldcyan, 96],
  [:boldwhite, 97],
  [:boldbgblack, 100],
  [:boldbgred, 101],
  [:boldbggreen, 102],
  [:boldbgyellow, 103],
  [:boldbgblue, 104],
  [:boldbgmagenta, 105],
  [:boldbgpurple, 105],
  [:boldbgcyan, 106],
  [:boldbgwhite, 107],
  [:softpurple, '0;35;40'],
  [:hotpants, '7;34;40'],
  [:knightrider, '7;30;40'],
  [:flamingo, '7;31;47'],
  [:yeller, '1;37;43'],
  [:whiteboard, '1;30;47'],
  [:chalkboard, '1;37;40'],
  [:led, '0;32;40'],
  [:redacted, '0;30;40'],
  [:alert, '1;31;43'],
  [:error, '1;37;41'],
  [:default, '0;39']
].map(&:freeze).freeze
ATTRIBUTE_NAMES =

Returns all available color names.

Returns:

ATTRIBUTES.transpose.first
COLORED_REGEXP =

Regular expression that is used to scan for ANSI-sequences while uncoloring strings.

/\e\[(?:(?:(?:[349]|10)[0-9]|[0-9])?;?)+m/

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.coloringObject

Enables colored output

Examples:

Turn color on or off based on TTY

Color.coloring = STDOUT.isatty


219
220
221
# File 'lib/planter/color.rb', line 219

def coloring
  @coloring ||= true
end

Class Method Details

.coloring?Boolean

Returns true if the coloring function of this module is switched on, false otherwise.

Returns:

  • (Boolean)


208
209
210
# File 'lib/planter/color.rb', line 208

def coloring?
  @coloring
end

.template(input) ⇒ String

Convert a template string to a colored string. Colors are specified with single letters inside curly braces. Uppercase changes background color.

w: white, k: black, g: green, l: blue, y: yellow, c: cyan, m: magenta, r: red, b: bold, u: underline, i: italic, x: reset (remove background, color, emphasis)

Also accepts ((#)RGB and ((#)RRGGBB strings. Put a b before the hash to make it a background color

Examples:

Convert a templated string

Color.template('{Rwb}Warning:{x} {w}you look a little {g}ill{x}')

Convert using RGB colors

Color.template('{#f0a}This is an RGB color')

Parameters:

  • input (String, Array)

    The template string. If this is an array, the elements will be joined with a space.

Returns:

  • (String)

    Colorized string



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/planter/color.rb', line 248

def template(input)
  input = input.join(' ') if input.is_a? Array
  return input.strip_template unless Color.coloring?

  input = input.gsub(/(?<!\\)\{((?:[fb]g?)?#[a-f0-9]{3,6})\}/i) do
    hex = Regexp.last_match(1)
    rgb(hex)
  end

  fmt = input.gsub(/%/, '%%')
  fmt = fmt.gsub(/(?<!\\)\{(\w+)\}/i) do
    Regexp.last_match(1).chars.map { |c| "%<#{c}>s" }.join('')
  end

  colors = { w: white, k: black, g: green, l: blue,
             y: yellow, c: cyan, m: magenta, r: red,
             W: bgwhite, K: bgblack, G: bggreen, L: bgblue,
             Y: bgyellow, C: bgcyan, M: bgmagenta, R: bgred,
             d: dark, b: bold, u: underline, i: italic, x: reset }

  format(fmt, colors)
end

Instance Method Details

#attributesObject

Returns an array of all Color attributes as symbols.



369
370
371
# File 'lib/planter/color.rb', line 369

def attributes
  ATTRIBUTE_NAMES
end

#rgb(hex) ⇒ String

Generate escape codes for hex colors

Parameters:

  • hex (String)

    The hexadecimal color code

Returns:

  • (String)

    ANSI escape string



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/planter/color.rb', line 326

def rgb(hex)
  is_bg = /^bg?#/.match?(hex)
  hex_string = hex.sub(/^([fb]g?)?#/, '')

  if hex_string.length == 3
    parts = hex_string.match(/(?<r>.)(?<g>.)(?<b>.)/)

    t = []
    %w[r g b].each do |e|
      t << parts[e]
      t << parts[e]
    end
    hex_string = t.join('')
  end

  parts = hex_string.match(/(?<r>..)(?<g>..)(?<b>..)/)
  t = []
  %w[r g b].each do |e|
    t << parts[e].hex
  end

  "\e[#{is_bg ? '48' : '38'};2;#{t.join(';')}m"
end

#support?(feature) ⇒ Boolean

Returns true if Color supports the +feature+.

The feature :clear, that is mixing the clear color attribute into String, is only supported on ruby implementations, that do not already implement the String#clear method. It's better to use the reset color attribute instead.

Returns:

  • (Boolean)


93
94
95
96
97
98
# File 'lib/planter/color.rb', line 93

def support?(feature)
  case feature
  when :clear
    !String.instance_methods(false).map(&:to_sym).include?(:clear)
  end
end

#uncolor(string = nil) ⇒ Object

Returns an uncolored version of the string, that is all ANSI-sequences are stripped from the string.



356
357
358
359
360
361
362
363
364
365
366
# File 'lib/planter/color.rb', line 356

def uncolor(string = nil) # :yields:
  if block_given?
    yield.to_str.gsub(COLORED_REGEXP, '')
  elsif string.respond_to?(:to_str)
    string.to_str.gsub(COLORED_REGEXP, '')
  elsif respond_to?(:to_str)
    to_str.gsub(COLORED_REGEXP, '')
  else
    ''
  end
end