Perl: ANSI colors
Perl's Term::ANSIColor is good but sometime it's overkill. I wrote a function to change colors before your print.
$color = color("13_on_5");
$reset = color("reset");
print $color . "Pink on purple" . $reset . "\n";
# or
print color('yellow', "Warning:"); # Print text and reset
The ANSI color numbers can be determined using term-colors.pl.
# String format: '115', '165_bold', '10_on_140', 'reset', 'on_173', 'red', 'white_on_blue'
sub color {
my ($str, $txt) = @_;
state $notty = !-t STDOUT; # Cache the TTY check
if ($notty || $ENV{NO_COLOR}) { return $txt // ""; } # No interactive terminal
if (!length($str) || $str eq 'reset') { return "\e[0m"; } # No string = RESET
# Some predefined colors/commands
state %color_map = qw(red 160 blue 27 green 34 yellow 226 orange 214 purple 93 white 15 black 0);
state %cmd_map = qw(bold 1 italic 3 underline 4 blink 5 inverse 7);
# Pre-process the string
$str =~ s/on_/-/g; # "on_" becomes a negative number
$str =~ s|([A-Za-z]+)|$color_map{$1} // $1|eg; # color name -> number
my @parts = map { # If it's negative it's a background color, otherwise foreground
$cmd_map{$_} // ($_ =~ /^-(.+)/ ? "48;5;$1" : "38;5;$_")
} split("_", $str);
my $ret = "\e[" . join(";", @parts) . "m";
if (defined $txt) { $ret .= $txt . "\e[0m"; }
return $ret;
}
Note: You can test if you're outputting to a TTY which supports ANSI colors, or a file using the -t test.
See also: Regexp to check for ANSI color codes
See also: Tests



