Skip Menu |

This queue is for tickets about the Term-ANSIColor CPAN distribution.

Report information
The Basics
Id: 78342
Status: resolved
Priority: 0/
Queue: Term-ANSIColor

People
Owner: Nobody in particular
Requestors: stephen.thirlwall [...] strategicdata.com.au
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 3.02
Fixed in: 4.00



Subject: Patch: custom color names via environment variable
Hi Russ, Attached is a patch for your consideration which adds support for user-defined color mappings, such as 'alert=red' or 'gray=bright_black'. With these color mappings, the functions color(), colored() and colorvalid() will also understand 'alert' and 'gray' as colors. The custom colors are spceified with an environment variable like so: TERM_ANSICOLOR_CUSTOM_COLORS="alert=red,gray=bright_black" The impetus for this patch comes from the perl module Data::Printer, and the Solarized color scheme (http://ethanschoonover.com/solarized). I'd like to be able to create a Data::Printer config which uses the Solarized color names themselves. eg. hash => "orange on_base02" vs hash => "bright_red on_black" I'm pretty bad at designing color schemes anyway, and adding a layer of color name indirection makes it doubly difficult. With this patch I can set up a mapping for the Solarized color names and anything which uses Term::ANSIColor automatically just works with them. How does this sound to you? Steve
Subject: custom-colors.patch
diff --git a/ANSIColor.pm b/ANSIColor.pm index 9e3530e..5db5530 100644 --- a/ANSIColor.pm +++ b/ANSIColor.pm @@ -90,6 +90,11 @@ for (reverse sort keys %ATTRIBUTES) { $ATTRIBUTES_R{$ATTRIBUTES{$_}} = $_; } +# Add custom color names if required. +if (exists($ENV{TERM_ANSICOLOR_CUSTOM_COLORS})) { + _add_custom_colors($ENV{TERM_ANSICOLOR_CUSTOM_COLORS}); +} + ############################################################################## # Implementation (constant form) ############################################################################## @@ -272,6 +277,29 @@ sub colorvalid { return 1; } +# Parse a comma-separated line of custom color definitions, each of the +# form: newname=oldname +sub _add_custom_colors { + my ($str) = @_; + $str =~ s/\s+//g; # trim out all whitespace + for my $defn (split(/,/, $str)) { + my ($new, $old) = split(/=/, $defn, 2); + if (!$new || !$old) { + warn "Bad color mapping \"$defn\""; + } + elsif (! exists $ATTRIBUTES{$old}) { + warn "Unknown color mapping \"$old\""; + } + else { + $ATTRIBUTES{$new} = $ATTRIBUTES{$old}; + + # Could also do the the reverse mapping, but this may break + # client code which expects specific strings to be returned + # from uncolor. + } + } +} + ############################################################################## # Module return value and documentation ############################################################################## @@ -633,6 +661,33 @@ platforms that don't support ANSI escape sequences. For it to have its proper effect, this environment variable must be set before any color constants are used in the program. +=item TERM_ANSICOLOR_CUSTOM_COLORS + +This environment variable allows the user to specify custom color names +that will be understood by color(), colored() and colorvalid(). The custom +color names are simply aliases for existing color names. + +The format is: + + TERM_ANSICOLOR_CUSTOM_COLORS="newcolor1=oldcolor1,newcolor2=oldcolor2" + +Whitespace is ignored. + +For example the L<Solarized|http://ethanschoonover.com/solarized> colors can +be mapped with: + + TERM_ANSICOLOR_CUSTOM_COLORS="\ + base00=bright_yellow, on_base00=on_bright_yellow,\ + base01=bright_green, on_base01=on_bright_green, \ + base02=black, on_base02=on_black, \ + base03=bright_black, on_base03=on_bright_black, \ + base0=bright_blue, on_base0=on_bright_blue, \ + base1=bright_cyan, on_base1=on_bright_cyan, \ + base2=white, on_base2=on_white, \ + base3=bright_white, on_base3=on_bright_white, \ + orange=bright_red, on_orange=on_bright_red, \ + violet=bright_magenta,on_violet=on_bright_magenta" + =back =head1 RESTRICTIONS diff --git a/MANIFEST b/MANIFEST index 65ba31f..bca9351 100644 --- a/MANIFEST +++ b/MANIFEST @@ -4,6 +4,7 @@ Makefile.PL MANIFEST README t/basic.t +t/custom.t t/eval.t t/pod-spelling.t t/pod.t diff --git a/t/basic.t b/t/basic.t index 7f6bfff..235b29e 100755 --- a/t/basic.t +++ b/t/basic.t @@ -13,6 +13,7 @@ use Test::More tests => 54; BEGIN { delete $ENV{ANSI_COLORS_DISABLED}; + delete $ENV{TERM_ANSICOLOR_CUSTOM_COLORS}; use_ok ('Term::ANSIColor', qw/:pushpop color colored uncolor colorstrip colorvalid/); } diff --git a/t/custom.t b/t/custom.t new file mode 100644 index 0000000..1c1a048 --- /dev/null +++ b/t/custom.t @@ -0,0 +1,65 @@ +#!/usr/bin/perl -Tw +# +# t/config.t -- testing the custom user colors functionality +# +use strict; +use Test::More tests => 23; + +my @expected_warnings; +my @unexpected_warnings; + +BEGIN { + $ENV{TERM_ANSICOLOR_CUSTOM_COLORS} = join(',', + ' custom_black = black', + 'custom_red= red', + 'custom_green =green ', + 'custom_blue=blue', + 'custom_unknown=unknown', + '=no_new', + 'no_old=', + 'no_equals', + ); + delete $ENV{ANSI_COLORS_DISABLED}; + + # Test::Warn instead maybe? + local $SIG{__WARN__} = sub { + my ($msg) = @_; + if ($msg =~ /(?:Bad|Unknown) color mapping/) { + push(@expected_warnings, $msg); + } + else { + warn $msg; + push(@unexpected_warnings, $msg); + } + }; + + use_ok 'Term::ANSIColor', + qw/color colored uncolor colorvalid/; +} + +# Check that the appropriate warnings got issued +ok(grep(/Unknown color mapping "unknown"/, @expected_warnings), + 'Got unknown old color warning'); +for my $bad (qw( =no_new no_old= no_equals )) { + ok(grep(/Bad color mapping "$bad"/, @expected_warnings), + "Got warning for \"$bad\""); +} +is(scalar @unexpected_warnings, 0, "No unexpected warnings"); + + +# Check the custom colors all get assigned. They use various spacing formats +# and should all parse correctly. +for my $original (qw( black red green blue )) { + my $custom = 'custom_' . $original; + ok (colorvalid ($custom), "$custom is valid()"); + is (color ($custom), color ($original), + "custom $custom matches $original with color()"); + is (colored ('test', $custom), colored ('test', $original), + "custom $custom matches $original with colored()"); + is ((uncolor(color($custom)))[0], $original, + "uncolor works for $custom back to $original"); +} + + +# custom_unknown is mapped to an unknown color and should not appear +ok(! colorvalid('custom_unknown'), 'unknown color mapping fails'); diff --git a/t/eval.t b/t/eval.t index 394368e..08e6186 100755 --- a/t/eval.t +++ b/t/eval.t @@ -12,6 +12,7 @@ use Test::More tests => 5; BEGIN { delete $ENV{ANSI_COLORS_DISABLED}; + delete $ENV{TERM_ANSICOLOR_CUSTOM_COLORS}; use_ok ('Term::ANSIColor', qw/:constants/); } diff --git a/t/stringify.t b/t/stringify.t index a8eb448..56cc03f 100755 --- a/t/stringify.t +++ b/t/stringify.t @@ -20,6 +20,7 @@ use Test::More tests => 6; BEGIN { delete $ENV{ANSI_COLORS_DISABLED}; + delete $ENV{TERM_ANSICOLOR_CUSTOM_COLORS}; use_ok ('Term::ANSIColor', qw/:pushpop color colored uncolor colorstrip colorvalid/); }
Subject: Re: [rt.cpan.org #78342] Patch: custom color names via environment variable
Date: Sun, 30 Dec 2012 14:52:59 -0800
To: bug-Term-ANSIColor [...] rt.cpan.org
From: Russ Allbery <rra [...] stanford.edu>
"Stephen Thirlwall via RT" <bug-Term-ANSIColor@rt.cpan.org> writes: Show quoted text
> Attached is a patch for your consideration which adds support for > user-defined color mappings, such as 'alert=red' or 'gray=bright_black'.
Show quoted text
> With these color mappings, the functions color(), colored() and > colorvalid() will also understand 'alert' and 'gray' as colors.
Show quoted text
> The custom colors are spceified with an environment variable like so:
Show quoted text
> TERM_ANSICOLOR_CUSTOM_COLORS="alert=red,gray=bright_black"
Thank you for this patch! This has been merged now, although with some changes. The basic syntax is the same, but I added a coloralias() function that would provide a runtime interface to the same functionality. I used the environment variable name ANSI_COLORS_ALIASES to parallel ANSI_COLORS_DISABLED and to make it a bit clearer that these are just aliases. Term::ANSIColor 4.00 has just been released with this support (as well as 256-color support) and should show up on CPAN shortly. -- Russ Allbery (rra@stanford.edu) <http://www.eyrie.org/~eagle/>