File Coverage

blib/lib/HTML/Clean.pm
Criterion Covered Total %
statement 183 202 90.5
branch 52 94 55.3
condition 8 12 66.6
subroutine 20 22 90.9
pod 7 7 100.0
total 270 337 80.1


line stmt bran cond sub pod time code
1             package HTML::Clean;
2              
3 2     2   939 use Carp;
  2         8  
  2         155  
4 2     2   763 use IO::File;
  2         14085  
  2         196  
5 2     2   15 use Fcntl;
  2         4  
  2         462  
6 2     2   12 use strict;
  2         3  
  2         75  
7             require 5.004;
8              
9 2     2   10 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  2         3  
  2         1809  
10              
11             require Exporter;
12             require AutoLoader;
13              
14             # Items to export to callers namespace
15             @EXPORT = qw();
16              
17             $VERSION = '1.1';
18              
19             =pod
20              
21             =head1 NAME
22              
23             HTML::Clean - Cleans up HTML code for web browsers, not humans
24              
25             =head1 SYNOPSIS
26              
27             use HTML::Clean;
28             $h = new HTML::Clean($filename); # or..
29             $h = new HTML::Clean($htmlcode);
30              
31             $h->compat();
32             $h->strip();
33             $data = $h->data();
34             print $$data;
35              
36             =head1 DESCRIPTION
37              
38             The HTML::Clean module encapsulates a number of common techniques for
39             minimizing the size of HTML files. You can typically save between
40             10% and 50% of the size of a HTML file using these methods.
41             It provides the following features:
42              
43             =over 8
44              
45             =item Remove unneeded whitespace (begining of line, etc)
46              
47             =item Remove unneeded META elements.
48              
49             =item Remove HTML comments (except for styles, javascript and SSI)
50              
51             =item Replace tags with equivilant shorter tags ( --> )
52              
53             =item etc.
54              
55             =back
56              
57             The entire proces is configurable, so you can pick and choose what you want
58             to clean.
59              
60             =cut
61             =head1 THE HTML::Clean CLASS
62              
63             =over 4
64              
65             =cut
66              
67              
68             ######################################################################
69              
70             =head2 $h = HTML::Clean->new($dataorfile, [$level]);
71              
72             This creates a new HTML::Clean object. A Prerequisite for all other
73             functions in this module.
74              
75             The $dataorfile parameter supplies the input HTML, either a filename,
76             or a reference to a scalar value holding the HTML, for example:
77              
78             $h = HTML::Clean->new("/htdocs/index.html");
79             $html = "Hello!";
80             $h = HTML::Clean->new(\$html);
81              
82             An optional 'level' parameter controls the level of optimization
83             performed. Levels range from 1 to 9. Level 1 includes only simple
84             fast optimizations. Level 9 includes all optimizations.
85              
86             =cut
87              
88             sub new {
89 10     10 1 8349 my $this = shift;
90 10   33     115 my $class = ref($this) || $this;
91 10         23 my $self = {};
92 10         18 bless $self, $class;
93              
94 10         13 my $data = shift;
95 10         11 my $level = shift;
96              
97 10 50       24 if ($self->initialize($data)) {
98             # set the default level
99 10 50       61 $level = 9 if (!$level);
100 10         51 $self->level($level);
101 10         34 return $self;
102             } else {
103 0         0 undef $self;
104 0         0 return undef;
105             }
106             }
107              
108              
109             #
110             # Set up the data in the self hash..
111             #
112              
113             =head2 $h->initialize($dataorfile)
114              
115             This function allows you to reinitialize the HTML data used by the
116             current object. This is useful if you are processing many files.
117              
118             $dataorfile has the same usage as the new method.
119              
120             Return 0 for an error, 1 for success.
121              
122             =cut
123              
124             sub initialize {
125 13     13 1 90 my($self, $data) = @_;
126 13         37 $self->{'DATA'} = undef;
127              
128             # Not defined? Just return true.
129 13 100       27 return(1) if (!$data);
130              
131             # Check if it's a ref
132 12 100       27 if (ref($data)) {
133 4         6 $self->{DATA} = $data;
134 4         9 return(1);
135             }
136              
137             # Newline char, really an error, but just go with it..
138 8 50       42 if ($data =~ /\n/) {
139 0         0 $self->{'DATA'} = \$data;
140             }
141              
142             # No newline? Must be a filename
143 8 50       173 if (-f $data) {
144 8         15 my $storage;
145              
146 8 50       258 sysopen(IN, "$data", O_RDONLY) || return(0);
147 8         275 while () {
148 2759         4524 $storage .= $_;
149             }
150 8         62 close(IN);
151 8         22 $self->{'DATA'} = \$storage;
152 8         34 return(1);
153             }
154              
155 0         0 return(0); # file not found?
156             }
157              
158              
159             =head2 $h->level([$level])
160              
161             Get/set the optimization level. $level is a number from 1 to 9.
162              
163             =cut
164              
165             sub level {
166 13     13 1 78 my($self, $level) = @_;
167              
168 13 50 66     104 if (defined($level) && ($level > 0) && ($level < 10)) {
      66        
169 12         23 $self->{'LEVEL'} = $level
170             }
171 13         32 return($self->{'LEVEL'});
172             }
173              
174             =head2 $myref = $h->data()
175              
176             Returns the current HTML data as a scalar reference.
177              
178             =cut
179              
180             sub data {
181 8     8 1 651 my($self) = @_;
182              
183 8         375 return $self->{'DATA'};
184             }
185              
186              
187             # Junk HTML comments (INTERNAL)
188              
189             sub _commentcheck($) {
190 174     174   284 my($comment) = @_;
191              
192 174         208 $_ = $comment;
193              
194             # Server side include
195 174 50       246 return($comment) if (m,^$,si);
203 162 50       240 return($comment) if (m,navigator\.app(name|version),si);
204              
205             # Stylesheet
206 162 100       259 return($comment) if (m,[A-z0-9]+\:[A-z0-9]+\s*\{.*\},si);
207 161         656 return('');
208             }
209              
210              
211             # Remove javascript comments (INTERNAL)
212              
213             sub _jscomments {
214 12     12   35 my($js) = @_;
215              
216 12         92 $js =~ s,\n\s*//.*?\n,\n,sig;
217 12         145 $js =~ s,\s+//.*?\n,\n,sig;
218              
219             # insure javascript is hidden
220              
221 12 100       38 if ($js =~ m,\n,si;
223             }
224 12         503 return($js);
225             }
226              
227             # Clean up other javascript stuff..
228              
229             sub _javascript {
230 12     12   36 my($js) = @_;
231              
232             # remove excess whitespace at the beginning and end of lines
233 12         817 $js =~ s,\s*\n+\s*,\n,sig;
234              
235             # braces/semicolon at end of line, join next line
236 12         281 $js =~ s,([;{}])\n,$1,sig;
237              
238             # What else is safe to do?
239              
240 12         771 return($js);
241             }
242              
243             # replace #000000 -> black, etc..
244             # Does the browser render faster with RGB? You would think so..
245              
246             sub _defcolorcheck ($) {
247 238     238   414 my($c) = @_;
248              
249 238         386 $c =~ s/\#000000/black/;
250 238         303 $c =~ s/\#c0c0c0/silver/i;
251 238         245 $c =~ s/\#808080/gray/;
252 238         339 $c =~ s/\#ffffff/white/i;
253 238         253 $c =~ s/\#800000/maroon/;
254 238         279 $c =~ s/\#ff0000/red/i;
255 238         252 $c =~ s/\#800080/purple/;
256 238         246 $c =~ s/\#ff00ff/fuchsia/i;
257 238         244 $c =~ s/\#ff00ff/fuchsia/i;
258 238         229 $c =~ s/\#008000/green/;
259 238         280 $c =~ s/\#00ff00/lime/i;
260 238         230 $c =~ s/\#808000/olive/;
261 238         251 $c =~ s/\#ffff00/yellow/i;
262 238         259 $c =~ s/\#000080/navy/;
263 238         256 $c =~ s/\#0000ff/blue/i;
264 238         232 $c =~ s/\#008080/teal/i;
265 238         240 $c =~ s/\#00ffff/aqua/i;
266 238         2889 return($c);
267             }
268              
269             # For replacing entities with numerics
270 2     2   13 use vars qw/ %_ENTITIES/;
  2         2  
  2         297  
