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   479 use strict;
  1         8  
  1         57  
4              
5             require HTML::PullParser;
6             our @ISA = qw(HTML::PullParser);
7             our $VERSION = '3.81';
8              
9 1     1   6 use Carp ();
  1         2  
  1         28  
10 1     1   419 use HTML::Entities qw(decode_entities);
  1         5  
  1         63  
11 1     1   437 use HTML::Tagset ();
  1         1302  
  1         992  
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 5293 my $class = shift;
30 10         17 my %cnf;
31              
32 10 50       26 if (@_ == 1) {
33 10 100       26 my $type = (ref($_[0]) eq "SCALAR") ? "doc" : "file";
34 10         26 %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     57 my $textify = delete $cnf{textify} || {img => "alt", applet => "alt"};
42              
43 10   100     52 my $self = $class->SUPER::new(%ARGS, %cnf) || return undef;
44              
45 9         19 $self->{textify} = $textify;
46 9         27 $self;
47             }
48              
49              
50             sub get_tag
51             {
52 43     43 1 1581 my $self = shift;
53 43         56 my $token;
54 43         52 while (1) {
55 117   100     212 $token = $self->get_token || return undef;
56 115         157 my $type = shift @$token;
57 115 100 100     296 next unless $type eq "S" || $type eq "E";
58 57 100       100 substr($token->[0], 0, 0) = "/" if $type eq "E";
59 57 100       112 return $token unless @_;
60 21         32 for (@_) {
61 24 100       65 return $token if $token->[0] eq $_;
62             }
63             }
64             }
65              
66              
67             sub _textify {
68 10     10   18 my($self, $token) = @_;
69 10         16 my $tag = $token->[1];
70 10 100       30 return undef unless exists $self->{textify}{$tag};
71              
72 1         33 my $alt = $self->{textify}{$tag};
73 1         22 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       4 $text = "[\U$tag]" unless defined $text;
79             }
80 1         4 return $text;
81             }
82              
83              
84             sub get_text
85             {
86 5     5 1 8 my $self = shift;
87 5         7 my @text;
88 5         11 while (my $token = $self->get_token) {
89 19         31 my $type = $token->[0];
90 19 100       56 if ($type eq "T") {
    100          
91 9         15 my $text = $token->[1];
92 9 50       41 decode_entities($text) unless $token->[2];
93 9         28 push(@text, $text);
94             } elsif ($type =~ /^[SE]$/) {
95 9         23 my $tag = $token->[1];
96 9 100       18 if ($type eq "S") {
97 5 100       10 if (defined(my $text = _textify($self, $token))) {
98 1         3 push(@text, $text);
99 1         5 next;
100             }
101             } else {
102 4         9 $tag = "/$tag";
103             }
104 8 100 100     34 if (!@_ || grep $_ eq $tag, @_) {
105 5         20 $self->unget_token($token);
106 5         11 last;
107             }
108             push(@text, " ")
109 3 100 66     20 if $tag eq "br" || !$HTML::Tagset::isPhraseMarkup{$token->[1]};
110             }
111             }
112 5         18 join("", @text);
113             }
114              
115              
116             sub get_trimmed_text
117             {
118 4     4 1 14 my $self = shift;
119 4         10 my $text = $self->get_text(@_);
120 4         17 $text =~ s/^\s+//; $text =~ s/\s+$//; $text =~ s/\s+/ /g;
  4         19  
  4         16  
121 4         19 $text;
122             }
123              
124             sub get_phrase {
125 3     3 1 516 my $self = shift;
126 3         5 my @text;
127 3         9 while (my $token = $self->get_token) {
128 19         27 my $type = $token->[0];
129 19 100       50 if ($type eq "T") {
    50          
130 9         14 my $text = $token->[1];
131 9 50       32 decode_entities($text) unless $token->[2];
132 9         27 push(@text, $text);
133             } elsif ($type =~ /^[SE]$/) {
134 10         18 my $tag = $token->[1];
135 10 100       19 if ($type eq "S") {
136 5 50       8 if (defined(my $text = _textify($self, $token))) {
137 0         0 push(@text, $text);
138 0         0 next;
139             }
140             }
141 10 100       29 if (!$HTML::Tagset::isPhraseMarkup{$tag}) {
142 3         8 $self->unget_token($token);
143 3         5 last;
144             }
145 7 100       23 push(@text, " ") if $tag eq "br";
146             }
147             }
148 3         9 my $text = join("", @text);
149 3         9 $text =~ s/^\s+//; $text =~ s/\s+$//; $text =~ s/\s+/ /g;
  3         10  
  3         14  
150 3         21 $text;
151             }
152              
153             1;
154              
155              
156             __END__