Module: Color

Extended by:
Color
Included in:
Color
Defined in:
lib/journal-cli/color.rb

Overview

Cribbed from <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 =

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-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


203
204
205
# File 'lib/journal-cli/color.rb', line 203

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)


192
193
194
# File 'lib/journal-cli/color.rb', line 192

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



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/journal-cli/color.rb', line 232

def template(input)
  input = input.join(" ") if input.is_a? Array
  return input.gsub(/(?<!\\)\{(\w+)\}/i, "") 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.



353
354
355
# File 'lib/journal-cli/color.rb', line 353

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



310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/journal-cli/color.rb', line 310

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)


92
93
94
95
96
97
# File 'lib/journal-cli/color.rb', line 92

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.



340
341
342
343
344
345
346
347
348
349
350
# File 'lib/journal-cli/color.rb', line 340

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