File Coverage

blib/lib/Regexp/HTMLify.pm
Criterion Covered Total %
statement 78 81 96.3
branch 22 34 64.7
condition 5 7 71.4
subroutine 11 11 100.0
pod 0 3 0.0
total 116 136 85.2


line stmt bran cond sub pod time code
1             # Regexp::HTMLify.pm
2              
3             # Copyright (c) 2008-2011 Niels van Dijke http://PerlBoy.net
4             # All rights reserved. This program is free software.
5             #
6             # You may distribute under the terms of either the GNU General Public
7             # License or the Artistic License, as specified in the Perl README file.
8              
9             package Regexp::HTMLify;
10              
11             require 5.008002;
12             require Exporter;
13 1     1   12440 use vars qw(@ISA @EXPORT);
  1         2  
  1         65  
14              
15 1     1   5 use strict;
  1         2  
  1         84  
16 1     1   7 use Carp 'croak';
  1         8  
  1         131  
17 1     1   2882 use CGI qw/:standard/;
  1         42902  
  1         6  
18              
19 1     1   3514 use vars qw($VERSION);
  1         2  
  1         81  
20             $VERSION = sprintf('%d.%03d', q$Revision: 0.002 $ =~ m#(\d+)\.(\d+)#);
21              
22 1     1   5 use vars qw($MAXCOLORS $CSS_COLORMAP);
  1         2  
  1         297  
23              
24             ###############################################################################
25             # prototypes
26             ###############################################################################
27             sub HTMLifyGetColormapCSS (;$$);
28             sub HTMLifyRE ($;\@$$);
29             sub HTMLifyREmatches ($;\@$$);
30              
31             @ISA = qw(Exporter);
32             @EXPORT = qw(
33             HTMLifyGetColormapCSS
34             HTMLifyRE
35             HTMLifyREmatches
36             );
37              
38             sub HTMLifyGetColormapCSS (;$$) {
39 2     2 0 502 my $fHandle = $_[0];
40 2 50       8 my $prefix = defined($_[1]) ? $_[1] : 'cDef';
41              
42 2         4 local $_;
43              
44 2 50       7 if (!defined $fHandle) {
45 2 100       7 if (!defined $CSS_COLORMAP) {
46 1         3 $fHandle = *Regexp::HTMLify::DATA;
47             } else {
48             # hide $CSS_COLORMAP and return cached version
49 1         6 return $CSS_COLORMAP;
50             }
51             }
52              
53 1         68 my @colorMap = <$fHandle>;
54 1 100 100     5 map { $MAXCOLORS++ if (/^\s*\.$prefix(\d+)\s*{/ and $1 > 0) } @colorMap;
  76         542  
55 1         9 $CSS_COLORMAP = join('',@colorMap);
56              
57 1         19 return $CSS_COLORMAP;
58             }
59              
60             sub _init {
61 1     1   90 return HTMLifyGetColormapCSS() ne '';
62             }
63              
64             # sub HTMLifyRE ($RegExp,[\@variables,$startColorIndex,$templateClass])
65             sub HTMLifyRE ($;\@$$) {
66 1     1 0 4 my $re = shift;
67 1   50     9 my $varnames = shift || [];
68 1 50       6 my $startColorIndex = defined $_[0] ? $_[0] : 1;
69 1 50       5 my $cssClass = defined $_[1] ? $_[1] : 'cDef';
70              
71 1         3 local $_;
72              
73             # perl 5.12 qr((.)) => '(?-xism:(.))'
74             # perl 5.14 qr((.)) => '(?:(.))'
75            
76             # No support for code execution in regexp
77 1     1   6 no re 'eval';
  1         1  
  1         608  
78 1         13 eval { my $tmpRe = qr($re)};
  1         7  
79 1 50       8 if ($@) {
80 0         0 croak("HTMLifyRE('\$regexp') => $@\n");
81             }
82              
83             # Check whether we support the given regexp
84 1 50       9 if ($re =~ m#\)[*+?{]#sm) {
85 0         0 croak("HTMLre: Unsupported regexp (backref quantifiers)");
86             }
87 1 50       7 if ($re =~ m#\(\?\|#sm) {
88 0         0 croak("HTMLre: Unsupported regexp (branch reset (v5.10.x and higher))");
89             }
90              
91 1         4 my $i = 1;
92 1         3 my @brStack = ('(');
93 1         2 my $ret;
94              
95             # find first 'real' (non escaped) '(' or ')'
96 1         8 while ($re =~ m#^(.*?)(?!\\)([()])(.*)#sm) {
97 4         14 my ($pre,$br,$post) = ($1,$2,$3);
98 4         85 $ret .= escapeHTML($pre);
99             #print STDERR scalar(@brStack)."($brStack[-1]) [".join("] [",$pre,$br,$post)."]
\n";
100 4 100       6330 if ($br eq '(') {
101             # a bracket which creates a capture buffer?
102             #(capture buffer: $1, $2, etc. or \g{1}, \g{2} etc. in Perl v5.10.x)
103 2 100       9 if ($post =~ m#^[\?\*]#) {
104 1         5 push(@brStack,'');
105 1         3 $ret .= '(';
106             } else {
107 1 50       8 my $title = defined $varnames->[$i-1] ?
108             qq(title="$varnames->[$i-1]") : '';
109 1         6 my $cdef = ($startColorIndex - 1 + (13 * $i++) % $MAXCOLORS) + 1;
110 1         6 $ret .= qq[(];
111 1         23 push(@brStack,'(');
112             }
113             } else {
114 2         4 $br = pop(@brStack);
115 2 100       5 if ($br eq '(') {
116 1         3 $ret .= ')';
117             } else {
118 1         3 $ret .= ')';
119             }
120             }
121 4         24 $re = $post;
122             }
123 1         25 $ret .= escapeHTML($re);
124 1         57 return $ret;
125             }
126              
127              
128             # sub HTMLifyREmatches ($var,\@variables[,$startColorIndex,$cssClass])
129             sub HTMLifyREmatches ($;\@$$) {
130 1     1 0 3 my $var = shift;
131 1   50     9 my $varnames = shift || [];
132 1 50       6 my $startColorIndex = defined $_[0] ? $_[0] : 1;
133 1 50       4 my $cssClass = defined $_[1] ? $_[1] : 'cDef';
134              
135 1         2 local $_;
136              
137 1         5 my @c = split(//,$var);
138 1         6 for (my $i = 1; $i < scalar(@-); $i++) {
139 1 50       6 next if !defined $-[$i];
140 1 50       5 my $title = defined $varnames->[$i-1] ?
141             qq(title="$varnames->[$i-1]") : '';
142 1         5 my $cdef = ($startColorIndex - 1 + (13 * $i) % $MAXCOLORS) + 1;
143 1         8 $c[$-[$i]] = qq[$c[$-[$i]]];
144 1         7 $c[$+[$i]-1] .= '';
145             }
146 1         9 return join('',@c);
147             }
148              
149             _init();
150              
151              
152             =head1 NAME
153              
154             Regexp::HTMLify - Highlight regular expression capture buffers and matches using HTML and CSS
155              
156             =head1 SYNOPSIS
157              
158             use Regexp::HTMLify;
159              
160             my $re = qr((?i)(This) (?!and not that )(will match));
161             my $match = 'This will match';
162             my @titles = qw(this matches);
163            
164             print
165             start_html('A simple example of Regexp::HTMLify'),
166             HTMLifyGetColormapCSS(),
167             p('Regexp: ',HTMLifyRE($re,@titles));
168            
169             if ($match =~ m#$re#) {
170             print p('MATCH :',HTMLifyREmatches($match,@titles));
171             } else {
172             print p('NO match');
173             }
174            
175             print end_html;
176              
177              
178             =head1 DESCRIPTION
179              
180             This library offers (limited, see below) functionality to highlight
181             regular expression capture buffers using HTML and CSS.
182              
183             =head1 LIMITATIONS
184              
185             This library has the following limitations:
186              
187             =over
188              
189             =item *
190              
191             No support for code execution within regexp; B<(?{....})>
192              
193             =item *
194              
195             No support for regexp capture buffer quantifiers;
196              
197             =over
198              
199             =item *
200              
201             (...)B<*>
202              
203             =item *
204              
205             (...)B<+>
206              
207             =item *
208              
209             (...)B
210              
211             =item *
212              
213             (...)B<{n}>
214              
215             =item *
216              
217             (...)B<{n,}>
218              
219             =item *
220              
221             (...)B<{n,m}>
222              
223             =back
224              
225             =back
226              
227             =head1 AUTHOR
228              
229             Niels van Dijke
230              
231             =head1 TODO
232              
233             =over
234              
235             =item *
236              
237             Speedup of HTMLifyREmatches()
238              
239             =item *
240              
241             Work on capture buffer quantifier limitations
242              
243             =item *
244              
245             Add support for backrefs (\1, \2 and Perl v5.10.x \g{1}, \g{2})
246              
247             =item *
248              
249             Add more 'real life' tests and/or examples
250              
251             =item *
252              
253             Enhance documentation instead of RTFS (read the fine source)
254              
255             =back
256              
257             =head1 NOTES
258              
259             This is alpha code and not extensively tested. Use with care!
260              
261             =head1 COPYRIGHT
262              
263             Copyright (c) 2008-2011 Niels van Dijke L L
264             All rights reserved. This program is free software.
265              
266             You may distribute under the terms of either the GNU General Public
267             License or the Artistic License, as specified in the Perl README file.
268              
269             =cut
270              
271             __DATA__