File Coverage

blib/lib/HTML/Stream.pm
Criterion Covered Total %
statement 71 162 43.8
branch 9 38 23.6
condition 2 8 25.0
subroutine 19 38 50.0
pod 19 25 76.0
total 120 271 44.2


line stmt bran cond sub pod time code
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("<>");
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 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, 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 '© 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 value (I the empty string!):
79              
80             print html_tag(TD, NOWRAP=>undef, ALIGN=>'LEFT');
81            
82            
83            
84             print html_tag(IMG, SRC=>'logo.gif', ALT=>'');
85            
86            
87              
88             There are also some routines for reversing the process, like:
89              
90             $text = "This isn't "fun"...";
91             print html_unmarkup($text);
92            
93             This isn't "fun"...
94            
95             print html_unescape($text);
96            
97             This isn't "fun"...
98              
99             I, I hear you cry. I
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 , possibly with parameters.
123             The parameters will all be HTML-escaped automatically.
124            
125             ent() Outputs an HTML entity, like the © or < .
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 and C instead of C
130             and C: 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 and C shortcuts
138             without giving you one for C, would it? Of course not...
139              
140              
141             =head2 OO interface, chocolate
142              
143             The known HTML tags are even given their own B 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) ==
154             _A == tag(_A) ==
155              
156             All of the autoloaded "tag-methods" use the tagname in I.
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 because of the straight line.
162              
163             =over 4
164              
165             =item *
166              
167             I
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 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 operation, and not stream-specific), do this:
183              
184             accept_tag HTML::Stream 'MARQUEE'; # for you MSIE fans...
185              
186             B 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 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
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, and strings to
215             C.
216              
217              
218             =head1 ADVANCED TOPICS
219              
220             =head2 Auto-formatting and inserting newlines
221              
222             I 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            
236            
237             Hello!
238            
239            
240              
241             B on a given HTML::Stream object,
242             use the C method:
243              
244             $HTML->auto_format(0); # stop autoformatting!
245              
246             B before/after the
247             begin/end form of a tag at a B level, use C:
248              
249             HTML::Stream->set_tag('B', Newlines=>15); # 15 means "\n\n \n\n"
250             HTML::Stream->set_tag('I', Newlines=>7); # 7 means "\n\n \n "
251              
252             B before/after the
253             begin/end form of a tag B level, give the stream
254             its own private "tag info" table, and then use C:
255              
256             $HTML->private_tags;
257             $HTML->set_tag('B', Newlines=>0); # won't affect anyone else!
258              
259             B, just use the special C 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
 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 (or C) 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 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 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\)/©/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 of HTML::Stream which installs
350             your custom function when constructed. For an example, see the
351             B 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 with a
357             filehandle: I.
358             Of course, this includes B 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 & <>!") -> _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 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 3     3   96139 use Carp;
  3         8  
  3         339  
422 3     3   18 use Exporter;
  3         7  
  3         102  
423 3     3   17 use strict;
  3         10  
  3         126  
424 3     3   15 use vars qw(@ISA %EXPORT_TAGS $AUTOLOAD $DASH_TO_SLASH $VERSION %Tags);
  3         3  
  3         12688  
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 0     0 0 0 my $text = shift;
479 0         0 $text =~ s/([<>"&])/\&$Escape{$1};/mg;
480 0         0 $text =~ s/([\x80-\xFF])/'&#'.unpack('C',$1).';'/eg;
  0         0  
481 0         0 $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 0     0 0 0 my $text = shift;
495 0         0 HTML::Entities::encode($text); # can't use $_[0]! encode is destructive!
496 0         0 $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 0     0 0 0 my $text = shift;
508 0         0 $text =~ s/([<>"])/\&$Escape{$1};/mg;
509 0         0 $text =~ s/([\x80-\xFF])/'&#'.unpack('C',$1).';'/eg;
  0         0  
510 0         0 $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     0 0 0 $_[0];
520             }
521              
522             #------------------------------
523             # build_tag ESCAPEFUNC, \@TAGINFO
524             #
525             # I 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 1     1 0 2 my $esc = shift; # escape function
531 1         2 my $taginfo = shift; # tag info
532              
533             # Start off, converting "_x" to "/x":
534 1         2 my $tag = shift @$taginfo;
535 1         3 $tag =~ s|^_|/|;
536 1         3 my $s = '<' . $tag;
537              
538             # Add parameters, if any:
539 1         6 while (@$taginfo) {
540 1         3 my $k = shift @$taginfo;
541 1         2 my $v = shift @$taginfo;
542 1         4 $s .= " $k";
543 1 50       5 defined($v) and ((($s .= '="') .= &$esc($v)) .= '"');
544             }
545 1         6 $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 provided for convenience and backwards-compatibility only.
572             You may want to use the more-powerful B
573             function instead.
574              
575             =cut
576              
577             sub html_escape {
578 1     1 1 138 my $text = shift;
579 1         14 $text =~ s/([<>"&])/\&$Escape{$1};/mg;
580 1         3 $text =~ s/([\x80-\xFF])/'&#'.unpack('C',$1).';'/eg;
  0         0  
581 1         6 $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 1     1 1 8 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, C, C, C, and C<#ddd>) into ASCII characters.
607              
608             B provided for convenience and backwards-compatibility only.
609             You may want to use the more-powerful B
610             function instead: unlike this function, it can collapse entities
611             like C and C into their Latin-1 byte values.
612              
613             =cut
614              
615             sub html_unescape {
616 1     1 1 2 my ($text) = @_;
617              
618             # Remove sequences. KLUDGE! I'll code a better way later.
619 1         7 $text =~ s/\<[^>]+\>//g;
620 1 50       7 $text =~ s/\&([a-z]+);/($Unescape{$1}||'')/gie;
  2         12  
621 1         19 $text =~ s/\&\#(\d+);/pack("C",$1)/gie;
  0         0  
622 1         5 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 1     1 1 8 my ($text) = @_;
638              
639             # Remove sequences. KLUDGE! I'll code a better way later.
640 1         10 $text =~ s/\<[^>]+\>//g;
641 1         7 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
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 message.
675             If no PRINTABLE is given, does a select() and uses that.
676              
677             =cut
678              
679             sub new {
680 1     1 1 14 my $class = shift;
681 1   33     5 my $out = shift || select; # defaults to current output stream
682              
683             # If it looks like an unblessed filehandle, bless it:
684 1 50 33     12 if (!ref($out) || ref($out) eq 'GLOB') {
685 1         9 $out = new HTML::Stream::FileHandle $out;
686             }
687              
688             # Create the object:
689 1         9 my $self = {
690             OUT => $out,
691             Esc => \&escape_all,
692             Tags => \%Tags, # reference to the master table
693             Flags => $F_NEWLINE, # autonewline
694             };
695 1         4 bless $self, $class;
696             }
697              
698             #------------------------------
699             # DESTROY
700             #
701             # Destructor. Does I close the filehandle!
702              
703 1     1   3440 sub DESTROY { 1 }
704              
705             #------------------------------
706             # autoescape - DEPRECATED as of 1.31 due to bad name choice
707             #
708             sub autoescape {
709 0     0 0 0 my $self = shift;
710 0         0 warn "HTML::Stream's autoescape() method is deprecated.\n",
711             "Please use the identical (and more nicely named) auto_escape().\n";
712 0         0 $self->auto_escape(@_);
713             }
714              
715             #------------------------------
716              
717             =item auto_escape [NAME|SUBREF]
718              
719             I
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) 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).
748              
749             B If you specify this option, you'll find that it attempts
750             to "require" B at run time. That's because I didn't want
751             to I 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 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°";
766              
767             =back
768              
769             Returns the previously-installed function, in the manner of C.
770             No arguments just returns the currently-installed function.
771              
772             =cut
773              
774             sub auto_escape {
775 0     0 1 0 my $self = shift;
776              
777             # Grab existing value:
778 0         0 my $oldesc = $self->{Esc};
779              
780             # If arguments were given, they specify the new value:
781 0 0       0 if (@_) {
782 0         0 my $newesc = shift;
783 0 0       0 if (ref($newesc) ne 'CODE') { # must be a string: map it to a subref
784 0 0       0 require HTML::Entities if ($newesc eq 'LATIN_1');
785 0 0       0 $newesc = $AutoEscapeSubs{uc($newesc)} or
786             croak "never heard of auto-escape option '$newesc'";
787             }
788 0         0 $self->{Esc} = $newesc;
789             }
790              
791             # Return old value:
792 0         0 $oldesc;
793             }
794              
795             #------------------------------
796              
797             =item auto_format ONOFF
798              
799             I
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 0     0 1 0 my ($self, $onoff) = @_;
811 0         0 ($self->{Flags} &= (~1 << 0)) |= ($onoff << 0);
812 0         0 $self;
813             }
814              
815             #------------------------------
816              
817             =item comment COMMENT
818              
819             I
820             Output an HTML comment.
821             As of 1.29, a newline is automatically appended.
822              
823             =cut
824              
825             sub comment {
826 0     0 1 0 my $self = shift;
827 0         0 $self->{OUT}->print('\n");
  0         0  
828 0         0 $self;
829             }
830              
831             #------------------------------
832              
833             =item ent ENTITY
834              
835             I
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:
842              
843             $html->e('nbsp');
844              
845             B this function assumes that the entity argument is legal.
846              
847             =cut
848              
849             sub ent {
850 0     0 1 0 my ($self, $entity) = @_;
851 0         0 $self->{OUT}->print("\&$entity;");
852 0         0 $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 0     0 1 0 shift->{OUT};
871             }
872              
873              
874             #------------------------------
875              
876             =item nl [COUNT]
877              
878             I
879             Output COUNT newlines. If undefined, COUNT defaults to 1.
880              
881             =cut
882              
883             sub nl {
884 0     0 1 0 my ($self, $count) = @_;
885 0 0       0 $self->{OUT}->print("\n" x (defined($count) ? $count : 1));
886 0         0 $self;
887             }
888              
889             #------------------------------
890              
891             =item tag TAGNAME [, PARAM=>VALUE, ...]
892              
893             I
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 0     0 1 0 my $self = shift;
901 0         0 $self->{OUT}->print(build_tag($self->{Esc}, \@_));
902 0         0 $self;
903             }
904              
905             #------------------------------
906              
907             =item text TEXT...
908              
909             I
910             Output some text. You may abbreviate this method name as C:
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 0     0 1 0 my $self = shift;
920 0         0 $self->{OUT}->print(&{$self->{Esc}}(join('',@_)));
  0         0  
921 0         0 $self;
922             }
923             *t = \&text;
924              
925             #------------------------------
926              
927             =item text_nbsp TEXT...
928              
929             I
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 0     0 1 0 my $self = shift;
942 0         0 my $txt = &{$self->{Esc}}(join('',@_));
  0         0  
943 0         0 $txt =~ s/ / /g;
944 0         0 $self->{OUT}->print($txt);
945 0         0 $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
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 0     0 1 0 my $self = shift;
977 0         0 my $out = $self->{OUT};
978 0         0 my $esc = $self->{Esc};
979 0         0 foreach (@_) {
980 0 0       0 if (ref($_) eq 'ARRAY') { # E.g., $_ is [A, HREF=>$url]
    0          
981 0         0 $out->print(&build_tag($esc, $_));
982             }
983             elsif (!ref($_)) { # E.g., $_ is "Some text"
984 0         0 $out->print(&$esc($_));
985             }
986             else {
987 0         0 confess "bad argument to output: $_";
988             }
989             }
990 0         0 $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
1012             # 0x02 newline after
1013             # 0x04 newline before
1014             # 0x08 newline after
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
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 1     1 1 2356 my ($self, $tag) = @_;
1166 1 50       5 my $class = (ref($self) ? ref($self) : $self); # force it, for now
1167 1         5 $class->set_tag($tag);
1168             }
1169              
1170              
1171             #------------------------------
1172              
1173             =item private_tags
1174              
1175             I
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 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 (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 0     0 1 0 my $self = shift;
1203 0         0 my %newtags = %Tags;
1204 0         0 $self->{Tags} = \%newtags;
1205 0         0 $self;
1206             }
1207              
1208             #------------------------------
1209              
1210             =item set_tag TAG, [TAGINFO...]
1211              
1212             I
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 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 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 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 by default, an HTML stream just references the "master tag table"
1235             (this makes C more efficient), so I
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 stream's auto-formatting I
1242             you'll need to give that stream its own I 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 this will still force an default entry for BLINK in the I
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 of the
1251             BLINK tag (like auto-formatting) in the I 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 .. ..
1266             0x02 newline after | | | |
1267             0x04 newline before 1 2 4 8
1268             0x08 newline after
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 1     1 1 3 my ($self, $tag, %params) = @_;
1282 1         3 $tag = uc($tag); # it's GOT to be uppercase!!!
1283              
1284             # Force it to BE in the MASTER tag table, regardless:
1285 1 50       7 defined($Tags{$tag}) or $Tags{$tag} = 0; # default value
1286              
1287             # Determine what table we ALTER, and force membership in that table:
1288 1 50       4 my $tags = (ref($self) ? $self->{Tags} : \%Tags);
1289 1 50       5 defined($tags->{$tag}) or $tags->{$tag} = 0; # default value
1290              
1291             # Now, set selected characteristics in that table:
1292 1 50       4 if (defined($params{Newlines})) {
1293 0   0     0 $tags->{$tag} = ($params{Newlines} || 0);
1294             }
1295 1         5 $self;
1296             }
1297              
1298             #------------------------------
1299              
1300             =item tags
1301              
1302             I
1303             Returns an unsorted list of all tags in the class/instance tag table
1304             (see C for class/instance method differences).
1305              
1306             =cut
1307              
1308             sub tags {
1309 2     2 1 857 my $self = shift;
1310 2 50       3 return (keys %{ref($self) ? $self->{Tags} : \%Tags});
  2         104  
1311             }
1312              
1313              
1314             #------------------------------
1315             # AUTOLOAD
1316             #
1317             # The custom autoloader, for the chocolate interface.
1318             #
1319             # B 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 0     0   0 my $funcname = $AUTOLOAD;
1324 0         0 $funcname =~ s/.*:://; # get rid of package name
1325 0         0 my $tag;
1326 0         0 ($tag = $funcname) =~ s/^_//; # get rid of leading "_"
1327              
1328             # If it's a tag method that's been approved in the master table...
1329 0 0       0 if (defined($Tags{$tag})) {
1330              
1331             # A begin-tag, like "IMG"...
1332 0 0       0 if ($funcname !~ /^_/) {
1333 0         0 eval <
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 0         0 eval <
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("");
1353             \$self->{OUT}->print("\n") if (\$self->{Tags}{'$tag'} & 8 and
1354             \$self->{Flags} & $F_NEWLINE);
1355             \$self;
1356             }
1357             EOF
1358             }
1359 0 0       0 if ($@) { $@ =~ s/ at .*\n//; croak $@ } # die!
  0         0  
  0         0  
1360 0         0 my $fn = "HTML::Stream::$funcname"; # KLUDGE: is this right???
1361 0         0 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 0         0 croak "Sorry: $AUTOLOAD is neither defined or loadable";
1368             }
1369 0         0 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 3     3   36 use strict;
  3         7  
  3         1568  
1388 3     3   22 no strict 'refs';
  3         5  
  3         430  
1389              
1390             sub new {
1391 1     1   3 my ($class, $raw) = @_;
1392 1         7 bless \$raw, $class;
1393             }
1394             sub print {
1395 0     0     my $self = shift;
1396 0           print { $$self } @_;
  0            
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, which tries to output
1407             the mnemonic entity markup (e.g., C<ç>) 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             «A right angle is 90°, ¿No?»
1419              
1420             Instead of what HTML::Stream would print, which is this:
1421              
1422             «A right angle is 90°, ¿No?»
1423              
1424             B 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 using this class "requires" that you have HTML::Entities.
1429              
1430             =cut
1431              
1432             package HTML::Stream::Latin1;
1433              
1434 3     3   20 use strict;
  3         7  
  3         111  
1435 3     3   19 use vars qw(@ISA);
  3         5  
  3         545  
1436             @ISA = qw(HTML::Stream);
1437              
1438             # Constructor:
1439             sub new {
1440 0     0     my $class = shift;
1441 0           my $self = HTML::Stream->new(@_);
1442 0           $self->auto_escape('LATIN_1');
1443 0           bless $self, $class;
1444             }
1445              
1446              
1447             __END__