use strict; use warnings; use HTML::Parser; # tags with allowable attributes my %tags = ( img => { map { $_ => 1 } qw(width height src border) }, a => { map { $_ => 1 } qw(href target name) }, ); # tags with no attributes $tags{$_} = {} foreach qw(b i u br p code pre); my $html = ""; sub safe_html { my $p = new HTML::Parser( api_version => 3, start_h => [ \&_start, 'tagname, attr' ], end_h => [ \&_end, 'tagname'], text_h => [ \&_text, 'text' ], ); $p->parse(shift); $html =~ s/\s+/ /g; return $html; } sub _start { my ($tag, $attrs) = @_; return unless $tags{$tag}; $html .= '<' . $tag; while (my ($attr, $value) = each %$attrs) { if ($tags{$tag}->{$attr}) { $html .= sprintf(q{ %s="%s"}, $attr, $value); } } $html .= '>'; } sub _end { my $tag = shift; $html .= '' if $tags{$tag}; } sub _text { $html .= shift; }