class Tco::Colouring

Constants

ANSI_BG_BASE
ANSI_FG_BASE

Attributes

palette[R]

Public Class Methods

new(configuration) click to toggle source
# File lib/tco/colouring.rb, line 34
def initialize(configuration)
  @palette = Palette.new configuration.options["palette"]
  @output_type = configuration.options["output"]
  @disabled = configuration.options["disabled"]

  configuration.colour_values.each do |id, value|
    @palette.set_colour_value(parse_colour_id(id), parse_rgb_value(value))
  end

  @names = {}
  configuration.names.each do |name, colour_def|
    @names[name] = resolve_colour_def colour_def
  end

  @styles = {}
  configuration.styles.each do |name, style|
    @styles[name] = Style.new(resolve_colour_def(style[:fg]),
                              resolve_colour_def(style[:bg]),
                              style[:bright], style[:underline])
  end
end

Public Instance Methods

decorate(string, (fg, bg, bright, underline)) click to toggle source

Decorate a string according to the style passed. The input string is processed line-by-line (the escape sequences are added to each line). This is due to some problems I've been having with some terminal emulators not handling multi-line coloured sequences well.

# File lib/tco/colouring.rb, line 60
def decorate(string, (fg, bg, bright, underline))
  if (!STDOUT.isatty) || @output_type == :raw || @disabled
    return string
  end

  fg = get_colour_instance fg
  bg = get_colour_instance bg

  output = []
  lines = string.lines.map(&:chomp)
  lines.each do |line|
    unless line.length <= 0
      line = case @palette.type
             when "ansi" then colour_ansi line, fg, bg
             when "extended" then colour_extended line, fg, bg
             else raise "Unknown palette '#{@palette.type}'."
             end

      if bright
        line = e(1) + line
      end

      if underline
        line = e(4) + line
      end

      if (bright or underline) and fg == nil and bg == nil
        line << e(0)
      end
    end

    output.push line
  end

  output << "" if string =~ /\n$/
  output.join "\n"
end
get_best_font_colour(background) click to toggle source
# File lib/tco/colouring.rb, line 111
def get_best_font_colour(background)
    black = Tco::Colour.new([0,0,0])
    white = Tco::Colour.new([255,255,255])

    if background.is_a?(Colour) &&
       (background - black).abs < (background - white).abs
      return white
    end

    black
end
get_colour_instance(value) click to toggle source
# File lib/tco/colouring.rb, line 123
def get_colour_instance(value)
  case
  when value.is_a?(String)
    resolve_colour_def value
  when value.is_a?(Array)
    Colour.new value
  when value.is_a?(Colour) || value.is_a?(Unknown)
    value
  when value == nil
    nil
  else
    raise "Colour value type '#{value.class}' not supported."
  end
end
get_style(name) click to toggle source
# File lib/tco/colouring.rb, line 98
def get_style(name)
  raise "Style '#{name}' not found." unless @styles.has_key? name

  @styles[name]
end
set_output(output_type) click to toggle source
# File lib/tco/colouring.rb, line 104
def set_output(output_type)
  unless [:term, :raw].include? output_type
    raise "Output '#{output_type}' not supported."
  end
  @output_type = output_type
end

Private Instance Methods

colour_ansi(string, fg=nil, bg=nil) click to toggle source
# File lib/tco/colouring.rb, line 147
def colour_ansi(string, fg=nil, bg=nil)
  unless fg == nil
    colour_id = if fg.is_a? Unknown
      fg.id
    else
      @palette.match_colour(fg)
    end
    string = e(colour_id + 30) + string
  end

  unless bg == nil
    colour_id = if bg.is_a? Unknown
      bg.id
    else
      @palette.match_colour(bg)
    end
    string = e(colour_id + 40) + string
  end

  unless fg == nil and bg == nil
    string << e(0)
  end

  string
end
colour_extended(string, fg=nil, bg=nil) click to toggle source
# File lib/tco/colouring.rb, line 173
def colour_extended(string, fg=nil, bg=nil)
  unless fg == nil
    colour_id = if fg.is_a? Unknown
      fg.id
    else
      @palette.match_colour(fg)
    end
    string = e("38;5;#{colour_id}") + string
  end

  unless bg == nil
    colour_id = if bg.is_a? Unknown
      bg.id
    else
      @palette.match_colour(bg)
    end
    string = e("48;5;#{colour_id}") + string
  end

  unless fg == nil and bg == nil
    string << e(0)
  end

  string
end
e(seq) click to toggle source
# File lib/tco/colouring.rb, line 139
def e(seq)
  if @output_type == :raw
    "\\033[#{seq}m"
  else
    "\033[#{seq}m"
  end
end
parse_colour_id(id_in_string) click to toggle source
# File lib/tco/colouring.rb, line 199
def parse_colour_id(id_in_string)
  id = String.new(id_in_string)
  if id[0] == '@'
    id[0] = ''
    return id.to_i
  end

  raise "Invalid colour id #{id_in_string}."
end
parse_rgb_value(rgb_value_in_string) click to toggle source
# File lib/tco/colouring.rb, line 209
def parse_rgb_value(rgb_value_in_string)
  error_msg = "Invalid RGB value '#{rgb_value_in_string}'."
  rgb_value = String.new rgb_value_in_string
  case
  when rgb_value[0] == '#'
    rgb_value[0] = ''
  when rgb_value[0..1] == '0x'
    rgb_value[0..1] = ''
  else
    raise error_msg
  end

  raise error_msg unless rgb_value =~ /^[0-9a-fA-F]+$/

  case rgb_value.length
  when 3
    rgb_value.scan(/./).map { |c| c.to_i 16 }
  when 6
    rgb_value.scan(/../).map { |c| c.to_i 16 }
  else
    raise error_msg
  end
end
resolve_colour_def(colour_def) click to toggle source
# File lib/tco/colouring.rb, line 239
def resolve_colour_def(colour_def)
  return nil if colour_def == "" || colour_def == "default"

  begin
    id = parse_colour_id colour_def
    if @palette.is_known? id
      Colour.new @palette.get_colour_value id
    else
      Unknown.new id
    end
  rescue RuntimeError
    begin
      Colour.new parse_rgb_value colour_def
    rescue RuntimeError
      begin
        colour_def = resolve_colour_name colour_def
        if colour_def.is_a? String
          resolve_colour_def colour_def
        else
          colour_def
        end
      rescue RuntimeError
        raise "Invalid colour definition '#{colour_def}'."
      end
    end
  end
end
resolve_colour_name(name) click to toggle source
# File lib/tco/colouring.rb, line 233
def resolve_colour_name(name)
  raise "Name '#{name}' not found." unless @names.has_key? name

  @names[name]
end