File Coverage

blib/lib/Text/Colorizer.pm
Criterion Covered Total %
statement 85 164 51.8
branch 8 46 17.3
condition 10 27 37.0
subroutine 14 25 56.0
pod 10 11 90.9
total 127 273 46.5


line stmt bran cond sub pod time code
1              
2             package Text::Colorizer ;
3              
4 2     2   42408 use strict;
  2         2  
  2         55  
5 2     2   7 use warnings ;
  2         3  
  2         45  
6 2     2   8 use Carp ;
  2         4  
  2         167  
7              
8             BEGIN
9             {
10              
11 2         15 use Sub::Exporter -setup =>
12             {
13             exports => [ qw() ],
14             groups =>
15             {
16             all => [ qw() ],
17             }
18 2     2   1234 };
  2         19883  
19            
20 2     2   680 use vars qw ($VERSION);
  2         3  
  2         78  
21 2     2   41 $VERSION = '0.03';
22             }
23              
24             #-------------------------------------------------------------------------------
25              
26 2     2   1260 use English qw( -no_match_vars ) ;
  2         8022  
  2         8  
27              
28 2     2   1536 use Readonly ;
  2         5130  
  2         99  
29             Readonly my $EMPTY_STRING => q{} ;
30              
31 2     2   8 use Carp qw(carp croak confess) ;
  2         2  
  2         69  
32 2     2   1196 use Term::ANSIColor qw(colored) ;
  2         9418  
  2         3999  
33              
34             #-------------------------------------------------------------------------------
35              
36             =head1 NAME
37              
38             Text::Colorizer - Create colored text from text and color descrition. An ANSI to HTML tranformation is provided
39              
40             =head1 SYNOPSIS
41              
42             my $c= Text::Colorizer->new
43             (
44             NAME => '' ,
45             INTERACTION =>
46             {
47             INFO => sub {print @_},
48             WARN => \&Carp::carp,
49             DIE => \&Carp::confess,
50             }
51            
52             FORMAT => 'HTML' | 'ANSI' |'ASCII',
53              
54             DEFAULT_COLOR => 'bright_white on_black',
55             COLORS =>
56             {
57             HTML =>
58             {
59             white => "color:#888;",
60             black => "color:#000;",
61             ...
62             }
63             ANSI => ...
64             ASCII => ...
65             }
66             ) ;
67              
68             # or
69            
70             my $c= Text::Colorizer->new() ;
71            
72             my $colored_text = $c->color
73             (
74             'red on_black' => 'string',
75             $color => [... many strings..],
76             'user_defined_color_name' => 'string'
77             ) ;
78              
79             =head1 DESCRIPTION
80              
81             This module defined methods to produce colored html from ANSI color description. The generated code use I
 tags.  
