This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: Finance/YahooChart,  Next: Finance/YahooQuote,  Prev: Finance/QuoteHist/Yahoo,  Up: Module List

Get a chart from Yahoo! Finance
*******************************

NAME
====

   Finance::YahooChart - Get a chart from Yahoo! Finance

SYNOPSIS
========

     use Finance::YahooChart;
     %img = getchart(symbol => $symbol, size => $size, type => $type,
     		  include => $include);
     print "<IMG SRC=$img{'url'} WIDTH=$img{'width'} HEIGHT=$img{'height'}>";

DESCRIPTION
===========

   This module gets charts from Yahoo! Finance.  The only function in the
module is the *getchart* function, which takes the stock symbol, size of
the chart (b for big, s for small), the type of chart (i for intraday, w
for week, 3 for 3-month, 1 for 1-year, 2 for 2-year, and 5 for 5-year),
and any extra information to include (s for a comparison to the S&P 500, m
for a moving average).  It returns a hash with the following elements:

     'url' => The URL of the chart
     'width' => The width of the chart
     'height' => The height of the chart

   Note that not all combinations are available for all charts.

   Big charts are available for all types.

   Small charts are only available for i, w, and 1 charts.

   Includes are only available for big 3, 1, 2, and 5 charts.

   In most cases, if an invalid configuration is passed,
*$Finance::YahooChart::Error* will be set to some kind of error message.

COPYRIGHT
=========

   Copyright 1998, Dj Padzensky

   This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.

   The information that you obtain with this library may be copyrighted by
Yahoo! Inc., and is governed by their usage license.  See
http://www.yahoo.com/docs/info/gen_disclaimer.html for more information.

