Terminal colours made simple

The first release of tco
2014-03-30
~
5 min read

Over the weekend, I pushed out the first release of the tco gem. Its goal is to make working with terminal colours as simple as possible; hence the name tco. The main feature of this tool is the way it works with colours. Instead of an oddly organised sequence of colour codes, tco uses simple RGB. It provides a library for your Ruby gems and apps, and also a standalone command-line tool that you can use anywhere else.

Tco example
Figure 1: Example of a Ruby program using the tco library

If you’ve ever worked with the extended colour palette in the terminal, you probably know that it’s not really easy to find the colour you want. The palette consists of 256 colours that are evenly sampled through the RGB space. As opposed to the ANSI palette, the colours tend to be the same across different terminals. They are assigned linearly to a set of escape sequences that are used to apply the colours. And that is the problem; searching through the palette is very unintuitive.

Extended palete
Figure 2: A part of the extended colour palette

On the other hand, selecting a RGB colour using your favourite colour picker is a nice, buttery piece of cake with a bit of cream on top. That is everything you need to do; pass the value to tco and it will sort out all the boring bits for you. Using the RGB value, the library will find the perceptually closest option that is displayable in your terminal and decorate the string with the appropriate escape sequences, letting you focus on more interesting things in life instead.

How does it work then?

Let me start with explaining the tco command-line tool first. Among all the parameters it accepts, there are four essential ones that control directly how the output will look like. That includes setting the foreground -f and background -b colours, and also the bold -B and underline -u flags. The actual input can be passed either as an argument or piped to stdin. See the following examples:

Tco in the terminal
Figure 3: Ways of using tco in the terminal

In most cases, you will probably use several colours and settings over and over again. To help you with that, tco comes with configurable colour names and style definitions. You can set them either system-wide in /etc/tco.conf or just for a single user in the ~/.tco.conf file (for more information on its format, see the example on Github). Once you’ve configured some, you can access them through the -s option.

Tco styles
Figure 4: Specify and use your own style definitions

Fairly often, you might want to decorate different parts of a string with different colours. Instead of having to split the string and print it in parts, you can use a simple template syntax to indicate how should each of the parts be decorated. These templates are enclosed in double curly brackets {{ }}. The first part of a template is the colour definition fg:bg:ub, followed by a space and the string to be decorated. You can even nest them; see the few examples below:

Using templates
Figure 5: Several examples of different templates

There are a few more options available for different things; get the full up-to-date list by passing -h to the program.

Using the Ruby library

tco is a gem, so you can use the same functionality in your own Ruby apps and scripts too. The interface is pretty simple with just a few methods that cover all the functionality. For convenience, there is a String extension that makes these functions accessible directly from all string objects.

require 'tco'

puts "Red font on grey background".fg("#ff0000").bg("#bebebe")
puts "Bold and underlined".bold.underline

puts "{{#000:#ff0000 R}}{{#000:#00ff00 G}}{{#000:#0000ff B}}".decorate

Most applications are likely to use a fixed palette of colours only. Therfore, it is really simple to reconfigure the library to match the needs of your program. You can define your own colour names and styles to which you can refer to later on. These settings will be applied on top of the user and system configurations, but they won’t be saved when you application terminates. The following example shows exactly how to do it:

require "tco"

conf = Tco.config
conf.names["purple"] = "#622e90"
conf.names["dark-blue"] = "#2d3091"
conf.names["blue"] = "#00aaea"
conf.names["green"] = "#02a552"
conf.names["yellow"] = "#fdea22"
conf.names["orange"] = "#f37f5a"
conf.names["red"] = "#eb443b"
Tco.reconfigure conf

rainbow = ["purple", "dark-blue", "blue", "green", "yellow", "orange", "red"]
10.times do
  rainbow.each { |colour| print "    ".bg colour }
  puts
end
Drawing a rainbow
Figure 6: Drawing a simple rainbow

If you would like to get really crazy, you can even render a very low resolution images inside the terminal. You’ll need to print roughly 2 spaces for each pixel (it’s not perfect, but close enough). The following example reads a PNG picture of the Tux using the rmagick gem and displays it in the terminal.

#!/usr/bin/env ruby

require "tco"
require "rmagick"

Magick::Image.read("tux.png")[0].each_pixel do |pixel, col, row|
  c = [pixel.red, pixel.green, pixel.blue].map { |v| 255*(v/65535.0) }
  print "  ".bg c
  puts if col >= 53
end
tco with ImageMagick
Figure 7: Rendering low-res pictures in the terminal

Summary

And that’s it! It’s quite a simple gem, but it can help you make your console apps more lively and their output much easier to navigate with barely any additional effort. It’s available right now on RubyGems, the sources are hosted on GitHub, licensed under MIT.

If you have any questions, comments, suggestions, or problems, please let me know, I’ll be happy to help you :-).