0: package STDOUT::Capture;
1: use strict;
2: use Carp qw(confess);
3:
4: # Read ze POD, ze POD! :)
5: #
6: # A complete tarball with some examples and a
7: # HTML version of the POD can currently be found at:
8: #
9: # http://dogandpony.perlmonk.org
10: # /downloads/perl/STDOUT-Capture-0.01.tar.gz
11: #
12: # Comments, suggestions, previous art etc.
13: # is very welcome.
14:
15: use vars qw($VERSION $stdout %callbacks);
16: $VERSION = 0.01;
17:
18: sub TIEHANDLE
19: {
20: bless {}, shift;
21: }
22:
23: # Capture all that is printed, and do callbacks etc.
24: sub PRINT
25: {
26: shift; # Throw away.
27:
28: my $input = join '', @_;
29: if(exists $callbacks{'on_print'})
30: {
31: $callbacks{'on_print'}->(\$input);
32: }
33: $stdout .= $input;
34: }
35:
36: sub BINMODE
37: {
38: # Finish all such manipluation before tieing STDOUT:
39: confess "Too late for binmode. If you are using CGI.pm, "
40: . "try to use it before you use this module.";
41: }
42:
43: # Tie STDOUT, and set up any callbacks:
44: sub import
45: {
46: my $self = shift;
47:
48: %callbacks = @_;
49: tie *STDOUT, __PACKAGE__;
50: }
51:
52: # Lastly, flush the output we do have:
53: END
54: {
55: if(exists $callbacks{'on_finish'})
56: {
57: $callbacks{'on_finish'}->(\$stdout);
58: }
59:
60: untie *STDOUT;
61: print $stdout;
62: }
63:
64: =head1 NAME
65:
66: STDOUT::Capture - Simple base package for capturing
67: the output of STDOUT from your programs.
68:
69:
70: =head1 SYNOPSIS
71:
72: # In MyCapture.pm:
73:
74: package MyCapture;
75:
76: use STDOUT::Capture on_finish => \&on_finish;
77:
78: sub on_finish
79: {
80: my $stdout_ref = shift;
81:
82: # Insert a stylesheet link last in the head section
83: $$stdout_ref =~
84: s{(</head>)}
85: {<link rel="stylesheet" type="text/css" href="/css/style.css" />\n$1}i;
86: }
87: 1;
88:
89: # In your program:
90:
91: use CGI qw(:standard); # import CGI.pm first!
92: use MyCapture; # import your callbacks, capture STDOUT
93:
94: print header;
95: print start_html(-title => 'Cool CGI program');
96: print h1('Welcome to my cool CGI!');
97: print p('This is just a test page.');
98: print end_html;
99:
100:
101: See the examples/ directory of this distribution for other,
102: and non-CGI related examples.
103:
104:
105: =head1 DESCRIPTION
106:
107: STDOUT::Capture is a base package for creating packages that can be
108: used to manipulate the output of your programs.
109:
110: Typical usage might be if you already have some CGI scripts that you
111: want to use on your site, but do not want to code the layout into
112: them. Examples of this could be if you want to be able to display
113: the raw code for them easily (without the layout stuff), if you want
114: to use the same program on several sites or if you just are lazy or
115: want a quick and dirty solution.
116:
117: You could also use it if you have a normal, non-CGI program that you
118: want to display the output of, as CGI, without recoding the program
119: itself.
120:
121: Other uses include mailing the output of your program somewhere, or
122: look for certain patterns in a resuable way, and without having to
123: set up "complex" commands in cron or the like.
124:
125: STDOUT::Capture works by capturing all prints to STDOUT and providing
126: callbacks for each one, or for all of it at once. You get a reference
127: to the current (or all) text that is to be printed, and can manipulate
128: it before it is finally sent out.
129:
130: I started writing this because I considered redesigning a web site a
131: little, and figured I could get away with a little CSS, and simple
132: output for most things, and maybe use HTML::Template for the extras.
133: But I didn't really want to go in and prod inside all my CGI programs
134: to add this new look, even though it wasn't much, and figured that
135: maybe I could write a wrapper instead.
136:
137: That way, all my CGI:s have just one extra line of code, which is the
138: use statement for my redesign module. So the scripts are still very
139: movable, and clean, plus I need only change something in one place.
140:
141: Had I used HTML::Template or some such in the beginning, I could have
142: avoided this, but with this, I can even switch HTML::Template out and
143: in, with almost no hassle at all. Depending on how much rework of the
144: output one does, however, it may be too much overhead.
145:
146: Then I realized this module could be used for all sorts of other things
147: too, preferably when something is already in place and tough to change,
148: so I renamed it STDOUT::Capture, from CGI::Capture which was the
149: intended name.
150:
151:
152: =head1 USAGE
153:
154: Your package, that contains your callbacks, extends STDOUT::Capture.
155: Depending on which callbacks you choose, you will get the chance to
156: modify the output from prints on STDOUT before they are actually
157: printed.
158:
159: Current callbacks are B<on_print>, which is called on each print,
160: and B<on_finish> that is called upon exit of the program, with
161: all output. You set them up in your package that inherits from
162: STDOUT::Capture as you call use, like so:
163:
164: use STDOUT::Capture on_finish => \&on_finish,
165: on_print => \&on_print;
166:
167: sub on_print
168: {
169: my $$stdout_ref = shift;
170: # Do stuff on the current print
171: }
172:
173: sub on_finish
174: {
175: my $$stdout_ref = shift;
176: # Do stuff on all output
177: }
178:
179: Input to these subs is a scalar reference that holds the contents
180: of either the current print (B<on_print>) or the total output upon
181: finish of the program (B<on_finish>). You can prod, look at and
182: manipulate the contents of this scalar as you wish.
183:
184: The callbacks expect no return value, you only modify the scalar
185: reference in place.
186:
187:
188: =head2 Using STDOUT::Capture together with CGI.pm
189:
190: CGI.pm wants to do some things to STDOUT upon initialize, in
191: particular it wants to set binmode on certain platforms. So when
192: you are using CGI.pm together with this, you should use CGI.pm
193: I<before> your own derived class, like so:
194:
195: use CGI;
196: use MyCapture;
197:
198: # Rest of program...
199:
200: This will let CGI set up all things it wants to to do STDOUT
201: before we tie it down.
202:
203: =head2 Using STDOUT::Capture together with CGI::Carp
204:
205: CGI::Carp, when "fatalsToBrowser" is imported, will emit the
206: warnings on STDOUT, so you can (and will) capture that just
207: as any other output and display it nicely formatted.
208:
209: There are some caveats though, since the output from
210: fatalsToBrowser is pretty terse - for instance, in the normal
211: case it is probably likely that you would like to seach for
212: everything inside the body tags, but CGI::Carp does not emit
213: any body tags. So you will have to compensate for that, if
214: you wish this information to still be printed (maybe check
215: for the event of no body tag present?).
216:
217:
218: =head1 CAVEATS
219:
220: STDOUT::Capture prevents autoflushing, since it captures all
221: the output and flushes it all when it exits.
222:
223:
224: =head1 AUTHOR
225:
226: Kristoffer Lundén
227: kung.stoffe@home.se
228:
229:
230: =head1 COPYRIGHT
231:
232: Copyright (c) 2002 Kristoffer Lundén. All rights reserved.
233: This program is free software; you can redistribute
234: it and/or modify it under the same terms as Perl itself.
235:
236: The full text of the license can be found in the
237: LICENSE file included with this module.
238:
239:
240: =head1 SEE ALSO
241:
242: L<perltie>, L<CGI.pm>, L<CGI::Carp>
243:
244:
245: =cut
246:
247: 1;
In reply to STDOUT::Capture - manipulate STDOUT by Dog and Pony
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |