.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "HTML::Tiny 3pm" .TH HTML::Tiny 3pm "2010-02-18" "perl v5.10.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" HTML::Tiny \- Lightweight, dependency free HTML/XML generation .SH "VERSION" .IX Header "VERSION" This document describes HTML::Tiny version 1.05 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use HTML::Tiny; \& \& my $h = HTML::Tiny\->new; \& \& # Generate a simple page \& print $h\->html( \& [ \& $h\->head( $h\->title( \*(AqSample page\*(Aq ) ), \& $h\->body( \& [ \& $h\->h1( { class => \*(Aqmain\*(Aq }, \*(AqSample page\*(Aq ), \& $h\->p( \*(AqHello, World\*(Aq, { class => \*(Aqdetail\*(Aq }, \*(AqSecond para\*(Aq ) \& ] \& ) \& ] \& ); \& \& # Outputs \& \& \& Sample page \& \& \&

Sample page

\&

Hello, World

\&

Second para

\& \& .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\f(CW\*(C`HTML::Tiny\*(C'\fR is a simple, dependency free module for generating \&\s-1HTML\s0 (and \s-1XML\s0). It concentrates on generating syntactically correct \&\s-1XHTML\s0 using a simple Perl notation. .PP In addition to the \s-1HTML\s0 generation functions utility functions are provided to .IP "\(bu" 4 encode and decode \s-1URL\s0 encoded strings .IP "\(bu" 4 entity encode \s-1HTML\s0 .IP "\(bu" 4 build query strings .IP "\(bu" 4 \&\s-1JSON\s0 encode data structures .SH "INTERFACE" .IX Header "INTERFACE" .ie n .IP """new""" 4 .el .IP "\f(CWnew\fR" 4 .IX Item "new" Create a new \f(CW\*(C`HTML::Tiny\*(C'\fR. The constructor takes one optional argument: \f(CW\*(C`mode\*(C'\fR. \f(CW\*(C`mode\*(C'\fR can be either \f(CW\*(Aqxml\*(Aq\fR (default) or \f(CW\*(Aqhtml\*(Aq\fR. The difference is that in \s-1HTML\s0 mode, closed tags will not be closed with a forward slash; instead, closed tags will be returned as single open tags. .Sp Example: .Sp .Vb 2 \& # Set HTML mode. \& my $h = HTML::Tiny\->new( mode => \*(Aqhtml\*(Aq ); \& \& # The default is XML mode, but this can also be defined explicitly. \& $h = HTML::Tiny\->new( mode => \*(Aqxml\*(Aq ); .Ve .Sp \&\s-1HTML\s0 is a dialect of \s-1SGML\s0, and is not \s-1XML\s0 in any way. \*(L"Orphan\*(R" open tags or unclosed tags are legal and in fact expected by user agents. In practice, if you want to generate \s-1XML\s0 or \s-1XHTML\s0, supply no arguments. If you want valid \s-1HTML\s0, use \f(CW\*(C`mode => \*(Aqhtml\*(Aq\*(C'\fR. .SS "\s-1HTML\s0 Generation" .IX Subsection "HTML Generation" .ie n .IP """tag( $name, ... )""" 4 .el .IP "\f(CWtag( $name, ... )\fR" 4 .IX Item "tag( $name, ... )" Returns \s-1HTML\s0 (or \s-1XML\s0) that encloses each of the arguments in the specified tag. For example .Sp .Vb 1 \& print $h\->tag(\*(Aqp\*(Aq, \*(AqHello\*(Aq, \*(AqWorld\*(Aq); .Ve .Sp would print .Sp .Vb 1 \&

Hello

World

.Ve .Sp notice that each argument is individually wrapped in the specified tag. To avoid this multiple arguments can be grouped in an anonymous array: .Sp .Vb 1 \& print $h\->tag(\*(Aqp\*(Aq, [\*(AqHello\*(Aq, \*(AqWorld\*(Aq]); .Ve .Sp would print .Sp .Vb 1 \&

HelloWorld

.Ve .Sp The [ and ] can be thought of as grouping a number of arguments. .Sp Attributes may be supplied by including an anonymous hash as the first element in the argument list (after the tag name): .Sp .Vb 1 \& print $h\->tag(\*(Aqp\*(Aq, { class => \*(Aqnormal\*(Aq }, \*(AqFoo\*(Aq); .Ve .Sp would print .Sp .Vb 1 \&

Foo

.Ve .Sp Attribute values will be \s-1HTML\s0 entity encoded as necessary. .Sp Multiple hashes may be supplied in which case they will be merged: .Sp .Vb 4 \& print $h\->tag(\*(Aqp\*(Aq, \& { class => \*(Aqnormal\*(Aq }, \*(AqBar\*(Aq, \& { style => \*(Aqcolor: red\*(Aq }, \*(AqBang!\*(Aq \& ); .Ve .Sp would print .Sp .Vb 1 \&

Bar

Bang!

.Ve .Sp Notice that the class=\*(L"normal\*(R" attribute is merged with the style attribute for the second paragraph. .Sp To remove an attribute set its value to undef: .Sp .Vb 4 \& print $h\->tag(\*(Aqp\*(Aq, \& { class => \*(Aqnormal\*(Aq }, \*(AqBar\*(Aq, \& { class => undef }, \*(AqBang!\*(Aq \& ); .Ve .Sp would print .Sp .Vb 1 \&

Bar

Bang!

.Ve .Sp An empty attribute \- such as 'checked' in a checkbox can be encoded by passing an empty array reference: .Sp .Vb 1 \& print $h\->closed( \*(Aqinput\*(Aq, { type => \*(Aqcheckbox\*(Aq, checked => [] } ); .Ve .Sp would print .Sp .Vb 1 \& .Ve .Sp \&\fBReturn Value\fR .Sp In a scalar context \f(CW\*(C`tag\*(C'\fR returns a string. In a list context it returns an array each element of which corresponds to one of the original arguments: .Sp .Vb 1 \& my @html = $h\->tag(\*(Aqp\*(Aq, \*(Aqthis\*(Aq, \*(Aqthat\*(Aq); .Ve .Sp would return .Sp .Vb 4 \& @html = ( \& \*(Aq

this

\*(Aq, \& \*(Aq

that

\*(Aq \& ); .Ve .Sp That means that when you nest calls to tag (or the equivalent \s-1HTML\s0 aliases \- see below) the individual arguments to the inner call will be tagged separately by each enclosing call. In practice this means that .Sp .Vb 1 \& print $h\->tag(\*(Aqp\*(Aq, $h\->tag(\*(Aqb\*(Aq, \*(AqFoo\*(Aq, \*(AqBar\*(Aq)); .Ve .Sp would print .Sp .Vb 1 \&

Foo

Bar

.Ve .Sp You can modify this behavior by grouping multiple args in an anonymous array: .Sp .Vb 1 \& print $h\->tag(\*(Aqp\*(Aq, [ $h\->tag(\*(Aqb\*(Aq, \*(AqFoo\*(Aq, \*(AqBar\*(Aq) ] ); .Ve .Sp would print .Sp .Vb 1 \&

FooBar

.Ve .Sp This behaviour is powerful but can take a little time to master. If you imagine '[' and ']' preventing the propagation of the 'tag individual items' behaviour it might help visualise how it works. .Sp Here's an \s-1HTML\s0 table (using the tag-name convenience methods \- see below) that demonstrates it in more detail: .Sp .Vb 10 \& print $h\->table( \& [ \& $h\->tr( \& [ $h\->th( \*(AqName\*(Aq, \*(AqScore\*(Aq, \*(AqPosition\*(Aq ) ], \& [ $h\->td( \*(AqTherese\*(Aq, 90, 1 ) ], \& [ $h\->td( \*(AqChrissie\*(Aq, 85, 2 ) ], \& [ $h\->td( \*(AqAndy\*(Aq, 50, 3 ) ] \& ) \& ] \& ); .Ve .Sp which would print the unformatted version of: .Sp .Vb 6 \& \& \& \& \& \&
NameScorePosition
Therese901
Chrissie852
Andy503
.Ve .Sp Note how you don't need a \fItd()\fR for every cell or a \fItr()\fR for every row. Notice also how the square brackets around the rows prevent \fItr()\fR from wrapping each individual cell. .Sp Often when generating nested \s-1HTML\s0 you will find yourself writing corresponding nested calls to \s-1HTML\s0 generation methods. The table generation code above is an example of this. .Sp If you prefer these nested method calls can be deferred like this: .Sp .Vb 9 \& print $h\->table( \& [ \& \e\*(Aqtr\*(Aq, \& [ \e\*(Aqth\*(Aq, \*(AqName\*(Aq, \*(AqScore\*(Aq, \*(AqPosition\*(Aq ], \& [ \e\*(Aqtd\*(Aq, \*(AqTherese\*(Aq, 90, 1 ], \& [ \e\*(Aqtd\*(Aq, \*(AqChrissie\*(Aq, 85, 2 ], \& [ \e\*(Aqtd\*(Aq, \*(AqAndy\*(Aq, 50, 3 ] \& ] \& ); .Ve .Sp In general a nested call like .Sp .Vb 1 \& $h\->method( args ) .Ve .Sp may be rewritten like this .Sp .Vb 1 \& [ \e\*(Aqmethod\*(Aq, args ] .Ve .Sp This allows complex \s-1HTML\s0 to be expressed as a pure data structure. See the \f(CW\*(C`stringify\*(C'\fR method for more information. .ie n .IP """open( $name, ... )""" 4 .el .IP "\f(CWopen( $name, ... )\fR" 4 .IX Item "open( $name, ... )" Generate an opening \s-1HTML\s0 or \s-1XML\s0 tag. For example: .Sp .Vb 1 \& print $h\->open(\*(Aqmarker\*(Aq); .Ve .Sp would print .Sp .Vb 1 \& .Ve .Sp Attributes can be provided in the form of anonymous hashes in the same way as for \f(CW\*(C`tag\*(C'\fR. For example: .Sp .Vb 1 \& print $h\->open(\*(Aqmarker\*(Aq, { lat => 57.0, lon => \-2 }); .Ve .Sp would print .Sp .Vb 1 \& .Ve .Sp As for \f(CW\*(C`tag\*(C'\fR multiple attribute hash references will be merged. The example above could be written: .Sp .Vb 1 \& print $h\->open(\*(Aqmarker\*(Aq, { lat => 57.0 }, { lon => \-2 }); .Ve .ie n .IP """close( $name )""" 4 .el .IP "\f(CWclose( $name )\fR" 4 .IX Item "close( $name )" Generate a closing \s-1HTML\s0 or \s-1XML\s0 tag. For example: .Sp .Vb 1 \& print $h\->close(\*(Aqmarker\*(Aq); .Ve .Sp would print: .Sp .Vb 1 \& .Ve .ie n .IP """closed( $name, ... )""" 4 .el .IP "\f(CWclosed( $name, ... )\fR" 4 .IX Item "closed( $name, ... )" Generate a closed \s-1HTML\s0 or \s-1XML\s0 tag. For example .Sp .Vb 1 \& print $h\->closed(\*(Aqmarker\*(Aq); .Ve .Sp would print: .Sp .Vb 1 \& .Ve .Sp As for \f(CW\*(C`tag\*(C'\fR and \f(CW\*(C`open\*(C'\fR attributes may be provided as hash references: .Sp .Vb 1 \& print $h\->closed(\*(Aqmarker\*(Aq, { lat => 57.0 }, { lon => \-2 }); .Ve .Sp would print: .Sp .Vb 1 \& .Ve .ie n .IP """auto_tag( $name, ... )""" 4 .el .IP "\f(CWauto_tag( $name, ... )\fR" 4 .IX Item "auto_tag( $name, ... )" Calls either \f(CW\*(C`tag\*(C'\fR or \f(CW\*(C`closed\*(C'\fR based on built in rules for the tag. Used internally to implement the tag-named methods. .ie n .IP """stringify( $obj )""" 4 .el .IP "\f(CWstringify( $obj )\fR" 4 .IX Item "stringify( $obj )" Called internally to obtain string representations of values. .Sp It also implements the deferred method call notation (mentioned above) so that .Sp .Vb 10 \& my $table = $h\->table( \& [ \& $h\->tr( \& [ $h\->th( \*(AqName\*(Aq, \*(AqScore\*(Aq, \*(AqPosition\*(Aq ) ], \& [ $h\->td( \*(AqTherese\*(Aq, 90, 1 ) ], \& [ $h\->td( \*(AqChrissie\*(Aq, 85, 2 ) ], \& [ $h\->td( \*(AqAndy\*(Aq, 50, 3 ) ] \& ) \& ] \& ); .Ve .Sp may also be written like this: .Sp .Vb 12 \& my $table = $h\->stringify( \& [ \& \e\*(Aqtable\*(Aq, \& [ \& \e\*(Aqtr\*(Aq, \& [ \e\*(Aqth\*(Aq, \*(AqName\*(Aq, \*(AqScore\*(Aq, \*(AqPosition\*(Aq ], \& [ \e\*(Aqtd\*(Aq, \*(AqTherese\*(Aq, 90, 1 ], \& [ \e\*(Aqtd\*(Aq, \*(AqChrissie\*(Aq, 85, 2 ], \& [ \e\*(Aqtd\*(Aq, \*(AqAndy\*(Aq, 50, 3 ] \& ] \& ] \& ); .Ve .Sp Any reference to an array whose first element is a reference to a scalar .Sp .Vb 1 \& [ \e\*(Aqmethodname\*(Aq, args ] .Ve .Sp is executed as a call to the named method with the specified args. .SS "Methods named after tags" .IX Subsection "Methods named after tags" In addition to the methods described above \f(CW\*(C`HTML::Tiny\*(C'\fR provides all of the following \s-1HTML\s0 generation methods: .PP .Vb 7 \& a abbr acronym address area b base bdo big blockquote body br \& button caption cite code col colgroup dd del div dfn dl dt em \& fieldset form frame frameset h1 h2 h3 h4 h5 h6 head hr html i \& iframe img input ins kbd label legend li link map meta noframes \& noscript object ol optgroup option p param pre q samp script select \& small span strong style sub sup table tbody td textarea tfoot th \& thead title tr tt ul var .Ve .PP The following methods generate closed \s-1XHTML\s0 (
) tags by default: .PP .Vb 1 \& area base br col frame hr img input meta param .Ve .PP So: .PP .Vb 5 \& print $h\->br; # prints
\& print $h\->input({ name => \*(Aqfield1\*(Aq }); \& # prints \& print $h\->img({ src => \*(Aqpic.jpg\*(Aq }); \& # prints .Ve .PP All other tag methods generate tags to wrap whatever content they are passed: .PP .Vb 1 \& print $h\->p(\*(AqHello, World\*(Aq); .Ve .PP prints: .PP .Vb 1 \&

Hello, World

.Ve .PP So the following are equivalent: .PP .Vb 1 \& print $h\->a({ href => \*(Aqhttp://hexten.net\*(Aq }, \*(AqHexten\*(Aq); .Ve .PP and .PP .Vb 1 \& print $h\->tag(\*(Aqa\*(Aq, { href => \*(Aqhttp://hexten.net\*(Aq }, \*(AqHexten\*(Aq); .Ve .SS "Utility Methods" .IX Subsection "Utility Methods" .ie n .IP """url_encode( $str )""" 4 .el .IP "\f(CWurl_encode( $str )\fR" 4 .IX Item "url_encode( $str )" \&\s-1URL\s0 encode a string. Spaces become '+' and non-alphanumeric characters are encoded as '%' + their hexadecimal character code. .Sp .Vb 1 \& $h\->url_encode( \*(Aq \*(Aq ) # returns \*(Aq+%3chello%3e+\*(Aq .Ve .ie n .IP """url_decode( $str )""" 4 .el .IP "\f(CWurl_decode( $str )\fR" 4 .IX Item "url_decode( $str )" \&\s-1URL\s0 decode a string. Reverses the effect of \f(CW\*(C`url_encode\*(C'\fR. .Sp .Vb 1 \& $h\->url_decode( \*(Aq+%3chello%3e+\*(Aq ) # returns \*(Aq \*(Aq .Ve .ie n .IP """query_encode( $hash_ref )""" 4 .el .IP "\f(CWquery_encode( $hash_ref )\fR" 4 .IX Item "query_encode( $hash_ref )" Generate a query string from an anonymous hash of key, value pairs: .Sp .Vb 1 \& print $h\->query_encode({ a => 1, b => 2 }) .Ve .Sp would print .Sp .Vb 1 \& a=1&b=2 .Ve .ie n .IP """entity_encode( $str )""" 4 .el .IP "\f(CWentity_encode( $str )\fR" 4 .IX Item "entity_encode( $str )" Encode the characters '<', '>', '&', '\e'' and '"' as their \s-1HTML\s0 entity equivalents: .Sp .Vb 1 \& print $h\->entity_encode( \*(Aq<>\e\*(Aq"&\*(Aq ); .Ve .Sp would print: .Sp .Vb 1 \& <>'"& .Ve .ie n .IP """json_encode""" 4 .el .IP "\f(CWjson_encode\fR" 4 .IX Item "json_encode" Encode a data structure in \s-1JSON\s0 (Javascript) format: .Sp .Vb 1 \& print $h\->json_encode( { ar => [ 1, 2, 3, { a => 1, b => 2 } ] } ); .Ve .Sp would print: .Sp .Vb 1 \& {"ar":[1,2,3,{"a":1,"b":2}]} .Ve .Sp Because \s-1JSON\s0 is valid Javascript this method can be useful when generating ad-hoc Javascript. For example .Sp .Vb 5 \& my $some_perl_data = { \& score => 45, \& name => \*(AqFred\*(Aq, \& history => [ 32, 37, 41, 45 ] \& }; \& \& # Transfer value to Javascript \& print $h\->script( { type => \*(Aqtext/javascript\*(Aq }, \& "\envar someVar = " . $h\->json_encode( $some_perl_data ) . ";\en " ); \& \& # Prints \& # .Ve .Sp If you attempt to json encode a blessed object \f(CW\*(C`json_encode\*(C'\fR will look for a \f(CW\*(C`TO_JSON\*(C'\fR method and, if found, use its return value as the structure to be converted in place of the object. An attempt to encode a blessed object that does not implement \f(CW\*(C`TO_JSON\*(C'\fR will fail. .SS "Subclassing" .IX Subsection "Subclassing" An \f(CW\*(C`HTML::Tiny\*(C'\fR is a blessed hash ref. .ie n .IP """validate_tag( $closed, $name, $attr )""" 4 .el .IP "\f(CWvalidate_tag( $closed, $name, $attr )\fR" 4 .IX Item "validate_tag( $closed, $name, $attr )" Subclass \f(CW\*(C`validate_tag\*(C'\fR to throw an error or issue a warning when an attempt is made to generate an invalid tag. .SH "CONFIGURATION AND ENVIRONMENT" .IX Header "CONFIGURATION AND ENVIRONMENT" HTML::Tiny requires no configuration files or environment variables. .SH "DEPENDENCIES" .IX Header "DEPENDENCIES" By design HTML::Tiny has no non-core dependencies. .PP To run the tests you will require Test::More. .SH "INCOMPATIBILITIES" .IX Header "INCOMPATIBILITIES" None reported. .SH "BUGS AND LIMITATIONS" .IX Header "BUGS AND LIMITATIONS" No bugs have been reported. .PP Please report any bugs or feature requests to \&\f(CW\*(C`bug\-html\-tiny@rt.cpan.org\*(C'\fR, or through the web interface at . .SH "AUTHOR" .IX Header "AUTHOR" Andy Armstrong \f(CW\*(C`\*(C'\fR .PP Aristotle Pagaltzis \f(CW\*(C`\*(C'\fR .SH "LICENCE AND COPYRIGHT" .IX Header "LICENCE AND COPYRIGHT" Copyright (c) 2008, Andy Armstrong \f(CW\*(C`\*(C'\fR. All rights reserved. .PP This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic. .SH "DISCLAIMER OF WARRANTY" .IX Header "DISCLAIMER OF WARRANTY" \&\s-1BECAUSE\s0 \s-1THIS\s0 \s-1SOFTWARE\s0 \s-1IS\s0 \s-1LICENSED\s0 \s-1FREE\s0 \s-1OF\s0 \s-1CHARGE\s0, \s-1THERE\s0 \s-1IS\s0 \s-1NO\s0 \s-1WARRANTY\s0 \&\s-1FOR\s0 \s-1THE\s0 \s-1SOFTWARE\s0, \s-1TO\s0 \s-1THE\s0 \s-1EXTENT\s0 \s-1PERMITTED\s0 \s-1BY\s0 \s-1APPLICABLE\s0 \s-1LAW\s0. \s-1EXCEPT\s0 \s-1WHEN\s0 \&\s-1OTHERWISE\s0 \s-1STATED\s0 \s-1IN\s0 \s-1WRITING\s0 \s-1THE\s0 \s-1COPYRIGHT\s0 \s-1HOLDERS\s0 \s-1AND/OR\s0 \s-1OTHER\s0 \s-1PARTIES\s0 \&\s-1PROVIDE\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \*(L"\s-1AS\s0 \s-1IS\s0\*(R" \s-1WITHOUT\s0 \s-1WARRANTY\s0 \s-1OF\s0 \s-1ANY\s0 \s-1KIND\s0, \s-1EITHER\s0 \&\s-1EXPRESSED\s0 \s-1OR\s0 \s-1IMPLIED\s0, \s-1INCLUDING\s0, \s-1BUT\s0 \s-1NOT\s0 \s-1LIMITED\s0 \s-1TO\s0, \s-1THE\s0 \s-1IMPLIED\s0 \&\s-1WARRANTIES\s0 \s-1OF\s0 \s-1MERCHANTABILITY\s0 \s-1AND\s0 \s-1FITNESS\s0 \s-1FOR\s0 A \s-1PARTICULAR\s0 \s-1PURPOSE\s0. \s-1THE\s0 \&\s-1ENTIRE\s0 \s-1RISK\s0 \s-1AS\s0 \s-1TO\s0 \s-1THE\s0 \s-1QUALITY\s0 \s-1AND\s0 \s-1PERFORMANCE\s0 \s-1OF\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \s-1IS\s0 \s-1WITH\s0 \&\s-1YOU\s0. \s-1SHOULD\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \s-1PROVE\s0 \s-1DEFECTIVE\s0, \s-1YOU\s0 \s-1ASSUME\s0 \s-1THE\s0 \s-1COST\s0 \s-1OF\s0 \s-1ALL\s0 \&\s-1NECESSARY\s0 \s-1SERVICING\s0, \s-1REPAIR\s0, \s-1OR\s0 \s-1CORRECTION\s0. .PP \&\s-1IN\s0 \s-1NO\s0 \s-1EVENT\s0 \s-1UNLESS\s0 \s-1REQUIRED\s0 \s-1BY\s0 \s-1APPLICABLE\s0 \s-1LAW\s0 \s-1OR\s0 \s-1AGREED\s0 \s-1TO\s0 \s-1IN\s0 \s-1WRITING\s0 \&\s-1WILL\s0 \s-1ANY\s0 \s-1COPYRIGHT\s0 \s-1HOLDER\s0, \s-1OR\s0 \s-1ANY\s0 \s-1OTHER\s0 \s-1PARTY\s0 \s-1WHO\s0 \s-1MAY\s0 \s-1MODIFY\s0 \s-1AND/OR\s0 \&\s-1REDISTRIBUTE\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \s-1AS\s0 \s-1PERMITTED\s0 \s-1BY\s0 \s-1THE\s0 \s-1ABOVE\s0 \s-1LICENCE\s0, \s-1BE\s0 \&\s-1LIABLE\s0 \s-1TO\s0 \s-1YOU\s0 \s-1FOR\s0 \s-1DAMAGES\s0, \s-1INCLUDING\s0 \s-1ANY\s0 \s-1GENERAL\s0, \s-1SPECIAL\s0, \s-1INCIDENTAL\s0, \&\s-1OR\s0 \s-1CONSEQUENTIAL\s0 \s-1DAMAGES\s0 \s-1ARISING\s0 \s-1OUT\s0 \s-1OF\s0 \s-1THE\s0 \s-1USE\s0 \s-1OR\s0 \s-1INABILITY\s0 \s-1TO\s0 \s-1USE\s0 \&\s-1THE\s0 \s-1SOFTWARE\s0 (\s-1INCLUDING\s0 \s-1BUT\s0 \s-1NOT\s0 \s-1LIMITED\s0 \s-1TO\s0 \s-1LOSS\s0 \s-1OF\s0 \s-1DATA\s0 \s-1OR\s0 \s-1DATA\s0 \s-1BEING\s0 \&\s-1RENDERED\s0 \s-1INACCURATE\s0 \s-1OR\s0 \s-1LOSSES\s0 \s-1SUSTAINED\s0 \s-1BY\s0 \s-1YOU\s0 \s-1OR\s0 \s-1THIRD\s0 \s-1PARTIES\s0 \s-1OR\s0 A \&\s-1FAILURE\s0 \s-1OF\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \s-1TO\s0 \s-1OPERATE\s0 \s-1WITH\s0 \s-1ANY\s0 \s-1OTHER\s0 \s-1SOFTWARE\s0), \s-1EVEN\s0 \s-1IF\s0 \&\s-1SUCH\s0 \s-1HOLDER\s0 \s-1OR\s0 \s-1OTHER\s0 \s-1PARTY\s0 \s-1HAS\s0 \s-1BEEN\s0 \s-1ADVISED\s0 \s-1OF\s0 \s-1THE\s0 \s-1POSSIBILITY\s0 \s-1OF\s0 \&\s-1SUCH\s0 \s-1DAMAGES\s0.