AUTHOR
======

   Dj Padzensky (`djpadz@padz.net'), PadzNet, Inc.

   The Finance::YahooChart home page can be found at
http://www.padz.net/~djpadz/YahooChart/


File: pm.info,  Node: Finance/YahooQuote,  Next: FindBin,  Prev: Finance/YahooChart,  Up: Module List

Get a stock quote from Yahoo!
*****************************

NAME
====

   Finance::YahooQuote - Get a stock quote from Yahoo!

SYNOPSIS
========

     use Finance::YahooQuote;
     $Finance::YahooQuote::TIMEOUT = 60;
     @quote = getonequote $symbol;	# Get a quote for a single symbol
     @quotes = getquote @symbols;	# Get quotes for a bunch of symbols

DESCRIPTION
===========

   This module gets stock quotes from Yahoo! Finance.  The *getonequote*
function will return a quote for a single stock symbol, while the
*getquote* function will return a quote for each of the stock symbols
passed to it.  The return value of *getonequote* is an array, with the
following elements:

     0 Symbol
     1 Company Name
     2 Last Price
     3 Last Trade Date
     4 Last Trade Time
     5 Change
     6 Percent Change
     7 Volume
     8 Average Daily Vol
     9 Bid
     10 Ask
     11 Previous Close
     12 Today's Open
     13 Day's Range
     14 52-Week Range
     15 Earnings per Share
     16 P/E Ratio
     17 Dividend Pay Date
     18 Dividend per Share
     19 Dividend Yield
     20 Market Capitalization
     21 Stock Exchange

   The *getquote* function returns an array of pointers to arrays with the
above structure.

   You may optionally override the default LWP timeout of 180 seconds by
setting $Finance::YahooQuote::TIMEOUT to your preferred value.

FAQ
===

   If there's one question I get asked over and over again, it's how did I
figure out the format string?  Having typed the answer in innumerable
emails, I figure sticking it directly into the man page might help save my
fingers a bit...

   If you have a My Yahoo! (http://my.yahoo.com) account, go to the
following URL:

     http://edit.my.yahoo.com/config/edit_pfview?.vk=v1

   Viewing the source of this page, you'll come across the section that
defines the menus that let you select which elements go into a particular
view.  The <option> values are the strings that pick up the information
described in the menu item.  For example, Symbol refers to the string "s"
and name refers to the string "l".  Using "sl" as the format string, we
would get the symbol followed by the name of the security.

   If you have questions regarding this, play around with $QURL, changing
the value of the f parameter.

COPYRIGHT
=========

   Copyright 1998, Dj Padzensky

   This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.

   The information that you obtain with this library may be copyrighted by
Yahoo! Inc., and is governed by their usage license.  See
http://www.yahoo.com/docs/info/gen_disclaimer.html for more information.

AUTHOR
======

   Dj Padzensky (`djpadz@padz.net'), PadzNet, Inc.

SEE ALSO
========

   The Finance::YahooQuote home page can be found at
http://www.padz.net/~djpadz/YahooQuote/

   Show Me The Money, a derivative work by Dirk Eddelbüttel, that uses
Finance::YahooQuote in a graphical environment, can be found at
http://rosebud.sps.queensu.ca/~edd/code/smtm.html.


File: pm.info,  Node: FindBin,  Next: FirstGoodURL,  Prev: Finance/YahooQuote,  Up: Module List

Locate directory of original perl script
****************************************

NAME
====

   FindBin - Locate directory of original perl script

SYNOPSIS
========

     use FindBin;
     use lib "$FindBin::Bin/../lib";

     or

     use FindBin qw($Bin);
     use lib "$Bin/../lib";

DESCRIPTION
===========

   Locates the full path to the script bin directory to allow the use of
paths relative to the bin directory.

   This allows a user to setup a directory tree for some software with
directories <root>/bin and <root>/lib and then the above example will allow
the use of modules in the lib directory without knowing where the software
tree is installed.

   If perl is invoked using the -e option or the perl script is read from
STDIN then FindBin sets both `$Bin' and `$RealBin' to the current
directory.

EXPORTABLE VARIABLES
====================

     $Bin         - path to bin directory from where script was invoked
     $Script      - basename of script from which perl was invoked
     $RealBin     - $Bin with all links resolved
     $RealScript  - $Script with all links resolved

KNOWN BUGS
==========

   if perl is invoked as

     perl filename

   and filename does not have executable rights and a program called
filename exists in the users `$ENV{PATH}' which satisfies both -x and -T
then FindBin assumes that it was invoked via the `$ENV{PATH}'.

   Workaround is to invoke perl as

     perl ./filename

AUTHORS
=======

   FindBin is supported as part of the core perl distribution. Please send
bug reports to <`perlbug@perl.org'> using the perlbug program included
with perl.

   Graham Barr <`gbarr@pobox.com'> Nick Ing-Simmons <`nik@tiuk.ti.com'>

COPYRIGHT
=========

   Copyright (c) 1995 Graham Barr & Nick Ing-Simmons. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.


File: pm.info,  Node: FirstGoodURL,  Next: Font/AFM,  Prev: FindBin,  Up: Module List

determines first successful URL in list
***************************************

NAME
====

   FirstGoodURL - determines first successful URL in list

SYNOPSIS
========

     use FirstGoodURL;
     use strict;
     
     my @URLs = (...);
     my $match;
     
     if ($match = FirstGoodURL->in(@URLs)) {
       print "good URL: $match\n";
     }
     else {
       print "no URL was alive\n";
     }
     
     if ($match = FirstGoodURL->with('image/png')->in(@URLs)) {
       print "PNG found at $match\n";
     }
     else {
       print "no PNG found\n";
     }
     
     if ($match = FirstGoodURL->with(200,204)->in(@URLs)) {
       print "Status: OK or No Content at $match\n";
     }
     else {
       print "no 200/204 found\n";
     }

DESCRIPTION
===========

   This module uses the LWP suite to scan through a list of URLs.  It
determines the first URL that returns a specified status code (with
defaults to `200'), and optionally, a specified Content-type.

Methods
=======

   * `FirstGoodURL->in(...)'

     Scans a list of URLs for a specified response code, and possibly a
     requisite Content-type (see the with method below)

   * `FirstGoodURL->with(...)'

     Sets a Content-type and/or Status requisite value for future calls to
     in.  It is destructive to the previous settings given, so you must
     send all settings at once.

     *This is not backward compatible.*

     The argument list can contain a list of Status response codes, and
     either a list of Content-type response values or a regex to match
     acceptable Content-type response values.  These can appear in any
     order.  The regex must be a compiled one (formed by using `qr//').

     This method returns the class name, so that you can daisy-chain calls
     for readability/snazziness:

          my $match = FirstGoodURL->with(qr/image/)->in(@URLs);

TODO
====

   Here is a listing of things that might be added to future versions.

   * Object support (with attributes per object)

AUTHOR
======

     Jeff "japhy" Pinyan
     CPAN ID: PINYAN
     japhy@pobox.com
     http://www.pobox.com/~japhy/


File: pm.info,  Node: Font/AFM,  Next: Font/Fret,  Prev: FirstGoodURL,  Up: Module List

Interface to Adobe Font Metrics files
*************************************

NAME
====

   Font::AFM - Interface to Adobe Font Metrics files

SYNOPSIS
========

     use Font::AFM;
     $h = new Font::AFM "Helvetica";
     $copyright = $h->Notice;
     $w = $h->Wx->{"aring"};
     $w = $h->stringwidth("Gisle", 10);
     $h->dump;  # for debugging

DESCRIPTION
===========

   This module implements the Font::AFM class. Objects of this class are
initialised from an AFM-file and allows you to obtain information about
the font and the metrics of the various glyphs in the font.

   All measurements in AFM files are given in terms of units equal to
1/1000 of the scale factor of the font being used. To compute actual sizes
in a document, these amounts should be multiplied by (scale factor of
font)/1000.

   The following methods are available:

$afm = Font::AFM->new($fontname)
     Object constructor. Takes the name of the font as argument. It will
     croak if the font can not be found.

$afm->latin1_wx_table()
     Returns a 256 element array, where each element contains the width of
     the corresponding character in the iso-8859-1 character set.

$afm->stringwidth($string, [$fontsize])
     Returns the width of the string passed as argument. The string is
     assumed to be encoded in the iso-8859-1 character set.  A second
     argument can be used to scale the width according to the font size.

$afm->FontName
     The name of the font as presented to the PostScript language
     `findfont' operator, for instance "Times-Roman".

$afm->FullName
     Unique, human-readable name for an individual font, for instance
     "Times Roman".

$afm->FamilyName
     Human-readable name for a group of fonts that are stylistic variants
     of a single design. All fonts that are member of such a group should
     have exactly the same FamilyName. Example of a family name is "Times".

$afm->Weight
     Human-readable name for the weight, or "boldness", attribute of a
     font.  Exampes are `Roman', `Bold', `Light'.

$afm->ItalicAngle
     Angle in degrees counterclockwise from the vertical of the dominant
     vertical strokes of the font.

$afm->IsFixedPitch
     If the value is `true', it indicated that the font is a fixed-pitch
     (monospaced) font.

$afm->FontBBox
     A string of four numbers giving the lower-left x, lower-left y,
     upper-right x, and upper-right y of the font bounding box. The font
     bounding box is the smallest rectangle enclosing the shape that would
     result if all the characters of the font were placed with their
     origins coincident, and then painted.

$afm->UnderlinePosition
     Recommended distance from the baseline for positioning underline
     stokes. This number is the y coordinate of the center of the stroke.

$afm->UnderlineThickness
     Recommended stroke width for underlining.

$afm->Version
     Version number of the font.

$afm->Notice
     Trademark or copyright notice, if applicable.

$afm->Comment
     Comments found in the AFM file.

$afm->EncodingScheme
     The name of the standard encoding scheme for the font. Most Adobe
     fonts use the `AdobeStandardEncoding'. Special fonts might state
     `FontSpecific'.

$afm->CapHeight
     Usually the y-value of the top of the capital H.

$afm->XHeight
     Typically the y-value of the top of the lowercase x.

$afm->Ascender
     Typically the y-value of the top of the lowercase d.

$afm->Descender
     Typically the y-value of the bottom of the lowercase p.

$afm->Wx
     Returns a hash table that maps from glyph names to the width of that
     glyph.

$afm->BBox
     Returns a hash table that maps from glyph names to bounding box
     information.  The bounding box consist of 4 numbers: llx, lly, urx,
     ury.

$afm->dump
     Dumps the content of the Font::AFM object to STDOUT.  Might sometimes
     be useful for debugging.

   The AFM specification can be found at:

     ftp://ftp.adobe.com/pub/adobe/DeveloperSupport/TechNotes/PSfiles/5004.AFM_Spec.ps

ENVIRONMENT
===========

METRICS
     Contains the path to seach for AFM-files.  Format is as for the PATH
     environment variable. The default path built into this library is:

          /usr/lib/afm:/usr/local/lib/afm:/usr/openwin/lib/fonts/afm/:.

BUGS
====

   Kerning data and composite character data is not yet parsed.  Ligature
data is not parsed.

COPYRIGHT
=========

   Copyright 1995-1998 Gisle Aas. All rights reserved.

   This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.


File: pm.info,  Node: Font/Fret,  Next: Font/TFM,  Prev: Font/AFM,  Up: Module List

Font REporting Tool
*******************

NAME
====

   Fret - Font REporting Tool

SYNOPSIS
========

     use Font::Fret;
     fret('', @ARGV);

   or

     package myFret;
     use Font::Fret;
     @ISA = qw(Font::Fret::Default);
     fret('myFret', @ARGV);

DESCRIPTION
===========

   Fret is a font reporting tool system which allows for different reports
to be written. A report is a package on which calls are made to give
specific information for a specific report. The rest of Fret does the
housekeeping of generating the report in PDF format.

   The function `fret' which is imported when the Fret moduled is 'use'd,
takes two arguments: the name of the report package and the command line
array. Fret does all the work of parsing the command line, etc. and just
makes call-backs into the package it is asked to use.

   Fret.pm comes with its own default report package (called
Font::Fret::Default) which may be subclassed to generate other reports.

   The overall structure of the interaction between Fret and the reporting
package is that Fret will ask the package for a list of character ids in
the order in which those characters should appear in the report. For each
character, Fret will ask the package to create a glyph id for that
character. This allows a double layer of indirection in arriving at the
list of glyph ids to process, allowing a glyph to appear twice in the
report with different information about it each time.

   There are two important areas in a report: inside the glyph box (where
there are four corners in which information may be displayed) and the
report area, which consists of two independent rows of information for
each glyph. Each row type is columnated independently across all the
glyphs on a page.

   In addition to where the report information is displayed, there is also
a mechanism which allows a limited level of formatting of the information.
The text may be justified left, right or centre and the font styling may
be adjusted between regular, bold, italic and bold italic and the colour
of the text may be changed.  Notice that the font face may not be changed
or the font size or anything else.  A formatted string consists of
formatting information separated from the string by |. If a string needs
to contain a | it should be escaped thus: `\|' (notice that there is no
need to escape \ or any other character).

   The formatting is structured as a comma separated list of 3 elements:
justification, font styling and then colour.

justification
     The values are r: right justified; c: centred and the default of l:
     left justified

font styling
     The values are r: regular (by default); i: italic; b: bold; bi:
     bold-italic

colour
     The colour is a string of 6 hex digits corresponding to 8-bits of
     Red, Green and Blue information

METHODS
=======

make_cids
---------

   This subroutine is called to ask for a list of character ids, which
will be used to generate glyph ids and thence glyphs. The returned list is
rendered in the order of the list.

   The first item on the returned list is used to display the type of
report in the box header. This string may not be formatted.

   This allows a FRET report writer to generate any sequence of glyphs in
their report (e.g. Unicode based, pass/fail conditions, etc.)

cid_gid
-------

   This is called to convert a character id into a glyph id for rendering.

boxhdr
------

   This subroutine is called to ask the report for the headings for the
four items displayed in a box. The headings appear in the box header. The
order of the returned list of string is: bottom left, bottom right, top
left, top right.  The strings may not be formatted in any way.

topdat
------

   This subroutine returns the two strings that constitute what should be
displayed in the top of a glyph box. The two strings allow for per glyph
formatting. Notice that the default action is to render the right hand
element (the second element) right justified.

lowdat
------

   This subroutine returns two elements for the two elements displayed at
the bottom of a glyph box. The elements may be formatted for colour, etc.
and the second should be right formatted.

row1hdr
-------

   This returns the heading information for the first report row. The
value returned is a list of formatted items, which will be used to head
the columns in row 1 of the report area. These will be combined in the
column width calculations.

row2hdr
-------

   Returns a list of formatted items corresponding to the column headers
for row 2 of the report area.

row1
----

   This subroutine is called for each glyph to return the content of each
column in row 1 as a list of formatted items. The values passed in are:

     cid     character id as passed to cid_gid
     gid     glyph id as returned from cid_gid and is an index into the font
             for such tables as hmtx.
     glyph   the glyph object from the font i.e. $font->{'loca'}{glyphs}[$gid]
     uid     unicode reverse lookup of the gid. This is the lowest Unicode value
             which maps to this gid
     font    the font object corresponding to this font

   Each element in the returned list corresponds to an element in the
returned list for row1hdr

row2
----

   As per row 1 for row 2

label
-----

   Given:

     Glyph
     Point number
     [x, y] point co-ordinates
     path number
     on or off point
     font

   Returns a simple string for the label for the point


File: pm.info,  Node: Font/TFM,  Next: FormMagick,  Prev: Font/Fret,  Up: Module List

read information from TeX font metric files
*******************************************

NAME
====

   Font::TFM - read information from TeX font metric files

SYNOPSIS
========

     use Font::TFM;
     ### $Font::TFM::TEXFONTSDIR = 'your directories';
     ### to change the default

     my $cmr = new Font::TFM 'cmr10'
     	or die "Error reading font: $Font::TFM::errstr\n";
     print 'Designsize: ', $cmr->designsize(), "\n";
     print $cmr->width('A'), ', ', $cmr->kern('Wo'), "\n";

   should print

     Designsize: 10
     491521.25, -54613.75

DESCRIPTION
===========

   To read the information from TFM (TeX font metrics) file, you first
create the object of *Font::TFM* class in memory. You do this by calling
method *Font::TFM::new* with font name and it creates a new TFM object in
memory, loading all the necessary information from the `.tfm' file. Second
(optional) parameter means scale of the font. You can also use
*Font::TFM::new_at* and as the second parameter put requested size in pt:

     my $cmr10_12 = new_at Font::TFM 'cmr10', 12;

   The methods new and *new_at* search for the `.tfm' files in the
directories listed colon separated in a variable
*$Font::TFM::TEXFONTSDIR*, and also in all of their subdirectories.  By
default, they use files `ls-R' (this name can be changed in the
*$Font::TFM::LSFILENAME* variable) to speed up the search. This feature
can be disabled by setting variable *$Font::TFM::TEXFONTSUSELS* to 0.
Suffix `.tfm' is appended if necessary.

   If the file is not found (or there is some other problem), new returns
undef and sets error message to *$Font::TFM::errstr*.

   After the file was loaded, you can use the following methods of the
object to query information about the font's properties and about the
characters, etc.

designsize, fontsize
     Returns the design size and the actual size of the font in pt.

          $cmr->designsize;	returns 10
          $cmr->fontsize;			10
          $cmr10_12->fontsize;		12

width, height, depth, italic
     Returns the requested dimension for a specified character of the font.

          $cmr->height("A")		447828.75
          $cmr10_12->height("A")		537394.5
          $cmr->italic("I")		0
          $cmr10_12->italic("f")		61167.75

kern, lig, ligpassover
     For a two-letter string returns kern between them, ligature formed and
     number of characters to pass over after the ligature, respectivelly.

          $cmr->lig("fi")			\014
          $cmr->lig("ff")			\013
          $cmr->lig("\013i")		\016
          $cmr10_12->kern("AV")		-87381.75

expand
     One string parameter undergoes ligature expansion and then kernings
     are inserted. Returns array containing of string, kern, string, ...

          $cmr->expand("AV--fix")		"A", -72818.125, "V{\014x"

word_dimensions
     Returns the width, height and depth of a word. Does the lig/kern
     expansion, so the result is the real space it will take on output.

          $cmr->word_dimensions("AV--fix")
          				1947881.875, 455111.25, 0
          $cmr->word_dimensions("pm")	910225, 282168.75, 127431.25

word_width, word_height, word_depth
     Calls word_dimensions and returns appropriate element. No caching is
     done, so it is better to call word_dimensions yourself if you will
     need more than one dimension of one word.

param
     Returns parameter of the font, indexed from 1.

slant, x_height, em_width, quad
space, space_stretch, space_shrink, extra_space
     Returns the parameter of the font, by name.

          $cmr->slant()			0
          $cmsl10->slant()		0.166671752929688
          $cmr->x_height()		282168.75
          $cmr->height("x")		282168.75
          $cmr->em_width()		655361.875
          $cmr->quad()			655361.875

          $cmr->space()			218453.75
          $cmr->space_stretch()		109226.875
          $cmtt10->space()		344061.25
          $cmtt10->space_stretch()	0

name
     Returns the name of the font.

   Dimensions are multiplied by *$Font::TFM::MULTIPLY* * actual size of
the font. Value of *$Font::TFM::MULTIPLY* defaults to 65536, so the
dimensions can be used directly when writing the `.dvi' file.

   Variable *$Font::TFM::DEBUG* may be set to 1 to get the processing
messages on the standard error output.

   The module is subclassable. You can define you own module that would
provide alternate way of finding and opening the file. Just make new
module and defined your own method open_tfm in it.

VERSION
=======

   0.100

SEE ALSO
========

   TeX::DVI(3), TeX::DVI::Parse(3), perl(1).

AUTHOR
======

   (c) 1996-2000 Jan Pazdziora, adelton@fi.muni.cz,
http://www.fi.muni.cz/~adelton/ at Faculty of Informatics, Masaryk
University, Brno, Czech Republic


File: pm.info,  Node: FormMagick,  Next: FormMagick/FAQ,  Prev: Font/TFM,  Up: Module List

easily create CGI form-based applications
*****************************************

NAME
====

   FormMagick - easily create CGI form-based applications

SYNOPSIS
========

     use FormMagick;

     my $f = new FormMagick();
     my $f = new FormMagick(TYPE => FILE,  SOURCE => $myxmlfile, DEBUG => 1);

     $f->add_lexicon("fr", { "Yes" => "Oui", "No" => "Non"});

     $f->display();

DESCRIPTION
===========

   FormMagick is a toolkit for easily building fairly complex form-based
web applications.  It allows the developer to specify the structure of a
multi-page "wizard" style form using XML, then display that form using
only a few lines of Perl.

How it works:
-------------

   You (the developer) provide at least:

   * Form descriptions (XML)

   * HTML templates (Text::Template format) for the page headers and
     footers

   And may optionally provide:

   * L10N lexicon entries

   * Validation routines for user input data

   * Routines to run before or after a page of the form is displayed

   FormMagick brings them all together to create a full application.

METHODS
=======

new()
-----

   The new() method requires no arguments, but may take the following
optional arguments (as a hash):

TYPE
     Defaults to "FILE" (the only currently implemented type).  Eventually
     we'll also allow such things as FILEHANDLE, STRING, etc (c.f.
     Text::Template, which does this quite nicely).

SOURCE
     Defaults to a filename matching that of your script, only with an
     extension of .xml (we got this idea from XML::Simple).

DEBUG
     Defaults to 0 (no debug output).  Setting it to 1 (or any other true
     value) will cause debugging messages to be output.

display()
---------

   The display method displays your form.  It takes no arguments.

add_lexicon()
-------------

   This method takes two arguments.  The first is a two-letter string
representing the language to which entries should be added.  These are
standard ISO language abbreviations, eg "en" for English, "fr" for French,
"de" for German, etc.

   The second argument is a hashref in which the keys of the hash are the
phrases to be translated and the values are the translations.

   For more information about how localization (L10N) works in FormMagick,
see `FormMagick::L10N'.

debug($msg)
-----------

   The debug method prints out a nicely formatted debug message.  It's
usually called from your script as `$f-'debug($msg)>

Form descriptions
-----------------

   Sample form description

   The following is an example of how a form is described in XML. More
complete examples can be found in the `examples/' subdirectory in the
FormMagick distribution.

     <FORM TITLE="My form application" HEADER="myform_header.tmpl"
       FOOTER="myform_footer.tmpl" POST-EVENT="submit_order">
       <PAGE NAME="Personal" TITLE="Personal details" DESCRIPTION="Please
       provide us with the following personal details for our records">
         <FIELD ID="firstname" LABEL="Your first name" TYPE="TEXT"
           VALIDATION="nonblank"/>
         <FIELD ID="lastname" LABEL="Your surname" TYPE="TEXT"
           VALIDATION="nonblank"/>
         <FIELD ID="username" LABEL="Choose a username" TYPE="TEXT"
           VALIDATION="username" DESCRIPTION="Your username must
     	be between 3 and 8 characters in length and contain only letters
     	and numbers."/>
       </PAGE>
       <PAGE NAME="Payment" TITLE="Payment details"
       POST-EVENT="check_credit_card" DESCRIPTION="We need your full credit
       card details to process your order.  Please fill in all fields.
       Your card will be charged within 48 hours.">
         <FIELD ID="cardtype" LABEL="Credit card type" TYPE="SELECT"
           OPTIONS="list_credit_card_types" VALIDATION="credit_card_type"/>
         <FIELD ID="cardnumber" LABEL="Credit card number" TYPE="TEXT"
           VALIDATION="credit_card_number"/>
         <FIELD ID="cardexpiry" LABEL="Expiry date (MM/YY)" TYPE="TEXT"
           VALIDATION="credit_card_expiry"/>
       </PAGE>
     </FORM>

   The XML must comply with the FormMagick DTD (included in the
distribution as FormMagick.dtd).  A command-line tool to test compliance
is planned for a future release.

SEE ALSO
========

   FormMagick::L10N

   FormMagick::Validator

   FormMagick::FAQ

BUGS
====

   There are a number of features which have not yet been implemented.
Also, there are probably mismatches between this perldoc and the actual
functionality.

AUTHOR
======

   Kirrily "Skud" Robert <skud@infotrope.net>

   Contributors:

   Shane R. Landrum <slandrum@turing.csc.smith.edu>

   James Ramirez <jamesr@cogs.susx.ac.uk>

   More information about FormMagick may be found at
http://sourceforge.net/projects/formmagick/


File: pm.info,  Node: FormMagick/FAQ,  Next: FormMagick/L10N,  Prev: FormMagick,  Up: Module List

Frequently asked questions about FormMagick
*******************************************

NAME
====

   FormMagick FAQ - Frequently asked questions about FormMagick

HOW DO I...
===========

How do I check that my XML is valid?
------------------------------------

How do I customise the look and feel of my forms?
-------------------------------------------------

   Use cascading style sheets.  Take a look at the HTML source output by
FormMagick, and you'll see that most things have a "label" attribute to
make CSS easier.

How do I make my own validation routines?
-----------------------------------------

   Simply create a routine in your CGI script which accepts the data to
validate as an argument.  Have it return "OK" on success or a detailed
error message on failure.

     sub my_validation {
         my $data = shift;
         if ($data =~ /$some_pattern/) {
             return "OK";
         } else {
             return "That looks wrong to me.";
         }
     }

How do I add translations into another language?
------------------------------------------------

   Use the add_lexicon() method:

     $f->add_lexicon("fr", { "Yes" => "Oui", "No" => "Non" });

How do I do extra processing when a user clicks "Next"?
-------------------------------------------------------

   Use a POST-EVENT on the PAGE element.  Create a subroutine that does
what you want:

     sub process_credit_card {
         my $cgi = shift;
     	my $cardnum = $cgi->param("cardnum");
     	my $response = do_processing($cardnum);
     	print "<p>$response</p>";
     }

How do I choose which page to go to based on user input?
--------------------------------------------------------

   Use a PAGE POST-EVENT and set the value of the "wherenext" CGI
parameter:

     sub my_post_page_event {
         my $cgi = shift;
     	if ($cgi->param("foo") eq "bar") {
             $cgi->param(-name => "wherenext", -value => "GoToThisPageName")
         } elsif ($cgi->param("had_enough") eq "Yes") {
             $cgi->param(-name => "wherenext", -value => "Finish")
         }
     }

TROUBLESHOOTING
===============

General troubleshooting tips
----------------------------

   Try turning on debugging when you invoke FormMagick:

   my $f = new FormMagick( DEBUG => 1 );

Why isn't my data preserved from one page to the next?
------------------------------------------------------

   You probably need to make your `session-tokens' directory writable and
executable by the web server.  Either:

     chown www session-tokens
        (assuming your webserver runs as the www user)
     chmod 700 session-tokens

   Or...

     chown 777 session-tokens


File: pm.info,  Node: FormMagick/L10N,  Next: FormMagick/TagMaker,  Prev: FormMagick/FAQ,  Up: Module List

   FormMagick::L10N - localization routines for FormMagick

SYNOPSIS
========

     use FormMagick::L10N;

DESCRIPTION
===========

   L10N (Localisation) is the name given to the process of providing
translations into another language.  The previous step to this is I18N
(internationalisation) which is the process of making an application ready
to accept the translations.

   We've done the work of I18N for you, so all you have to do is provide
translations for your apps.

   FormMagick uses the `Locale::Maketext' module for L10N.  It stores its
translations for each language in a hash like this:

     %Lexicon = (
     	"Hello"		=> "Bonjour",
     	"Click here"	=> "Appuyez ici"
     );

   You can add your own entries to any language lexicon using the
add_lexicon() method (see `FormMagick' for how to call that method).

   Localisation preferences are picked up from the HTTP_ACCEPT_LANGUAGE
environment variable passed by the user's browser.  In Netscape, you set
this by choosing "Edit, Preferences, Navigator, Languages" and then
choosing your preferred language.

   Localisation is performed on:

   * Form titles

   * Page titles and descriptions

   * Field labels and descriptions

   * Validation error messages

   If you wish to localise other textual information such as your HTML
Templates, you will have to explicitly call the l10n routines.

SEE ALSO
========

   The general documentation for FormMagick (`perldoc FormMagick')

   More information about FormMagick may be found at
http://sourceforge.net/projects/formmagick/


File: pm.info,  Node: FormMagick/TagMaker,  Next: FormMagick/Validator,  Prev: FormMagick/L10N,  Up: Module List

Perl module that can create any HTML tags, as well as groups of or just parts of them, and complete html headers or footers.
****************************************************************************************************************************

NAME
====

   HTML::TagMaker - Perl module that can create any HTML tags, as well as
groups of or just parts of them, and complete html headers or footers.

DEPENDENCIES
============

Perl Version
------------

     5.004

Standard Modules
----------------

     I<none>

Nonstandard Modules
-------------------

     Class::ParamParser

SYNOPSIS
========

     use HTML::TagMaker;

     my $html = HTML::TagMaker->new();
     $html->groups_by_default( 1 );

     print
     	'Content-type: text/html'."\n\n",
     	$html->start_html(
     		-title => "This Is My Page",
     		-style => { -code => <<__endquote },
     \nBODY {
     	background-color: #ffffff;
     	background-image: none;
     }
     __endquote
     	),
     	$html->h1( 'A Simple Example' ),
     	$html->p(
     		"Click " .
     		$html->a( href => 'http://search.cpan.org', text => 'here' ) .
     		" for more."
     	),
     	$html->hr,
     	$html->table(
     		$html->tr( [
     			$html->th( [ 'Name', 'Count', 'URL', 'First Access' ] ),
     			$html->td( [ 'Old Page', 33, 'http://www.domain.com',
     				'1999/04/23 13:55:02' ] )
     		] )
     	),
     	$html->hr,
     	$html->form_start( method => 'post', action => 'http://localhost' ),
     	$html->p(
     		"What's your name? " .
     		$html->input( type => 'text', name => 'name' )
     	),
     	$html->p(
     		"What's the combination?" .
     		$html->input_group(
     			-type => 'checkbox',
     			-name => 'words',
     			-value => ['eenie', 'meenie', 'minie', 'moe'],
     			-checked => [1, 0, 1, 0],
     			-text => ['eenie', 'meenie', 'minie', 'moe'] ),
     	),
     	$html->p(
     		"What's your favorite colour? " .
     		$html->select_start( -size => 1, -name => 'color' ) .
     		$html->option_group(
     			-value => ['red', 'green', 'blue', 'chartreuse'],
     			-text => ['Red', 'Green', 'Blue', 'Chartreuse'] ) .
     		$html->select_end
     	),
     	$html->input( type => 'submit' ),
     	$html->form_end,
     	$html->end_html;

DESCRIPTION
===========

   This Perl 5 object class can be used to generate any HTML tags in a
format that is consistent with the W3C HTML 4.0 standard.  There are no
restrictions on what tags are named, however; you can ask for any new or
unsupported tag that comes along from Netscape or Microsoft, and it will
be made.  Additionally, you can generate lists of said tags with one
method call, or just parts of said tags (but not both at once).

   In this implementation, "standard format" means that tags are made as
pairs (<TAG></TAG>) by default, unless they are known to be "no pair"
tags.  Tags that I know to be "no pair" are [basefont, img, area, param,
br, hr, input, option, tbody, frame, comment, isindex, base, link, meta].
However, you can force any tag to be "pair" or "start only" or "end only"
by appropriately modifying your call to the tag making method.

   Also, "standard format" means that tag modifiers are formatted as
"key=value" by default, unless they are known to be "no value" modifiers.
Modifiers that I know to be "no value" are [ismap, noshade, compact,
checked, multiple, selected, nowrap, noresize, param].  These are
formatted simply as "key" because their very presence indicates positive
assertion, while their absense means otherwise.  For modifiers with
values, the values will always become bounded by quotes, which ensures
they work with both string and numerical quantities (eg: key="value").

   Note that this class is a subclass of Class::ParamParser, and inherits
all of its methods, "params_to_hash()" and "params_to_array()".

HTML CODE FROM SYNOPSIS PROGRAM
===============================

     Content-type: text/html

     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
     <HTML>
     <HEAD>
     <TITLE>This Is My Page</TITLE>
     <STYLE>
     <!--
     BODY {
     	background-color: #ffffff;
     	background-image: none;
     }
      --></STYLE>
     </HEAD>
     <BODY>
     <H1>A Simple Example</H1>
     <P>Click
     <A HREF="http://search.cpan.org">here</A> for more.</P>
     <HR>
     <TABLE>
     <TR>
     <TH>Name</TH>
     <TH>Count</TH>
     <TH>URL</TH>
     <TH>First Access</TH></TR>
     <TR>
     <TD>Old Page</TD>
     <TD>33</TD>
     <TD>http://www.domain.com</TD>
     <TD>1999/04/23 13:55:02</TD></TR></TABLE>
     <HR>
     <FORM METHOD="post" ACTION="http://localhost">
     <P>What's your name?
     <INPUT TYPE="text" NAME="name"></P>
     <P>What's the combination?
     <INPUT TYPE="checkbox" NAME="words" CHECKED VALUE="eenie">eenie
     <INPUT TYPE="checkbox" NAME="words" VALUE="meenie">meenie
     <INPUT TYPE="checkbox" NAME="words" CHECKED VALUE="minie">minie
     <INPUT TYPE="checkbox" NAME="words" VALUE="moe">moe</P>
     <P>What's your favorite colour?
     <SELECT NAME="color" SIZE="1">
     <OPTION VALUE="red">Red
     <OPTION VALUE="green">Green
     <OPTION VALUE="blue">Blue
     <OPTION VALUE="chartreuse">Chartreuse
     </SELECT></P>
     <INPUT TYPE="submit">
     </FORM>
     </BODY>
     </HTML>

SYNTAX
======

   This class does not export any functions or methods, so you need to
call them using indirect notation.  This means using *Class->function()*
for functions and *$object->method()* for methods.

   Methods of this class always "return" their results, rather than
printing them out to a file or the screen.  Not only is this simpler, but
it gives the calling code the maximum amount of control over what happens
in the program.  They may wish to do post-processing with the generated
HTML, or want to output it in a different order than it is generated.  By
default, all results are returned as a scalar, but methods which generate
a list of tags can optionally return an ARRAY ref, with each element
containing a single tag.  This can aid in post-processing and possibly
speed up the program because there is less copying done.

   Through the magic of autoloading, this class can make any html tag by
calling a class method with the same name as the tag you want.  For
examples, use "hr()" to make a "<HR>" tag, or "p('text')" to make
"<P>text</P>".  This also means that if you mis-spell any method name, it
will still make a new tag with the mis-spelled name.  For autoloaded
methods only, the method names are case-insensitive.

   If you call a class method whose name ends in either of ['_start',
'_end', '_pair'], this will be interpreted as an instruction to make just
part of one tag whose name are the part of the method name preceeding that
suffix.  For example, calling "p_start( 'text' )" results in "<P>text"
rather than "<P>text</P>".  Similarly, calling "p_end()" will generate a
"</P>" only.  Using the '_pair' suffix will force tags to be made as a
pair, whether or not they would do so naturally.  For example, calling
"br_pair" would produce a "<BR></BR>" rather than the normal "<BR>".  When
using either of ['_start','_pair'], the arguments you pass the method are
exactly the same as the unmodified method would use, and there are no
other symantec differences.  However, when using the '_end' suffix, any
arguments are ignored, as the latter member of a tag pair never carries any
attributes anyway.

   If you call a class method whose name ends in "_group", this will be
interpreted as an instruction to make a list of tags whose name are the
part of the method name preceeding the "_group".  For example, calling
"td_group( ['here','we','are'] )" results in
"<TD>here</TD><TD>we</TD><TD>are</TD>" being generated.  The arguments
that you call this method are exactly the same as for calling a method to
make a single tag of the same name, except that the extra optional
parameter "list" can be used to force an ARRAY ref of the new tags to be
returned instead of a scalar.  The symantec difference is that any
arguments whose values are ARRAY refs are interpreted as a list of values
where each one is used in a separate tag; for a single tag, the literal
ARRAY ref itself would be used.  The number of tags produced is equal to
the length of the longest ARRAY ref passed as an argument.  For any other
arguments who have fewer than this count, their last value is replicated
and appended enough times as necessary to make them the same length.  The
value of a scalar argument is used for all the tags.  For example, calling
"input_group( type => checkbox, name => 'letters', value => ['a','b','c']
)" produces '<INPUT TYPE="checkbox" NAME="letters" VALUE="a"><INPUT
TYPE="checkbox" NAME="letters" VALUE="b"><INPUT TYPE="checkbox"
NAME="letters" VALUE="c">'.

   All autoloaded methods require their parameters to be in named format.
These names and values correspond to attribute names and values for the
new tags.  Since "no value" attributes are essentially booleans, they can
have any true or false value associated with them in the parameter list,
which won't be printed.  If an autoloaded method is passed exactly one
parameter, it will be interpreted as the "text" that goes between the tag
pair (<TAG>text</TAG>) or after "start tags" (<TAG>text).  The same result
can be had explicitely by passing the named parameter "text".  Most static
(non-autoloaded) methods require positional parameters, except for
start_html(), which can take either format.  The names of any named
parameters can optionally start with a "-".

FUNCTIONS AND METHODS
=====================

   Note that all the methods defined below are static, so information
specific to autoloaded methods won't likely apply to them.  All of these
methods take positional arguments unless otherwise specified.

new()
-----

   This function creates a new HTML::TagMaker object (or subclass thereof)
and returns it.

initialize()
------------

   This method is used by new() to set the initial properties of an object,
that it creates.  All page attributes are wiped clean, resulting in an
empty page.

clone([ CLONE ])
----------------

   This method initializes a new object to have all of the same properties
of the current object and returns it.  This new object can be provided in
the optional argument CLONE (if CLONE is an object of the same class as
the current object); otherwise, a brand new object of the current class is
used.  Only object properties recognized by HTML::TagMaker are set in the
clone; other properties are not changed.

groups_by_default([ VALUE ])
----------------------------

   This method is an accessor for the boolean "automatic grouping"
property of this object, which it returns.  If VALUE is defined, this
property is set to it.  In cases where we aren't told explicitely that
autoloaded methods are making a single or multiple tags (using ['_start',
'_end', '_pair'] and '_group' respectively), we look to this property to
determine what operation we guess.  The default is "single".  When this
property is true, we can make both single and groups of tags by using a
suffix-less method name; however, making single tags this way is slower
than when this property is false.  Also, be aware that when we are making
a "group", arguments that are ARRAY refs are always flattened, and when we
are making a "single", ARRAY ref arguments are always used literally.

positional_by_default([ VALUE ])
--------------------------------

   This method is an accessor for the boolean "positional arguments"
property of this object, which it returns.  If VALUE is defined, this
property is set to it.  With methods whose parameters could be either
named or positional, when we aren't sure what we are given, do we guess
positional?  Default is named.

prologue_tag()
--------------

   This method returns a prologue tag, which is meant to be the very first
thing in an HTML document.  It tells the web browser such things as what
version of the HTML standard we are adhering to, version 4.0 in this case.
The prologue tag we make looks like '<!DOCTYPE HTML PUBLIC "-//W3C//DTD
HTML 4.0//EN">'.

comment_tag( TEXT )
-------------------

   This method returns a comment tag, which is only visible to people
viewing the HTML source of a document, and not otherwise.  It can take
either a scalar or a list or an Array ref as its TEXT argument.  If a
single item of text is passed, then a comment tag that looks like "<!-
text ->" is made.  If more than one item of text is passed, then a
multi-line comment is made, which has each item of text on its own line
and indented with a single tab.  The latter is suitable for displaying CSS
or JavaScript code in an elegant manner.

make_html_tag( NAME[, PARAMS[, TEXT[, PART]]] )
-----------------------------------------------

   This method is used internally to do the actual construction of single
html tags.   You can call it directly when you want faster code and/or
more control over how tags are made.  The first argument, NAME, is a
scalar that defines the actual name of the tag we are making (eg: 'br');
it is case-insensitive.  The optional second argument, PARAMS, is a HASH
ref containing attribute names and values for the new tag; the names
(keys) are case-insensitive.  The attribute values are all printed
literally, so they should be scalars.  The optional third argument, TEXT,
is a scalar containing the text that goes between the tag pairs; it is not
a tag attribute.  The optional fourth argument, PART, is a scalar which
indicates we should make just a certain part of the tag; acceptable values
are ['pair', 'start', 'end'], and it is case-insensitive.  This method
knows which HTML tags are normally paired or not, which tag attributes
take specified values or not, and acts accordingly.

make_html_tag_group( NAME[, PARAMS[, TEXT[, LIST]]] )
-----------------------------------------------------

   This method is used internally to do the actual construction of html
tag groups.  You can call it directly when you want faster code and/or
more control over how tags are made.  The first argument, NAME, is a
scalar that defines the actual name of the tag we are making (eg: 'br');
it is case-insensitive.  The optional second argument, PARAMS, is a HASH
ref containing attribute names and values for the new tag; the names
(keys) are case-insensitive.  Any attribute values which are ARRAY refs
are flattened, and the number of tags made is determined by the length of
the longest one.  The optional third argument, TEXT, is a HASH ref (or
scalar) containing the text that goes between the tag pairs; it is not a
tag attribute, but if its an ARRAY ref then its length will influence the
number of tags that are made as the length of tag attribute arrays do.
The optional fourth argument, LIST, is a boolean/scalar which indicates
whether this method returns the new tags in an ARRAY ref (one tag per
element) or as a scalar (tags are concatenated together); a true value
forces an ARRAY ref, scalar is the default.  This method knows which HTML
tags are normally paired or not, which tag attributes take specified
values or not, and acts accordingly.

start_html([ TITLE[, AUTHOR[, META[, STYLE[, HEAD[, BODY]]]]] ])
----------------------------------------------------------------

   This method returns a canned HTML template that is suitable for use as
the top of an HTML page.  It consists of the prologue tag (<!DOCTYPE...),
the opening 'html' tag, the entire 'head' section, and the opening 'body'
tag.  The prologue tag looks the same as that generated by the class
method prologue_tag().  This method can take its optional six arguments in
either named or positional format; in the first case, the names look the
same as the positional placeholders above, except they must be in lower
case.  The first two arguments, TITLE and AUTHOR, are scalars which
respectively define the title and author for the document.  The default
value for TITLE is 'Untitled Document', and a '<LINK REV="made">' tag is
made if AUTHOR is present.  The third argument, META, is a HASH ref
containing name/value pairs of meta information, and a '<META NAME="n"
VALUE="v">' tag is made for each one.  The fourth argument, STYLE, allows
Cascading Style Sheets to be used in the document.  See the method
*css_for_start_html()*, which handles the particulars of this argument.
The fifth argument, HEAD, is an ARRAY ref (or scalar) containing anything
else you would like to appear in the 'head' section; it is flattened and
the elements used as-is.  The sixth argument, BODY, is a HASH ref
containing attributes and values for the opening 'body' tag.

end_html()
----------

   This method returns a canned HTML template that is suitable for use as
the bottom of an HTML page.  It consists of the closing 'body' and 'html'
tags.

css_for_start_html([ SRC[, CODE] ])
-----------------------------------

   This method returns HTML code that allows Cascading Style Sheets to be
used in the document when the code is included in its "head" section.
This method is used by start_html() to handle its STYLE argument.  This
method can take its optional arguments in either named or positional
format; in the first case, the names look the same as the positional
placeholders above, except they must be in lower case.  The first
argument, SRC, is an Array ref (or scalar) whose elements are urls for
external StyleSheet documents that should be linked to by the browser, and
a '<LINK REL="stylesheet" SRC="url">' tag is made for each one.  The
second argument, CODE, is an Array ref (or scalar) whose elements are
lines of StyleSheet code that are to be embedded in the HTML document
itself; a "<STYLE><!- code -></STYLE>" multi-line tag is made for them.
When both arguments are used, the SRC appears first in the new HTML.

COMPATABILITY WITH OTHER MODULES
================================

   The methods of this class and their parameters are designed to be
compatible with any same-named methods in the popular CGI.pm class.  This
class will produce identical or browser-compatible HTML from such methods,
and this class can accept all the same argument formats.  Exceptions to
this include:

  1. None of our methods are exported and must be called using indirect
     notation, whereas CGI.pm can export any of it's methods.

  2. start_html() doesn't support all the same arguments, but those that
     do have the same names.  However, the effects of the missing
     arguments can be easily replicated by making the appropriate tags
     explicitely and handing them in via either the "head" or "body"
     arguments, where appropriate.  The common arguments are ['title',
     'author', 'meta', 'style', 'head', 'body'], in that order.

  3. Our textarea() method is autoloaded, and doesn't have the special
     symantecs that CGI.pm's textarea() does.  However, any module who
     subclasses from this one can override textarea() with one that
     matches CGI.pm's symantecs.  The "HTML::FormMaker" module does this.

  4. Autoloaded methods do not use the presence or absense of arguments to
     decide whether to make the new tag as a pair or as "start only".

  5. Autoloaded methods that make html tags won't concatenate their
     arguments into a single argument under any circumstances, but in some
     cases the "shortcuts" of CGI.pm will do so.

  6. Currently we don't html-escape any argument values passed to our tag
     making functions, whereas CGI.pm sometimes does.  While we expect our
     caller to do the escaping themselves where necessary, we may do it
     later in an update.

  7. We go further to make the generated HTML human-readable by: 1. having
     each new tag start on a new line; 2. making all tag and attribute
     names uppercase; 3.  ensuring that about 20 often-used tag attributes
     always appear in the same order (eg: 'type' is before 'name' is
     before 'value'), and before any others.


AUTHOR
======

   Copyright (c) 1999-2000, Darren R. Duncan. All rights reserved. This
module is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.  However, I do request that this copyright
information remain attached to the file.  If you modify this module and
redistribute a changed version then please attach a note listing the
modifications.

   I am always interested in knowing how my work helps others, so if you
put this module to use in any of your own code then please send me the
URL.  Also, if you make modifications to the module because it doesn't
work the way you need, please send me a copy so that I can roll desirable
changes into the main release.

   Address comments, suggestions, and bug reports to
*perl@DarrenDuncan.net*.

CREDITS
=======

   Thanks very much to *Kevin Werbach* for publishing "The Bare Bones
Guide to HTML", which I found to be an invaluable resource when writing
this module (and at other times as well).  The latest version of the
document is available at *http://werbach.com/barebones/*.

   This quick reference lists all the HTML tags that current browsers are
likely to recognize, including all the elements of the official HTML 4.0
recommendation, and some Netscape and Microsoft extensions as well.
Common attributes for these tags are also included in context, giving a
good idea on how they are used.

   When writing this module, I used the Bare Bones reference to verify the
consistant formatting used by all HTML tags, including how tag attributes
are formatted.  I could see the proper formatting for prologue and comment
tags as well; their formats are unique compared to all the other tags.
The other main uses I had for the document was in determining all the HTML
tags which were not used as a pair (most use pairs, few don't), and for
determining which tag attributes made a positive assertion just by their
presence, without need for any associated values (most have values, few
don't).

   Thanks also to *Lincoln D. Stein* for publishing the popular CGI.pm
module, which I found very useful in my programs.  Moreover, I have
decided to emulate much of its functionality in some of my own modules, so
I should give credit where its due for implementing that functionality
first.  Lincoln should be pleased that I am following his advice (look
under heading "BUGS" in CGI) and discarding his large and monolithic
module in favor of simpler ones.

SEE ALSO
========

   perl(1), CGI, Class::ParamParser.


