Move CGI.pm from lib to ext
[p5sagit/p5-mst-13.2.git] / ext / CGI / lib / CGI / Pretty.pm
CommitLineData
3538e1d5 1package CGI::Pretty;
2
3# See the bottom of this file for the POD documentation. Search for the
4# string '=head'.
5
6# You can run this file through either pod2man or pod2html to produce pretty
7# documentation in manual or html file format (these utilities are part of the
8# Perl 5 distribution).
9
ffd2dff2 10use strict;
3538e1d5 11use CGI ();
12
68a4c8b9 13$CGI::Pretty::VERSION = '3.44';
3538e1d5 14$CGI::DefaultClass = __PACKAGE__;
ffd2dff2 15$CGI::Pretty::AutoloadClass = 'CGI';
16@CGI::Pretty::ISA = qw( CGI );
3538e1d5 17
ffd2dff2 18initialize_globals();
19
20sub _prettyPrint {
21 my $input = shift;
188ba755 22 return if !$$input;
23 return if !$CGI::Pretty::LINEBREAK || !$CGI::Pretty::INDENT;
24
25# print STDERR "'", $$input, "'\n";
ffd2dff2 26
27 foreach my $i ( @CGI::Pretty::AS_IS ) {
188ba755 28 if ( $$input =~ m{</$i>}si ) {
29 my ( $a, $b, $c ) = $$input =~ m{(.*)(<$i[\s/>].*?</$i>)(.*)}si;
30 next if !$b;
31 $a ||= "";
32 $c ||= "";
33
34 _prettyPrint( \$a ) if $a;
35 _prettyPrint( \$c ) if $c;
ffd2dff2 36
188ba755 37 $b ||= "";
38 $$input = "$a$b$c";
ffd2dff2 39 return;
40 }
41 }
188ba755 42 $$input =~ s/$CGI::Pretty::LINEBREAK/$CGI::Pretty::LINEBREAK$CGI::Pretty::INDENT/g;
ffd2dff2 43}
44
45sub comment {
46 my($self,@p) = CGI::self_or_CGI(@_);
47
48 my $s = "@p";
ba056755 49 $s =~ s/$CGI::Pretty::LINEBREAK/$CGI::Pretty::LINEBREAK$CGI::Pretty::INDENT/g if $CGI::Pretty::LINEBREAK;
ffd2dff2 50
51 return $self->SUPER::comment( "$CGI::Pretty::LINEBREAK$CGI::Pretty::INDENT$s$CGI::Pretty::LINEBREAK" ) . $CGI::Pretty::LINEBREAK;
52}
3538e1d5 53
54sub _make_tag_func {
55 my ($self,$tagname) = @_;
3538e1d5 56
ffd2dff2 57 # As Lincoln as noted, the last else clause is VERY hairy, and it
58 # took me a while to figure out what I was trying to do.
59 # What it does is look for tags that shouldn't be indented (e.g. PRE)
60 # and makes sure that when we nest tags, those tags don't get
61 # indented.
62 # For an example, try print td( pre( "hello\nworld" ) );
63 # If we didn't care about stuff like that, the code would be
64 # MUCH simpler. BTW: I won't claim to be a regular expression
65 # guru, so if anybody wants to contribute something that would
66 # be quicker, easier to read, etc, I would be more than
67 # willing to put it in - Brian
3538e1d5 68
188ba755 69 my $func = qq"
70 sub $tagname {";
71
72 $func .= q'
73 shift if $_[0] &&
74 (ref($_[0]) &&
75 (substr(ref($_[0]),0,3) eq "CGI" ||
76 UNIVERSAL::isa($_[0],"CGI")));
77 my($attr) = "";
78 if (ref($_[0]) && ref($_[0]) eq "HASH") {
79 my(@attr) = make_attributes(shift()||undef,1);
80 $attr = " @attr" if @attr;
81 }';
82
83 if ($tagname=~/start_(\w+)/i) {
84 $func .= qq!
85 return "<\L$1\E\$attr>\$CGI::Pretty::LINEBREAK";} !;
86 } elsif ($tagname=~/end_(\w+)/i) {
87 $func .= qq!
88 return "<\L/$1\E>\$CGI::Pretty::LINEBREAK"; } !;
89 } else {
90 $func .= qq#
91 return ( \$CGI::XHTML ? "<\L$tagname\E\$attr />" : "<\L$tagname\E\$attr>" ) .
92 \$CGI::Pretty::LINEBREAK unless \@_;
93 my(\$tag,\$untag) = ("<\L$tagname\E\$attr>","</\L$tagname>\E");
94
95 my \%ASIS = map { lc("\$_") => 1 } \@CGI::Pretty::AS_IS;
96 my \@args;
97 if ( \$CGI::Pretty::LINEBREAK || \$CGI::Pretty::INDENT ) {
98 if(ref(\$_[0]) eq 'ARRAY') {
99 \@args = \@{\$_[0]}
100 } else {
101 foreach (\@_) {
102 \$args[0] .= \$_;
103 \$args[0] .= \$CGI::Pretty::LINEBREAK if \$args[0] !~ /\$CGI::Pretty::LINEBREAK\$/ && 0;
104 chomp \$args[0] if exists \$ASIS{ "\L$tagname\E" };
105
106 \$args[0] .= \$" if \$args[0] !~ /\$CGI::Pretty::LINEBREAK\$/ && 1;
107 }
68a4c8b9 108 chop \$args[0] unless \$" eq "";
188ba755 109 }
110 }
111 else {
112 \@args = ref(\$_[0]) eq 'ARRAY' ? \@{\$_[0]} : "\@_";
113 }
114
115 my \@result;
116 if ( exists \$ASIS{ "\L$tagname\E" } ) {
ffd2dff2 117 \@result = map { "\$tag\$_\$untag\$CGI::Pretty::LINEBREAK" }
188ba755 118 \@args;
3538e1d5 119 }
120 else {
121 \@result = map {
122 chomp;
188ba755 123 my \$tmp = \$_;
124 CGI::Pretty::_prettyPrint( \\\$tmp );
125 \$tag . \$CGI::Pretty::LINEBREAK .
126 \$CGI::Pretty::INDENT . \$tmp . \$CGI::Pretty::LINEBREAK .
127 \$untag . \$CGI::Pretty::LINEBREAK
ac734d8b 128 } \@args;
3538e1d5 129 }
68a4c8b9 130 if (\$CGI::Pretty::LINEBREAK || \$CGI::Pretty::INDENT) {
131 return join ("", \@result);
132 } else {
133 return "\@result";
134 }
188ba755 135 }#;
136 }
137
138 return $func;
3538e1d5 139}
140
ffd2dff2 141sub start_html {
142 return CGI::start_html( @_ ) . $CGI::Pretty::LINEBREAK;
143}
144
145sub end_html {
146 return CGI::end_html( @_ ) . $CGI::Pretty::LINEBREAK;
147}
148
3538e1d5 149sub new {
150 my $class = shift;
151 my $this = $class->SUPER::new( @_ );
152
8f3ccfa2 153 if ($CGI::MOD_PERL) {
8f3ccfa2 154 if ($CGI::MOD_PERL == 1) {
741ff09d 155 my $r = Apache->request;
8f3ccfa2 156 $r->register_cleanup(\&CGI::Pretty::_reset_globals);
157 }
158 else {
741ff09d 159 my $r = Apache2::RequestUtil->request;
8f3ccfa2 160 $r->pool->cleanup_register(\&CGI::Pretty::_reset_globals);
161 }
162 }
ffd2dff2 163 $class->_reset_globals if $CGI::PERLEX;
164
3538e1d5 165 return bless $this, $class;
166}
167
ffd2dff2 168sub initialize_globals {
169 # This is the string used for indentation of tags
170 $CGI::Pretty::INDENT = "\t";
171
172 # This is the string used for seperation between tags
188ba755 173 $CGI::Pretty::LINEBREAK = $/;
ffd2dff2 174
175 # These tags are not prettify'd.
188ba755 176 @CGI::Pretty::AS_IS = qw( a pre code script textarea td );
ffd2dff2 177
178 1;
179}
180sub _reset_globals { initialize_globals(); }
181
f8a128a9 182# ugly, but quick fix
183sub import {
184 my $self = shift;
185 no strict 'refs';
186 ${ "$self\::AutoloadClass" } = 'CGI';
187
188 # This causes modules to clash.
189 undef %CGI::EXPORT;
190 undef %CGI::EXPORT;
191
192 $self->_setup_symbols(@_);
193 my ($callpack, $callfile, $callline) = caller;
194
195 # To allow overriding, search through the packages
196 # Till we find one in which the correct subroutine is defined.
197 my @packages = ($self,@{"$self\:\:ISA"});
198 foreach my $sym (keys %CGI::EXPORT) {
199 my $pck;
200 my $def = ${"$self\:\:AutoloadClass"} || $CGI::DefaultClass;
201 foreach $pck (@packages) {
202 if (defined(&{"$pck\:\:$sym"})) {
203 $def = $pck;
204 last;
205 }
206 }
207 *{"${callpack}::$sym"} = \&{"$def\:\:$sym"};
208 }
209}
210
3538e1d5 2111;
212
213=head1 NAME
214
215CGI::Pretty - module to produce nicely formatted HTML code
216
217=head1 SYNOPSIS
218
219 use CGI::Pretty qw( :html3 );
220
221 # Print a table with a single data element
222 print table( TR( td( "foo" ) ) );
223
224=head1 DESCRIPTION
225
226CGI::Pretty is a module that derives from CGI. It's sole function is to
227allow users of CGI to output nicely formatted HTML code.
228
229When using the CGI module, the following code:
230 print table( TR( td( "foo" ) ) );
231
232produces the following output:
233 <TABLE><TR><TD>foo</TD></TR></TABLE>
234
235If a user were to create a table consisting of many rows and many columns,
236the resultant HTML code would be quite difficult to read since it has no
237carriage returns or indentation.
238
239CGI::Pretty fixes this problem. What it does is add a carriage
240return and indentation to the HTML code so that one can easily read
241it.
242
243 print table( TR( td( "foo" ) ) );
244
245now produces the following output:
246 <TABLE>
247 <TR>
248 <TD>
249 foo
250 </TD>
251 </TR>
252 </TABLE>
253
254
255=head2 Tags that won't be formatted
256
257The <A> and <PRE> tags are not formatted. If these tags were formatted, the
258user would see the extra indentation on the web browser causing the page to
259look different than what would be expected. If you wish to add more tags to
260the list of tags that are not to be touched, push them onto the C<@AS_IS> array:
261
262 push @CGI::Pretty::AS_IS,qw(CODE XMP);
263
ffd2dff2 264=head2 Customizing the Indenting
265
266If you wish to have your own personal style of indenting, you can change the
267C<$INDENT> variable:
268
269 $CGI::Pretty::INDENT = "\t\t";
270
271would cause the indents to be two tabs.
272
273Similarly, if you wish to have more space between lines, you may change the
274C<$LINEBREAK> variable:
275
276 $CGI::Pretty::LINEBREAK = "\n\n";
277
278would create two carriage returns between lines.
279
280If you decide you want to use the regular CGI indenting, you can easily do
281the following:
282
283 $CGI::Pretty::INDENT = $CGI::Pretty::LINEBREAK = "";
284
3538e1d5 285=head1 BUGS
286
287This section intentionally left blank.
288
289=head1 AUTHOR
290
ffd2dff2 291Brian Paulsen <Brian@ThePaulsens.com>, with minor modifications by
3538e1d5 292Lincoln Stein <lstein@cshl.org> for incorporation into the CGI.pm
293distribution.
294
ffd2dff2 295Copyright 1999, Brian Paulsen. All rights reserved.
3538e1d5 296
297This library is free software; you can redistribute it and/or modify
298it under the same terms as Perl itself.
299
ffd2dff2 300Bug reports and comments to Brian@ThePaulsens.com. You can also write
3538e1d5 301to lstein@cshl.org, but this code looks pretty hairy to me and I'm not
302sure I understand it!
303
304=head1 SEE ALSO
305
306L<CGI>
307
308=cut