82             The generated HTML can be embeded in your pod documentation.
83              
84             =head1 DOCUMENTATION
85              
86             Valid colors:
87            
88             black red green yellow blue magenta cyan white
89            
90             bright_black bright_red bright_green bright_yellow
91             bright_blue bright_magenta bright_cyan bright_white
92              
93             on_black on_red on_green on yellow
94             on_blue on_magenta on_cyan on_white
95            
96             on_bright_black on_bright_red on_bright_green on_bright_yellow
97             on_bright_blue on_bright_magenta on_bright_cyan on_bright_white
98              
99             #256 colors terminals
100             rgbRGB on_rgbRGB
101             greyX on_greyX
102              
103             =head1 SUBROUTINES/METHODS
104              
105             =cut
106              
107              
108             #-------------------------------------------------------------------------------
109              
110             Readonly my $NEW_ARGUMENTS => [qw(NAME INTERACTION VERBOSE JOIN JOIN_FLAT FORMAT DEFAULT_COLOR COLORS)] ;
111              
112             sub new
113             {
114              
115             =head2 new(NAMED_ARGUMENTS)
116              
117             Create a Text::Colorizer object.
118              
119             my $c= Text::Colorizer->new() ;
120              
121             I - a list of pairs - Option => Value
122              
123             =over 2
124              
125             =item * NAME - String - Name of the Data::HexDump::Range object, set to 'Anonymous' by default
126              
127             =item * INTERACTION - Hash reference - Set of subs that are used to display information to the user
128              
129             Useful if you use Data::HexDump::Range in an application without terminal.
130              
131             =item * VERBOSE - Boolean - Display information about the creation of the object. Default is I
132              
133             =item * JOIN - String - string used to join colored elements. Default is an empty string.
134              
135             =item * JOIN_FLAT - String - string used to join colored elements passed in array references. Default is an empty string.
136              
137             =item * FORMAT - String - format of the dump string generated by Data::HexDump::Range.
138              
139             Default is B which allows for colors. Other formats are 'ASCII' and 'HTML'.
140              
141             =item * DEFAULT_COLOR - the color used if no color is defined
142              
143             DEFAULT_COLOR => {ANSI => 'bright_white', HTML => 'color:#aaa; '} ;
144              
145             =item * COLORS - A hash reference or a file name
146              
147             {
148             HTML =>
149             {
150             white => "color:#888;",
151             black => "color:#000;",
152             ...
153             }
154             ANSI => ...
155             ASCII => ...
156             }
157              
158             =back
159              
160             I - Text::Colorizer
161              
162             I - Dies if the color description are not valid
163              
164             =cut
165              
166 3     3 1 1118 my ($invocant, @setup_data) = @_ ;
167              
168 3   100     10 my $class = ref($invocant) || $invocant ;
169 3 100       21 confess 'Invalid constructor call!' unless defined $class ;
170              
171 2         2 my $object = {} ;
172              
173 2         5 my ($package, $file_name, $line) = caller() ;
174 2         25 bless $object, $class ;
175              
176 2         5 $object->Setup($package, $file_name, $line, @setup_data) ;
177              
178 2         5 return($object) ;
179             }
180              
181             #-------------------------------------------------------------------------------
182              
183             sub Setup
184             {
185              
186             =head2 Setup
187              
188             Helper sub called by new. This is a private sub.
189              
190             =cut
191              
192 2     2 1 2 my ($self, $package, $file_name, $line, @setup_data) = @_ ;
193              
194 2 50       5 if (@setup_data % 2)
195             {
196 0         0 croak "Invalid number of argument '$file_name, $line'!" ;
197             }
198              
199 2         2 my %valid_argument = map {$_ => 1} @{$NEW_ARGUMENTS} ;
  16         29  
  2         7  
200              
201 2         7 $self->CheckOptionNames(\%valid_argument, @setup_data) ;
202              
203 2         10 %{$self} =
  2         9  
204             (
205             NAME => 'Anonymous',
206             FILE => $file_name,
207             LINE => $line,
208            
209             JOIN => $EMPTY_STRING,
210             JOIN_FLAT => $EMPTY_STRING,
211            
212             FORMAT => 'ANSI',
213             DEFAULT_COLOR => {ANSI => 'bright_white', HTML => 'color:#fff; '},
214            
215             COLORS => {ANSI => {}, HTML => {}},
216              
217             @setup_data,
218             ) ;
219              
220 2   50 0   23 $self->{INTERACTION}{INFO} ||= sub {print @_} ;
  0         0  
221 2   50     13 $self->{INTERACTION}{WARN} ||= \&Carp::carp ;
222 2   50     7 $self->{INTERACTION}{DIE} ||= \&Carp::croak ;
223              
224             #default colors
225 2         3 my $default_colors = GetDefaultColors() ;
226              
227             #lookup colors for user
228 2         4 while (my ($k, $v) = each %{$self->{COLORS}{ANSI}})
  2         11  
229             {
230 0 0       0 if($v =~ /^lookup:(.*)/)
231             {
232 0 0       0 if(exists $default_colors->{ANSI}{$1})
233             {
234 0         0 $self->{COLORS}{ANSI}{$k} = $default_colors->{ANSI}{$1} ;
235             }
236             else
237             {
238 0         0 $self->{INTERACTION}{DIE}("Can't lookup color '$1'.\n") ;
239             }
240             }
241             }
242              
243 2         1 while (my ($k, $v) = each %{$self->{COLORS}{HTML}})
  2         6  
244             {
245 0 0       0 if($v =~ /^lookup:(.*)/)
246             {
247 0 0       0 if(exists $default_colors->{HTML}{$1})
248             {
249 0         0 $self->{COLORS}{HTML}{$k} = $default_colors->{HTML}{$1} ;
250             }
251             else
252             {
253 0         0 $self->{INTERACTION}{DIE}("Can't lookup color '$1'.\n") ;
254             }
255             }
256             }
257              
258             #add default colors not set by user
259              
260 2         2 $self->{COLORS}{ANSI} = { %{$default_colors->{ANSI}}, %{$self->{COLORS}{ANSI}} } ;
  2         64  
  2         216  
261 2         36 $self->{COLORS}{HTML} = { %{$default_colors->{HTML}}, %{$self->{COLORS}{HTML}} } ;
  2         59  
  2         150  
262              
263 2         29 my $location = "$self->{FILE}:$self->{LINE}" ;
264              
265 2 50       5 if($self->{VERBOSE})
266             {
267 0         0 $self->{INTERACTION}{INFO}('Creating ' . ref($self) . " '$self->{NAME}' at $location.\n") ;
268             }
269              
270 2 50 33     11 if(defined $self->{COLORS} && 'HASH' ne ref $self->{COLORS})
271             {
272             my $colors = do $self->{COLORS}
273 0 0       0 or $self->{INTERACTION}{DIE}("Can't load color file '$self->{COLORS}'.\n") ;
274            
275             'HASH' eq ref $colors
276 0 0       0 or $self->{INTERACTION}{DIE}("Invalid color file '$self->{COLORS}'.\n") ;
277            
278 0         0 $self->{COLORS} = $colors ;
279             }
280              
281 2         105 return ;
282             }
283              
284             #-------------------------------------------------------------------------------
285              
286             sub GetDefaultColors
287             {
288              
289             =head2 GetDefaultColor
290              
291             =cut
292              
293 2     2 0 1 my (@ansi_rgb, @ansi_on_rgb, @html_rgb, @html_on_rgb) ;
294 2         5 for my $blue (0 .. 5)
295             {
296 12         12 for my $green (0 .. 5)
297             {
298 72         56 for my $red (0 .. 5)
299             {
300 432         538 push @ansi_rgb, "rgb$red$green$blue" => "rgb$red$green$blue" ;
301 432         504 push @ansi_on_rgb, "on_rgb$red$green$blue" => "on_rgb$red$green$blue" ;
302              
303 432         502 push @html_rgb, "rgb$red$green$blue" => "color:#$red$green$blue; " ;
304 432         631 push @html_on_rgb, "on_rgb$red$green$blue" => "background-color:#$red$green$blue; " ;
305             }
306             }
307             }
308            
309              
310 2         3 my (@ansi_greys, @ansi_on_greys, @html_greys, @html_on_greys) ;
311 2         2 for my $grey (0 .. 15)
312             {
313 32         38 push @ansi_greys, "grey$grey" => "grey$grey" ;
314 32         39 push @ansi_on_greys, "on_grey$grey" => "on_grey$grey" ;
315              
316 32         33 my $hex = sprintf("%x",$grey) ;
317 32         50 push @html_greys, "grey$grey" => "color:#$hex$hex$hex; " ;
318 32         54 push @html_on_greys, "on_grey$grey" => "background-color:#$hex$hex$hex; " ;
319             }
320              
321             return
322             {
323 2         620 ANSI =>
324             {
325             # you can defined aliases too
326             # alarm => 'bright_red on_bright_yellwo',
327             reset => 'reset',
328            
329             white => 'white',
330             black => 'black',
331             green => 'green',
332             yellow => 'yellow',
333             cyan => 'cyan',
334             red => 'red',
335             blue => 'blue',
336             magenta => 'magenta',
337            
338             bright_white => 'bright_white',
339             bright_black => 'bright_black',
340             bright_green => 'bright_green',
341             bright_yellow => 'bright_yellow',
342             bright_cyan => 'bright_cyan',
343             bright_red => 'bright_red',
344             bright_blue => 'bright_blue',
345             bright_magenta => 'bright_magenta',
346            
347             on_white => 'on_white',
348             on_black => 'on_black',
349             on_green => 'on_green',
350             on_yellow => 'on_yellow',
351             on_cyan => 'on_cyan',
352             on_red => 'on_red',
353             on_blue => 'on_blue',
354             on_magenta => 'on_magenta',
355            
356             on_bright_white => 'on_bright_white',
357             on_bright_black => 'on_bright_black',
358             on_bright_green => 'on_bright_green',
359             on_bright_yellow => 'on_bright_yellow',
360             on_bright_cyan => 'on_bright_cyan',
361             on_bright_red => 'on_bright_red',
362             on_bright_blue => 'on_bright_blue',
363             on_bright_magenta => 'on_bright_magenta',
364             @ansi_rgb,
365             @ansi_on_rgb,
366             @ansi_greys,
367             @ansi_on_greys,
368             },
369            
370             HTML =>
371             {
372             # any attribute you can put in a span
373             reset => '',
374            
375             white => 'color:#aaa; ',
376             black => 'color:#000; ',
377             green => 'color:#0a0; ',
378             yellow => 'color:#aa0; ',
379             cyan => 'color:#0aa; ',
380             red => 'color:#a00; ',
381             blue => 'color:#00a; ',
382             magenta => 'color:#a0a; ',
383            
384             bright_white => 'color:#fff; ',
385             bright_black => 'color:#000; ',
386             bright_green => 'color:#0f0; ',
387             bright_yellow => 'color:#ff0; ',
388             bright_cyan => 'color:#0ff; ',
389             bright_red => 'color:#f00; ',
390             bright_blue => 'color:#00f; ',
391             bright_magenta => 'color:#f0f; ',
392              
393             on_white => 'background-color:#aaa; ',
394             on_black => 'background-color:#000; ',
395             on_green => 'background-color:#0a0; ',
396             on_yellow => 'background-color:#aa0; ',
397             on_cyan => 'background-color:#0aa; ',
398             on_red => 'background-color:#a00; ',
399             on_blue => 'background-color:#00a; ',
400             on_magenta => 'background-color:#a0a; ',
401            
402             on_bright_white => 'background-color:#fff; ',
403             on_bright_black => 'background-color:#000; ',
404             on_bright_green => 'background-color:#0f0; ',
405             on_bright_yellow => 'background-color:#ff0; ',
406             on_bright_cyan => 'background-color:#0ff; ',
407             on_bright_red => 'background-color:#f00; ',
408             on_bright_blue => 'background-color:#00f; ',
409             on_bright_magenta => 'background-color:#f0f; ',
410              
411             @html_rgb,
412             @html_on_rgb,
413             @html_greys,
414             @html_on_greys,
415             },
416             } ;
417             }
418              
419              
420             #-------------------------------------------------------------------------------
421              
422             sub CheckOptionNames
423             {
424              
425             =head2 CheckOptionNames
426              
427             Verifies the named options passed to the members of this class. Calls B<{INTERACTION}{DIE}> in case
428             of error. This shall not be used directly.
429              
430             =cut
431              
432 2     2 1 3 my ($self, $valid_options, @options) = @_ ;
433              
434 2 50       3 if (@options % 2)
435             {
436 0         0 $self->{INTERACTION}{DIE}->('Invalid number of argument!') ;
437             }
438              
439 2 50       6 if('HASH' eq ref $valid_options)
    0          
440             {
441             # OK
442             }
443             elsif('ARRAY' eq ref $valid_options)
444             {
445 0         0 $valid_options = map{$_ => 1} @{$valid_options} ;
  0         0  
  0         0  
446             }
447             else
448             {
449 0         0 $self->{INTERACTION}{DIE}->("Invalid argument '$valid_options'!") ;
450             }
451              
452 2         3 my %options = @options ;
453              
454 2         5 for my $option_name (keys %options)
455             {
456 0 0       0 unless(exists $valid_options->{$option_name})
457             {
458 0         0 $self->{INTERACTION}{DIE}->("$self->{NAME}: Invalid Option '$option_name' at '$self->{FILE}:$self->{LINE}'!") ;
459             }
460             }
461              
462 2 50 33     14 if
      33        
      33        
463             (
464             (defined $options{FILE} && ! defined $options{LINE})
465             || (!defined $options{FILE} && defined $options{LINE})
466             )
467             {
468 0         0 $self->{INTERACTION}{DIE}->("$self->{NAME}: Incomplete option FILE::LINE!") ;
469             }
470              
471 2         3 return(1) ;
472             }
473              
474             #-------------------------------------------------------------------------------
475              
476             sub get_colors
477             {
478              
479             =head2 get_colors( )
480              
481             Returns the colors defined in the object
482              
483             my $colors = $c->get_colors( ) ;
484              
485             I - None
486              
487             I - A hash reference
488              
489             I - None
490              
491             =cut
492              
493 0     0 1   my ($self) = @_ ;
494              
495 0           return $self->{COLORS} ;
496             }
497              
498             #-------------------------------------------------------------------------------
499              
500             sub set_colors
501             {
502              
503             =head2 set_colors(\%colors)
504              
505             Copies
506              
507             my %colors =
508             (
509             HTML =>
510             {
511             white => "style='color:#888;'",
512             black => "style='color:#000;'",
513             ...
514             bright_white => "style='color:#fff;'",
515             bright_black => "style='color:#000;'",
516             bright_green => "style='color:#0f0;'",
517             ...
518             }
519             ) ;
520            
521             $c->set_color(\%colors) ;
522              
523             I
524              
525             =over 2
526              
527             =item * \%colors - A hash reference
528              
529             =back
530              
531             I - Nothing
532              
533             I - dies if the color definitions are invalid
534              
535             =cut
536              
537 0     0 1   my ($self, $colors) = @_ ;
538              
539 0           $self->{COLORS} = $colors ;
540              
541 0           return ;
542             }
543              
544             #-------------------------------------------------------------------------------
545              
546             sub flatten
547             {
548            
549             =head2 [P] flatten($scalar || \@array)
550              
551             Transforms array references to a flat list
552              
553             I -
554              
555             =over 2
556              
557             =item * $scalar -
558              
559             =back
560              
561             I - a lsit of scalars
562              
563             =cut
564              
565             map
566             {
567 0     0 1   my $description = $_ ;
  0            
568            
569 0 0         if(ref($description) eq 'ARRAY')
570             {
571 0           flatten(@{$description}) ;
  0            
572             }
573             else
574             {
575 0           $description
576             }
577             } @_
578             }
579              
580             #-------------------------------------------------------------------------------
581              
582             sub color
583             {
584              
585             =head2 color($color_name, $text, $color_name, \@many_text_strings, ...) ;
586              
587             Returns colored text. according to the object setting. Default is HTML color coded.
588              
589             my $colored_text = $c->color
590             (
591             'red on_black' => 'string',
592             $color => [... many strings..]
593             'user_defined_color_name' => 'string'
594             ) ;
595            
596             I - A list of colors and text pairs
597              
598             =over 2
599              
600             =item * $color -
601              
602             =item * $text -
603              
604             =back
605              
606             I - A single string
607              
608             I - Dies if the color is invalid
609              
610             =cut
611              
612 0     0 1   my ($self) = shift @_ ;
613              
614 0           my ($header, $footer, $colorizer) = ('', '') ;
615              
616 0           my %ascii_to_html =
617             (
618             '<' => '<',
619             '>' => '>',
620             '&' => '&',
621             "'" => ''',
622             '"' => '"',
623             ) ;
624              
625 0           for ($self->{FORMAT})
626             {
627             /ASCII/ and do
628 0 0         {
629             $colorizer =
630             sub
631             {
632             #~ my ($text, $color) = @_ ;
633             #~ return $text ;
634            
635 0     0     $_[0] ;
636 0           } ;
637            
638 0           last ;
639             } ;
640            
641             /ANSI/ and do
642 0 0         {
643 0 0 0 0     $colorizer = sub { my ($text, $color) = @_ ; (defined $color && $color ne '') ? colored($text, $color) : $text ; } ;
  0            
  0            
644            
645 0           last ;
646             } ;
647            
648             /HTML/ and do
649 0 0         {
650 0           $header = qq~
\n~ ; 
651             $colorizer =
652             sub
653             {
654 0     0     my ($text, $color) = @_ ;
655            
656 0           $text =~ s/(<|>|&|\'|\")/$ascii_to_html{$1}/eg ;
  0            
657            
658 0           "" . $text . "" ;
659 0           } ;
660            
661 0           $footer .= "\n\n" ;
662            
663 0           last ;
664             } ;
665            
666 0           $self->{INTERACTION}{DIE}("Error: Invalid format '$self->{FORMAT}'.\n");
667             }
668              
669 0 0         $self->{INTERACTION}{DIE}("Error: number of elements in argument list'.\n") if @_ % 2 ;
670              
671 0           my @formated ;
672              
673 0           while(@_)
674             {
675 0           my ($color_tag, $text) = (shift, shift) ;
676 0           my $colors = $self->{DEFAULT_COLOR}{$self->{FORMAT}} ;
677            
678 0 0 0       if(defined $color_tag && $self->{FORMAT} ne 'ASCII')
679             {
680 0           for my $color_tag_component (split /\s+/, $color_tag)
681             {
682 0           $color_tag_component =~ s/\s+//g ;
683            
684 0           my $color = $self->{COLORS}{$self->{FORMAT}}{$color_tag_component} ;
685            
686 0 0         $self->{INTERACTION}{DIE}("Error: Invalid color component '$self->{FORMAT}::$color_tag_component'.\n") unless defined $color ;
687            
688 0           $colors .= ' ' . $color ;
689             }
690             }
691            
692 0           push @formated, join $self->{JOIN_FLAT}, map {$colorizer->($_, $colors)} flatten($text) ;
  0            
693             }
694              
695 0           return $header . join($self->{JOIN}, @formated) . $footer ;
696             }
697              
698             #-------------------------------------------------------------------------------
699              
700             sub color_all
701             {
702              
703             =head2 color_all($color, $string, \@many_text_strings, ...)
704              
705             Uses a single color to colorize all the strings
706              
707             my $colored_text = $c->color_all($color, $string, \@many_text_strings, ...) ;
708              
709             I
710              
711             =over 2
712              
713             =item * $xxx -
714              
715             =back
716              
717             I - Nothing
718              
719             I
720              
721             =cut
722              
723 0     0 1   my ($self, $color) = (shift @_, shift @_) ;
724              
725             #todo: verify colors
726              
727 0           return $self->color(map{$color, $_} @_) ;
  0            
728             }
729              
730             #-------------------------------------------------------------------------------
731              
732             sub color_with
733             {
734              
735             =head2 color_with(\%color_definitions, 'color' => 'text', $color => \@many_text_strings, ...) ;
736              
737             Colors a text, temporarely overridding the colors defined in the object.
738              
739             my %colors =
740             {
741             HTML =>
742             {
743             white => "style='color:#888;'",
744             black => "style='color:#000;'",
745             ...
746             bright_white => "style='color:#fff;'",
747             bright_black => "style='color:#000;'",
748             bright_green => "style='color:#0f0;'",
749             ...
750             }
751             },
752            
753             my $colored_text = $c->color_with
754             (
755             \%colors,
756             'red on_black' => 'string',
757             'blue on_yellow' => [... many strings..]
758             'user_defined_color_name' => 'string'
759             ) ;
760              
761             I
762              
763             =over 2
764              
765             =item * $ -
766              
767             =item * $color -
768              
769             =item * $xxx -
770              
771             =back
772              
773             I - Nothing
774              
775             I - Dies if any argument is invalid
776              
777             =cut
778              
779 0     0 1   my ($self, $colors) = (shift @_, shift @_) ;
780              
781 0           local $self->{COLORS} = $colors ;
782 0           return $self->color(@_) ;
783             }
784              
785             #-------------------------------------------------------------------------------
786              
787             sub color_all_with
788             {
789              
790             =head2 color_all_with($temporary_colors, $color, $text | \@many_text_string, ...) ;
791              
792             Uses a single color to colorize all the strings, using a temporary color definition
793              
794             my $temporary_colors =
795             {
796             HTML =>
797             {
798             white => "style='color:#888;'",
799             black => "style='color:#000;'",
800             ...
801             bright_white => "style='color:#fff;'",
802             bright_black => "style='color:#000;'",
803             bright_green => "style='color:#0f0;'",
804             ...
805             }
806             },
807            
808             my $colored_text = $c->color_all_with($temporary_colors, $color, 'string', [... many strings..], ...) ;
809              
810             I
811              
812             =over 2
813              
814             =item * $xxx -
815              
816             =back
817              
818             I - A colorized string
819              
820             I Dies if invalid input is received
821              
822             =cut
823              
824 0     0 1   my ($self, $colors) = (shift @_, shift @_) ;
825              
826 0           local $self->{COLORS} = $colors ;
827 0           return $self->color_all(@_) ;
828             }
829              
830             #-------------------------------------------------------------------------------
831              
832             1 ;
833              
834             =head1 BUGS AND LIMITATIONS
835              
836             None so far.
837              
838             =head1 AUTHOR
839              
840             Nadim ibn hamouda el Khemir
841             CPAN ID: NKH
842             mailto: nadim@cpan.org
843              
844             =head1 COPYRIGHT & LICENSE
845              
846             Copyright 2010 Nadim Khemir.
847              
848             This program is free software; you can redistribute it and/or
849             modify it under the terms of either:
850              
851             =over 4
852              
853             =item * the GNU General Public License as published by the Free
854             Software Foundation; either version 1, or (at your option) any
855             later version, or
856              
857             =item * the Artistic License version 2.0.
858              
859             =back
860              
861             =head1 SUPPORT
862              
863             You can find documentation for this module with the perldoc command.
864              
865             perldoc Text::Colorizer
866              
867             You can also look for information at:
868              
869             =over 4
870              
871             =item * AnnoCPAN: Annotated CPAN documentation
872              
873             L
874              
875             =item * RT: CPAN's request tracker
876              
877             Please report any bugs or feature requests to L .
878              
879             We will be notified, and then you'll automatically be notified of progress on
880             your bug as we make changes.
881              
882             =item * Search CPAN
883              
884             L
885              
886             =back
887              
888             =head1 SEE ALSO
889              
890             L
891              
892             =cut