If you want to colorize screen output in your programs, chances are you’ve encountered the core Term::ANSIColor module.

It works just as expected, which means it deals with the standard ANSI colors. Nowadays, most terminals support the extended colorset as well, and I was quite surprised there wasn’t a module dealing with this already.

I present to you Term::ExtendedColor.

As of today, it’s really hard to find a terminal that does not support these extended colors.

256 colors supported
----------------------
eterm
gnome-terminal
konsole
lxterminal
mrxvt
roxterm
rxvt-unicode
sakura
terminal
terminator
vte
xterm

GNU Screen
tmux

Not supported
---------------------
aterm
rxvt
TTY/VC

The biggest obstacle I encountered was how to name the colors. With a total of 240 additional colors with about 30 shades of green, 20 shades of yellow and so on, it wasn’t obvious.

My first thought was to map them against some standard color names, like the HTML or SVG ones. They didn’t match.

Then I thought of the X11 color names

  • they surely must match! They didn’t.

So the solution was pretty simple - create one table per base color ( green, blue, yellow ), make the brightest shade the first element and name the colors by their base color plus index.

If you happen to know of a better way to solve this, please let me know.

The interface is almost identical to the functional interface from Term::ANSIColor, with a few exceptions.

First, there’s no need to separate a color() and colored() function.

=for autoreset(1)

Autoreset is enabled by default.
Every string you apply an attribute to also gets the 'reset' attribute attached to it.

=cut

my $colored_text = fg('blue2', 'This is blue');
$colored_text .= " while this isn't.";

=for autoreset(0)

There are times where you might want to disable autoreset.

=cut

Term::ExtendedColor::autoreset(0);

my $blue = fg('blue4', 'This is blue');
print fg('bold', "This is bold and blue"), "\n";

Second, two separate functions are exported to deal with foreground and background attributes.

my $green_fg = fg('green3', 'This is green foreground');
my $grey_bg  = bg('grey10', 'This is default foreground on grey background');

my $blue_on_red = fg('blue1', bg('red4', 'Blue text on red background'));

The colorstrip() function in Term::ANSIColor is called uncolor().

my $colored = fg('red1', fg('bold', bg('blue2', 'Lots of attributes')));
print uncolored($colored); # Normal text

set_color() allows you to change mapped colors, ANSI as well as the extended ones. This is the same technique that’s used in colorcoke.

# Change the first ANSI color (usually black) to red
print set_color(0, 'ff0000');
# Change extended color 196 (#ff0000) to yellow
print set_color(196, 'ffff00');

get_colors() returns a hash reference with all available colors:

my $colors = get_colors();

for my $c(sort(keys(%{$colors}))) {
  print "$c\n";

  # Or, print them in their respective color
  print fg($c, $c), "\n";
}

lookup() allows you to lookup a color by their index.

for(0..255) {
  my $color_str = lookup($_);
  if(defined($color_str)) {
    printf("%25s => %s\n", fg($color_str, $color_str), $_);
  }
}