File Coverage

blib/lib/Term/ANSIColor/Print.pm
Criterion Covered Total %
statement 53 71 74.6
branch 17 34 50.0
condition n/a
subroutine 7 8 87.5
pod 0 1 0.0
total 77 114 67.5


line stmt bran cond sub pod time code
1             package Term::ANSIColor::Print;
2              
3             $VERSION = '0.08';
4              
5 1     1   22946 use strict;
  1         3  
  1         36  
6 1     1   5 use warnings;
  1         1  
  1         27  
7 1     1   5 use Carp;
  1         5  
  1         87  
8 1     1   5 use vars qw( $AUTOLOAD );
  1         2  
  1         76  
9              
10             my ( $COLOR_REGEX, $SUB_COLOR_REGEX, %ANSI_CODE_FOR );
11             {
12 1     1   35203 use Readonly;
  1         9370  
  1         2579  
13              
14             Readonly $COLOR_REGEX => qr{
15             \A ( . \[\d+m .*? . \[0m ) \z
16             }xms;
17              
18             Readonly $SUB_COLOR_REGEX => qr{
19             \A ( .+? )
20             ( . \[\d+m .* . \[0m )
21             (?! . \[0m )
22             ( .+ ) \z
23             }xms;
24              
25             # http://en.wikipedia.org/wiki/ANSI_escape_code
26             Readonly %ANSI_CODE_FOR => (
27             black => 30,
28             blue => 94,
29             bold => 1,
30             cyan => 96,
31             green => 92,
32             grey => 37,
33             magenta => 95,
34             red => 91,
35             white => 97,
36             yellow => 93,
37             conceal => 8,
38             faint => 2,
39             italic => 3,
40             negative => 7,
41             positive => 27,
42             reset => 0,
43             reveal => 28,
44             underline => 4,
45             normal => {
46             foreground => 39,
47             background => 99,
48             },
49             blink => {
50             slow => 5,
51             rapid => 6,
52             },
53             light => {
54             black => 90,
55             },
56             double => {
57             underline => 21,
58             },
59             normal => {
60             intensity => 22,
61             },
62             no => {
63             underline => 24,
64             blink => 25,
65             },
66             dark => {
67             red => 31,
68             green => 32,
69             yellow => 33,
70             blue => 34,
71             magenta => 35,
72             cyan => 36,
73             },
74             on => {
75             red => 101,
76             green => 102,
77             yellow => 103,
78             blue => 104,
79             magenta => 105,
80             cyan => 106,
81             white => 107,
82             normal => 109,
83             black => 40,
84             grey => 47,
85             light => {
86             black => 100,
87             },
88             dark => {
89             red => 41,
90             green => 42,
91             yellow => 43,
92             blue => 44,
93             magenta => 45,
94             cyan => 46,
95             normal => 49,
96             },
97             },
98             );
99             }
100              
101             sub new {
102 1     1 0 17 my $class = shift;
103 1         6 my %args = @_;
104              
105 1 50       73 my $self = bless {
    50          
    50          
    50          
106             output => defined $args{output} ? $args{output} : \*STDOUT,
107             eol => defined $args{eol} ? $args{eol} : "\n",
108             pad => defined $args{pad} ? $args{pad} : "",
109             alias => defined $args{alias} ? $args{alias} : {},
110             }, $class;
111              
112 1         5 delete @args{qw( output eol pad alias )};
113              
114 1         3647 for my $arg ( keys %args ) {
115 0         0 warn "unrecognized argument $arg";
116             }
117              
118 1         10 return $self;
119             }
120              
121             sub AUTOLOAD {
122 4     4   3683 my ($self,@strings) = @_;
123              
124 4         42 my $method = ( split /::/, $AUTOLOAD )[-1];
125              
126 8         294 ALIAS:
127 4         10 while ( my ( $alias, $token ) = each %{ $self->{alias} } ) {
128              
129 4 50       31 if ( $token !~ m{\A \w+ \z}xms ) {
130              
131 0         0 carp "alias '$alias': token '$token' is invalid\n";
132 0         0 next ALIAS;
133             }
134              
135 4 50       138 if ( $alias !~ m{\A \w+ \z}xms ) {
136              
137 0         0 carp "alias key '$alias' is a invalid\n";
138 0         0 next ALIAS;
139             }
140              
141 4         45 $method =~ s{$alias}{$token}g;
142             }
143              
144 4 100       27 my $eol = $method =~ s{ _+ \z}{}xms ? "" : $self->{eol};
145              
146 4         18 my @tokens = split /_/, $method;
147              
148 4         9 my $color_start = "";
149 4         7 my $color_end = "\x{1B}[0m";
150              
151 4         7 my $code_for_rh = \%ANSI_CODE_FOR;
152              
153             TOK:
154 4         12 for my $token (@tokens) {
155              
156 12         61 my $code = $code_for_rh->{$token};
157              
158 12 100       102 if ( ref $code eq 'HASH' ) {
159 5         9 $code_for_rh = $code;
160 5         12 next TOK;
161             }
162              
163 7 50       17 if ( not $code ) {
164              
165 0 0       0 if ( defined $ANSI_CODE_FOR{$token} ) {
166              
167 0         0 $code_for_rh = \%ANSI_CODE_FOR;
168 0         0 redo TOK;
169             }
170              
171 0         0 carp "unrecognized token: $token";
172 0         0 next TOK;
173             }
174              
175 7         24 $color_start .= "\x{1B}[${code}m";
176             }
177              
178 4         6 my @color_strings;
179              
180 4 50       10 @strings = map { ref $_ eq 'ARRAY' ? @{ $_ } : $_ } @strings;
  3         17  
  0         0  
181              
182 4         8 for my $string ( @strings ) {
183              
184             # pre text ESC sub text ESC end text
185 3 50       14 if ( $string =~ $SUB_COLOR_REGEX ) {
    50          
186              
187 0 0       0 my $pre
188             = $1
189             ? $color_start . $1 . $color_end
190             : "";
191              
192 0         0 my $sub = $2;
193              
194 0 0       0 my $end
195             = $3
196             ? $color_start . $3 . $color_end
197             : "";
198              
199 0         0 $string
200             = $pre
201             . $sub
202             . $end;
203             }
204              
205             # no color ESC
206             elsif ( $string !~ $COLOR_REGEX ) {
207              
208 3         56 $string
209             = $color_start
210             . $string
211             . $color_end;
212             }
213              
214             # else ESC text ESC
215              
216 3         11 push @color_strings, $string;
217             }
218              
219 4 100       12 if ( @strings ) {
220              
221 3         7 $strings[-1] .= $eol;
222             }
223             else {
224              
225 1         3 push @strings, $eol;
226             }
227              
228 4         13 my $string = join $self->{pad}, @strings;
229              
230 4 50       14 if ( ref $self->{output} eq 'GLOB' ) {
231              
232 0         0 print { $self->{output} } $string;
  0         0  
233             }
234              
235 4         20 return $string;
236             }
237              
238             sub DESTROY {
239 0     0     return;
240             }
241              
242             1;