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

,

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