File Coverage

blib/lib/HTML/TokeParser.pm
Criterion Covered Total %
statement 85 90 94.4
branch 39 50 78.0
condition 14 17 82.3
subroutine 10 10 100.0
pod 5 5 100.0
total 153 172 88.9


line stmt bran cond sub pod time code
1             package HTML::TokeParser;
2              
3 1     1   397 use strict;
  1         5  
  1         44  
4              
5             require HTML::PullParser;
6             our @ISA = qw(HTML::PullParser);
7             our $VERSION = '3.79';
8              
9 1     1   4 use Carp ();
  1         2  
  1         22  
10 1     1   339 use HTML::Entities qw(decode_entities);
  1         2  
  1         82  
11 1     1   478 use HTML::Tagset ();
  1         1033  
  1         784  
12              
13             my %ARGS =
14             (
15             start => "'S',tagname,attr,attrseq,text",
16             end => "'E',tagname,text",
17             text => "'T',text,is_cdata",
18             process => "'PI',token0,text",
19             comment => "'C',text",
20             declaration => "'D',text",
21              
22             # options that default on
23             unbroken_text => 1,
24             );
25              
26              
27             sub new
28             {
29 10     10 1 4292 my $class = shift;
30 10         15 my %cnf;
31              
32 10 50       24 if (@_ == 1) {
33 10 100       26 my $type = (ref($_[0]) eq "SCALAR") ? "doc" : "file";
34 10         21 %cnf = ($type => $_[0]);
35             }
36             else {
37 0 0       0 unshift @_, (ref($_[0]) eq "SCALAR") ? "doc" : "file" if(scalar(@_) % 2 == 1);
    0          
38 0         0 %cnf = @_;
39             }
40              
41 10   50     48 my $textify = delete $cnf{textify} || {img => "alt", applet => "alt"};
42              
43 10   100     48 my $self = $class->SUPER::new(%ARGS, %cnf) || return undef;
44              
45 9         18 $self->{textify} = $textify;
46 9         20 $self;
47             }
48              
49              
50             sub get_tag
51             {
52 43     43 1 1227 my $self = shift;
53 43         39 my $token;
54 43         36 while (1) {
55 117   100     167 $token = $self->get_token || return undef;
56 115         117 my $type = shift @$token;
57 115 100 100     205 next unless $type eq "S" || $type eq "E";
58 57 100       83 substr($token->[0], 0, 0) = "/" if $type eq "E";
59 57 100       86 return $token unless @_;
60 21         23 for (@_) {
61 24 100       44 return $token if $token->[0] eq $_;
62             }
63             }
64             }
65              
66              
67             sub _textify {
68 10     10   14 my($self, $token) = @_;
69 10         13 my $tag = $token->[1];
70 10 100       23 return undef unless exists $self->{textify}{$tag};
71              
72 1         32 my $alt = $self->{textify}{$tag};
73 1         36 my $text;
74 1 50       5 if (ref($alt)) {
75 0         0 $text = &$alt(@$token);
76             } else {
77 1   50     5 $text = $token->[2]{$alt || "alt"};
78 1 50       3 $text = "[\U$tag]" unless defined $text;
79             }
80 1         4 return $text;
81             }
82              
83              
84             sub get_text
85             {
86 5     5 1 7 my $self = shift;
87 5         6 my @text;
88 5         11 while (my $token = $self->get_token) {
89 19         21 my $type = $token->[0];
90 19 100       47 if ($type eq "T") {
    100          
91 9         9 my $text = $token->[1];
92 9 50       38 decode_entities($text) unless $token->[2];
93 9         21 push(@text, $text);
94             } elsif ($type =~ /^[SE]$/) {
95 9         11 my $tag = $token->[1];
96 9 100       20 if ($type eq "S") {
97 5 100       10 if (defined(my $text = _textify($self, $token))) {
98 1         2 push(@text, $text);
99 1         5 next;
100             }
101             } else {
102 4         8 $tag = "/$tag";
103             }
104 8 100 100     28 if (!@_ || grep $_ eq $tag, @_) {
105 5         18 $self->unget_token($token);
106 5         7 last;
107             }
108             push(@text, " ")
109 3 100 66     16 if $tag eq "br" || !$HTML::Tagset::isPhraseMarkup{$token->[1]};
110             }
111             }
112 5         16 join("", @text);
113             }
114              
115              
116             sub get_trimmed_text
117             {
118 4     4 1 15 my $self = shift;
119 4         15 my $text = $self->get_text(@_);
120 4         14 $text =~ s/^\s+//; $text =~ s/\s+$//; $text =~ s/\s+/ /g;
  4         16  
  4         13  
121 4         10 $text;
122             }
123              
124             sub get_phrase {
125 3     3 1 393 my $self = shift;
126 3         3 my @text;
127 3         7 while (my $token = $self->get_token) {
128 19         22 my $type = $token->[0];
129 19 100       37 if ($type eq "T") {
    50          
130 9         9 my $text = $token->[1];
131 9 50       26 decode_entities($text) unless $token->[2];
132 9         22 push(@text, $text);
133             } elsif ($type =~ /^[SE]$/) {
134 10         11 my $tag = $token->[1];
135 10 100       15 if ($type eq "S") {
136 5 50       7 if (defined(my $text = _textify($self, $token))) {
137 0         0 push(@text, $text);
138 0         0 next;
139             }
140             }
141 10 100       18 if (!$HTML::Tagset::isPhraseMarkup{$tag}) {
142 3         7 $self->unget_token($token);
143 3         3 last;
144             }
145 7 100       19 push(@text, " ") if $tag eq "br";
146             }
147             }
148 3         9 my $text = join("", @text);
149 3         7 $text =~ s/^\s+//; $text =~ s/\s+$//; $text =~ s/\s+/ /g;
  3         8  
  3         8  
150 3         8 $text;
151             }
152              
153             1;
154              
155              
156             __END__