Oh, okay. I decided to take a whack at it. Normal HTML caveats apply, edge cases and all that, but this should work pretty well. It even tries to determine if the font tag is alone in a parent so that the style can be bumped to the parent. In cases like-
<td><font size="6">Pretty BIG</font></td>
# we'll get (updated typo in "larg")
<td style="font-size:x-large">Pretty BIG</td>
Barely tested though I think it's pretty solid. Improvements welcome. (Update: tested a bit and found 2 bugs, fixed now with inline test case.)
use strict;
use warnings;
no warnings 'uninitialized';
use HTML::TreeBuilder;
use HTML::Element;
my %size_convert = qw(
1 xx-small
2 x-small
3 small
4 medium
5 large
6 x-large
7 xx-large
-6 40%
-5 50%
-4 60%
-3 70%
-2 80%
-1 90%
-0 100%
+0 100%
+1 120%
+2 140%
+3 160%
+4 180%
+5 200%
+6 250%
);
# Program proper
#=====================================================================
my $file = shift;
$file or warn "No file given, using test HTML!\n";
$file = \*DATA;
my $tree = HTML::TreeBuilder->new(); # empty tree
$tree->parse_file($file);
for my $node ( $tree->descendants() ) {
next unless $node->tag() eq 'font';
my $font_style = extract_style( $node );
$font_style->{"font-size"} = $size_convert{ $node->attr('size') }
if $size_convert{ $node->attr('size') };
$font_style->{"font-family"} = $node->attr('face')
if $node->attr('face');
$font_style->{color} = $node->attr('color')
if $node->attr('color');
if ( $node->parent() and
$node->parent->content_list() == 1 ) {
my $parent = $node->parent;
my $parent_style = extract_style( $parent );
$font_style = {
%{$parent_style},
%{$font_style},
};
my $style = generate_style_string($font_style);
$parent->attr("style", $style);
$parent->push_content( $node->as_text() );
$node->delete();
}
else # replace font with span
{
my $style = generate_style_string($font_style);
my $span = HTML::Element->new('span', style => $style );
$node->replace_with($span);
}
}
print $tree->as_HTML();
exit 0;
# Subroutines
#=====================================================================
sub generate_style_string {
my $style_hash = shift;
my @style;
while ( my ( $k, $v ) = each %{$style_hash} ) {
push @style, join(":", $k, $v);
}
return join "; ", @style;
}
sub extract_style {
my $node = shift;
my %style;
%style = map { split /:/ } split /;/, $node->attr('style')
if $node->attr('style');
return \%style
}
__DATA__
<table><tr>
<td style="border:solid 1px black;"><font size="+2">Some text</font></
+td>
</tr>
</table>
<p>Something with <font color="#ffee98" size="7" face="Times">3 style
points</font></p>
<p style="color:#aaa"><font color="red" face="Times">3 style points</f
+ont></p>
|