pci:v00001AF4d00001050sv00001AF4sd00001100bc03sc00i00 $ˆl–ß=¿J¥4Å@½p ÜiÅ1hßà „eö‚÷ÂÀÆ?÷package HTML::Parser; use strict; our $VERSION = '3.76'; require HTML::Entities; require XSLoader; XSLoader::load('HTML::Parser', $VERSION); sub new { my $class = shift; my $self = bless {}, $class; return $self->init(@_); } sub init { my $self = shift; $self->_alloc_pstate; my %arg = @_; my $api_version = delete $arg{api_version} || (@_ ? 3 : 2); if ($api_version >= 4) { require Carp; Carp::croak("API version $api_version not supported " . "by HTML::Parser $VERSION"); } if ($api_version < 3) { # Set up method callbacks compatible with HTML-Parser-2.xx $self->handler(text => "text", "self,text,is_cdata"); $self->handler(end => "end", "self,tagname,text"); $self->handler(process => "process", "self,token0,text"); $self->handler(start => "start", "self,tagname,attr,attrseq,text"); $self->handler(comment => sub { my($self, $tokens) = @_; for (@$tokens) { $self->comment($_); } }, "self,tokens"); $self->handler(declaration => sub { my $self = shift; $self->declaration(substr($_[0], 2, -1)); }, "self,text"); } if (my $h = delete $arg{handlers}) { $h = {@$h} if ref($h) eq "ARRAY"; while (my($event, $cb) = each %$h) { $self->handler($event => @$cb); } } # In the end we try to assume plain attribute or handler while (my($option, $val) = each %arg) { if ($option =~ /^(\w+)_h$/) { $self->handler($1 => @$val); } elsif ($option =~ /^(text|start|end|process|declaration|comment)$/) { require Carp; Carp::croak("Bad constructor option '$option'"); } else { $self->$option($val); } } return $self; } sub parse_file { my($self, $file) = @_; my $opened; if (!ref($file) && ref(\$file) ne "GLOB") { # Assume $file is a filename local(*F); open(F, "<", $file) || return undef; binmode(F); # should we? good for byte counts $opened++; $file = *F; } my $chunk = ''; while (read($file, $chunk, 512)) { $self->parse($chunk) || last; } close($file) if $opened; $self->eof; } sub netscape_buggy_comment # legacy { my $self = shift; require Carp; Carp::carp("netscape_buggy_comment() is deprecated. " . "Please use the strict_comment() method instead"); my $old = !$self->strict_comment; $self->strict_comment(!shift) if @_; return $old; } # set up method stubs sub text { } *start = \&text; *end = \&text; *comment = \&text; *declaration = \&text; *process = \&text; 1; __END__ =head1 NAME HTML::Parser - HTML parser class =head1 SYNOPSIS use strict; use warnings; use HTML::Parser (); # Create parser object my $p = HTML::Parser->new( api_version => 3, start_h => [\&start, "tagname, attr"], end_h => [\&end, "tagname"], marked_sections => 1, ); # Parse document text chunk by chunk $p->parse($chunk1); $p->parse($chunk2); # ... # signal end of document $p->eof; # Parse directly from file $p->parse_file("foo.html"); # or open(my $fh, "<:utf8", "foo.html") || die; $p->parse_file($fh); =head1 DESCRIPTION Objects of the C class will recognize markup and separate it from plain text (alias data content) in HTML documents. As different kinds of markup and text are recognized, the corresponding event handlers are invoked. C is not a generic SGML parser. We have tried to make it able to deal with the HTML that is actually "out there", and it normally parses as closely as possible to the way the popular web browsers do it instead of strictly following one of the many HTML specifications from W3C. Where there is disagreement, there is often an option that you can enable to get the official behaviour. The document to be parsed may be supplied in arbitrary chunks. This makes