File Coverage

blib/lib/HTML/Highlight.pm
Criterion Covered Total %
statement 92 99 92.9
branch 28 40 70.0
condition 3 9 33.3
subroutine 10 11 90.9
pod 2 3 66.6
total 135 162 83.3


line stmt bran cond sub pod time code
1              
2             package HTML::Highlight;
3              
4 1     1   1710 use locale;
  1         253  
  1         5  
5              
6 1     1   30 use strict;
  1         2  
  1         32  
7 1     1   6 use Carp;
  1         5  
  1         96  
8              
9             BEGIN {
10 1     1   6 use vars qw ($VERSION @ISA);
  1         1  
  1         72  
11 1     1   2 $VERSION = 0.20;
12 1         1200 @ISA = ();
13             }
14              
15 1     1   169 END { }
16              
17             my $MIN_SECTION_LENGTH = 60;
18             my $DEFAULT_SECTION_LENGTH = 80;
19              
20             sub new {
21 1     1 0 51 $_ = shift;
22 1   33     6 my $class = ref($_) || $_;
23              
24 1 50       5 croak ('HTML::Highlight - even number of parameters expected.')
25             if (@_ % 2);
26              
27             # set the defaults
28 1         22 my $self = {
29             words => [],
30             wildcards => [],
31             colors => [
32             '#ffff66',
33             '#A0FFFF',
34             '#99ff99',
35             '#ff9999',
36             '#ff66ff'
37             ],
38             czech_language => 0,
39             debug => 0
40             };
41              
42 1         4 bless ($self, $class);
43              
44             # get parameters, overiding the defaults
45 1         5 for (my $i = 0; $i <= $#_; $i += 2) {
46 4 50       17 exists ( $self->{lc($_[$i])} ) or
47             croak ('HTML::Highlight - invalid parameter ' . $_[$i] . '.');
48 4         19 $self->{lc($_[$i])} = $_[($i + 1)];
49             }
50              
51 1 50 33     11 croak ('HTML::Highlight - "words" and "wildcards" parameters must be references to arrays')
52             if (ref($self->{words}) ne 'ARRAY' or ref($self->{wildcards}) ne 'ARRAY');
53              
54 1 50       11 require CzFast if ($self->{czech_language});
55              
56 1         4 return $self;
57             }
58              
59              
60             sub highlight {
61 1     1 1 6 my $self = shift;
62 1         2 my $document = shift;
63              
64 1 50       5 croak ('HTML::Highlight - no document defined')
65             if (not defined($document));
66 1 50       5 return '' if (length($document) == 0);
67              
68 1         2 my $doc = $document;
69              
70 1         3 for (my $i = 0, my $cindex = 0; $i < @{$self->{words}}; $i++, $cindex++) {
  5         16  
71 4         5 my $color;
72             my $out;
73 4 100       11 if ($self->{colors}->[$cindex]) {
74 3         5 $color = $self->{colors}->[$cindex];
75             }
76             else {
77 1         1 $cindex = 0;
78 1         5 $color = $self->{colors}->[$cindex];
79             }
80 4         10 while($doc) {
81 44 100       174 if ($doc !~ /(.*?)(<.*?>)(.*)/s) {
82 4         10 $out .= $self->_highlight($doc, $i, $color);
83 4         7 last;
84             }
85             else {
86 40         68 my $str = $1;
87 40         62 my $html = $2;
88 40         173 my $rest = $3;
89 40         86 $out .= $self->_highlight($str, $i, $color);
90 40         59 $out .= $html;
91 40         119 $doc = $rest;
92             }
93             }
94 4         11 $doc = $out;
95             }
96              
97 1         5 return $doc;
98             }
99              
100             sub preview_context {
101 1     1 1 44 my $self = shift;
102 1         2 my $document = shift;
103 1         34 my $sectlen = shift;
104              
105 1         4 $self->{context} = {};
106 1 50       6 $self->{sectlen} = $sectlen >= $MIN_SECTION_LENGTH ?
107             $sectlen : $DEFAULT_SECTION_LENGTH;
108 1         4 $self->{sections} = [];
109              
110 1         16 $document =~ s/<.*?>//g;
111              
112 1         3 for (my $i = 0; $i < @{$self->{words}}; $i++) {
  5         19  
113 4 50       15 my $pattern = $self->{czech_language} ?
114             &CzFast::czregexp($self->{words}->[$i]) :
115             $self->{words}->[$i];
116              
117 4         8 my $wildcard = $self->{wildcards}->[$i];
118 4         5 my $regexp;
119              
120 4 100       14 if ($wildcard eq '%') {
    100          
121 1         2 $regexp = "${pattern}\\w*";
122             }
123             elsif ($wildcard eq '*') {
124 1         3 $regexp = "${pattern}s?";
125             }
126             else {
127 2         4 $regexp = $pattern;
128             }
129              
130 4 100 33     17 if (not $self->{context}->{$pattern}
  4         45  
131             and not grep (/$regexp/i, values %{$self->{context}})) {
132 3         11 my $chars = int(($self->{sectlen} - length($pattern)) / 2);
133 3 50       9 print "Chars: $chars\n" if ($self->{debug});
134 3 100       714 if ($document =~ /(?:^|\W)(.{0,$chars})(\W+|^)($regexp)(\W+|$)(.{0,$chars})(?:\W|$)/six) {
135 2         12 my $section = $1.$2.$3.$4.$5;
136 2         7 $self->{context}->{$pattern} = $section;
137 2         3 push(@{$self->{sections}}, $section);
  2         10  
138             }
139             }
140             }
141              
142 1         4 return $self->{sections};
143             }
144              
145             #########################
146             #### private methods ####
147             #########################
148              
149             sub _highlight {
150 44     44   50 my $self = shift;
151 44         52 my $str = shift;
152 44         47 my $word = shift;
153 44         45 my $color = shift;
154              
155 44         70 my $pattern = $self->{words}->[$word];
156 44 50       89 $pattern = &CzFast::czregexp($pattern) if ($self->{czech_language});
157              
158 44         64 my $wildcard = $self->{wildcards}->[$word];
159 44         46 my $regexp;
160              
161 44 100       98 if ($wildcard eq '%') {
    100          
162 9 50       25 my $pat = $self->{czech_language} ? &_cz_pattern : '\w*';
163 9         13 $regexp = "${pattern}$pat";
164             }
165             elsif ($wildcard eq '*') {
166 13         20 $regexp = "${pattern}s?";
167             }
168             else {
169 22         32 $regexp = $pattern;
170             }
171              
172 44 50       92 print "$str: $pattern | $wildcard | $regexp | $color\n" if ($self->{debug});
173 44         501 $str =~ s!(\W+|^)($regexp)!$1$2!sig;
174 44         122 return $str;
175             }
176              
177             sub _cz_pattern {
178 0     0     my @chars;
179 0           my $pat = '(';
180 0           foreach my $char ('a'..'z') {
181 0           push(@chars, &CzFast::czregexp($char));
182             }
183 0           $pat .= join('|',@chars);
184 0           $pat .= ')*';
185 0           return $pat;
186             }
187              
188              
189             1;
190              
191             __END__