/usr/local/CPAN/Tk-HTML/HTML/TkText.pm
package HTML::TkText;
use base qw(HTML::Parser);
use Data::Dumper;
my %empty;
my %autoclose;
sub autoclose
{
while (@_)
{
$autoclose{shift(@_)} = 1;
}
}
sub emptytags
{
while (@_)
{
$empty{shift(@_)} = 1;
}
}
autoclose qw(p li html);
emptytags qw(br hr img);
sub new
{
my $class = shift;
my $obj = $class->SUPER::new;
$obj->{'TAGS'} = [];
while (@_)
{
my ($key,$val) = splice(@_,0,2);
$obj->{$key} = $val;
}
return $obj;
}
sub inside
{
my $self = shift;
my $re = '^('.join('|',@_).')$';
$re = qr/$re/;
my $tags = $self->{'TAGS'};
my $i = @$tags;
while ($i-- > 0)
{
return $1 if $tags->[$i] =~ $re;
}
return 0;
}
sub start
{
my ($self,$tag, $attr, $attrseq, $origtext) = @_;
if ($tag =~ /^(\w+)=/)
{
warn "Treating '<$tag>' as '<$1>'";
$tag = $1;
}
if ($autoclose{$tag} && $self->inside($tag))
{
warn "Autoclose <$tag>";
$self->end($tag)
}
my $method = "start_$tag";
$self->$method($tag,$attr,$attrseq,$origtext) if $self->can($method);
if ($empty{$tag})
{
print "<$tag />\n";
my $method = "end_$tag";
$self->$method($tag,$origtext) if $self->can($method);
}
else
{
print "<$tag>\n";
push(@{$self->{'TAGS'}},$tag);
}
}
sub end
{
my ($self,$tag,$origtext) = @_;
my @list = @{$self->{'TAGS'}};
my @popped;
while (@list)
{
my $top = pop(@list);
if ($top eq $tag)
{
while (@popped)
{
my $inner = shift(@popped);
warn "<$inner> closed by <$tag>";
$self->end($inner);
}
$self->{'TAGS'} = \@list;
my $method = "end_$tag";
$self->$method($tag,$origtext) if $self->can($method);
print "</$tag>\n";
return;
}
else
{
push(@popped,$top);
}
}
warn "No $tag in ".join(',',@{$self->{'TAGS'}});
}
sub text
{
my ($self,$text) = @_;
print $text;
$text =~ s/\s+/ /g;
my $t = $self->{Widget};
if ($t)
{
$t->insert('end',$text,$self->{'TAGS'});
}
}
sub force_parent
{
my ($self,$tag,@parents) = @_;
unless ($self->inside(@parents))
{
warn "<$tag> not in <".join('> or <',@parents).">";
$self->start($parents[0]);
}
}
sub start_title
{
my ($self,$tag, $attr, $attrseq, $origtext) = @_;
$self->force_parent($tag,'head');
}
sub start_head
{
my ($self,$tag, $attr, $attrseq, $origtext) = @_;
$self->force_parent($tag,'html');
}
sub start_body
{
my ($self,$tag, $attr, $attrseq, $origtext) = @_;
$self->end('head') if $self->inside('head');
$self->force_parent($tag,'html');
}
sub start_td
{
my ($self, $tag, $attr, $attrseq, $origtext) = @_;
$self->force_parent($tag,'tr');
}
*start_th = \&start_td;
sub start_tr
{
my ($self,$tag, $attr, $attrseq, $origtext) = @_;
$self->force_parent($tag,'table');
}
sub start_li
{
my ($self,$tag, $attr, $attrseq, $origtext) = @_;
$self->force_parent($tag,qw(ul ol));
}
sub eof
{
my $self = shift;
$self->SUPER::eof;
while (@{$self->{'TAGS'}})
{
my $tag = $self->{'TAGS'}[-1];
warn "<$tag> closed by eof";
$self->end($tag);
}
}
1;
__END__