271             %_ENTITIES = (
272             'Agrave' => 192,
273             'Aacute' => 193,
274             'Acirc' => 194,
275             'Atilde' => 195,
276             'Auml' => 196,
277             'Aring' => 197,
278             'AElig' => 198,
279             'Ccedil' => 199,
280             'Egrave' => 200,
281             'Eacute' => 201,
282             'Ecirc' => 202,
283             'Euml' => 203,
284             'Igrave' => 204,
285             'Iacute' => 205,
286             'Icirc' => 206,
287             'Iuml' => 207,
288             'ETH' => 208,
289             'Ntilde' => 209,
290             'Ograve' => 210,
291             'Oacute' => 211,
292             'Ocirc' => 212,
293             'Otilde' => 213,
294             'Ouml' => 214,
295             'Oslash' => 216,
296             'Ugrave' => 217,
297             'Uacute' => 218,
298             'Ucirc' => 219,
299             'Uuml' => 220,
300             'Yacute' => 221,
301             'THORN' => 222,
302             'szlig' => 223,
303             'agrave' => 224,
304             'aacute' => 225,
305             'acirc' => 226,
306             'atilde' => 227,
307             'auml' => 228,
308             'aring' => 229,
309             'aelig' => 230,
310             'ccedil' => 231,
311             'egrave' => 232,
312             'eacute' => 233,
313             'ecirc' => 234,
314             'euml' => 235,
315             'igrave' => 236,
316             'iacute' => 237,
317             'icirc' => 238,
318             'iuml' => 239,
319             'eth' => 240,
320             'ntilde' => 241,
321             'ograve' => 242,
322             'oacute' => 243,
323             'ocirc' => 244,
324             'otilde' => 245,
325             'ouml' => 246,
326             'oslash' => 248,
327             'ugrave' => 249,
328             'uacute' => 250,
329             'ucirc' => 251,
330             'uuml' => 252,
331             'yacute' => 253,
332             'thorn' => 254,
333             'yuml' => 255
334             );
335              
336             =head2 strip(\%options);
337              
338             Removes excess space from HTML
339              
340             You can control the optimizations used by specifying them in the
341             %options hash reference.
342              
343             The following options are recognized:
344              
345             =over 8
346              
347             =item boolean values (0 or 1 values)
348              
349             whitespace Remove excess whitespace
350             shortertags -> , etc..
351             blink No blink tags.
352             contenttype Remove default contenttype.
353             comments Remove excess comments.
354             entities " -> ", etc.
355             dequote remove quotes from tag parameters where possible.
356             defcolor recode colors in shorter form. (#ffffff -> white, etc.)
357             javascript remove excess spaces and newlines in javascript code.
358             htmldefaults remove default values for some html tags
359             lowercasetags translate all HTML tags to lowercase
360              
361             =item parameterized values
362              
363             meta Takes a space separated list of meta tags to remove,
364             default "GENERATOR FORMATTER"
365              
366             emptytags Takes a space separated list of tags to remove when there is no
367             content between the start and end tag, like this: .
368             The default is 'b i font center'
369              
370             =back
371              
372             =cut
373              
374 2         416 use vars qw/
375             $do_whitespace
376             $do_shortertags
377             $do_meta
378             $do_blink
379             $do_contenttype
380             $do_comments
381             $do_entities
382             $do_dequote
383             $do_defcolor
384             $do_emptytags
385             $do_javascript
386             $do_htmldefaults
387             $do_lowercasetags
388             $do_defbaseurl
389 2     2   10 /;
  2         4  
390              
391             $do_whitespace = 1;
392             $do_shortertags = 1;
393             $do_meta = "generator formatter";
394             $do_blink = 1;
395             $do_contenttype = 1;
396             $do_comments = 1;
397             $do_entities = 1;
398             $do_dequote = 1;
399             $do_defcolor = 1;
400             $do_emptytags = 'b i font center';
401             $do_javascript = 1;
402             $do_htmldefaults = 1;
403             $do_lowercasetags = 1;
404             $do_defbaseurl = '';
405              
406             sub strip {
407 11     11 1 107 my($self, $options) = @_;
408              
409 11         22 my $h = $self->{'DATA'};
410 11         17 my $level = $self->{'LEVEL'};
411              
412             # Select a set of options based on $level, and then modify based on
413             # user supplied options.
414              
415 11         77 _level_defaults($level);
416              
417 11 50       20 if(defined($options)) {
418 2     2   11 no strict 'refs';
  2         3  
  2         3208  
419 0         0 for (keys(%$options)) {
420 0 0       0 ${"do_" . lc($_)} = $options->{$_} if defined ${"do_" . lc($_)};
  0         0  
  0         0  
421             }
422             }
423              
424 11 50       27 if ($do_shortertags) {
425 11         546 $$h =~ s,,,sgi;
426 11         555 $$h =~ s,,,sgi;
427 11         482 $$h =~ s,,,sgi;
428 11         463 $$h =~ s,,,sgi;
429             }
430              
431 11 50       23 if ($do_whitespace) {
432 11         1403 $$h =~ s,[\r\n]+,\n,sg; # Carriage/LF -> LF
433 11         1601 $$h =~ s,\s+\n,\n,sg; # empty line
434 11         750 $$h =~ s,\n\s+<,\n<,sg; # space before tag
435 11         467 $$h =~ s,\n\s+,\n ,sg; # other spaces
436              
437 11         977 $$h =~ s,>\n\s*<,><,sg; # LF/spaces between tags..
438              
439             # Remove excess spaces within tags.. note, we could parse out the elements
440             # and rewrite for excess spaces between elements. perhaps next version.
441             # removed due to problems with > and < in tag elements..
442             #$$h =~ s,\s+>,>,sg;
443             #$$h =~ s,<\s+,<,sg;
444             # do this again later..
445             }
446              
447 11 50       28 if ($do_entities) {
448 11         52 $$h =~ s,",\",sg;
449             # Simplify long entity names if using default charset...
450 11         111 $$h =~ m,charset=([^\"]+)\",;
451 11 100 100     90 if (!defined($1) || ($1 eq 'iso-8859-1')) {
452 10 100       98 $$h =~ s,&([A-z]+);,($_ENTITIES{$1}) ? chr($_ENTITIES{$1}) : $&,sige;
  307         1202  
453             }
454             }
455              
456 11 50       38 if ($do_meta) {
457 11         67 foreach my $m (split(/\s+/, $do_meta)) {
458 22         1947 $$h =~ s,]*?>,,sig;
459             }
460             }
461 11 50       29 if ($do_contenttype) {
462             # Don't need this, since it is the default for most web servers
463             # Also gets rid of 'blinking pages' in older versions of netscape.
464 11         510 $$h =~ s,,,sig;
465             }
466              
467 11 50       19 if ($do_defcolor) {
468 11         454 $$h =~ s,(<[^<]+?color=['"]?\#[0-9A-Fa-f]+["']?),_defcolorcheck($&),sige;
  238         384  
469             }
470 11 50       38 if ($do_comments) {
471             # don't strip server side includes..
472             # try not to get javascript, or styles...
473 11         66 $$h =~ s,,_commentcheck($&),sige;
  174         258  
474              
475             # Remove javascript comments
476 11         407 $$h =~ s,]*(java|ecma)script[^>]*>.*?,_jscomments($&),sige;
  12         44  
477             }
478              
479 11 50       23 if ($do_javascript) {
480             #
481 11         387 $$h =~ s,]*(java|ecma)script[^>]*>.*?,_javascript($&),sige;
  12         38  
482             }
483              
484 11 50       22 if ($do_blink) {
485 11         434 $$h =~ s,,,sgi;
486 11         413 $$h =~ s,,,sgi;
487             }
488              
489 11 50       30 if ($do_dequote) {
490 11         3054 while ($$h =~ s,<([A-z]+ [A-z]+=)(['"])([A-z0-9]+)\2(\s*?[^>]*?>),<$1$3$4,sig)
491             {
492             # Remove alphanumeric quotes. Note, breaks DTD..
493             ;
494             }
495             }
496             # remove , etc..
497 11 50       29 if ($do_emptytags) {
498 11         24 my $pat = $do_emptytags;
499 11         96 $pat =~ s/\s+/|/g;
500              
501 11         1774 while ($$h =~ s,<($pat)(\s+[^>]*?)?>\s*,,siog){}
502              
503             }
504 11 50       25 if ($do_htmldefaults) {
505             # Tables
506             # seems to break things..
507             #$$h =~ s,(]*)\s+border=0([^>]*>),$1$2,sig;
508 11         933 $$h =~ s,(]*)\s+rowspan=1([^>]*>),$1$2,sig;
509 11         947 $$h =~ s,(]*)\s+colspan=1([^>]*>),$1$2,sig;
510              
511             #
512              
513             # P, TABLE tags are default left aligned..
514             # lynx is inconsistent in this manner though..
515              
516 11         998 $$h =~ s,<(P|table|td)( [^>]*)align=\"?left\"?([^>]*)>,<$1$2$3>,sig;
517              
518             # OL start=1
519 11         537 $$h =~ s,(
    ]*)start=\"?1\"?([^>]*>),$1$2,sig;
520              
521             # FORM
522 11         756 $$h =~ s,(
]*)method=\"?get\"?([^>]*>),$1$2,sig;
523 11         520 $$h =~ s,(]*)enctype=\"application/x-www-form-urlencoded\"([^>]*>),$1$2,sig;
524              
525             # hr
526 11         554 $$h =~ s,(
]*)align=\"?center\"?([^>]*>),$1$2,sig;
527 11         175 $$h =~ s,(
]*)width=\"?100%\"?([^>]*>),$1$2,sig;
528              
529             # URLs
530 11         140 $$h =~ s,(href|src)(=\"?http://[^/:]+):80/,$1$2/,sig;
531             }
532              
533 11 50       26 if ($do_whitespace) {
534             # remove space within tags
becomes
535 11         1188 $$h =~ s,\s+>,>,sg;
536 11         558 $$h =~ s,<\s+,<,sg;
537             # join lines with a space at the beginning/end of the line
538             # and a line that begins with a tag
539 11         237 $$h =~ s,>\n ,> ,sig;
540 11         123 $$h =~ s, \n<, <,sig;
541             }
542              
543 11 50       24 if ($do_lowercasetags) {
544             # translate tags to lowercase to (hopefully) improve compressability..
545              
546             # simple tags

,

etc.
547 11         3173 $$h =~ s,(<[/]?[a-zA-Z][a-zA-Z0-9_-]*\s*>),\L$1\E,sg;
548              
549             # the rest..
550 11         78 $$h =~ s/(<[a-zA-Z][a-zA-Z0-9_-]*)(\s+.*?>)/_lowercasetag($1,$2)/sge;
  2101         2876  
551             }
552             }
553              
554             sub _lowercasetag {
555 2101     2101   3942 my($prefix, $body) = @_;
556 2101         5781 $prefix =~ s/^(.+)$/\L$1\E/;
557 2101         10620 $body =~ s/(\s+[a-zA-Z][a-zA-Z0-9_-]*)(\s*=\s*[^"\s]+|\s*=\s*"[^"]*"|>|\s)/\L$1\E$2/sg;
558 2101         7978 return $prefix.$body;
559             }
560              
561             # set options based on the level provided.. INTERNAL
562              
563             sub _level_defaults($) {
564 11     11   19 my ($level) = @_;
565              
566 11         14 $do_whitespace = 1; # always do this...
567              
568             # level 2
569 11 50       20 $do_shortertags = ($level > 1) ? 1 : 0;
570 11 50       56 $do_meta = ($level > 1) ? "generator formatter" : "";
571 11 50       22 $do_contenttype = ($level > 1) ? 1 : 0;
572              
573             # level 3
574 11 50       21 $do_entities = ($level > 2) ? 1 : 0;
575 11 50       15 $do_blink = ($level > 2) ? 1 : 0;
576              
577             # level 4
578 11 50       13 $do_comments = ($level > 3) ? 1 : 0;
579 11 50       18 $do_dequote = ($level > 3) ? 1 : 0;
580 11 50       27 $do_defcolor = ($level > 3) ? 1 : 0;
581 11 50       36 $do_emptytags = ($level > 3) ? 'b i font center' : 0;
582 11 50       19 $do_javascript = ($level > 3) ? 1 : 0;
583 11 50       19 $do_htmldefaults = ($level > 3) ? 1 : 0;
584 11 50       18 $do_lowercasetags = ($level > 3) ? 1 : 0;
585              
586             # higher levels reserved for more intensive optimizations.
587             }
588              
589             ######################################################################
590              
591             =head2 compat()
592              
593             This function improves the cross-platform compatibility of your HTML.
594             Currently checks for the following problems:
595              
596             =over 8
597              
598             =item Insuring all IMG tags have ALT elements.
599              
600             =item Use of Arial, Futura, or Verdana as a font face.
601              
602             =item Positioning the tag immediately after the <head> tag. </td> </tr> <tr> <td class="h" > <a name="603">603</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="604">604</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =back </td> </tr> <tr> <td class="h" > <a name="605">605</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="606">606</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="607">607</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="608">608</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub compat { </td> </tr> <tr> <td class="h" > <a name="609">609</a> </td> <td class="c3" > 3 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-HTML-Clean-pm--subroutine.html#609-1"> 3 </a> </td> <td class="c3" > <a href="blib-lib-HTML-Clean-pm--subroutine.html#609-1"> 1 </a> </td> <td > 12 </td> <td class="s"> my($self, $level, $options) = @_; </td> </tr> <tr> <td class="h" > <a name="610">610</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="611">611</a> </td> <td class="c3" > 3 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 4 </td> <td class="s"> my $h = $self->{'DATA'}; </td> </tr> <tr> <td class="h" > <a name="612">612</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="613">613</a> </td> <td class="c3" > 3 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 8 </td> <td class="s"> $$h =~ s/face="arial"/face="arial,helvetica,sansserif"/sgi; </td> </tr> <tr> <td class="h" > <a name="614">614</a> </td> <td class="c3" > 3 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 7 </td> <td class="s"> $$h =~ s/face="(verdana|futura)"/face="$1,arial,helvetica,sansserif"/sgi; </td> </tr> <tr> <td class="h" > <a name="615">615</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="616">616</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # insure that <title> tag is directly after the <head> tag </td> </tr> <tr> <td class="h" > <a name="617">617</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # Some search engines only search the first N chars. (PLweb for instance..) </td> </tr> <tr> <td class="h" > <a name="618">618</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="619">619</a> </td> <td class="c3" > 3 </td> <td class="c0" > <a href="blib-lib-HTML-Clean-pm--branch.html#619-1"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 8 </td> <td class="s"> if ($$h =~ s,<title>(.*),,si) {
620 0         0 my $title = $1;
621 0         0 $$h =~ s,,$title,si;
622             }
623              
624             # Look for IMG without ALT tags.
625 3         9 $$h =~ s/(]+>)/_imgalt($1)/segi;
  0            
626             }
627              
628             sub _imgalt {
629 0     0     my($tag) = @_;
630              
631 0 0         $tag =~ s/>/ alt="">/ if ($tag !~ /alt=/i);
632 0           return($tag);
633             }
634              
635             =head2 defrontpage();
636              
637             This function converts pages created with Microsoft Frontpage to
638             something a Unix server will understand a bit better. This function
639             currently does the following:
640              
641             =over 8
642              
643             =item Converts Frontpage 'hit counters' into a unix specific format.
644              
645             =item Removes some frontpage specific html comments
646              
647             =back
648              
649             =cut
650              
651              
652             sub defrontpage {
653 0     0 1   my($self) = @_;
654              
655 0           my $h = $self->{'DATA'};
656              
657 0           while ($$h =~ s,,,xis) {
658 0           print "Converted a Hitcounter.. $1, $2, $3\n";
659             }
660 0           $$h =~ s,,,sgx;
661             }
662              
663              
664             =head1 SEE ALSO
665              
666             =head2 Modules
667              
668             FrontPage::Web, FrontPage::File
669              
670             =head2 Web Sites
671              
672             =over 6
673              
674             =item Distribution Site - http://people.itu.int/~lindner/
675              
676             =back
677              
678             =head1 AUTHORS
679              
680             Paul Lindner for the International Telecommunication Union (ITU)
681              
682             =head1 COPYRIGHT
683              
684             The HTML::Strip module is Copyright (c) 1998,99 by the ITU, Geneva Switzerland.
685             All rights reserved.
686              
687             You may distribute under the terms of either the GNU General Public
688             License or the Artistic License, as specified in the Perl README file.
689              
690             =cut
691              
692             1;
693             __END__