"Fossies" - the Fresh Open Source Software Archive

Member "HTML-Stream-1.60/lib/HTML/Stream.pm" (7 Aug 2008, 43684 Bytes) of package /linux/www/old/HTML-Stream-1.60.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Stream.pm" see the Fossies "Dox" file reference documentation.

    1 package HTML::Stream;
    2 
    3 =head1 NAME
    4 
    5 HTML::Stream - HTML output stream class, and some markup utilities
    6 
    7 
    8 =head1 SYNOPSIS
    9 
   10 Here's small sample of some of the non-OO ways you can use this module:
   11 
   12       use HTML::Stream qw(:funcs);
   13       
   14       print html_tag('A', HREF=>$link);     
   15       print html_escape("<<Hello & welcome!>>");      
   16 
   17 And some of the OO ways as well:
   18 
   19       use HTML::Stream;
   20       $HTML = new HTML::Stream \*STDOUT;
   21       
   22       # The vanilla interface...
   23       $HTML->tag('A', HREF=>"$href");
   24       $HTML->tag('IMG', SRC=>"logo.gif", ALT=>"LOGO");
   25       $HTML->text($copyright);
   26       $HTML->tag('_A');
   27       
   28       # The chocolate interface...
   29       $HTML -> A(HREF=>"$href");
   30       $HTML -> IMG(SRC=>"logo.gif", ALT=>"LOGO");
   31       $HTML -> t($caption);
   32       $HTML -> _A;
   33        
   34       # The chocolate interface, with whipped cream...
   35       $HTML -> A(HREF=>"$href")
   36             -> IMG(SRC=>"logo.gif", ALT=>"LOGO")
   37             -> t($caption)
   38             -> _A;
   39 
   40       # The strawberry interface...
   41       output $HTML [A, HREF=>"$href"], 
   42                    [IMG, SRC=>"logo.gif", ALT=>"LOGO"],
   43                    $caption,
   44                    [_A];
   45 
   46 
   47 =head1 DESCRIPTION
   48 
   49 The B<HTML::Stream> module provides you with an object-oriented
   50 (and subclassable) way of outputting HTML.  Basically, you open up 
   51 an "HTML stream" on an existing filehandle, and then do all of your  
   52 output to the HTML stream.  You can intermix HTML-stream-output and 
   53 ordinary-print-output, if you like.
   54 
   55 There's even a small built-in subclass, B<HTML::Stream::Latin1>, which can
   56 handle Latin-1 input right out of the box.   But all in good time...
   57 
   58 
   59 =head1 INTRODUCTION (the Neapolitan dessert special)
   60 
   61 =head2 Function interface
   62 
   63 Let's start out with the simple stuff.
   64 This module provides a collection of non-OO utility functions
   65 for escaping HTML text and producing HTML tags, like this:
   66 
   67     use HTML::Stream qw(:funcs);        # imports functions from @EXPORT_OK
   68     
   69     print html_tag(A, HREF=>$url);
   70     print '&copy; 1996 by', html_escape($myname), '!';
   71     print html_tag('/A');
   72 
   73 By the way: that last line could be rewritten as:
   74 
   75     print html_tag(_A);
   76 
   77 And if you need to get a parameter in your tag that doesn't have an
   78 associated value, supply the I<undefined> value (I<not> the empty string!):
   79 
   80     print html_tag(TD, NOWRAP=>undef, ALIGN=>'LEFT');
   81     
   82          <TD NOWRAP ALIGN=LEFT>
   83     
   84     print html_tag(IMG, SRC=>'logo.gif', ALT=>'');
   85     
   86          <IMG SRC="logo.gif" ALT="">
   87 
   88 There are also some routines for reversing the process, like:
   89 
   90     $text = "This <i>isn't</i> &quot;fun&quot;...";    
   91     print html_unmarkup($text);
   92        
   93          This isn't &quot;fun&quot;...
   94       
   95     print html_unescape($text);
   96        
   97          This isn't "fun"...
   98 
   99 I<Yeah, yeah, yeah>, I hear you cry.  I<We've seen this stuff before.>
  100 But wait!  There's more...
  101 
  102 
  103 =head2 OO interface, vanilla
  104 
  105 Using the function interface can be tedious... so we also
  106 provide an B<"HTML output stream"> class.  Messages to an instance of
  107 that class generally tell that stream to output some HTML.  Here's the
  108 above example, rewritten using HTML streams:
  109 
  110     use HTML::Stream;
  111     $HTML = new HTML::Stream \*STDOUT;
  112     
  113     $HTML->tag(A, HREF=>$url);
  114     $HTML->ent('copy');
  115     $HTML->text(" 1996 by $myname!");
  116     $HTML->tag(_A);
  117 
  118 As you've probably guessed:
  119 
  120     text()   Outputs some text, which will be HTML-escaped.
  121     
  122     tag()    Outputs an ordinary tag, like <A>, possibly with parameters.
  123              The parameters will all be HTML-escaped automatically.
  124      
  125     ent()    Outputs an HTML entity, like the &copy; or &lt; .
  126              You mostly don't need to use it; you can often just put the 
  127              Latin-1 representation of the character in the text().
  128 
  129 You might prefer to use C<t()> and C<e()> instead of C<text()> 
  130 and C<ent()>: they're absolutely identical, and easier to type:
  131 
  132     $HTML -> tag(A, HREF=>$url);
  133     $HTML -> e('copy');
  134     $HTML -> t(" 1996 by $myname!");
  135     $HTML -> tag(_A);
  136 
  137 Now, it wouldn't be nice to give you those C<text()> and C<ent()> shortcuts
  138 without giving you one for C<tag()>, would it?  Of course not...
  139 
  140 
  141 =head2 OO interface, chocolate
  142 
  143 The known HTML tags are even given their own B<tag-methods,> compiled on 
  144 demand.  The above code could be written even more compactly as:
  145 
  146     $HTML -> A(HREF=>$url);
  147     $HTML -> e('copy');
  148     $HTML -> t(" 1996 by $myname!");
  149     $HTML -> _A;
  150 
  151 As you've probably guessed:
  152 
  153     A(HREF=>$url)   ==   tag(A, HREF=>$url)   ==   <A HREF="/the/url">
  154     _A              ==   tag(_A)              ==   </A>
  155 
  156 All of the autoloaded "tag-methods" use the tagname in I<all-uppercase>.
  157 A C<"_"> prefix on any tag-method means that an end-tag is desired.
  158 The C<"_"> was chosen for several reasons: 
  159 (1) it's short and easy to type,
  160 (2) it doesn't produce much visual clutter to look at,
  161 (3) C<_TAG> looks a little like C</TAG> because of the straight line.
  162 
  163 =over 4 
  164 
  165 =item *
  166 
  167 I<I know, I know... it looks like a private method.
  168 You get used to it.  Really.>
  169 
  170 =back
  171 
  172 I should stress that this module will only auto-create tag methods
  173 for B<known> HTML tags.  So you're protected from typos like this
  174 (which will cause a fatal exception at run-time):
  175 
  176     $HTML -> IMGG(SRC=>$src);
  177 
  178 (You're not yet protected from illegal tag parameters, but it's a start, 
  179 ain't it?)
  180 
  181 If you need to make a tag known (sorry, but this is currently a 
  182 I<global> operation, and not stream-specific), do this:
  183 
  184     accept_tag HTML::Stream 'MARQUEE';       # for you MSIE fans...
  185 
  186 B<Note: there is no corresponding "reject_tag".>  I thought and thought
  187 about it, and could not convince myself that such a method would 
  188 do anything more useful than cause other people's modules to suddenly
  189 stop working because some bozo function decided to reject the C<FONT> tag.
  190 
  191 
  192 =head2 OO interface, with whipped cream
  193 
  194 In the grand tradition of C++, output method chaining is supported
  195 in both the Vanilla Interface and the Chocolate Interface.  
  196 So you can (and probably should) write the above code as:
  197 
  198     $HTML -> A(HREF=>$url) 
  199           -> e('copy') -> t(" 1996 by $myname!") 
  200           -> _A;
  201 
  202 I<But wait!  Neapolitan ice cream has one more flavor...>
  203 
  204 
  205 =head2 OO interface, strawberry
  206 
  207 I was jealous of the compact syntax of HTML::AsSubs, but I didn't
  208 want to worry about clogging the namespace with a lot of functions
  209 like p(), a(), etc. (especially when markup-functions like tr() conflict
  210 with existing Perl functions).  So I came up with this:
  211 
  212     output $HTML [A, HREF=>$url], "Here's my $caption", [_A];
  213 
  214 Conceptually, arrayrefs are sent to C<html_tag()>, and strings to 
  215 C<html_escape()>.
  216 
  217 
  218 =head1 ADVANCED TOPICS
  219 
  220 =head2 Auto-formatting and inserting newlines
  221 
  222 I<Auto-formatting> is the name I give to the Chocolate Interface feature
  223 whereby newlines (and maybe, in the future, other things)
  224 are inserted before or after the tags you output in order to make 
  225 your HTML more readable.  So, by default, this:
  226 
  227     $HTML -> HTML 
  228           -> HEAD  
  229           -> TITLE -> t("Hello!") -> _TITLE 
  230           -> _HEAD
  231           -> BODY(BGCOLOR=>'#808080');
  232 
  233 Actually produces this:
  234 
  235     <HTML><HTML>
  236     <HEAD>
  237     <TITLE>Hello!</TITLE>
  238     </HEAD>
  239     <BODY BGCOLOR="#808080">
  240 
  241 B<To turn off autoformatting altogether> on a given HTML::Stream object,
  242 use the C<auto_format()> method:
  243 
  244     $HTML->auto_format(0);        # stop autoformatting!
  245 
  246 B<To change whether a newline is automatically output> before/after the 
  247 begin/end form of a tag at a B<global> level, use C<set_tag()>:
  248 
  249     HTML::Stream->set_tag('B', Newlines=>15);   # 15 means "\n<B>\n \n</B>\n"
  250     HTML::Stream->set_tag('I', Newlines=>7);    # 7 means  "\n<I>\n \n</I>  "
  251 
  252 B<To change whether a newline is automatically output> before/after the 
  253 begin/end form of a tag B<for a given stream> level, give the stream
  254 its own private "tag info" table, and then use C<set_tag()>:
  255 
  256     $HTML->private_tags;
  257     $HTML->set_tag('B', Newlines=>0);     # won't affect anyone else!
  258 
  259 B<To output newlines explicitly>, just use the special C<nl> method
  260 in the Chocolate Interface:
  261 
  262     $HTML->nl;     # one newline
  263     $HTML->nl(6);  # six newlines
  264 
  265 I am sometimes asked, "why don't you put more newlines in automatically?"
  266 Well, mostly because...
  267 
  268 =over 4
  269 
  270 =item *
  271 
  272 Sometimes you'll be outputting stuff inside a C<PRE> environment.
  273 
  274 =item *
  275 
  276 Sometimes you really do want to jam things (like images, or table
  277 cell delimiters and the things they contain) right up against each other.
  278 
  279 =back
  280 
  281 So I've stuck to outputting newlines in places where it's most likely
  282 to be harmless. 
  283 
  284 
  285 =head2 Entities
  286 
  287 As shown above, You can use the C<ent()> (or C<e()>) method to output 
  288 an entity:
  289 
  290     $HTML->t('Copyright ')->e('copy')->t(' 1996 by Me!');
  291 
  292 But this can be a pain, particularly for generating output with
  293 non-ASCII characters:
  294 
  295     $HTML -> t('Copyright ') 
  296           -> e('copy') 
  297           -> t(' 1996 by Fran') -> e('ccedil') -> t('ois, Inc.!');
  298 
  299 Granted, Europeans can always type the 8-bit characters directly in
  300 their Perl code, and just have this:
  301 
  302     $HTML -> t("Copyright \251 1996 by Fran\347ois, Inc.!');
  303 
  304 But folks without 8-bit text editors can find this kind of output
  305 cumbersome to generate.  Sooooooooo...
  306 
  307 
  308 =head2 Auto-escaping: changing the way text is escaped
  309 
  310 I<Auto-escaping> is the name I give to the act of taking an "unsafe"
  311 string (one with ">", "&", etc.), and magically outputting "safe" HTML.
  312 
  313 The default "auto-escape" behavior of an HTML stream can be a drag if
  314 you've got a lot character entities that you want to output, or if 
  315 you're using the Latin-1 character set, or some other input encoding.  
  316 Fortunately, you can use the C<auto_escape()> method to change the 
  317 way a particular HTML::Stream works at any time.
  318 
  319 First, here's a couple of special invocations:
  320 
  321     $HTML->auto_escape('ALL');      # Default; escapes [<>"&] and 8-bit chars.
  322     $HTML->auto_escape('LATIN_1');  # Like ALL, but uses Latin-1 entities
  323                                     #   instead of decimal equivalents.
  324     $HTML->auto_escape('NON_ENT');  # Like ALL, but leaves "&" alone.
  325 
  326 You can also install your own auto-escape function (note
  327 that you might very well want to install it for just a little bit
  328 only, and then de-install it):
  329 
  330     sub my_auto_escape {
  331         my $text = shift;
  332     HTML::Entities::encode($text);     # start with default
  333         $text =~ s/\(c\)/&copy;/ig;        # (C) becomes copyright
  334         $text =~ s/\\,(c)/\&$1cedil;/ig;   # \,c becomes a cedilla
  335     $text;
  336     }
  337     
  338     # Start using my auto-escape:
  339     my $old_esc = $HTML->auto_escape(\&my_auto_escape);  
  340     
  341     # Output some stuff:
  342     $HTML-> IMG(SRC=>'logo.gif', ALT=>'Fran\,cois, Inc');
  343     output $HTML 'Copyright (C) 1996 by Fran\,cois, Inc.!';
  344     
  345     # Stop using my auto-escape:
  346     $HTML->auto_escape($old_esc);
  347 
  348 If you find yourself in a situation where you're doing this a lot,
  349 a better way is to create a B<subclass> of HTML::Stream which installs
  350 your custom function when constructed.  For an example, see the 
  351 B<HTML::Stream::Latin1> subclass in this module.
  352 
  353 
  354 =head2 Outputting HTML to things besides filehandles
  355 
  356 As of Revision 1.21, you no longer need to supply C<new()> with a 
  357 filehandle: I<any object that responds to a print() method will do>.
  358 Of course, this includes B<blessed> FileHandles, and IO::Handles.
  359 
  360 If you supply a GLOB reference (like C<\*STDOUT>) or a string (like
  361 C<"Module::FH">), HTML::Stream will automatically create an invisible
  362 object for talking to that filehandle (I don't dare bless it into a
  363 FileHandle, since the underlying descriptor would get closed when 
  364 the HTML::Stream is destroyed, and you might not want that).
  365 
  366 You say you want to print to a string?  For kicks and giggles, try this:
  367 
  368     package StringHandle;
  369     sub new {
  370     my $self = '';
  371     bless \$self, shift;
  372     }
  373     sub print {
  374         my $self = shift;
  375         $$self .= join('', @_);
  376     }
  377     
  378   
  379     package main;
  380     use HTML::Stream;
  381     
  382     my $SH = new StringHandle;
  383     my $HTML = new HTML::Stream $SH;
  384     $HTML -> H1 -> t("Hello & <<welcome>>!") -> _H1;
  385     print "PRINTED STRING: ", $$SH, "\n";
  386 
  387 
  388 =head2 Subclassing
  389 
  390 This is where you can make your application-specific HTML-generating code
  391 I<much> easier to look at.  Consider this:
  392 
  393     package MY::HTML;
  394     @ISA = qw(HTML::Stream);
  395      
  396     sub Aside {
  397     $_[0] -> FONT(SIZE=>-1) -> I;
  398     }
  399     sub _Aside {
  400     $_[0] -> _I -> _FONT;
  401     }
  402 
  403 Now, you can do this:
  404 
  405     my $HTML = new MY::HTML \*STDOUT;
  406     
  407     $HTML -> Aside
  408           -> t("Don't drink the milk, it's spoiled... pass it on...")
  409           -> _Aside;
  410 
  411 If you're defining these markup-like, chocolate-interface-style functions,
  412 I recommend using mixed case with a leading capital.  You probably 
  413 shouldn't use all-uppercase, since that's what this module uses for
  414 real HTML tags.
  415 
  416 
  417 =head1 PUBLIC INTERFACE
  418 
  419 =cut
  420 
  421 use Carp;
  422 use Exporter;
  423 use strict;
  424 use vars qw(@ISA %EXPORT_TAGS $AUTOLOAD $DASH_TO_SLASH $VERSION %Tags);
  425 
  426 # Exporting...
  427 @ISA = qw(Exporter);
  428 %EXPORT_TAGS = (
  429       'funcs' => [qw(html_escape html_unescape html_unmarkup html_tag)]
  430 );
  431 Exporter::export_ok_tags('funcs');
  432 
  433 # The package version, both in 1.23 style *and* usable by MakeMaker:
  434 $VERSION = substr q$Revision: 1.60$, 10;
  435 
  436 
  437 
  438 #------------------------------
  439 #
  440 # GLOBALS
  441 #
  442 #------------------------------
  443 
  444 # Allow dashes to become slashes?
  445 $DASH_TO_SLASH = 1;
  446 
  447 # HTML escape sequences.  This bit was stolen from html_escape() in CGI::Base.
  448 my %Escape = (
  449     '&'    => 'amp', 
  450     '>'    => 'gt', 
  451     '<'    => 'lt', 
  452     '"'    => 'quot',
  453 );
  454 my %Unescape;
  455 {my ($k, $v); $Unescape{$v} = $k while (($k, $v) = each %Escape);}
  456 
  457 # Flags for streams:
  458 my $F_NEWLINE = 0x01;      # is autonewlining allowed?
  459 
  460 
  461 
  462 #------------------------------
  463 #
  464 # PRIVATE UTILITIES
  465 #
  466 #------------------------------
  467 
  468 #------------------------------
  469 # escape_all TEXT
  470 #
  471 # Given a TEXT string, turn the text into valid HTML by interpolating the 
  472 # appropriate escape sequences for all troublesome characters
  473 # (angles, double-quotes, ampersands, and 8-bit characters).
  474 #
  475 # Uses the decimal-value syntax for 8-bit characters).
  476 
  477 sub escape_all {
  478     my $text = shift;
  479     $text =~ s/([<>"&])/\&$Escape{$1};/mg; 
  480     $text =~ s/([\x80-\xFF])/'&#'.unpack('C',$1).';'/eg;
  481     $text;
  482 }
  483 
  484 #------------------------------
  485 # escape_latin_1 TEXT
  486 #
  487 # Given a TEXT string, turn the text into valid HTML by interpolating the 
  488 # appropriate escape sequences for all troublesome characters
  489 # (angles, double-quotes, ampersands, and 8-bit characters).
  490 #
  491 # Uses the Latin-1 entities for 8-bit characters.
  492 
  493 sub escape_latin_1 {
  494     my $text = shift;
  495     HTML::Entities::encode($text);  # can't use $_[0]! encode is destructive!
  496     $text;
  497 }
  498 
  499 #------------------------------
  500 # escape_non_ent TEXT
  501 #
  502 # Given a TEXT string, turn the text into valid HTML by interpolating the 
  503 # appropriate escape sequences for angles, double-quotes, and 8-bit
  504 # characters only (i.e., ampersands are left alone).
  505 
  506 sub escape_non_ent {
  507     my $text = shift;
  508     $text =~ s/([<>"])/\&$Escape{$1};/mg; 
  509     $text =~ s/([\x80-\xFF])/'&#'.unpack('C',$1).';'/eg;
  510     $text;
  511 }
  512 
  513 #------------------------------
  514 # escape_none TEXT
  515 #
  516 # No-op, provided for very simple compatibility.  Just returns TEXT.
  517 
  518 sub escape_none {
  519     $_[0];
  520 }
  521 
  522 #------------------------------
  523 # build_tag ESCAPEFUNC, \@TAGINFO
  524 #
  525 # I<Internal use only!>  Build an HTML tag using the given ESCAPEFUNC.
  526 # As an efficiency hack, only the values are HTML-escaped currently:
  527 # it is assumed that the tag and parameters will already be safe.
  528 
  529 sub build_tag {
  530     my $esc = shift;       # escape function
  531     my $taginfo = shift;   # tag info
  532 
  533     # Start off, converting "_x" to "/x":
  534     my $tag = shift @$taginfo;
  535     $tag =~ s|^_|/|;
  536     my $s = '<' . $tag;
  537 
  538     # Add parameters, if any:
  539     while (@$taginfo) {
  540     my $k = shift @$taginfo;
  541     my $v = shift @$taginfo;
  542     $s .= " $k";
  543     defined($v) and ((($s .= '="') .= &$esc($v)) .= '"');
  544     }
  545     $s .= '>';
  546 }
  547 
  548 
  549 #------------------------------
  550 
  551 
  552 
  553 =head2 Functions
  554 
  555 =over 4
  556 
  557 =cut
  558 
  559 #------------------------------
  560 
  561 
  562 #------------------------------
  563 
  564 =item html_escape TEXT
  565 
  566 Given a TEXT string, turn the text into valid HTML by escaping "unsafe" 
  567 characters.  Currently, the "unsafe" characters are 8-bit characters plus:
  568 
  569     <  >  =  &
  570 
  571 B<Note:> provided for convenience and backwards-compatibility only.
  572 You may want to use the more-powerful B<HTML::Entities::encode>
  573 function instead.
  574 
  575 =cut
  576 
  577 sub html_escape {
  578     my $text = shift;
  579     $text =~ s/([<>"&])/\&$Escape{$1};/mg; 
  580     $text =~ s/([\x80-\xFF])/'&#'.unpack('C',$1).';'/eg;
  581     $text;
  582 }
  583  
  584 #------------------------------
  585 
  586 =item html_tag TAG [, PARAM=>VALUE, ...]
  587 
  588 Return the text for a given TAG, possibly with parameters.
  589 As an efficiency hack, only the values are HTML-escaped currently:
  590 it is assumed that the tag and parameters will already be safe.
  591 
  592 For convenience and readability, you can say C<_A> instead of C<"/A">
  593 for the first tag, if you're into barewords.
  594 
  595 =cut
  596 
  597 sub html_tag {
  598     build_tag(\&html_escape, \@_);    # warning! using ref to @_!
  599 }
  600 
  601 #------------------------------
  602 
  603 =item html_unescape TEXT
  604 
  605 Remove angle-tag markup, and convert the standard ampersand-escapes
  606 (C<lt>, C<gt>, C<amp>, C<quot>, and C<#ddd>) into ASCII characters.
  607 
  608 B<Note:> provided for convenience and backwards-compatibility only.
  609 You may want to use the more-powerful B<HTML::Entities::decode>
  610 function instead: unlike this function, it can collapse entities
  611 like C<copy> and C<ccedil> into their Latin-1 byte values.
  612 
  613 =cut
  614 
  615 sub html_unescape {
  616     my ($text) = @_;
  617 
  618     # Remove <tag> sequences.  KLUDGE!  I'll code a better way later.
  619     $text =~ s/\<[^>]+\>//g;
  620     $text =~ s/\&([a-z]+);/($Unescape{$1}||'')/gie;
  621     $text =~ s/\&\#(\d+);/pack("C",$1)/gie;
  622     return $text;
  623 }
  624 
  625 #------------------------------
  626 
  627 =item html_unmarkup TEXT
  628 
  629 Remove angle-tag markup from TEXT, but do not convert ampersand-escapes.  
  630 Cheesy, but theoretically useful if you want to, say, incorporate
  631 externally-provided HTML into a page you're generating, and are worried
  632 that the HTML might contain undesirable markup.
  633 
  634 =cut
  635 
  636 sub html_unmarkup {
  637     my ($text) = @_;
  638 
  639     # Remove <tag> sequences.  KLUDGE!  I'll code a better way later.
  640     $text =~ s/\<[^>]+\>//g;
  641     return $text;
  642 }
  643 
  644 
  645 
  646 #------------------------------
  647 
  648 =back
  649 
  650 =head2 Vanilla
  651 
  652 =over 4
  653 
  654 =cut
  655 
  656 #------------------------------
  657 
  658 # Special mapping from names to utility functions (more stable than symtable):
  659 my %AutoEscapeSubs = 
  660     ('ALL'     => \&HTML::Stream::escape_all,
  661      'LATIN_1' => \&HTML::Stream::escape_latin_1,
  662      'NON_ENT' => \&HTML::Stream::escape_non_ent,
  663      );
  664 
  665 
  666 #------------------------------
  667 
  668 =item new [PRINTABLE] 
  669 
  670 I<Class method.>
  671 Create a new HTML output stream.
  672 
  673 The PRINTABLE may be a FileHandle, a glob reference, or any object
  674 that responds to a C<print()> message.
  675 If no PRINTABLE is given, does a select() and uses that.
  676 
  677 =cut
  678 
  679 sub new {
  680     my $class = shift;
  681     my $out = shift || select;      # defaults to current output stream
  682 
  683     # If it looks like an unblessed filehandle, bless it:
  684     if (!ref($out) || ref($out) eq 'GLOB') {
  685     $out = new HTML::Stream::FileHandle $out;
  686     }
  687 
  688     # Create the object:
  689     my $self = { 
  690     OUT   => $out,
  691     Esc   => \&escape_all,
  692     Tags  => \%Tags,          # reference to the master table
  693     Flags => $F_NEWLINE,      # autonewline
  694     };
  695     bless $self, $class;
  696 }
  697 
  698 #------------------------------
  699 # DESTROY
  700 #
  701 # Destructor.  Does I<not> close the filehandle!
  702 
  703 sub DESTROY { 1 }
  704 
  705 #------------------------------
  706 # autoescape - DEPRECATED as of 1.31 due to bad name choice
  707 #
  708 sub autoescape {
  709     my $self = shift;
  710     warn "HTML::Stream's autoescape() method is deprecated.\n",
  711          "Please use the identical (and more nicely named) auto_escape().\n";
  712     $self->auto_escape(@_);
  713 }
  714 
  715 #------------------------------
  716 
  717 =item auto_escape [NAME|SUBREF]
  718 
  719 I<Instance method.>
  720 Set the auto-escape function for this HTML stream.
  721 
  722 If the argument is a subroutine reference SUBREF, then that subroutine 
  723 will be used.  Declare such subroutines like this:
  724 
  725     sub my_escape {
  726     my $text = shift;     # it's passed in the first argument
  727         ...
  728         $text;
  729     }
  730 
  731 If a textual NAME is given, then one of the appropriate built-in 
  732 functions is used.  Possible values are:
  733 
  734 =over 4
  735 
  736 =item ALL
  737 
  738 Default for HTML::Stream objects.  This escapes angle brackets, 
  739 ampersands, double-quotes, and 8-bit characters.  8-bit characters 
  740 are escaped using decimal entity codes (like C<#123>).
  741 
  742 =item LATIN_1
  743 
  744 Like C<"ALL">, but uses Latin-1 entity names (like C<ccedil>) instead of
  745 decimal entity codes to escape characters.  This makes the HTML more readable
  746 but it is currently not advised, as "older" browsers (like Netscape 2.0)
  747 do not recognize many of the ISO-8859-1 entity names (like C<deg>).
  748 
  749 B<Warning:> If you specify this option, you'll find that it attempts
  750 to "require" B<HTML::Entities> at run time.  That's because I didn't want 
  751 to I<force> you to have that module just to use the rest of HTML::Stream.
  752 To pick up problems at compile time, you are advised to say:
  753 
  754     use HTML::Stream;
  755     use HTML::Entities;
  756 
  757 in your source code.
  758 
  759 =item NON_ENT
  760 
  761 Like C<"ALL">, except that ampersands (&) are I<not> escaped.
  762 This allows you to use &-entities in your text strings, while having
  763 everything else safely escaped:
  764 
  765     output $HTML "If A is an acute angle, then A > 90&deg;";
  766 
  767 =back
  768 
  769 Returns the previously-installed function, in the manner of C<select()>.
  770 No arguments just returns the currently-installed function.
  771 
  772 =cut
  773 
  774 sub auto_escape {
  775     my $self = shift;
  776 
  777     # Grab existing value:
  778     my $oldesc = $self->{Esc}; 
  779 
  780     # If arguments were given, they specify the new value:
  781     if (@_) { 
  782     my $newesc = shift;
  783     if (ref($newesc) ne 'CODE') {  # must be a string: map it to a subref
  784         require HTML::Entities if ($newesc eq 'LATIN_1');
  785         $newesc = $AutoEscapeSubs{uc($newesc)} or
  786         croak "never heard of auto-escape option '$newesc'";
  787     }
  788     $self->{Esc} = $newesc;
  789     }
  790 
  791     # Return old value:
  792     $oldesc;
  793 }
  794 
  795 #------------------------------
  796 
  797 =item auto_format ONOFF
  798 
  799 I<Instance method.>
  800 Set the auto-formatting characteristics for this HTML stream.
  801 Currently, all you can do is supply a single defined boolean
  802 argument, which turns auto-formatting ON (1) or OFF (0). 
  803 The self object is returned.
  804 
  805 Please use no other values; they are reserved for future use.
  806 
  807 =cut
  808 
  809 sub auto_format {
  810     my ($self, $onoff) = @_;
  811     ($self->{Flags} &= (~1 << 0)) |= ($onoff << 0);
  812     $self;
  813 }
  814 
  815 #------------------------------
  816 
  817 =item comment COMMENT
  818 
  819 I<Instance method.>
  820 Output an HTML comment.
  821 As of 1.29, a newline is automatically appended.
  822 
  823 =cut
  824 
  825 sub comment {
  826     my $self = shift;
  827     $self->{OUT}->print('<!-- ', &{$self->{Esc}}(join('',@_)), " -->\n");
  828     $self;
  829 }
  830 
  831 #------------------------------
  832 
  833 =item ent ENTITY
  834 
  835 I<Instance method.>
  836 Output an HTML entity.  For example, here's how you'd output a 
  837 non-breaking space:
  838 
  839       $html->ent('nbsp');
  840 
  841 You may abbreviate this method name as C<e>:
  842 
  843       $html->e('nbsp');
  844 
  845 B<Warning:> this function assumes that the entity argument is legal.
  846 
  847 =cut
  848 
  849 sub ent {
  850     my ($self, $entity) = @_;
  851     $self->{OUT}->print("\&$entity;");
  852     $self;
  853 }
  854 *e = \&ent;
  855 
  856 
  857 #------------------------------
  858 
  859 =item io
  860 
  861 Return the underlying output handle for this HTML stream.
  862 All you can depend upon is that it is some kind of object
  863 which responds to a print() message:
  864 
  865     $HTML->io->print("This is not auto-escaped or nuthin!");
  866 
  867 =cut
  868 
  869 sub io {
  870     shift->{OUT};
  871 }
  872 
  873 
  874 #------------------------------
  875 
  876 =item nl [COUNT]
  877 
  878 I<Instance method.>
  879 Output COUNT newlines.  If undefined, COUNT defaults to 1.
  880 
  881 =cut
  882 
  883 sub nl {
  884     my ($self, $count) = @_;
  885     $self->{OUT}->print("\n" x (defined($count) ? $count : 1));
  886     $self;
  887 }
  888 
  889 #------------------------------
  890 
  891 =item tag TAGNAME [, PARAM=>VALUE, ...]
  892 
  893 I<Instance method.>
  894 Output a tag.  Returns the self object, to allow method chaining.
  895 You can say C<_A> instead of C<"/A">, if you're into barewords.
  896 
  897 =cut
  898 
  899 sub tag {
  900     my $self = shift;
  901     $self->{OUT}->print(build_tag($self->{Esc}, \@_));
  902     $self;
  903 }
  904 
  905 #------------------------------
  906 
  907 =item text TEXT...
  908 
  909 I<Instance method.>
  910 Output some text.  You may abbreviate this method name as C<t>:
  911 
  912       $html->t('Hi there, ', $yournamehere, '!');
  913 
  914 Returns the self object, to allow method chaining.
  915 
  916 =cut
  917 
  918 sub text {
  919     my $self = shift;
  920     $self->{OUT}->print(&{$self->{Esc}}(join('',@_)));
  921     $self;
  922 }
  923 *t = \&text;
  924 
  925 #------------------------------
  926 
  927 =item text_nbsp TEXT...
  928 
  929 I<Instance method.>
  930 Output some text, but with all spaces output as non-breaking-space
  931 characters: 
  932 
  933       $html->t("To list your home directory, type: ")
  934            ->text_nbsp("ls -l ~yourname.")
  935 
  936 Returns the self object, to allow method chaining.
  937 
  938 =cut
  939 
  940 sub text_nbsp {
  941     my $self = shift;
  942     my $txt = &{$self->{Esc}}(join('',@_));
  943     $txt =~ s/ /&nbsp;/g;
  944     $self->{OUT}->print($txt);
  945     $self;
  946 }
  947 *nbsp_text = \&text_nbsp;      # deprecated, but supplied for John :-)
  948 
  949 
  950 #------------------------------
  951 
  952 =back
  953 
  954 =head2 Strawberry
  955 
  956 =over 4
  957 
  958 =cut
  959 
  960 #------------------------------
  961 
  962 #------------------------------
  963 
  964 =item output ITEM,...,ITEM
  965 
  966 I<Instance method.>
  967 Go through the items.  If an item is an arrayref, treat it like
  968 the array argument to html_tag() and output the result.  If an item
  969 is a text string, escape the text and output the result.  Like this:
  970 
  971      output $HTML [A, HREF=>$url], "Here's my $caption!", [_A];
  972 
  973 =cut
  974 
  975 sub output {
  976     my $self = shift;
  977     my $out = $self->{OUT};
  978     my $esc = $self->{Esc};
  979     foreach (@_) {
  980     if (ref($_) eq 'ARRAY') {    # E.g., $_ is [A, HREF=>$url]
  981         $out->print(&build_tag($esc, $_));
  982     }
  983     elsif (!ref($_)) {           # E.g., $_ is "Some text"
  984         $out->print(&$esc($_));
  985     }
  986     else {
  987         confess "bad argument to output: $_";
  988     }
  989     }
  990     $self;        # heh... why not...
  991 }
  992 
  993 
  994 #------------------------------
  995 
  996 =back
  997 
  998 =head2 Chocolate
  999 
 1000 =over 4
 1001 
 1002 =cut
 1003 
 1004 #------------------------------
 1005 
 1006 #------------------------------
 1007 # %Tags
 1008 #------------------------------
 1009 # The default known HTML tags.  The value if each is CURRENTLY a set of flags:
 1010 #
 1011 #     0x01    newline before <TAG>
 1012 #     0x02    newline after <TAG>
 1013 #     0x04    newline before </TAG>
 1014 #     0x08    newline after </TAG>
 1015 #
 1016 # This can be summarized as:
 1017 
 1018 my $TP     = 1 | 0 | 0 | 0;
 1019 my $TBR    = 0 | 2 | 0 | 0;
 1020 my $TFONT  = 0 | 0 | 0 | 0;  # fontlike
 1021 my $TOUTER = 1 | 0 | 0 | 8;
 1022 my $TBOTH  = 0 | 2 | 0 | 8;
 1023 my $TLIST  = 0 | 2 | 0 | 8;
 1024 my $TELEM  = 0 | 0 | 0 | 8; 
 1025 my $TTITLE = 0 | 0 | 0 | 8;
 1026 my $TSOLO  = 0 | 2 | 0 | 0;
 1027 
 1028 %Tags = 
 1029     (
 1030      A       => 0,
 1031      ABBR    => 0,
 1032      ACRONYM => 0,
 1033      ADDRESS => $TBOTH,
 1034      APPLET  => $TBOTH,
 1035      AREA    => $TELEM,
 1036      B       => 0,
 1037      BASE    => 0,
 1038     BASEFONT => $TBOTH,
 1039      BDO     => $TBOTH,
 1040      BIG     => 0,
 1041      BGSOUND => $TELEM,
 1042      BLINK   => 0,
 1043   BLOCKQUOTE => $TBOTH,
 1044      BODY    => $TBOTH,
 1045      BUTTON  => $TP,
 1046      BR      => $TBR,
 1047      CAPTION => $TTITLE,
 1048      CENTER  => $TBOTH,
 1049      CITE    => 0,
 1050      CODE    => 0,
 1051      COMMENT => $TBOTH,
 1052     COLGROUP => $TP,
 1053      COL     => $TP,
 1054      DEL     => 0,
 1055      DFN     => 0,
 1056      DD      => $TLIST,
 1057      DIR     => $TLIST,
 1058      DIV     => $TP,
 1059      DL      => $TELEM,
 1060      DT      => $TELEM,
 1061      EM      => 0,
 1062      EMBED   => $TBOTH,
 1063      FONT    => 0,
 1064      FORM    => $TBOTH,
 1065     FIELDSET => $TBOTH,
 1066      FRAME   => $TBOTH,
 1067     FRAMESET => $TBOTH,
 1068      H1      => $TTITLE,
 1069      H2      => $TTITLE,
 1070      H3      => $TTITLE,
 1071      H4      => $TTITLE,
 1072      H5      => $TTITLE,
 1073      H6      => $TTITLE,
 1074      HEAD    => $TBOTH,
 1075      HR      => $TBOTH,
 1076      HTML    => $TBOTH,
 1077      I       => 0,
 1078      IFRAME  => $TBOTH,
 1079      IMG     => 0,
 1080      INPUT   => 0,
 1081      INS     => 0,
 1082      ISINDEX => 0,
 1083      KEYGEN  => $TBOTH,
 1084      KBD     => 0,
 1085      LABEL   => $TP,
 1086      LEGEND  => $TP,
 1087      LI      => $TELEM,
 1088      LINK    => 0,
 1089      LISTING => $TBOTH,
 1090      MAP     => $TBOTH,
 1091      MARQUEE => $TTITLE,
 1092      MENU    => $TLIST,
 1093      META    => $TSOLO,
 1094      NEXTID  => $TBOTH,
 1095      NOBR    => $TFONT,
 1096      NOEMBED => $TBOTH,
 1097      NOFRAME => $TBOTH,
 1098     NOFRAMES => $TBOTH,
 1099     NOSCRIPT => $TBOTH,
 1100      OBJECT  => 0,
 1101      OL      => $TLIST, 
 1102      OPTION  => $TELEM,
 1103     OPTGROUP => $TELEM,
 1104      P       => $TP,
 1105      PARAM   => $TP,
 1106    PLAINTEXT => $TBOTH,
 1107      PRE     => $TOUTER,
 1108      Q       => 0,
 1109      SAMP    => 0,
 1110      SCRIPT  => $TBOTH,
 1111      SELECT  => $TBOTH,
 1112      SERVER  => $TBOTH,
 1113      SMALL   => 0,
 1114      SPAN    => 0,
 1115      STRONG  => 0,
 1116      STRIKE  => 0,
 1117      STYLE   => 0,
 1118      SUB     => 0,
 1119      SUP     => 0,
 1120      TABLE   => $TBOTH,
 1121      TBODY   => $TP,
 1122      TD      => 0,
 1123     TEXTAREA => 0,
 1124      TFOOT   => $TP,
 1125      TH      => 0,
 1126      THEAD   => $TP,
 1127      TITLE   => $TTITLE,
 1128      TR      => $TOUTER,
 1129      TT      => 0,
 1130      U       => 0,
 1131      UL      => $TLIST, 
 1132      VAR     => 0,
 1133      WBR     => 0,
 1134      XMP     => 0,
 1135      );
 1136 
 1137 
 1138 #------------------------------
 1139 
 1140 =item accept_tag TAG
 1141 
 1142 I<Class method.>
 1143 Declares that the tag is to be accepted as valid HTML (if it isn't already).
 1144 For example, this...
 1145 
 1146      # Make sure methods MARQUEE and _MARQUEE are compiled on demand:
 1147      HTML::Stream->accept_tag('MARQUEE'); 
 1148 
 1149 ...gives the Chocolate Interface permission to create (via AUTOLOAD)
 1150 definitions for the MARQUEE and _MARQUEE methods, so you can then say:
 1151 
 1152      $HTML -> MARQUEE -> t("Hi!") -> _MARQUEE;
 1153 
 1154 If you want to set the default attribute of the tag as well, you can
 1155 do so via the set_tag() method instead; it will effectively do an
 1156 accept_tag() as well.
 1157 
 1158      # Make sure methods MARQUEE and _MARQUEE are compiled on demand,
 1159      #   *and*, set the characteristics of that tag.
 1160      HTML::Stream->set_tag('MARQUEE', Newlines=>9);
 1161 
 1162 =cut
 1163 
 1164 sub accept_tag {
 1165     my ($self, $tag) = @_;
 1166     my $class = (ref($self) ? ref($self) : $self);   # force it, for now
 1167     $class->set_tag($tag);
 1168 }
 1169 
 1170 
 1171 #------------------------------
 1172 
 1173 =item private_tags 
 1174 
 1175 I<Instance method.>
 1176 Normally, HTML streams use a reference to a global table of tag
 1177 information to determine how to do such things as auto-formatting,
 1178 and modifications made to that table by C<set_tag> will
 1179 affect everyone.
 1180 
 1181 However, if you want an HTML stream to have a private copy of that
 1182 table to munge with, just send it this message after creating it.  
 1183 Like this:
 1184 
 1185     my $HTML = new HTML::Stream \*STDOUT;
 1186     $HTML->private_tags;
 1187 
 1188 Then, you can say stuff like:
 1189 
 1190     $HTML->set_tag('PRE',   Newlines=>0);
 1191     $HTML->set_tag('BLINK', Newlines=>9);
 1192 
 1193 And it won't affect anyone else's I<auto-formatting> (although they will 
 1194 possibly be able to use the BLINK tag method without a fatal
 1195 exception C<:-(> ).
 1196 
 1197 Returns the self object.
 1198 
 1199 =cut
 1200 
 1201 sub private_tags {
 1202     my $self = shift;
 1203     my %newtags = %Tags;
 1204     $self->{Tags} = \%newtags;
 1205     $self;
 1206 }
 1207 
 1208 #------------------------------
 1209 
 1210 =item set_tag TAG, [TAGINFO...]
 1211 
 1212 I<Class/instance method.>
 1213 Accept the given TAG in the Chocolate Interface, and (if TAGINFO
 1214 is given) alter its characteristics when being output.
 1215 
 1216 =over 4
 1217 
 1218 =item *
 1219 
 1220 B<If invoked as a class method,> this alters the "master tag table",
 1221 and allows a new tag to be supported via an autoloaded method:
 1222 
 1223      HTML::Stream->set_tag('MARQUEE', Newlines=>9);
 1224 
 1225 Once you do this, I<all> HTML streams you open from then on 
 1226 will allow that tag to be output in the chocolate interface.
 1227 
 1228 =item *
 1229 
 1230 B<If invoked as an instance method,> this alters the "tag table" referenced
 1231 by that HTML stream, usually for the purpose of affecting things like
 1232 the auto-formatting on that HTML stream.  
 1233 
 1234 B<Warning:> by default, an HTML stream just references the "master tag table" 
 1235 (this makes C<new()> more efficient), so I<by default, the 
 1236 instance method will behave exactly like the class method.>
 1237 
 1238      my $HTML = new HTML::Stream \*STDOUT;
 1239      $HTML->set_tag('BLINK', Newlines=>0);  # changes it for others!
 1240 
 1241 If you want to diddle with I<one> stream's auto-formatting I<only,> 
 1242 you'll need to give that stream its own I<private> tag table.  Like this:
 1243 
 1244      my $HTML = new HTML::Stream \*STDOUT;
 1245      $HTML->private_tags;
 1246      $HTML->set_tag('BLINK', Newlines=>0);  # doesn't affect other streams
 1247 
 1248 B<Note:> this will still force an default entry for BLINK in the I<master> 
 1249 tag table: otherwise, we'd never know that it was legal to AUTOLOAD a 
 1250 BLINK method.   However, it will only alter the I<characteristics> of the 
 1251 BLINK tag (like auto-formatting) in the I<object's> tag table.
 1252 
 1253 =back
 1254 
 1255 The TAGINFO, if given, is a set of key=>value pairs with the following 
 1256 possible keys:
 1257 
 1258 =over 4
 1259 
 1260 =item Newlines
 1261 
 1262 Assumed to be a number which encodes how newlines are to be output 
 1263 before/after a tag.   The value is the logical OR (or sum) of a set of flags:
 1264 
 1265      0x01    newline before <TAG>         .<TAG>.     .</TAG>.    
 1266      0x02    newline after <TAG>          |     |     |      |
 1267      0x04    newline before </TAG>        1     2     4      8
 1268      0x08    newline after </TAG>    
 1269 
 1270 Hence, to output BLINK environments which are preceded/followed by newlines:
 1271 
 1272      set_tag HTML::Stream 'BLINK', Newlines=>9;
 1273 
 1274 =back
 1275 
 1276 Returns the self object on success.
 1277 
 1278 =cut
 1279 
 1280 sub set_tag {
 1281     my ($self, $tag, %params) = @_;
 1282     $tag = uc($tag);                           # it's GOT to be uppercase!!!
 1283 
 1284     # Force it to BE in the MASTER tag table, regardless:
 1285     defined($Tags{$tag}) or $Tags{$tag} = 0;       # default value
 1286 
 1287     # Determine what table we ALTER, and force membership in that table:
 1288     my $tags = (ref($self) ? $self->{Tags} : \%Tags);
 1289     defined($tags->{$tag}) or $tags->{$tag} = 0;   # default value
 1290 
 1291     # Now, set selected characteristics in that table:
 1292     if (defined($params{Newlines})) {
 1293     $tags->{$tag} = ($params{Newlines} || 0);
 1294     }
 1295     $self;
 1296 }
 1297 
 1298 #------------------------------
 1299 
 1300 =item tags 
 1301 
 1302 I<Class/instance method.>
 1303 Returns an unsorted list of all tags in the class/instance tag table 
 1304 (see C<set_tag> for class/instance method differences).
 1305 
 1306 =cut
 1307 
 1308 sub tags {
 1309     my $self = shift;
 1310     return (keys %{ref($self) ? $self->{Tags} : \%Tags});
 1311 }
 1312 
 1313 
 1314 #------------------------------
 1315 # AUTOLOAD
 1316 #
 1317 # The custom autoloader, for the chocolate interface.
 1318 #
 1319 # B<WARNING:> I have no idea if the mechanism I use to put the
 1320 # functions in this module (HTML::Stream) is perlitically correct.
 1321 
 1322 sub AUTOLOAD {
 1323     my $funcname = $AUTOLOAD;
 1324     $funcname =~ s/.*:://;            # get rid of package name 
 1325     my $tag;
 1326     ($tag = $funcname) =~ s/^_//;     # get rid of leading "_"
 1327 
 1328     # If it's a tag method that's been approved in the master table...
 1329     if (defined($Tags{$tag})) {
 1330 
 1331     # A begin-tag, like "IMG"...
 1332     if ($funcname !~ /^_/) {     
 1333         eval <<EOF;
 1334             sub HTML::Stream::$funcname { 
 1335         my \$self = shift; 
 1336         \$self->{OUT}->print("\n") if (\$self->{Tags}{'$tag'} & 1 and
 1337                            \$self->{Flags} & $F_NEWLINE);
 1338                 \$self->{OUT}->print(html_tag('$tag',\@_));
 1339         \$self->{OUT}->print("\n") if (\$self->{Tags}{'$tag'} & 2 and
 1340                            \$self->{Flags} & $F_NEWLINE);
 1341                 \$self;
 1342             }
 1343 EOF
 1344     }
 1345         # An end-tag, like "_IMG"...
 1346     else { 
 1347         eval <<EOF;
 1348             sub HTML::Stream::$funcname { 
 1349         my \$self = shift; 
 1350         \$self->{OUT}->print("\n") if (\$self->{Tags}{'$tag'} & 4 and
 1351                            \$self->{Flags} & $F_NEWLINE);
 1352                 \$self->{OUT}->print("</$tag>");
 1353         \$self->{OUT}->print("\n") if (\$self->{Tags}{'$tag'} & 8 and
 1354                            \$self->{Flags} & $F_NEWLINE);
 1355                 \$self;
 1356             }
 1357 EOF
 1358     }
 1359     if ($@) { $@ =~ s/ at .*\n//; croak $@ }   # die!
 1360         my $fn = "HTML::Stream::$funcname";        # KLUDGE: is this right???
 1361         goto &$fn;
 1362     }
 1363 
 1364     # If it's NOT a tag method...
 1365     else { 
 1366     # probably should call the *real* autoloader in the future...
 1367     croak "Sorry: $AUTOLOAD is neither defined or loadable";
 1368     }
 1369     goto &$AUTOLOAD;
 1370 }
 1371 
 1372 
 1373 =back
 1374 
 1375 =head1 SUBCLASSES
 1376 
 1377 =cut
 1378 
 1379 
 1380 # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 1381 # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 1382 
 1383 # A small, private package for turning FileHandles into safe printables:
 1384 
 1385 package HTML::Stream::FileHandle;
 1386 
 1387 use strict;
 1388 no strict 'refs';
 1389 
 1390 sub new {
 1391     my ($class, $raw) = @_;
 1392     bless \$raw, $class;
 1393 }
 1394 sub print {
 1395     my $self = shift;
 1396     print { $$self } @_;
 1397 }
 1398 
 1399 
 1400 # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 1401 # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 1402 
 1403 =head2 HTML::Stream::Latin1
 1404 
 1405 A small, public package for outputting Latin-1 markup.  Its
 1406 default auto-escape function is C<LATIN_1>, which tries to output
 1407 the mnemonic entity markup (e.g., C<&ccedil;>) for ISO-8859-1 characters.
 1408 
 1409 So using HTML::Stream::Latin1 like this:
 1410 
 1411     use HTML::Stream;
 1412     
 1413     $HTML = new HTML::Stream::Latin1 \*STDOUT;
 1414     output $HTML "\253A right angle is 90\260, \277No?\273\n";
 1415 
 1416 Prints this:
 1417 
 1418     &laquo;A right angle is 90&deg;, &iquest;No?&raquo;
 1419 
 1420 Instead of what HTML::Stream would print, which is this:
 1421 
 1422     &#171;A right angle is 90&#176;, &#191;No?&#187;
 1423 
 1424 B<Warning:> a lot of Latin-1 HTML markup is not recognized by older 
 1425 browsers (e.g., Netscape 2.0).  Consider using HTML::Stream; it will output 
 1426 the decimal entities which currently seem to be more "portable".
 1427 
 1428 B<Note:> using this class "requires" that you have HTML::Entities.
 1429 
 1430 =cut
 1431 
 1432 package HTML::Stream::Latin1;
 1433 
 1434 use strict;
 1435 use vars qw(@ISA);
 1436 @ISA = qw(HTML::Stream);
 1437 
 1438 # Constructor:
 1439 sub new {
 1440     my $class = shift;
 1441     my $self = HTML::Stream->new(@_);
 1442     $self->auto_escape('LATIN_1');
 1443     bless $self, $class;
 1444 }
 1445 
 1446 
 1447 __END__
 1448 
 1449 # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 1450 # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 1451 
 1452 =head1 PERFORMANCE
 1453 
 1454 Slower than I'd like.  Both the output() method and the various "tag" 
 1455 methods seem to run about 5 times slower than the old 
 1456 just-hardcode-the-darn stuff approach.  That is, in general, this:
 1457 
 1458     ### Approach #1...
 1459     tag  $HTML 'A', HREF=>"$href";
 1460     tag  $HTML 'IMG', SRC=>"logo.gif", ALT=>"LOGO";
 1461     text $HTML $caption;
 1462     tag  $HTML '_A';
 1463     text $HTML $a_lot_of_text;
 1464 
 1465 And this:
 1466 
 1467     ### Approach #2...
 1468     output $HTML [A, HREF=>"$href"], 
 1469              [IMG, SRC=>"logo.gif", ALT=>"LOGO"],
 1470          $caption,
 1471          [_A];
 1472     output $HTML $a_lot_of_text;
 1473 
 1474 And this:
 1475 
 1476     ### Approach #3...
 1477     $HTML -> A(HREF=>"$href")
 1478       -> IMG(SRC=>"logo.gif", ALT=>"LOGO")
 1479       -> t($caption)
 1480       -> _A
 1481           -> t($a_lot_of_text);
 1482 
 1483 Each run about 5x slower than this:
 1484 
 1485     ### Approach #4...
 1486     print '<A HREF="', html_escape($href), '>',
 1487           '<IMG SRC="logo.gif" ALT="LOGO">',
 1488       html_escape($caption),
 1489           '</A>';
 1490     print html_escape($a_lot_of_text);
 1491 
 1492 Of course, I'd much rather use any of first three I<(especially #3)> 
 1493 if I had to get something done right in a hurry.  Or did you not notice
 1494 the typo in approach #4?  C<;-)>
 1495 
 1496 (BTW, thanks to Benchmark:: for allowing me to... er... benchmark stuff.)
 1497 
 1498 
 1499 
 1500 =head1 VERSION
 1501 
 1502 $Id: Stream.pm,v 1.60 2008/08/06 dstaal Exp $
 1503 
 1504 =head1 CHANGE LOG
 1505 
 1506 =over 4
 1507 
 1508 =item Version 1.60   (2008/08/06)
 1509 
 1510 Fixed up the tests some more, updated changelog.  (Which I'd forgotten 
 1511 about...)
 1512 
 1513 =item Version 1.59   (2008/06/01)
 1514 
 1515 Better tests, better Meta.yml.
 1516 
 1517 =item Version 1.58   (2008/05/28)
 1518 
 1519 Another attempt at cleanup, as well expanding the Meta.yml file.
 1520 
 1521 =item Version 1.57   (2008/05/28)
 1522 
 1523 Cleaned up the Mac-specific files that were getting created in the archive.
 1524 
 1525 =item Version 1.56   (2008/05/27)
 1526 
 1527 Added the start of a testing suite.  In the process, I found an error:
 1528 HTML defines the tag 'NOFRAMES', not 'NOFRAME'.  Both are currently in
 1529 the tag list, but consider 'NOFRAME' depriciated.
 1530 
 1531 The test suite requires Test::More and Test::Output.
 1532 
 1533 =item Version 1.55   (2003/10/28)
 1534 
 1535 New maintainer: Daniel T. Staal.  No major changes in the code, except
 1536 to complete the tag list to HTML 4.01 specifications. (With the
 1537 exception of the 'S' tag, which I want to test, and is depreciated
 1538 anyway.  Note that the DOCTYPE is not actually a HTML tag, and is not
 1539 currently included.)
 1540 
 1541 
 1542 =item Version 1.54   (2001/08/20)
 1543 
 1544 The terms-of-use have been placed in the distribution file "COPYING".  
 1545 Also, small documentation tweaks were made.
 1546 
 1547 =item Version 1.51   (2001/08/16)
 1548 
 1549 No real changes to code; just improved documentation,
 1550 and removed HTML::Entities and HTML::Parser from ./etc
 1551 at CPAN's request.
 1552 
 1553 
 1554 =item Version 1.47   (2000/06/10)
 1555 
 1556 No real changes to code; just improved documentation.
 1557 
 1558 
 1559 =item Version 1.45   (1999/02/09)
 1560 
 1561 Cleanup for Perl 5.005: removed duplicate typeglob assignments.
 1562 
 1563 
 1564 =item Version 1.44   (1998/01/14)
 1565 
 1566 Win95 install (5.004) now works.
 1567 Added SYNOPSIS to POD.
 1568 
 1569 
 1570 =item Version 1.41   (1998/01/02)
 1571 
 1572 Removed $& for efficiency.
 1573 I<Thanks, Andreas!>
 1574 
 1575 Added support for OPTION, and default now puts newlines after SELECT 
 1576 and /SELECT.  Also altered "TELEM" syntax to put newline after end-tags 
 1577 of list element tags (like /OPTION, /LI, etc.).  In theory, this change
 1578 could produce undesireable results for folks who embed lists inside of PRE 
 1579 environments... however, that kind of stuff was done in the days before 
 1580 TABLEs; also, you can always turn it off if you really need to.
 1581 I<Thanks to John D Groenveld for these patches.>
 1582 
 1583 Added text_nbsp().
 1584 I<Thanks to John D Groenveld for the patch.>
 1585 This method may also be invoked as nbsp_text() as in the original patch, 
 1586 but that's sort of a private tip-of-the-hat to the patch author, and the 
 1587 synonym may go away in the future.
 1588 
 1589 
 1590 =item Version 1.37   (1997/02/09)
 1591 
 1592 No real change; just trying to make CPAN.pm happier.
 1593 
 1594 
 1595 =item Version 1.32   (1997/01/12)
 1596 
 1597 B<NEW TOOL for generating Perl code which uses HTML::Stream!> 
 1598 Check your toolkit for B<html2perlstream>.
 1599 
 1600 Added built-in support for escaping 8-bit characters.
 1601 
 1602 Added C<LATIN_1> auto-escape, which uses HTML::Entities to generate
 1603 mnemonic entities.  This is now the default method for HTML::Stream::Latin1.
 1604 
 1605 Added C<auto_format(),> 
 1606 so you can now turn auto-formatting off/on.
 1607 
 1608 Added C<private_tags()>, 
 1609 so it is now possible for HTML streams to each have their own "private"
 1610 copy of the %Tags table, for use by C<set_tag()>.
 1611 
 1612 Added C<set_tag()>.  The tags tables may now be modified dynamically so 
 1613 as to change how formatting is done on-the-fly.  This will hopefully not
 1614 compromise the efficiency of the chocolate interface (until now,
 1615 the formatting was compiled into the method itself), and I<will> add
 1616 greater flexibility for more-complex programs.
 1617 
 1618 Added POD documentation for all subroutines in the public interface.
 1619 
 1620 
 1621 =item Version 1.29   (1996/12/10)
 1622 
 1623 Added terminating newline to comment().
 1624 I<Thanks to John D Groenveld for the suggestion and the patch.>
 1625 
 1626 
 1627 =item Version 1.27   (1996/12/10)
 1628 
 1629 Added built-in HTML::Stream::Latin1, which does a very simple encoding
 1630 of all characters above ASCII 127.
 1631 
 1632 Fixed bug in accept_tag(), where 'my' variable was shadowing argument.
 1633 I<Thanks to John D Groenveld for the bug report and the patch.>
 1634 
 1635 
 1636 =item Version 1.26   (1996/09/27)
 1637 
 1638 Start of history.
 1639 
 1640 =back
 1641 
 1642 =head1 COPYRIGHT
 1643 
 1644 This program is free software.  You may copy or redistribute it under
 1645 the same terms as Perl itself.
 1646 
 1647 =head1 ACKNOWLEDGEMENTS
 1648 
 1649 Warmest thanks to...
 1650 
 1651     Eryq                   For writing the orginal version of this module.
 1652 
 1653     John Buckman           For suggesting that I write an "html2perlstream",
 1654                            and inspiring me to look at supporting Latin-1.
 1655     Tony Cebzanov          For suggesting that I write an "html2perlstream"
 1656     John D Groenveld       Bug reports, patches, and suggestions
 1657     B. K. Oxley (binkley)  For suggesting the support of "writing to strings"
 1658                            which became the "printable" interface.
 1659 
 1660 =head1 AUTHOR
 1661 
 1662 Daniel T. Staal (F<DStaal@usa.net>).
 1663 
 1664 Enjoy.  Yell if it breaks.
 1665 
 1666 =cut
 1667 
 1668 #------------------------------
 1669 1;
 1670