File Coverage

blib/lib/Term/ANSIColor/Markup/Parser.pm
Criterion Covered Total %
statement 47 47 100.0
branch 12 12 100.0
condition n/a
subroutine 10 10 100.0
pod 4 6 66.6
total 73 75 97.3


line stmt bran cond sub pod time code
1             package Term::ANSIColor::Markup::Parser;
2 4     4   20 use strict;
  4         9  
  4         136  
3 4     4   21 use warnings;
  4         7  
  4         161  
4 4     4   22 use Carp qw(croak);
  4         7  
  4         267  
5 4         2649 use base qw(
6             HTML::Parser
7             Class::Accessor::Lvalue::Fast
8 4     4   22 );
  4         12  
9              
10             # copied from Term::ANSIColor
11             our %TAGS = (
12             clear => 0,
13             reset => 0,
14             bold => 1,
15             dark => 2,
16             faint => 2,
17             underline => 4,
18             underscore => 4,
19             blink => 5,
20             reverse => 7,
21             concealed => 8,
22              
23             black => 30, on_black => 40,
24             red => 31, on_red => 41,
25             green => 32, on_green => 42,
26             yellow => 33, on_yellow => 43,
27             blue => 34, on_blue => 44,
28             magenta => 35, on_magenta => 45,
29             cyan => 36, on_cyan => 46,
30             white => 37, on_white => 47,
31             );
32              
33             __PACKAGE__->mk_accessors(qw(result stack));
34              
35             sub new {
36 9     9 1 16 my $class = shift;
37 9         66 my $self = $class->SUPER::new(@_);
38 9         665 $self->result = '';
39 9         140 $self->stack = [];
40 9         93 $self;
41             }
42              
43             sub start {
44 23     23 1 104 my ($self, $tagname, $attr, $attrseq, $text) = @_;
45 23 100       54 if (my $escape_sequence = $self->get_escape_sequence($tagname)) {
46 21         29 push @{$self->stack}, $tagname;
  21         60  
47 21         137 $self->result .= $escape_sequence;
48             }
49             else {
50 2         10 $self->result .= $text;
51             }
52             }
53              
54             sub text {
55 59     59 1 496 my ($self, $text) = @_;
56 59         144 $self->result .= $self->unescape($text);
57             }
58              
59             sub end {
60 25     25 1 45 my ($self, $tagname, $text) = @_;
61 25 100       50 if (my $color = $self->get_escape_sequence($tagname)) {
62 21         28 my $top = pop @{$self->stack};
  21         62  
63 21 100       180 croak "Invalid end tag was found: $text" if $top ne $tagname;
64 20         63 $self->result .= $self->get_escape_sequence('reset');
65 20 100       26 if (scalar @{$self->stack}) {
  20         55  
66 10         69 $self->result .= $self->get_escape_sequence($self->stack->[-1]);
67             }
68             }
69             else {
70 4         15 $self->result .= $text;
71             }
72             }
73              
74             sub get_escape_sequence {
75 78     78 0 213 my ($self, $name) = @_;
76 78         109 my $escape_sequence = '';
77 78         365 for my $key (keys %TAGS) {
78 1106 100       2087 if (lc $name eq lc $key) {
79 72         200 $escape_sequence = sprintf "\e[%dm", $TAGS{$key};
80 72         99 last;
81             }
82             }
83 78         357 $escape_sequence;
84             }
85              
86             sub unescape {
87 59     59 0 277 my ($self, $text) = @_;
88 59 100       160 return '' if !defined $text;
89 51         76 $text =~ s/</
90 51         59 $text =~ s/>/>/ig;
91 51         335 $text;
92             }
93              
94             1;