.
HTML
my @links = $p->links;
# There should be 4 links in the document
is(@links, 4);
my $t;
my %attr;
for (@links) {
($t, %attr) = @$_ if $_->[0] eq 'img';
}
is($t, 'img');
is(delete $attr{src}, "http://www.sn.no/foo/img.jpg");
# there should be no more attributes
ok(!scalar(keys %attr));
HTML-Parser-3.83/t/tokeparser.t 0000644 0001750 0001750 00000006433 14652213774 014721 0 ustar olaf olaf use strict;
use warnings;
use HTML::TokeParser ();
use Test::More tests => 17;
# First we create an HTML document to test
my $file = "ttest$$.htm";
die "$file already exists" if -e $file;
{
open(my $fh, '>', $file) or die "Can't create $file: $!";
print {$fh} <<'EOT';
Institute
This is even some more. EOT $p->get_tag("/h1"); my $t = $p->get_trimmed_text("br", "p"); is($t, "This is some text."); $p->get_tag; $t = $p->get_trimmed_text("br", "p"); is($t, "This is some more text."); undef($p); $p = HTML::TokeParser->new(\<<'EOT');
This is even some more.
EOT
$p->get_tag("h1");
$t = $p->get_phrase;
is($t, "This is a bold heading");
$t = $p->get_phrase;
is($t, "");
$p->get_tag;
$t = $p->get_phrase;
is($t, "This is some italic text. This is some more text.");
undef($p);
HTML-Parser-3.83/t/offset.t 0000644 0001750 0001750 00000002421 14652213774 014021 0 ustar olaf olaf use strict;
use warnings;
use HTML::Parser ();
use Test::More tests => 1;
my $HTML = <<'EOT';

.
HTML
# Try the callback interface
my $links = "";
my $p = HTML::LinkExtor->new(sub {
my($tag, %links) = @_;
#diag "$tag @{[%links]}";
$links .= "$tag @{[%links]}\n";
});
$p->parse($HTML); $p->eof;
ok($links =~ m|^base href http://www\.sn\.no/$|m);
ok($links =~ m|^a href link\.html$|m);
# Used to be problems when using the links method on a document with
# no links it it. This is a test to prove that it works.
$p = new HTML::LinkExtor;
$p->parse("this is a document with no links"); $p->eof;
my @links = $p->links;
is(@links, 0);
HTML-Parser-3.83/t/argspec-bad.t 0000644 0001750 0001750 00000001556 14652213774 014713 0 ustar olaf olaf use strict;
use warnings;
use HTML::Parser ();
use Test::More tests => 6;
my $p = HTML::Parser->new(api_version => 3);
sub test_error {
my ($arg, $check_exp) = @_;
my $error;
{
local $@;
#<<< do not let perltidy touch this
$error = $@ || 'Error' unless eval {
$p->handler(end => "end", $arg);
1
};
#>>>
}
like($error, $check_exp);
}
test_error(q(xyzzy), qr/^Unrecognized identifier xyzzy/);
test_error(q(tagname text), qr/^Missing comma separator/);
test_error(q(tagname, "text), qr/^Unterminated literal string/);
test_error(q(tagname, "t\\t"), qr/^Backslash reserved for literal string/);
test_error('"' . ("x" x 256) . '"',
qr/^Literal string is longer than 255 chars/);
$p->handler(end => sub { is(length(shift), 255) }, '"' . ("x" x 255) . '"');
$p->parse("
By default, "LIST]" is parsed as a boolean attribute, not as part of
the ALT value as was clearly intended. This is also what Mozilla
sees.
The official behaviour is enabled by enabling this attribute. If
enabled, it will cause the tag above to be reported as text since
"LIST]" is not a legal attribute name.
$p->unbroken_text
$p->unbroken_text( $bool )
By default, blocks of text are given to the text handler as soon as
possible (but the parser takes care always to break text at a
boundary between whitespace and non-whitespace so single words and
entities can always be decoded safely). This might create breaks
that make it hard to do transformations on the text. When this
attribute is enabled, blocks of text are always reported in one
piece. This will delay the text event until the following (non-text)
event has been recognized by the parser.
Note that the "offset" argspec will give you the offset of the first
segment of text and "length" is the combined length of the segments.
Since there might be ignored tags in between, these numbers can't be
used to directly index in the original document file.
$p->utf8_mode
$p->utf8_mode( $bool )
Enable this option when parsing raw undecoded UTF-8. This tells the
parser that the entities expanded for strings reported by "attr",
@attr and "dtext" should be expanded as decoded UTF-8 so they end up
compatible with the surrounding text.
If "utf8_mode" is enabled then it is an error to pass strings
containing characters with code above 255 to the parse() method, and
the parse() method will croak if you try.
Example: The Unicode character "\x{2665}" is "\xE2\x99\xA5" when
UTF-8 encoded. The character can also be represented by the entity
"♥" or "♥". If we feed the parser:
$p->parse("\xE2\x99\xA5♥");
then "dtext" will be reported as "\xE2\x99\xA5\x{2665}" without
"utf8_mode" enabled, but as "\xE2\x99\xA5\xE2\x99\xA5" when enabled.
The later string is what you want.
This option is only available with perl-5.8 or better.
$p->xml_mode
$p->xml_mode( $bool )
Enabling this attribute changes the parser to allow some XML
constructs. This enables the behaviour controlled by individually by
the "case_sensitive", "empty_element_tags", "strict_names" and
"xml_pic" attributes and also suppresses special treatment of
elements that are parsed as CDATA for HTML.
$p->xml_pic
$p->xml_pic( $bool )
By default, *processing instructions* are terminated by ">". When
this attribute is enabled, processing instructions are terminated by
"?>" instead.
As markup and text is recognized, handlers are invoked. The following
method is used to set up handlers for different events:
$p->handler( event => \&subroutine, $argspec )
$p->handler( event => $method_name, $argspec )
$p->handler( event => \@accum, $argspec )
$p->handler( event => "" );
$p->handler( event => undef );
$p->handler( event );
This method assigns a subroutine, method, or array to handle an
event.
Event is one of "text", "start", "end", "declaration", "comment",
"process", "start_document", "end_document" or "default".
The "\&subroutine" is a reference to a subroutine which is called to
handle the event.
The $method_name is the name of a method of $p which is called to
handle the event.
The @accum is an array that will hold the event information as
sub-arrays.
If the second argument is "", the event is ignored. If it is undef,
the default handler is invoked for the event.
The $argspec is a string that describes the information to be
reported for the event. Any requested information that does not
apply to a specific event is passed as "undef". If argspec is
omitted, then it is left unchanged.
The return value from $p->handler is the old callback routine or a
reference to the accumulator array.
Any return values from handler callback routines/methods are always
ignored. A handler callback can request parsing to be aborted by
invoking the $p->eof method. A handler callback is not allowed to
invoke the $p->parse() or $p->parse_file() method. An exception will
be raised if it tries.
Examples:
$p->handler(start => "start", 'self, attr, attrseq, text' );
This causes the "start" method of object $p to be called for 'start'
events. The callback signature is "$p->start(\%attr, \@attr_seq,
$text)".
$p->handler(start => \&start, 'attr, attrseq, text' );
This causes subroutine start() to be called for 'start' events. The
callback signature is start(\%attr, \@attr_seq, $text).
$p->handler(start => \@accum, '"S", attr, attrseq, text' );
This causes 'start' event information to be saved in @accum. The
array elements will be ['S', \%attr, \@attr_seq, $text].
$p->handler(start => "");
This causes 'start' events to be ignored. It also suppresses
invocations of any default handler for start events. It is in most
cases equivalent to $p->handler(start => sub {}), but is more
efficient. It is different from the empty-sub-handler in that
"skipped_text" is not reset by it.
$p->handler(start => undef);
This causes no handler to be associated with start events. If there
is a default handler it will be invoked.
Filters based on tags can be set up to limit the number of events
reported. The main bottleneck during parsing is often the huge number of
callbacks made from the parser. Applying filters can improve performance
significantly.
The following methods control filters:
$p->ignore_elements( @tags )
Both the "start" event and the "end" event as well as any events
that would be reported in between are suppressed. The ignored
elements can contain nested occurrences of itself. Example:
$p->ignore_elements(qw(script style));
The "script" and "style" tags will always nest properly since their
content is parsed in CDATA mode. For most other tags
"ignore_elements" must be used with caution since HTML is often not
*well formed*.
$p->ignore_tags( @tags )
Any "start" and "end" events involving any of the tags given are
suppressed. To reset the filter (i.e. don't suppress any "start" and
"end" events), call "ignore_tags" without an argument.
$p->report_tags( @tags )
Any "start" and "end" events involving any of the tags *not* given
are suppressed. To reset the filter (i.e. report all "start" and
"end" events), call "report_tags" without an argument.
Internally, the system has two filter lists, one for "report_tags" and
one for "ignore_tags", and both filters are applied. This effectively
gives "ignore_tags" precedence over "report_tags".
Examples:
$p->ignore_tags(qw(style));
$p->report_tags(qw(script style));
results in only "script" events being reported.
Argspec
Argspec is a string containing a comma-separated list that describes the
information reported by the event. The following argspec identifier
names can be used:
"attr"
Attr causes a reference to a hash of attribute name/value pairs to
be passed.
Boolean attributes' values are either the value set by
$p->boolean_attribute_value, or the attribute name if no value has
been set by $p->boolean_attribute_value.
This passes undef except for "start" events.
Unless "xml_mode" or "case_sensitive" is enabled, the attribute
names are forced to lower case.
General entities are decoded in the attribute values and one layer
of matching quotes enclosing the attribute values is removed.
The Unicode character set is assumed for entity decoding.
@attr
Basically the same as "attr", but keys and values are passed as
individual arguments and the original sequence of the attributes is
kept. The parameters passed will be the same as the @attr calculated
here:
@attr = map { $_ => $attr->{$_} } @$attrseq;
assuming $attr and $attrseq here are the hash and array passed as
the result of "attr" and "attrseq" argspecs.
This passes no values for events besides "start".
"attrseq"
Attrseq causes a reference to an array of attribute names to be
passed. This can be useful if you want to walk the "attr" hash in
the original sequence.
This passes undef except for "start" events.
Unless "xml_mode" or "case_sensitive" is enabled, the attribute
names are forced to lower case.
"column"
Column causes the column number of the start of the event to be
passed. The first column on a line is 0.
"dtext"
Dtext causes the decoded text to be passed. General entities are
automatically decoded unless the event was inside a CDATA section or
was between literal start and end tags ("script", "style", "xmp",
"iframe", "title", "textarea" and "plaintext").
The Unicode character set is assumed for entity decoding. With Perl
version 5.6 or earlier only the Latin-1 range is supported, and
entities for characters outside the range 0..255 are left unchanged.
This passes undef except for "text" events.
"event"
Event causes the event name to be passed.
The event name is one of "text", "start", "end", "declaration",
"comment", "process", "start_document" or "end_document".
"is_cdata"
Is_cdata causes a TRUE value to be passed if the event is inside a
CDATA section or between literal start and end tags ("script",
"style", "xmp", "iframe", "title", "textarea" and "plaintext").
if the flag is FALSE for a text event, then you should normally
either use "dtext" or decode the entities yourself before the text
is processed further.
"length"
Length causes the number of bytes of the source text of the event to
be passed.
"line"
Line causes the line number of the start of the event to be passed.
The first line in the document is 1. Line counting doesn't start
until at least one handler requests this value to be reported.
"offset"
Offset causes the byte position in the HTML document of the start of
the event to be passed. The first byte in the document has offset 0.
"offset_end"
Offset_end causes the byte position in the HTML document of the end
of the event to be passed. This is the same as "offset" + "length".
"self"
Self causes the current object to be passed to the handler. If the
handler is a method, this must be the first element in the argspec.
An alternative to passing self as an argspec is to register closures
that capture $self by themselves as handlers. Unfortunately this
creates circular references which prevent the HTML::Parser object
from being garbage collected. Using the "self" argspec avoids this
problem.
"skipped_text"
Skipped_text returns the concatenated text of all the events that
have been skipped since the last time an event was reported. Events
might be skipped because no handler is registered for them or
because some filter applies. Skipped text also includes marked
section markup, since there are no events that can catch it.
If an ""-handler is registered for an event, then the text for this
event is not included in "skipped_text". Skipped text both before
and after the ""-event is included in the next reported
"skipped_text".
"tag"
Same as "tagname", but prefixed with "/" if it belongs to an "end"
event and "!" for a declaration. The "tag" does not have any prefix
for "start" events, and is in this case identical to "tagname".
"tagname"
This is the element name (or *generic identifier* in SGML jargon)
for start and end tags. Since HTML is case insensitive, this name is
forced to lower case to ease string matching.
Since XML is case sensitive, the tagname case is not changed when
"xml_mode" is enabled. The same happens if the "case_sensitive"
attribute is set.
The declaration type of declaration elements is also passed as a
tagname, even if that is a bit strange. In fact, in the current
implementation tagname is identical to "token0" except that the name
may be forced to lower case.
"token0"
Token0 causes the original text of the first token string to be
passed. This should always be the same as $tokens->[0].
For "declaration" events, this is the declaration type.
For "start" and "end" events, this is the tag name.
For "process" and non-strict "comment" events, this is everything
inside the tag.
This passes undef if there are no tokens in the event.
"tokenpos"
Tokenpos causes a reference to an array of token positions to be
passed. For each string that appears in "tokens", this array
contains two numbers. The first number is the offset of the start of
the token in the original "text" and the second number is the length
of the token.
Boolean attributes in a "start" event will have (0,0) for the
attribute value offset and length.
This passes undef if there are no tokens in the event (e.g., "text")
and for artificial "end" events triggered by empty element tags.
If you are using these offsets and lengths to modify "text", you
should either work from right to left, or be very careful to
calculate the changes to the offsets.
"tokens"
Tokens causes a reference to an array of token strings to be passed.
The strings are exactly as they were found in the original text, no
decoding or case changes are applied.
For "declaration" events, the array contains each word, comment, and
delimited string starting with the declaration type.
For "comment" events, this contains each sub-comment. If
$p->strict_comments is disabled, there will be only one sub-comment.
For "start" events, this contains the original tag name followed by
the attribute name/value pairs. The values of boolean attributes
will be either the value set by $p->boolean_attribute_value, or the
attribute name if no value has been set by
$p->boolean_attribute_value.
For "end" events, this contains the original tag name (always one
token).
For "process" events, this contains the process instructions (always
one token).
This passes "undef" for "text" events.
"text"
Text causes the source text (including markup element delimiters) to
be passed.
"undef"
Pass an undefined value. Useful as padding where the same handler
routine is registered for multiple events.
'...'
A literal string of 0 to 255 characters enclosed in single (') or
double (") quotes is passed as entered.
The whole argspec string can be wrapped up in '@{...}' to signal that
the resulting event array should be flattened. This only makes a
difference if an array reference is used as the handler target. Consider
this example:
$p->handler(text => [], 'text');
$p->handler(text => [], '@{text}']);
With two text events; "foo", "bar"; then the first example will end up
with [["foo"], ["bar"]] and the second with ["foo", "bar"] in the
handler target array.
Events
Handlers for the following events can be registered:
"comment"
This event is triggered when a markup comment is recognized.
Example:
"declaration"
This event is triggered when a *markup declaration* is recognized.
For typical HTML documents, the only declaration you are likely to
find is .
Example:
DTDs inside will confuse HTML::Parser.
"default"
This event is triggered for events that do not have a specific
handler. You can set up a handler for this event to catch stuff you
did not want to catch explicitly.
"end"
This event is triggered when an end tag is recognized.
Example: