xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/lib/CGI/Pretty.pm (revision 667:8508518800a9)
10Sstevel@tonic-gatepackage CGI::Pretty;
20Sstevel@tonic-gate
30Sstevel@tonic-gate# See the bottom of this file for the POD documentation.  Search for the
40Sstevel@tonic-gate# string '=head'.
50Sstevel@tonic-gate
60Sstevel@tonic-gate# You can run this file through either pod2man or pod2html to produce pretty
70Sstevel@tonic-gate# documentation in manual or html file format (these utilities are part of the
80Sstevel@tonic-gate# Perl 5 distribution).
90Sstevel@tonic-gate
100Sstevel@tonic-gateuse strict;
110Sstevel@tonic-gateuse CGI ();
120Sstevel@tonic-gate
130Sstevel@tonic-gate$CGI::Pretty::VERSION = '1.08';
140Sstevel@tonic-gate$CGI::DefaultClass = __PACKAGE__;
150Sstevel@tonic-gate$CGI::Pretty::AutoloadClass = 'CGI';
160Sstevel@tonic-gate@CGI::Pretty::ISA = qw( CGI );
170Sstevel@tonic-gate
180Sstevel@tonic-gateinitialize_globals();
190Sstevel@tonic-gate
200Sstevel@tonic-gatesub _prettyPrint {
210Sstevel@tonic-gate    my $input = shift;
220Sstevel@tonic-gate    return if !$$input;
230Sstevel@tonic-gate    return if !$CGI::Pretty::LINEBREAK || !$CGI::Pretty::INDENT;
240Sstevel@tonic-gate
250Sstevel@tonic-gate#    print STDERR "'", $$input, "'\n";
260Sstevel@tonic-gate
270Sstevel@tonic-gate    foreach my $i ( @CGI::Pretty::AS_IS ) {
280Sstevel@tonic-gate	if ( $$input =~ m{</$i>}si ) {
290Sstevel@tonic-gate	    my ( $a, $b, $c ) = $$input =~ m{(.*)(<$i[\s/>].*?</$i>)(.*)}si;
300Sstevel@tonic-gate	    next if !$b;
310Sstevel@tonic-gate	    $a ||= "";
320Sstevel@tonic-gate	    $c ||= "";
330Sstevel@tonic-gate
340Sstevel@tonic-gate	    _prettyPrint( \$a ) if $a;
350Sstevel@tonic-gate	    _prettyPrint( \$c ) if $c;
360Sstevel@tonic-gate
370Sstevel@tonic-gate	    $b ||= "";
380Sstevel@tonic-gate	    $$input = "$a$b$c";
390Sstevel@tonic-gate	    return;
400Sstevel@tonic-gate	}
410Sstevel@tonic-gate    }
420Sstevel@tonic-gate    $$input =~ s/$CGI::Pretty::LINEBREAK/$CGI::Pretty::LINEBREAK$CGI::Pretty::INDENT/g;
430Sstevel@tonic-gate}
440Sstevel@tonic-gate
450Sstevel@tonic-gatesub comment {
460Sstevel@tonic-gate    my($self,@p) = CGI::self_or_CGI(@_);
470Sstevel@tonic-gate
480Sstevel@tonic-gate    my $s = "@p";
490Sstevel@tonic-gate    $s =~ s/$CGI::Pretty::LINEBREAK/$CGI::Pretty::LINEBREAK$CGI::Pretty::INDENT/g if $CGI::Pretty::LINEBREAK;
500Sstevel@tonic-gate
510Sstevel@tonic-gate    return $self->SUPER::comment( "$CGI::Pretty::LINEBREAK$CGI::Pretty::INDENT$s$CGI::Pretty::LINEBREAK" ) . $CGI::Pretty::LINEBREAK;
520Sstevel@tonic-gate}
530Sstevel@tonic-gate
540Sstevel@tonic-gatesub _make_tag_func {
550Sstevel@tonic-gate    my ($self,$tagname) = @_;
560Sstevel@tonic-gate
570Sstevel@tonic-gate    # As Lincoln as noted, the last else clause is VERY hairy, and it
580Sstevel@tonic-gate    # took me a while to figure out what I was trying to do.
590Sstevel@tonic-gate    # What it does is look for tags that shouldn't be indented (e.g. PRE)
600Sstevel@tonic-gate    # and makes sure that when we nest tags, those tags don't get
610Sstevel@tonic-gate    # indented.
620Sstevel@tonic-gate    # For an example, try print td( pre( "hello\nworld" ) );
630Sstevel@tonic-gate    # If we didn't care about stuff like that, the code would be
640Sstevel@tonic-gate    # MUCH simpler.  BTW: I won't claim to be a regular expression
650Sstevel@tonic-gate    # guru, so if anybody wants to contribute something that would
660Sstevel@tonic-gate    # be quicker, easier to read, etc, I would be more than
670Sstevel@tonic-gate    # willing to put it in - Brian
680Sstevel@tonic-gate
690Sstevel@tonic-gate    my $func = qq"
700Sstevel@tonic-gate	sub $tagname {";
710Sstevel@tonic-gate
720Sstevel@tonic-gate    $func .= q'
730Sstevel@tonic-gate            shift if $_[0] &&
740Sstevel@tonic-gate                    (ref($_[0]) &&
750Sstevel@tonic-gate                     (substr(ref($_[0]),0,3) eq "CGI" ||
760Sstevel@tonic-gate                    UNIVERSAL::isa($_[0],"CGI")));
770Sstevel@tonic-gate	    my($attr) = "";
780Sstevel@tonic-gate	    if (ref($_[0]) && ref($_[0]) eq "HASH") {
790Sstevel@tonic-gate		my(@attr) = make_attributes(shift()||undef,1);
800Sstevel@tonic-gate		$attr = " @attr" if @attr;
810Sstevel@tonic-gate	    }';
820Sstevel@tonic-gate
830Sstevel@tonic-gate    if ($tagname=~/start_(\w+)/i) {
840Sstevel@tonic-gate	$func .= qq!
850Sstevel@tonic-gate            return "<\L$1\E\$attr>\$CGI::Pretty::LINEBREAK";} !;
860Sstevel@tonic-gate    } elsif ($tagname=~/end_(\w+)/i) {
870Sstevel@tonic-gate	$func .= qq!
880Sstevel@tonic-gate            return "<\L/$1\E>\$CGI::Pretty::LINEBREAK"; } !;
890Sstevel@tonic-gate    } else {
900Sstevel@tonic-gate	$func .= qq#
910Sstevel@tonic-gate	    return ( \$CGI::XHTML ? "<\L$tagname\E\$attr />" : "<\L$tagname\E\$attr>" ) .
920Sstevel@tonic-gate                   \$CGI::Pretty::LINEBREAK unless \@_;
930Sstevel@tonic-gate	    my(\$tag,\$untag) = ("<\L$tagname\E\$attr>","</\L$tagname>\E");
940Sstevel@tonic-gate
950Sstevel@tonic-gate            my \%ASIS = map { lc("\$_") => 1 } \@CGI::Pretty::AS_IS;
960Sstevel@tonic-gate            my \@args;
970Sstevel@tonic-gate            if ( \$CGI::Pretty::LINEBREAK || \$CGI::Pretty::INDENT ) {
980Sstevel@tonic-gate   	      if(ref(\$_[0]) eq 'ARRAY') {
990Sstevel@tonic-gate                 \@args = \@{\$_[0]}
1000Sstevel@tonic-gate              } else {
1010Sstevel@tonic-gate                  foreach (\@_) {
1020Sstevel@tonic-gate		      \$args[0] .= \$_;
1030Sstevel@tonic-gate                      \$args[0] .= \$CGI::Pretty::LINEBREAK if \$args[0] !~ /\$CGI::Pretty::LINEBREAK\$/ && 0;
1040Sstevel@tonic-gate                      chomp \$args[0] if exists \$ASIS{ "\L$tagname\E" };
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate  	              \$args[0] .= \$" if \$args[0] !~ /\$CGI::Pretty::LINEBREAK\$/ && 1;
1070Sstevel@tonic-gate		  }
1080Sstevel@tonic-gate                  chop \$args[0];
1090Sstevel@tonic-gate	      }
1100Sstevel@tonic-gate            }
1110Sstevel@tonic-gate            else {
1120Sstevel@tonic-gate              \@args = ref(\$_[0]) eq 'ARRAY' ? \@{\$_[0]} : "\@_";
1130Sstevel@tonic-gate            }
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate            my \@result;
1160Sstevel@tonic-gate            if ( exists \$ASIS{ "\L$tagname\E" } ) {
1170Sstevel@tonic-gate		\@result = map { "\$tag\$_\$untag\$CGI::Pretty::LINEBREAK" }
1180Sstevel@tonic-gate		 \@args;
1190Sstevel@tonic-gate	    }
1200Sstevel@tonic-gate	    else {
1210Sstevel@tonic-gate		\@result = map {
1220Sstevel@tonic-gate		    chomp;
1230Sstevel@tonic-gate		    my \$tmp = \$_;
1240Sstevel@tonic-gate		    CGI::Pretty::_prettyPrint( \\\$tmp );
1250Sstevel@tonic-gate                    \$tag . \$CGI::Pretty::LINEBREAK .
1260Sstevel@tonic-gate                    \$CGI::Pretty::INDENT . \$tmp . \$CGI::Pretty::LINEBREAK .
1270Sstevel@tonic-gate                    \$untag . \$CGI::Pretty::LINEBREAK
1280Sstevel@tonic-gate                } \@args;
1290Sstevel@tonic-gate	    }
1300Sstevel@tonic-gate	    local \$" = "" if \$CGI::Pretty::LINEBREAK || \$CGI::Pretty::INDENT;
1310Sstevel@tonic-gate	    return "\@result";
1320Sstevel@tonic-gate	}#;
1330Sstevel@tonic-gate    }
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate    return $func;
1360Sstevel@tonic-gate}
1370Sstevel@tonic-gate
1380Sstevel@tonic-gatesub start_html {
1390Sstevel@tonic-gate    return CGI::start_html( @_ ) . $CGI::Pretty::LINEBREAK;
1400Sstevel@tonic-gate}
1410Sstevel@tonic-gate
1420Sstevel@tonic-gatesub end_html {
1430Sstevel@tonic-gate    return CGI::end_html( @_ ) . $CGI::Pretty::LINEBREAK;
1440Sstevel@tonic-gate}
1450Sstevel@tonic-gate
1460Sstevel@tonic-gatesub new {
1470Sstevel@tonic-gate    my $class = shift;
1480Sstevel@tonic-gate    my $this = $class->SUPER::new( @_ );
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate    if ($CGI::MOD_PERL) {
1510Sstevel@tonic-gate        if ($CGI::MOD_PERL == 1) {
152*667Sps156622            my $r = Apache->request;
1530Sstevel@tonic-gate            $r->register_cleanup(\&CGI::Pretty::_reset_globals);
1540Sstevel@tonic-gate        }
1550Sstevel@tonic-gate        else {
156*667Sps156622            my $r = Apache2::RequestUtil->request;
1570Sstevel@tonic-gate            $r->pool->cleanup_register(\&CGI::Pretty::_reset_globals);
1580Sstevel@tonic-gate        }
1590Sstevel@tonic-gate    }
1600Sstevel@tonic-gate    $class->_reset_globals if $CGI::PERLEX;
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate    return bless $this, $class;
1630Sstevel@tonic-gate}
1640Sstevel@tonic-gate
1650Sstevel@tonic-gatesub initialize_globals {
1660Sstevel@tonic-gate    # This is the string used for indentation of tags
1670Sstevel@tonic-gate    $CGI::Pretty::INDENT = "\t";
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate    # This is the string used for seperation between tags
1700Sstevel@tonic-gate    $CGI::Pretty::LINEBREAK = $/;
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate    # These tags are not prettify'd.
1730Sstevel@tonic-gate    @CGI::Pretty::AS_IS = qw( a pre code script textarea td );
1740Sstevel@tonic-gate
1750Sstevel@tonic-gate    1;
1760Sstevel@tonic-gate}
1770Sstevel@tonic-gatesub _reset_globals { initialize_globals(); }
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate1;
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate=head1 NAME
1820Sstevel@tonic-gate
1830Sstevel@tonic-gateCGI::Pretty - module to produce nicely formatted HTML code
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate=head1 SYNOPSIS
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate    use CGI::Pretty qw( :html3 );
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate    # Print a table with a single data element
1900Sstevel@tonic-gate    print table( TR( td( "foo" ) ) );
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate=head1 DESCRIPTION
1930Sstevel@tonic-gate
1940Sstevel@tonic-gateCGI::Pretty is a module that derives from CGI.  It's sole function is to
1950Sstevel@tonic-gateallow users of CGI to output nicely formatted HTML code.
1960Sstevel@tonic-gate
1970Sstevel@tonic-gateWhen using the CGI module, the following code:
1980Sstevel@tonic-gate    print table( TR( td( "foo" ) ) );
1990Sstevel@tonic-gate
2000Sstevel@tonic-gateproduces the following output:
2010Sstevel@tonic-gate    <TABLE><TR><TD>foo</TD></TR></TABLE>
2020Sstevel@tonic-gate
2030Sstevel@tonic-gateIf a user were to create a table consisting of many rows and many columns,
2040Sstevel@tonic-gatethe resultant HTML code would be quite difficult to read since it has no
2050Sstevel@tonic-gatecarriage returns or indentation.
2060Sstevel@tonic-gate
2070Sstevel@tonic-gateCGI::Pretty fixes this problem.  What it does is add a carriage
2080Sstevel@tonic-gatereturn and indentation to the HTML code so that one can easily read
2090Sstevel@tonic-gateit.
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate    print table( TR( td( "foo" ) ) );
2120Sstevel@tonic-gate
2130Sstevel@tonic-gatenow produces the following output:
2140Sstevel@tonic-gate    <TABLE>
2150Sstevel@tonic-gate       <TR>
2160Sstevel@tonic-gate          <TD>
2170Sstevel@tonic-gate             foo
2180Sstevel@tonic-gate          </TD>
2190Sstevel@tonic-gate       </TR>
2200Sstevel@tonic-gate    </TABLE>
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate=head2 Tags that won't be formatted
2240Sstevel@tonic-gate
2250Sstevel@tonic-gateThe <A> and <PRE> tags are not formatted.  If these tags were formatted, the
2260Sstevel@tonic-gateuser would see the extra indentation on the web browser causing the page to
2270Sstevel@tonic-gatelook different than what would be expected.  If you wish to add more tags to
2280Sstevel@tonic-gatethe list of tags that are not to be touched, push them onto the C<@AS_IS> array:
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate    push @CGI::Pretty::AS_IS,qw(CODE XMP);
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate=head2 Customizing the Indenting
2330Sstevel@tonic-gate
2340Sstevel@tonic-gateIf you wish to have your own personal style of indenting, you can change the
2350Sstevel@tonic-gateC<$INDENT> variable:
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate    $CGI::Pretty::INDENT = "\t\t";
2380Sstevel@tonic-gate
2390Sstevel@tonic-gatewould cause the indents to be two tabs.
2400Sstevel@tonic-gate
2410Sstevel@tonic-gateSimilarly, if you wish to have more space between lines, you may change the
2420Sstevel@tonic-gateC<$LINEBREAK> variable:
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate    $CGI::Pretty::LINEBREAK = "\n\n";
2450Sstevel@tonic-gate
2460Sstevel@tonic-gatewould create two carriage returns between lines.
2470Sstevel@tonic-gate
2480Sstevel@tonic-gateIf you decide you want to use the regular CGI indenting, you can easily do
2490Sstevel@tonic-gatethe following:
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate    $CGI::Pretty::INDENT = $CGI::Pretty::LINEBREAK = "";
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate=head1 BUGS
2540Sstevel@tonic-gate
2550Sstevel@tonic-gateThis section intentionally left blank.
2560Sstevel@tonic-gate
2570Sstevel@tonic-gate=head1 AUTHOR
2580Sstevel@tonic-gate
2590Sstevel@tonic-gateBrian Paulsen <Brian@ThePaulsens.com>, with minor modifications by
2600Sstevel@tonic-gateLincoln Stein <lstein@cshl.org> for incorporation into the CGI.pm
2610Sstevel@tonic-gatedistribution.
2620Sstevel@tonic-gate
2630Sstevel@tonic-gateCopyright 1999, Brian Paulsen.  All rights reserved.
2640Sstevel@tonic-gate
2650Sstevel@tonic-gateThis library is free software; you can redistribute it and/or modify
2660Sstevel@tonic-gateit under the same terms as Perl itself.
2670Sstevel@tonic-gate
2680Sstevel@tonic-gateBug reports and comments to Brian@ThePaulsens.com.  You can also write
2690Sstevel@tonic-gateto lstein@cshl.org, but this code looks pretty hairy to me and I'm not
2700Sstevel@tonic-gatesure I understand it!
2710Sstevel@tonic-gate
2720Sstevel@tonic-gate=head1 SEE ALSO
2730Sstevel@tonic-gate
2740Sstevel@tonic-gateL<CGI>
2750Sstevel@tonic-gate
2760Sstevel@tonic-gate=cut
277