Module: Howzit::Color

Extended by:
Color
Included in:
Color
Defined in:
lib/howzit/colors.rb

Overview

Terminal output color functions.

Constant Summary collapse

ESCAPE_REGEX =

Regexp to match excape sequences

/(?<=\[)(?:(?:(?:[349]|10)[0-9]|[0-9])?;?)+(?=m)/.freeze
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 =

Array of attribute keys only

ATTRIBUTES.transpose.first
COLORED_REGEXP =

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

/\e\[(?:(?:[349]|10)[0-7]|[0-9])?m/.freeze

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

Howzit::Color.coloring = STDOUT.isatty


206
207
208
# File 'lib/howzit/colors.rb', line 206

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)


195
196
197
# File 'lib/howzit/colors.rb', line 195

def coloring?
  @coloring
end

.configured_colorsObject

Merge config file colors into attributes



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/howzit/colors.rb', line 237

def configured_colors
  color_file = File.join(File.expand_path(CONFIG_DIR), COLOR_FILE)
  if File.exist?(color_file)
    colors = YAML.load(Util.read_file(color_file))
    return ATTRIBUTES unless !colors.nil? && colors.is_a?(Hash)

    attrs = ATTRIBUTES.to_h
    attrs = attrs.merge(colors.symbolize_keys)
    new_colors = {}
    attrs.each { |k, v| new_colors[k] = translate_rgb(v) }
    new_colors.to_a
  else
    ATTRIBUTES
  end
end

.rgb(hex) ⇒ String

Generate escape codes for hex colors

Parameters:

  • hex (String)

    The hexadecimal color code

Returns:

  • (String)

    ANSI escape string



223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/howzit/colors.rb', line 223

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

  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(';')}"
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)

Examples:

Convert a templated string

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

Parameters:

  • input (String, Array)

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

Returns:

  • (String)

    Colorized string



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/howzit/colors.rb', line 272

def template(input)
  input = input.join(' ') if input.is_a? Array
  fmt = input.gsub(/%/, '%%')
  fmt = fmt.gsub(/(?<!\\u|\$)\{(\w+)\}/i) do
    m = Regexp.last_match(1)
    if m =~ /^[wkglycmrWKGLYCMRdbuix]+$/
      m.split('').map { |c| "%<#{c}>s" }.join('')
    else
      Regexp.last_match(0)
    end
  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 }

  fmt.empty? ? input : format(fmt, colors)
end

.translate_rgb(code) ⇒ Object



210
211
212
213
214
# File 'lib/howzit/colors.rb', line 210

def translate_rgb(code)
  return code if code.to_s !~ /#[A-Z0-9]{3,6}/i

  rgb(code)
end

Instance Method Details

#attributesObject

Returns an array of all Howzit::Color attributes as symbols.



381
382
383
# File 'lib/howzit/colors.rb', line 381

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



350
351
352
353
354
355
356
357
358
359
360
# File 'lib/howzit/colors.rb', line 350

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

  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 Howzit::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/howzit/colors.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.



368
369
370
371
372
373
374
375
376
377
378
# File 'lib/howzit/colors.rb', line 368

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