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