home *** CD-ROM | disk | FTP | other *** search
/ Netrunner 2004 October / NETRUNNER0410.ISO / regular / ActivePerl-5.8.4.810-MSWin32-x86.msi / _a52a522a60193397e05b07d511b5249a < prev    next >
Encoding:
Text File  |  2004-06-01  |  6.6 KB  |  253 lines

  1. package HTML::HeadParser;
  2.  
  3. =head1 NAME
  4.  
  5. HTML::HeadParser - Parse <HEAD> section of a HTML document
  6.  
  7. =head1 SYNOPSIS
  8.  
  9.  require HTML::HeadParser;
  10.  $p = HTML::HeadParser->new;
  11.  $p->parse($text) and  print "not finished";
  12.  
  13.  $p->header('Title')          # to access <title>....</title>
  14.  $p->header('Content-Base')   # to access <base href="http://...">
  15.  $p->header('Foo')            # to access <meta http-equiv="Foo" content="...">
  16.  
  17. =head1 DESCRIPTION
  18.  
  19. The I<HTML::HeadParser> is a specialized (and lightweight)
  20. I<HTML::Parser> that will only parse the E<lt>HEAD>...E<lt>/HEAD>
  21. section of an HTML document.  The parse() method
  22. will return a FALSE value as soon as some E<lt>BODY> element or body
  23. text are found, and should not be called again after this.
  24.  
  25. The I<HTML::HeadParser> keeps a reference to a header object, and the
  26. parser will update this header object as the various elements of the
  27. E<lt>HEAD> section of the HTML document are recognized.  The following
  28. header fields are affected:
  29.  
  30. =over 4
  31.  
  32. =item Content-Base:
  33.  
  34. The I<Content-Base> header is initialized from the E<lt>base
  35. href="..."> element.
  36.  
  37. =item Title:
  38.  
  39. The I<Title> header is initialized from the E<lt>title>...E<lt>/title>
  40. element.
  41.  
  42. =item Isindex:
  43.  
  44. The I<Isindex> header will be added if there is a E<lt>isindex>
  45. element in the E<lt>head>.  The header value is initialized from the
  46. I<prompt> attribute if it is present.  If no I<prompt> attribute is
  47. given it will have '?' as the value.
  48.  
  49. =item X-Meta-Foo:
  50.  
  51. All E<lt>meta> elements will initialize headers with the prefix
  52. "C<X-Meta->" on the name.  If the E<lt>meta> element contains a
  53. C<http-equiv> attribute, then it will be honored as the header name.
  54.  
  55. =back
  56.  
  57. =head1 METHODS
  58.  
  59. The following methods (in addition to those provided by the
  60. superclass) are available:
  61.  
  62. =over 4
  63.  
  64. =cut
  65.  
  66.  
  67. require HTML::Parser;
  68. @ISA = qw(HTML::Parser);
  69.  
  70. use HTML::Entities ();
  71.  
  72. use strict;
  73. use vars qw($VERSION $DEBUG);
  74. #$DEBUG = 1;
  75. $VERSION = sprintf("%d.%02d", q$Revision: 2.18 $ =~ /(\d+)\.(\d+)/);
  76.  
  77. =item $hp = HTML::HeadParser->new
  78.  
  79. =item $hp = HTML::HeadParser->new( $header )
  80.  
  81. The object constructor.  The optional $header argument should be a
  82. reference to an object that implement the header() and push_header()
  83. methods as defined by the I<HTTP::Headers> class.  Normally it will be
  84. of some class that isa or delegates to the I<HTTP::Headers> class.
  85.  
  86. If no $header is given I<HTML::HeadParser> will create an
  87. I<HTTP::Header> object by itself (initially empty).
  88.  
  89. =cut
  90.  
  91. sub new
  92. {
  93.     my($class, $header) = @_;
  94.     unless ($header) {
  95.     require HTTP::Headers;
  96.     $header = HTTP::Headers->new;
  97.     }
  98.  
  99.     my $self = $class->SUPER::new(api_version => 2,
  100.                   ignore_elements => [qw(script style)],
  101.                  );
  102.     $self->{'header'} = $header;
  103.     $self->{'tag'} = '';   # name of active element that takes textual content
  104.     $self->{'text'} = '';  # the accumulated text associated with the element
  105.     $self;
  106. }
  107.  
  108. =item $hp->header;
  109.  
  110. Returns a reference to the header object.
  111.  
  112. =item $hp->header( $key )
  113.  
  114. Returns a header value.  It is just a shorter way to write
  115. C<$hp-E<gt>header-E<gt>header($key)>.
  116.  
  117. =cut
  118.  
  119. sub header
  120. {
  121.     my $self = shift;
  122.     return $self->{'header'} unless @_;
  123.     $self->{'header'}->header(@_);
  124. }
  125.  
  126. sub as_string    # legacy
  127. {
  128.     my $self = shift;
  129.     $self->{'header'}->as_string;
  130. }
  131.  
  132. sub flush_text   # internal
  133. {
  134.     my $self = shift;
  135.     my $tag  = $self->{'tag'};
  136.     my $text = $self->{'text'};
  137.     $text =~ s/^\s+//;
  138.     $text =~ s/\s+$//;
  139.     $text =~ s/\s+/ /g;
  140.     print "FLUSH $tag => '$text'\n"  if $DEBUG;
  141.     if ($tag eq 'title') {
  142.     HTML::Entities::decode($text);
  143.     $self->{'header'}->header(Title => $text);
  144.     }
  145.     $self->{'tag'} = $self->{'text'} = '';
  146. }
  147.  
  148. # This is an quote from the HTML3.2 DTD which shows which elements
  149. # that might be present in a <HEAD>...</HEAD>.  Also note that the
  150. # <HEAD> tags themselves might be missing:
  151. #
  152. # <!ENTITY % head.content "TITLE & ISINDEX? & BASE? & STYLE? &
  153. #                            SCRIPT* & META* & LINK*">
  154. #
  155. # <!ELEMENT HEAD O O  (%head.content)>
  156.  
  157.  
  158. sub start
  159. {
  160.     my($self, $tag, $attr) = @_;  # $attr is reference to a HASH
  161.     print "START[$tag]\n" if $DEBUG;
  162.     $self->flush_text if $self->{'tag'};
  163.     if ($tag eq 'meta') {
  164.     my $key = $attr->{'http-equiv'};
  165.     if (!defined($key) || !length($key)) {
  166.         return unless $attr->{'name'};
  167.         $key = "X-Meta-\u$attr->{'name'}";
  168.     }
  169.     $self->{'header'}->push_header($key => $attr->{content});
  170.     } elsif ($tag eq 'base') {
  171.     return unless exists $attr->{href};
  172.     $self->{'header'}->header('Content-Base' => $attr->{href});
  173.     } elsif ($tag eq 'isindex') {
  174.     # This is a non-standard header.  Perhaps we should just ignore
  175.     # this element
  176.     $self->{'header'}->header(Isindex => $attr->{prompt} || '?');
  177.     } elsif ($tag =~ /^(?:title|script|style)$/) {
  178.     # Just remember tag.  Initialize header when we see the end tag.
  179.     $self->{'tag'} = $tag;
  180.     } elsif ($tag eq 'link') {
  181.     return unless exists $attr->{href};
  182.     # <link href="http:..." rel="xxx" rev="xxx" title="xxx">
  183.     my $h_val = "<" . delete($attr->{href}) . ">";
  184.     for (sort keys %{$attr}) {
  185.         $h_val .= qq(; $_="$attr->{$_}");
  186.     }
  187.     $self->{'header'}->push_header(Link => $h_val);
  188.     } elsif ($tag eq 'head' || $tag eq 'html') {
  189.     # ignore
  190.     } else {
  191.      # stop parsing
  192.     $self->eof;
  193.     }
  194. }
  195.  
  196. sub end
  197. {
  198.     my($self, $tag) = @_;
  199.     print "END[$tag]\n" if $DEBUG;
  200.     $self->flush_text if $self->{'tag'};
  201.     $self->eof if $tag eq 'head';
  202. }
  203.  
  204. sub text
  205. {
  206.     my($self, $text) = @_;
  207.     print "TEXT[$text]\n" if $DEBUG;
  208.     my $tag = $self->{tag};
  209.     if (!$tag && $text =~ /\S/) {
  210.     # Normal text means start of body
  211.         $self->eof;
  212.     return;
  213.     }
  214.     return if $tag ne 'title';
  215.     $self->{'text'} .= $text;
  216. }
  217.  
  218. 1;
  219.  
  220. __END__
  221.  
  222. =head1 EXAMPLE
  223.  
  224.  $h = HTTP::Headers->new;
  225.  $p = HTML::HeadParser->new($h);
  226.  $p->parse(<<EOT);
  227.  <title>Stupid example</title>
  228.  <base href="http://www.linpro.no/lwp/">
  229.  Normal text starts here.
  230.  EOT
  231.  undef $p;
  232.  print $h->title;   # should print "Stupid example"
  233.  
  234. =head1 SEE ALSO
  235.  
  236. L<HTML::Parser>, L<HTTP::Headers>
  237.  
  238. The I<HTTP::Headers> class is distributed as part of the
  239. I<libwww-perl> package.  If you don't have that distribution installed
  240. you need to provide the $header argument to the C<HTML::HeadParser>
  241. constructor with your own object that implements the documented
  242. protocol.
  243.  
  244. =head1 COPYRIGHT
  245.  
  246. Copyright 1996-2001 Gisle Aas. All rights reserved.
  247.  
  248. This library is free software; you can redistribute it and/or
  249. modify it under the same terms as Perl itself.
  250.  
  251. =cut
  252.  
  253.