1N/Apackage Pod::LaTeX;
1N/A
1N/A=head1 NAME
1N/A
1N/APod::LaTeX - Convert Pod data to formatted Latex
1N/A
1N/A=head1 SYNOPSIS
1N/A
1N/A use Pod::LaTeX;
1N/A my $parser = Pod::LaTeX->new ( );
1N/A
1N/A $parser->parse_from_filehandle;
1N/A
1N/A $parser->parse_from_file ('file.pod', 'file.tex');
1N/A
1N/A=head1 DESCRIPTION
1N/A
1N/AC<Pod::LaTeX> is a module to convert documentation in the Pod format
1N/Ainto Latex. The L<B<pod2latex>|pod2latex> X<pod2latex> command uses
1N/Athis module for translation.
1N/A
1N/AC<Pod::LaTeX> is a derived class from L<Pod::Select|Pod::Select>.
1N/A
1N/A=cut
1N/A
1N/A
1N/Ause strict;
1N/Arequire Pod::ParseUtils;
1N/Ause base qw/ Pod::Select /;
1N/A
1N/A# use Data::Dumper; # for debugging
1N/Ause Carp;
1N/A
1N/Ause vars qw/ $VERSION %HTML_Escapes @LatexSections /;
1N/A
1N/A$VERSION = '0.55';
1N/A
1N/A# Definitions of =headN -> latex mapping
1N/A@LatexSections = (qw/
1N/A chapter
1N/A section
1N/A subsection
1N/A subsubsection
1N/A paragraph
1N/A subparagraph
1N/A /);
1N/A
1N/A# Standard escape sequences converted to Latex.
1N/A# The Unicode name of each character is given in the comments.
1N/A# Complete LaTeX set added by Peter Acklam.
1N/A
1N/A%HTML_Escapes = (
1N/A 'sol' => '\textfractionsolidus{}', # xxx - or should it be just '/'
1N/A 'verbar' => '|',
1N/A
1N/A # The stuff below is based on the information available at
1N/A # http://www.w3.org/TR/html401/sgml/entities.html
1N/A
1N/A # All characters in the range 0xA0-0xFF of the ISO 8859-1 character set.
1N/A # Several of these characters require the `textcomp' LaTeX package.
1N/A 'nbsp' => q|~|, # 0xA0 - no-break space = non-breaking space
1N/A 'iexcl' => q|\textexclamdown{}|, # 0xA1 - inverted exclamation mark
1N/A 'cent' => q|\textcent{}|, # 0xA2 - cent sign
1N/A 'pound' => q|\textsterling{}|, # 0xA3 - pound sign
1N/A 'curren' => q|\textcurrency{}|, # 0xA4 - currency sign
1N/A 'yen' => q|\textyen{}|, # 0xA5 - yen sign = yuan sign
1N/A 'brvbar' => q|\textbrokenbar{}|, # 0xA6 - broken bar = broken vertical bar
1N/A 'sect' => q|\textsection{}|, # 0xA7 - section sign
1N/A 'uml' => q|\textasciidieresis{}|, # 0xA8 - diaeresis = spacing diaeresis
1N/A 'copy' => q|\textcopyright{}|, # 0xA9 - copyright sign
1N/A 'ordf' => q|\textordfeminine{}|, # 0xAA - feminine ordinal indicator
1N/A 'laquo' => q|\guillemotleft{}|, # 0xAB - left-pointing double angle quotation mark = left pointing guillemet
1N/A 'not' => q|\textlnot{}|, # 0xAC - not sign
1N/A 'shy' => q|\-|, # 0xAD - soft hyphen = discretionary hyphen
1N/A 'reg' => q|\textregistered{}|, # 0xAE - registered sign = registered trade mark sign
1N/A 'macr' => q|\textasciimacron{}|, # 0xAF - macron = spacing macron = overline = APL overbar
1N/A 'deg' => q|\textdegree{}|, # 0xB0 - degree sign
1N/A 'plusmn' => q|\textpm{}|, # 0xB1 - plus-minus sign = plus-or-minus sign
1N/A 'sup2' => q|\texttwosuperior{}|, # 0xB2 - superscript two = superscript digit two = squared
1N/A 'sup3' => q|\textthreesuperior{}|, # 0xB3 - superscript three = superscript digit three = cubed
1N/A 'acute' => q|\textasciiacute{}|, # 0xB4 - acute accent = spacing acute
1N/A 'micro' => q|\textmu{}|, # 0xB5 - micro sign
1N/A 'para' => q|\textparagraph{}|, # 0xB6 - pilcrow sign = paragraph sign
1N/A 'middot' => q|\textperiodcentered{}|, # 0xB7 - middle dot = Georgian comma = Greek middle dot
1N/A 'cedil' => q|\c{}|, # 0xB8 - cedilla = spacing cedilla
1N/A 'sup1' => q|\textonesuperior{}|, # 0xB9 - superscript one = superscript digit one
1N/A 'ordm' => q|\textordmasculine{}|, # 0xBA - masculine ordinal indicator
1N/A 'raquo' => q|\guillemotright{}|, # 0xBB - right-pointing double angle quotation mark = right pointing guillemet
1N/A 'frac14' => q|\textonequarter{}|, # 0xBC - vulgar fraction one quarter = fraction one quarter
1N/A 'frac12' => q|\textonehalf{}|, # 0xBD - vulgar fraction one half = fraction one half
1N/A 'frac34' => q|\textthreequarters{}|, # 0xBE - vulgar fraction three quarters = fraction three quarters
1N/A 'iquest' => q|\textquestiondown{}|, # 0xBF - inverted question mark = turned question mark
1N/A 'Agrave' => q|\`A|, # 0xC0 - latin capital letter A with grave = latin capital letter A grave
1N/A 'Aacute' => q|\'A|, # 0xC1 - latin capital letter A with acute
1N/A 'Acirc' => q|\^A|, # 0xC2 - latin capital letter A with circumflex
1N/A 'Atilde' => q|\~A|, # 0xC3 - latin capital letter A with tilde
1N/A 'Auml' => q|\"A|, # 0xC4 - latin capital letter A with diaeresis
1N/A 'Aring' => q|\AA{}|, # 0xC5 - latin capital letter A with ring above = latin capital letter A ring
1N/A 'AElig' => q|\AE{}|, # 0xC6 - latin capital letter AE = latin capital ligature AE
1N/A 'Ccedil' => q|\c{C}|, # 0xC7 - latin capital letter C with cedilla
1N/A 'Egrave' => q|\`E|, # 0xC8 - latin capital letter E with grave
1N/A 'Eacute' => q|\'E|, # 0xC9 - latin capital letter E with acute
1N/A 'Ecirc' => q|\^E|, # 0xCA - latin capital letter E with circumflex
1N/A 'Euml' => q|\"E|, # 0xCB - latin capital letter E with diaeresis
1N/A 'Igrave' => q|\`I|, # 0xCC - latin capital letter I with grave
1N/A 'Iacute' => q|\'I|, # 0xCD - latin capital letter I with acute
1N/A 'Icirc' => q|\^I|, # 0xCE - latin capital letter I with circumflex
1N/A 'Iuml' => q|\"I|, # 0xCF - latin capital letter I with diaeresis
1N/A 'ETH' => q|\DH{}|, # 0xD0 - latin capital letter ETH
1N/A 'Ntilde' => q|\~N|, # 0xD1 - latin capital letter N with tilde
1N/A 'Ograve' => q|\`O|, # 0xD2 - latin capital letter O with grave
1N/A 'Oacute' => q|\'O|, # 0xD3 - latin capital letter O with acute
1N/A 'Ocirc' => q|\^O|, # 0xD4 - latin capital letter O with circumflex
1N/A 'Otilde' => q|\~O|, # 0xD5 - latin capital letter O with tilde
1N/A 'Ouml' => q|\"O|, # 0xD6 - latin capital letter O with diaeresis
1N/A 'times' => q|\texttimes{}|, # 0xD7 - multiplication sign
1N/A 'Oslash' => q|\O{}|, # 0xD8 - latin capital letter O with stroke = latin capital letter O slash
1N/A 'Ugrave' => q|\`U|, # 0xD9 - latin capital letter U with grave
1N/A 'Uacute' => q|\'U|, # 0xDA - latin capital letter U with acute
1N/A 'Ucirc' => q|\^U|, # 0xDB - latin capital letter U with circumflex
1N/A 'Uuml' => q|\"U|, # 0xDC - latin capital letter U with diaeresis
1N/A 'Yacute' => q|\'Y|, # 0xDD - latin capital letter Y with acute
1N/A 'THORN' => q|\TH{}|, # 0xDE - latin capital letter THORN
1N/A 'szlig' => q|\ss{}|, # 0xDF - latin small letter sharp s = ess-zed
1N/A 'agrave' => q|\`a|, # 0xE0 - latin small letter a with grave = latin small letter a grave
1N/A 'aacute' => q|\'a|, # 0xE1 - latin small letter a with acute
1N/A 'acirc' => q|\^a|, # 0xE2 - latin small letter a with circumflex
1N/A 'atilde' => q|\~a|, # 0xE3 - latin small letter a with tilde
1N/A 'auml' => q|\"a|, # 0xE4 - latin small letter a with diaeresis
1N/A 'aring' => q|\aa{}|, # 0xE5 - latin small letter a with ring above = latin small letter a ring
1N/A 'aelig' => q|\ae{}|, # 0xE6 - latin small letter ae = latin small ligature ae
1N/A 'ccedil' => q|\c{c}|, # 0xE7 - latin small letter c with cedilla
1N/A 'egrave' => q|\`e|, # 0xE8 - latin small letter e with grave
1N/A 'eacute' => q|\'e|, # 0xE9 - latin small letter e with acute
1N/A 'ecirc' => q|\^e|, # 0xEA - latin small letter e with circumflex
1N/A 'euml' => q|\"e|, # 0xEB - latin small letter e with diaeresis
1N/A 'igrave' => q|\`i|, # 0xEC - latin small letter i with grave
1N/A 'iacute' => q|\'i|, # 0xED - latin small letter i with acute
1N/A 'icirc' => q|\^i|, # 0xEE - latin small letter i with circumflex
1N/A 'iuml' => q|\"i|, # 0xEF - latin small letter i with diaeresis
1N/A 'eth' => q|\dh{}|, # 0xF0 - latin small letter eth
1N/A 'ntilde' => q|\~n|, # 0xF1 - latin small letter n with tilde
1N/A 'ograve' => q|\`o|, # 0xF2 - latin small letter o with grave
1N/A 'oacute' => q|\'o|, # 0xF3 - latin small letter o with acute
1N/A 'ocirc' => q|\^o|, # 0xF4 - latin small letter o with circumflex
1N/A 'otilde' => q|\~o|, # 0xF5 - latin small letter o with tilde
1N/A 'ouml' => q|\"o|, # 0xF6 - latin small letter o with diaeresis
1N/A 'divide' => q|\textdiv{}|, # 0xF7 - division sign
1N/A 'oslash' => q|\o{}|, # 0xF8 - latin small letter o with stroke, = latin small letter o slash
1N/A 'ugrave' => q|\`u|, # 0xF9 - latin small letter u with grave
1N/A 'uacute' => q|\'u|, # 0xFA - latin small letter u with acute
1N/A 'ucirc' => q|\^u|, # 0xFB - latin small letter u with circumflex
1N/A 'uuml' => q|\"u|, # 0xFC - latin small letter u with diaeresis
1N/A 'yacute' => q|\'y|, # 0xFD - latin small letter y with acute
1N/A 'thorn' => q|\th{}|, # 0xFE - latin small letter thorn
1N/A 'yuml' => q|\"y|, # 0xFF - latin small letter y with diaeresis
1N/A
1N/A # Latin Extended-B
1N/A 'fnof' => q|\textflorin{}|, # latin small f with hook = function = florin
1N/A
1N/A # Greek
1N/A 'Alpha' => q|$\mathrm{A}$|, # greek capital letter alpha
1N/A 'Beta' => q|$\mathrm{B}$|, # greek capital letter beta
1N/A 'Gamma' => q|$\Gamma$|, # greek capital letter gamma
1N/A 'Delta' => q|$\Delta$|, # greek capital letter delta
1N/A 'Epsilon' => q|$\mathrm{E}$|, # greek capital letter epsilon
1N/A 'Zeta' => q|$\mathrm{Z}$|, # greek capital letter zeta
1N/A 'Eta' => q|$\mathrm{H}$|, # greek capital letter eta
1N/A 'Theta' => q|$\Theta$|, # greek capital letter theta
1N/A 'Iota' => q|$\mathrm{I}$|, # greek capital letter iota
1N/A 'Kappa' => q|$\mathrm{K}$|, # greek capital letter kappa
1N/A 'Lambda' => q|$\Lambda$|, # greek capital letter lambda
1N/A 'Mu' => q|$\mathrm{M}$|, # greek capital letter mu
1N/A 'Nu' => q|$\mathrm{N}$|, # greek capital letter nu
1N/A 'Xi' => q|$\Xi$|, # greek capital letter xi
1N/A 'Omicron' => q|$\mathrm{O}$|, # greek capital letter omicron
1N/A 'Pi' => q|$\Pi$|, # greek capital letter pi
1N/A 'Rho' => q|$\mathrm{R}$|, # greek capital letter rho
1N/A 'Sigma' => q|$\Sigma$|, # greek capital letter sigma
1N/A 'Tau' => q|$\mathrm{T}$|, # greek capital letter tau
1N/A 'Upsilon' => q|$\Upsilon$|, # greek capital letter upsilon
1N/A 'Phi' => q|$\Phi$|, # greek capital letter phi
1N/A 'Chi' => q|$\mathrm{X}$|, # greek capital letter chi
1N/A 'Psi' => q|$\Psi$|, # greek capital letter psi
1N/A 'Omega' => q|$\Omega$|, # greek capital letter omega
1N/A
1N/A 'alpha' => q|$\alpha$|, # greek small letter alpha
1N/A 'beta' => q|$\beta$|, # greek small letter beta
1N/A 'gamma' => q|$\gamma$|, # greek small letter gamma
1N/A 'delta' => q|$\delta$|, # greek small letter delta
1N/A 'epsilon' => q|$\epsilon$|, # greek small letter epsilon
1N/A 'zeta' => q|$\zeta$|, # greek small letter zeta
1N/A 'eta' => q|$\eta$|, # greek small letter eta
1N/A 'theta' => q|$\theta$|, # greek small letter theta
1N/A 'iota' => q|$\iota$|, # greek small letter iota
1N/A 'kappa' => q|$\kappa$|, # greek small letter kappa
1N/A 'lambda' => q|$\lambda$|, # greek small letter lambda
1N/A 'mu' => q|$\mu$|, # greek small letter mu
1N/A 'nu' => q|$\nu$|, # greek small letter nu
1N/A 'xi' => q|$\xi$|, # greek small letter xi
1N/A 'omicron' => q|$o$|, # greek small letter omicron
1N/A 'pi' => q|$\pi$|, # greek small letter pi
1N/A 'rho' => q|$\rho$|, # greek small letter rho
1N/A# 'sigmaf' => q||, # greek small letter final sigma
1N/A 'sigma' => q|$\sigma$|, # greek small letter sigma
1N/A 'tau' => q|$\tau$|, # greek small letter tau
1N/A 'upsilon' => q|$\upsilon$|, # greek small letter upsilon
1N/A 'phi' => q|$\phi$|, # greek small letter phi
1N/A 'chi' => q|$\chi$|, # greek small letter chi
1N/A 'psi' => q|$\psi$|, # greek small letter psi
1N/A 'omega' => q|$\omega$|, # greek small letter omega
1N/A# 'thetasym' => q||, # greek small letter theta symbol
1N/A# 'upsih' => q||, # greek upsilon with hook symbol
1N/A# 'piv' => q||, # greek pi symbol
1N/A
1N/A # General Punctuation
1N/A 'bull' => q|\textbullet{}|, # bullet = black small circle
1N/A # bullet is NOT the same as bullet operator
1N/A 'hellip' => q|\textellipsis{}|, # horizontal ellipsis = three dot leader
1N/A 'prime' => q|\textquotesingle{}|, # prime = minutes = feet
1N/A 'Prime' => q|\textquotedbl{}|, # double prime = seconds = inches
1N/A 'oline' => q|\textasciimacron{}|, # overline = spacing overscore
1N/A 'frasl' => q|\textfractionsolidus{}|, # fraction slash
1N/A
1N/A # Letterlike Symbols
1N/A 'weierp' => q|$\wp$|, # script capital P = power set = Weierstrass p
1N/A 'image' => q|$\Re$|, # blackletter capital I = imaginary part
1N/A 'real' => q|$\Im$|, # blackletter capital R = real part symbol
1N/A 'trade' => q|\texttrademark{}|, # trade mark sign
1N/A# 'alefsym' => q||, # alef symbol = first transfinite cardinal
1N/A # alef symbol is NOT the same as hebrew letter alef, although the same
1N/A # glyph could be used to depict both characters
1N/A
1N/A # Arrows
1N/A 'larr' => q|\textleftarrow{}|, # leftwards arrow
1N/A 'uarr' => q|\textuparrow{}|, # upwards arrow
1N/A 'rarr' => q|\textrightarrow{}|, # rightwards arrow
1N/A 'darr' => q|\textdownarrow{}|, # downwards arrow
1N/A 'harr' => q|$\leftrightarrow$|, # left right arrow
1N/A# 'crarr' => q||, # downwards arrow with corner leftwards = carriage return
1N/A 'lArr' => q|$\Leftarrow$|, # leftwards double arrow
1N/A # ISO 10646 does not say that lArr is the same as the 'is implied by'
1N/A # arrow but also does not have any other character for that function. So
1N/A # lArr can be used for 'is implied by' as ISOtech suggests
1N/A 'uArr' => q|$\Uparrow$|, # upwards double arrow
1N/A 'rArr' => q|$\Rightarrow$|, # rightwards double arrow
1N/A # ISO 10646 does not say this is the 'implies' character but does not
1N/A # have another character with this function so ? rArr can be used for
1N/A # 'implies' as ISOtech suggests
1N/A 'dArr' => q|$\Downarrow$|, # downwards double arrow
1N/A 'hArr' => q|$\Leftrightarrow$|, # left right double arrow
1N/A
1N/A # Mathematical Operators.
1N/A # Some of these require the `amssymb' package.
1N/A 'forall' => q|$\forall$|, # for all
1N/A 'part' => q|$\partial$|, # partial differential
1N/A 'exist' => q|$\exists$|, # there exists
1N/A 'empty' => q|$\emptyset$|, # empty set = null set = diameter
1N/A 'nabla' => q|$\nabla$|, # nabla = backward difference
1N/A 'isin' => q|$\in$|, # element of
1N/A 'notin' => q|$\notin$|, # not an element of
1N/A 'ni' => q|$\ni$|, # contains as member
1N/A 'prod' => q|$\prod$|, # n-ary product = product sign
1N/A # prod is NOT the same character as 'greek capital letter pi' though the
1N/A # same glyph might be used for both
1N/A 'sum' => q|$\sum$|, # n-ary sumation
1N/A # sum is NOT the same character as 'greek capital letter sigma' though
1N/A # the same glyph might be used for both
1N/A 'minus' => q|$-$|, # minus sign
1N/A 'lowast' => q|$\ast$|, # asterisk operator
1N/A 'radic' => q|$\surd$|, # square root = radical sign
1N/A 'prop' => q|$\propto$|, # proportional to
1N/A 'infin' => q|$\infty$|, # infinity
1N/A 'ang' => q|$\angle$|, # angle
1N/A 'and' => q|$\wedge$|, # logical and = wedge
1N/A 'or' => q|$\vee$|, # logical or = vee
1N/A 'cap' => q|$\cap$|, # intersection = cap
1N/A 'cup' => q|$\cup$|, # union = cup
1N/A 'int' => q|$\int$|, # integral
1N/A 'there4' => q|$\therefore$|, # therefore
1N/A 'sim' => q|$\sim$|, # tilde operator = varies with = similar to
1N/A # tilde operator is NOT the same character as the tilde
1N/A 'cong' => q|$\cong$|, # approximately equal to
1N/A 'asymp' => q|$\asymp$|, # almost equal to = asymptotic to
1N/A 'ne' => q|$\neq$|, # not equal to
1N/A 'equiv' => q|$\equiv$|, # identical to
1N/A 'le' => q|$\leq$|, # less-than or equal to
1N/A 'ge' => q|$\geq$|, # greater-than or equal to
1N/A 'sub' => q|$\subset$|, # subset of
1N/A 'sup' => q|$\supset$|, # superset of
1N/A # note that nsup, 'not a superset of' is not covered by the Symbol font
1N/A # encoding and is not included.
1N/A 'nsub' => q|$\not\subset$|, # not a subset of
1N/A 'sube' => q|$\subseteq$|, # subset of or equal to
1N/A 'supe' => q|$\supseteq$|, # superset of or equal to
1N/A 'oplus' => q|$\oplus$|, # circled plus = direct sum
1N/A 'otimes' => q|$\otimes$|, # circled times = vector product
1N/A 'perp' => q|$\perp$|, # up tack = orthogonal to = perpendicular
1N/A 'sdot' => q|$\cdot$|, # dot operator
1N/A # dot operator is NOT the same character as middle dot
1N/A
1N/A # Miscellaneous Technical
1N/A 'lceil' => q|$\lceil$|, # left ceiling = apl upstile
1N/A 'rceil' => q|$\rceil$|, # right ceiling
1N/A 'lfloor' => q|$\lfloor$|, # left floor = apl downstile
1N/A 'rfloor' => q|$\rfloor$|, # right floor
1N/A 'lang' => q|$\langle$|, # left-pointing angle bracket = bra
1N/A # lang is NOT the same character as 'less than' or 'single left-pointing
1N/A # angle quotation mark'
1N/A 'rang' => q|$\rangle$|, # right-pointing angle bracket = ket
1N/A # rang is NOT the same character as 'greater than' or 'single
1N/A # right-pointing angle quotation mark'
1N/A
1N/A # Geometric Shapes
1N/A 'loz' => q|$\lozenge$|, # lozenge
1N/A
1N/A # Miscellaneous Symbols
1N/A 'spades' => q|$\spadesuit$|, # black spade suit
1N/A 'clubs' => q|$\clubsuit$|, # black club suit = shamrock
1N/A 'hearts' => q|$\heartsuit$|, # black heart suit = valentine
1N/A 'diams' => q|$\diamondsuit$|, # black diamond suit
1N/A
1N/A # C0 Controls and Basic Latin
1N/A 'quot' => q|"|, # quotation mark = APL quote ["]
1N/A 'amp' => q|\&|, # ampersand
1N/A 'lt' => q|<|, # less-than sign
1N/A 'gt' => q|>|, # greater-than sign
1N/A 'OElig' => q|\OE{}|, # latin capital ligature OE
1N/A 'oelig' => q|\oe{}|, # latin small ligature oe
1N/A 'Scaron' => q|\v{S}|, # latin capital letter S with caron
1N/A 'scaron' => q|\v{s}|, # latin small letter s with caron
1N/A 'Yuml' => q|\"Y|, # latin capital letter Y with diaeresis
1N/A 'circ' => q|\textasciicircum{}|, # modifier letter circumflex accent
1N/A 'tilde' => q|\textasciitilde{}|, # small tilde
1N/A 'ensp' => q|\phantom{n}|, # en space
1N/A 'emsp' => q|\hspace{1em}|, # em space
1N/A 'thinsp' => q|\,|, # thin space
1N/A 'zwnj' => q|{}|, # zero width non-joiner
1N/A# 'zwj' => q||, # zero width joiner
1N/A# 'lrm' => q||, # left-to-right mark
1N/A# 'rlm' => q||, # right-to-left mark
1N/A 'ndash' => q|--|, # en dash
1N/A 'mdash' => q|---|, # em dash
1N/A 'lsquo' => q|\textquoteleft{}|, # left single quotation mark
1N/A 'rsquo' => q|\textquoteright{}|, # right single quotation mark
1N/A 'sbquo' => q|\quotesinglbase{}|, # single low-9 quotation mark
1N/A 'ldquo' => q|\textquotedblleft{}|, # left double quotation mark
1N/A 'rdquo' => q|\textquotedblright{}|, # right double quotation mark
1N/A 'bdquo' => q|\quotedblbase{}|, # double low-9 quotation mark
1N/A 'dagger' => q|\textdagger{}|, # dagger
1N/A 'Dagger' => q|\textdaggerdbl{}|, # double dagger
1N/A 'permil' => q|\textperthousand{}|, # per mille sign
1N/A 'lsaquo' => q|\guilsinglleft{}|, # single left-pointing angle quotation mark
1N/A 'rsaquo' => q|\guilsinglright{}|, # single right-pointing angle quotation mark
1N/A 'euro' => q|\texteuro{}|, # euro sign
1N/A);
1N/A
1N/A=head1 OBJECT METHODS
1N/A
1N/AThe following methods are provided in this module. Methods inherited
1N/Afrom C<Pod::Select> are not described in the public interface.
1N/A
1N/A=over 4
1N/A
1N/A=begin __PRIVATE__
1N/A
1N/A=item C<initialize>
1N/A
1N/AInitialise the object. This method is subclassed from C<Pod::Parser>.
1N/AThe base class method is invoked. This method defines the default
1N/Abehaviour of the object unless overridden by supplying arguments to
1N/Athe constructor.
1N/A
1N/AInternal settings are defaulted as well as the public instance data.
1N/AInternal hash values are accessed directly (rather than through
1N/Aa method) and start with an underscore.
1N/A
1N/AThis method should not be invoked by the user directly.
1N/A
1N/A=end __PRIVATE__
1N/A
1N/A=cut
1N/A
1N/A
1N/A
1N/A# - An array for nested lists
1N/A
1N/A# Arguments have already been read by this point
1N/A
1N/Asub initialize {
1N/A my $self = shift;
1N/A
1N/A # print Dumper($self);
1N/A
1N/A # Internals
1N/A $self->{_Lists} = []; # For nested lists
1N/A $self->{_suppress_all_para} = 0; # For =begin blocks
1N/A $self->{_dont_modify_any_para}=0; # For =begin blocks
1N/A $self->{_CURRENT_HEAD1} = ''; # Name of current HEAD1 section
1N/A
1N/A # Options - only initialise if not already set
1N/A
1N/A # Cause the '=head1 NAME' field to be treated specially
1N/A # The contents of the NAME paragraph will be converted
1N/A # to a section title. All subsequent =head1 will be converted
1N/A # to =head2 and down. Will not affect =head1's prior to NAME
1N/A # Assumes: 'Module - purpose' format
1N/A # Also creates a purpose field
1N/A # The name is used for Labeling of the subsequent subsections
1N/A $self->{ReplaceNAMEwithSection} = 0
1N/A unless exists $self->{ReplaceNAMEwithSection};
1N/A $self->{AddPreamble} = 1 # make full latex document
1N/A unless exists $self->{AddPreamble};
1N/A $self->{StartWithNewPage} = 0 # Start new page for pod section
1N/A unless exists $self->{StartWithNewPage};
1N/A $self->{TableOfContents} = 0 # Add table of contents
1N/A unless exists $self->{TableOfContents}; # only relevant if AddPreamble=1
1N/A $self->{AddPostamble} = 1 # Add closing latex code at end
1N/A unless exists $self->{AddPostamble}; # effectively end{document} and index
1N/A $self->{MakeIndex} = 1 # Add index (only relevant AddPostamble
1N/A unless exists $self->{MakeIndex}; # and AddPreamble)
1N/A
1N/A $self->{UniqueLabels} = 1 # Use label unique for each pod
1N/A unless exists $self->{UniqueLabels}; # either based on the filename
1N/A # or supplied
1N/A
1N/A # Control the level of =head1. default is \section
1N/A #
1N/A $self->{Head1Level} = 1 # Offset in latex sections
1N/A unless exists $self->{Head1Level}; # 0 is chapter, 2 is subsection
1N/A
1N/A # Control at which level numbering of sections is turned off
1N/A # ie subsection becomes subsection*
1N/A # The numbering is relative to the latex sectioning commands
1N/A # and is independent of Pod heading level
1N/A # default is to number \section but not \subsection
1N/A $self->{LevelNoNum} = 2
1N/A unless exists $self->{LevelNoNum};
1N/A
1N/A # Label to be used as prefix to all internal section names
1N/A # If not defined will attempt to derive it from the filename
1N/A # This can not happen when running parse_from_filehandle though
1N/A # hence the ability to set the label externally
1N/A # The label could then be Pod::Parser_DESCRIPTION or somesuch
1N/A
1N/A $self->{Label} = undef # label to be used as prefix
1N/A unless exists $self->{Label}; # to all internal section names
1N/A
1N/A # These allow the caller to add arbritrary latex code to
1N/A # start and end of document. AddPreamble and AddPostamble are ignored
1N/A # if these are set.
1N/A # Also MakeIndex and TableOfContents are also ignored.
1N/A $self->{UserPreamble} = undef # User supplied start (AddPreamble =1)
1N/A unless exists $self->{Label};
1N/A $self->{UserPostamble} = undef # Use supplied end (AddPostamble=1)
1N/A unless exists $self->{Label};
1N/A
1N/A # Run base initialize
1N/A $self->SUPER::initialize;
1N/A
1N/A}
1N/A
1N/A=back
1N/A
1N/A=head2 Data Accessors
1N/A
1N/AThe following methods are provided for accessing instance data. These
1N/Amethods should be used for accessing configuration parameters rather
1N/Athan assuming the object is a hash.
1N/A
1N/ADefault values can be supplied by using these names as keys to a hash
1N/Aof arguments when using the C<new()> constructor.
1N/A
1N/A=over 4
1N/A
1N/A=item B<AddPreamble>
1N/A
1N/ALogical to control whether a C<latex> preamble is to be written.
1N/AIf true, a valid C<latex> preamble is written before the pod data is written.
1N/AThis is similar to:
1N/A
1N/A \documentclass{article}
1N/A \usepackage[T1]{fontenc}
1N/A \usepackage{textcomp}
1N/A \begin{document}
1N/A
1N/Abut will be more complicated if table of contents and indexing are required.
1N/ACan be used to set or retrieve the current value.
1N/A
1N/A $add = $parser->AddPreamble();
1N/A $parser->AddPreamble(1);
1N/A
1N/AIf used in conjunction with C<AddPostamble> a full latex document will
1N/Abe written that could be immediately processed by C<latex>.
1N/A
1N/AFor some pod escapes it may be necessary to include the amsmath
1N/Apackage. This is not yet added to the preamble automaatically.
1N/A
1N/A=cut
1N/A
1N/Asub AddPreamble {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{AddPreamble} = shift;
1N/A }
1N/A return $self->{AddPreamble};
1N/A}
1N/A
1N/A=item B<AddPostamble>
1N/A
1N/ALogical to control whether a standard C<latex> ending is written to the output
1N/Afile after the document has been processed.
1N/AIn its simplest form this is simply:
1N/A
1N/A \end{document}
1N/A
1N/Abut can be more complicated if a index is required.
1N/ACan be used to set or retrieve the current value.
1N/A
1N/A $add = $parser->AddPostamble();
1N/A $parser->AddPostamble(1);
1N/A
1N/AIf used in conjunction with C<AddPreaamble> a full latex document will
1N/Abe written that could be immediately processed by C<latex>.
1N/A
1N/A=cut
1N/A
1N/Asub AddPostamble {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{AddPostamble} = shift;
1N/A }
1N/A return $self->{AddPostamble};
1N/A}
1N/A
1N/A=item B<Head1Level>
1N/A
1N/AThe C<latex> sectioning level that should be used to correspond to
1N/Aa pod C<=head1> directive. This can be used, for example, to turn
1N/Aa C<=head1> into a C<latex> C<subsection>. This should hold a number
1N/Acorresponding to the required position in an array containing the
1N/Afollowing elements:
1N/A
1N/A [0] chapter
1N/A [1] section
1N/A [2] subsection
1N/A [3] subsubsection
1N/A [4] paragraph
1N/A [5] subparagraph
1N/A
1N/ACan be used to set or retrieve the current value:
1N/A
1N/A $parser->Head1Level(2);
1N/A $sect = $parser->Head1Level;
1N/A
1N/ASetting this number too high can result in sections that may not be reproducible
1N/Ain the expected way. For example, setting this to 4 would imply that C<=head3>
1N/Ado not have a corresponding C<latex> section (C<=head1> would correspond to
1N/Aa C<paragraph>).
1N/A
1N/AA check is made to ensure that the supplied value is an integer in the
1N/Arange 0 to 5.
1N/A
1N/ADefault is for a value of 1 (i.e. a C<section>).
1N/A
1N/A=cut
1N/A
1N/Asub Head1Level {
1N/A my $self = shift;
1N/A if (@_) {
1N/A my $arg = shift;
1N/A if ($arg =~ /^\d$/ && $arg <= $#LatexSections) {
1N/A $self->{Head1Level} = $arg;
1N/A } else {
1N/A carp "Head1Level supplied ($arg) must be integer in range 0 to ".$#LatexSections . "- Ignoring\n";
1N/A }
1N/A }
1N/A return $self->{Head1Level};
1N/A}
1N/A
1N/A=item B<Label>
1N/A
1N/AThis is the label that is prefixed to all C<latex> label and index
1N/Aentries to make them unique. In general, pods have similarly titled
1N/Asections (NAME, DESCRIPTION etc) and a C<latex> label will be multiply
1N/Adefined if more than one pod document is to be included in a single
1N/AC<latex> file. To overcome this, this label is prefixed to a label
1N/Awhenever a label is required (joined with an underscore) or to an
1N/Aindex entry (joined by an exclamation mark which is the normal index
1N/Aseparator). For example, C<\label{text}> becomes C<\label{Label_text}>.
1N/A
1N/ACan be used to set or retrieve the current value:
1N/A
1N/A $label = $parser->Label;
1N/A $parser->Label($label);
1N/A
1N/AThis label is only used if C<UniqueLabels> is true.
1N/AIts value is set automatically from the C<NAME> field
1N/Aif C<ReplaceNAMEwithSection> is true. If this is not the case
1N/Ait must be set manually before starting the parse.
1N/A
1N/ADefault value is C<undef>.
1N/A
1N/A=cut
1N/A
1N/Asub Label {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{Label} = shift;
1N/A }
1N/A return $self->{Label};
1N/A}
1N/A
1N/A=item B<LevelNoNum>
1N/A
1N/AControl the point at which C<latex> section numbering is turned off.
1N/AFor example, this can be used to make sure that C<latex> sections
1N/Aare numbered but subsections are not.
1N/A
1N/ACan be used to set or retrieve the current value:
1N/A
1N/A $lev = $parser->LevelNoNum;
1N/A $parser->LevelNoNum(2);
1N/A
1N/AThe argument must be an integer between 0 and 5 and is the same as the
1N/Anumber described in C<Head1Level> method description. The number has
1N/Anothing to do with the pod heading number, only the C<latex> sectioning.
1N/A
1N/ADefault is 2. (i.e. C<latex> subsections are written as C<subsection*>
1N/Abut sections are numbered).
1N/A
1N/A=cut
1N/A
1N/Asub LevelNoNum {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{LevelNoNum} = shift;
1N/A }
1N/A return $self->{LevelNoNum};
1N/A}
1N/A
1N/A=item B<MakeIndex>
1N/A
1N/AControls whether C<latex> commands for creating an index are to be inserted
1N/Ainto the preamble and postamble
1N/A
1N/A $makeindex = $parser->MakeIndex;
1N/A $parser->MakeIndex(0);
1N/A
1N/AIrrelevant if both C<AddPreamble> and C<AddPostamble> are false (or equivalently,
1N/AC<UserPreamble> and C<UserPostamble> are set).
1N/A
1N/ADefault is for an index to be created.
1N/A
1N/A=cut
1N/A
1N/Asub MakeIndex {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{MakeIndex} = shift;
1N/A }
1N/A return $self->{MakeIndex};
1N/A}
1N/A
1N/A=item B<ReplaceNAMEwithSection>
1N/A
1N/AThis controls whether the C<NAME> section in the pod is to be translated
1N/Aliterally or converted to a slightly modified output where the section
1N/Aname is the pod name rather than "NAME".
1N/A
1N/AIf true, the pod segment
1N/A
1N/A =head1 NAME
1N/A
1N/A pod::name - purpose
1N/A
1N/A =head1 SYNOPSIS
1N/A
1N/Ais converted to the C<latex>
1N/A
1N/A \section{pod::name\label{pod_name}\index{pod::name}}
1N/A
1N/A Purpose
1N/A
1N/A \subsection*{SYNOPSIS\label{pod_name_SYNOPSIS}%
1N/A \index{pod::name!SYNOPSIS}}
1N/A
1N/A(dependent on the value of C<Head1Level> and C<LevelNoNum>). Note that
1N/Asubsequent C<head1> directives translate to subsections rather than
1N/Asections and that the labels and index now include the pod name (dependent
1N/Aon the value of C<UniqueLabels>).
1N/A
1N/AThe C<Label> is set from the pod name regardless of any current value
1N/Aof C<Label>.
1N/A
1N/A $mod = $parser->ReplaceNAMEwithSection;
1N/A $parser->ReplaceNAMEwithSection(0);
1N/A
1N/ADefault is to translate the pod literally.
1N/A
1N/A=cut
1N/A
1N/Asub ReplaceNAMEwithSection {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{ReplaceNAMEwithSection} = shift;
1N/A }
1N/A return $self->{ReplaceNAMEwithSection};
1N/A}
1N/A
1N/A=item B<StartWithNewPage>
1N/A
1N/AIf true, each pod translation will begin with a C<latex>
1N/AC<\clearpage>.
1N/A
1N/A $parser->StartWithNewPage(1);
1N/A $newpage = $parser->StartWithNewPage;
1N/A
1N/ADefault is false.
1N/A
1N/A=cut
1N/A
1N/Asub StartWithNewPage {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{StartWithNewPage} = shift;
1N/A }
1N/A return $self->{StartWithNewPage};
1N/A}
1N/A
1N/A=item B<TableOfContents>
1N/A
1N/AIf true, a table of contents will be created.
1N/AIrrelevant if C<AddPreamble> is false or C<UserPreamble>
1N/Ais set.
1N/A
1N/A $toc = $parser->TableOfContents;
1N/A $parser->TableOfContents(1);
1N/A
1N/ADefault is false.
1N/A
1N/A=cut
1N/A
1N/Asub TableOfContents {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{TableOfContents} = shift;
1N/A }
1N/A return $self->{TableOfContents};
1N/A}
1N/A
1N/A=item B<UniqueLabels>
1N/A
1N/AIf true, the translator will attempt to make sure that
1N/Aeach C<latex> label or index entry will be uniquely identified
1N/Aby prefixing the contents of C<Label>. This allows
1N/Amultiple documents to be combined without clashing
1N/Acommon labels such as C<DESCRIPTION> and C<SYNOPSIS>
1N/A
1N/A $parser->UniqueLabels(1);
1N/A $unq = $parser->UniqueLabels;
1N/A
1N/ADefault is true.
1N/A
1N/A=cut
1N/A
1N/Asub UniqueLabels {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{UniqueLabels} = shift;
1N/A }
1N/A return $self->{UniqueLabels};
1N/A}
1N/A
1N/A=item B<UserPreamble>
1N/A
1N/AUser supplied C<latex> preamble. Added before the pod translation
1N/Adata.
1N/A
1N/AIf set, the contents will be prepended to the output file before the translated
1N/Adata regardless of the value of C<AddPreamble>.
1N/AC<MakeIndex> and C<TableOfContents> will also be ignored.
1N/A
1N/A=cut
1N/A
1N/Asub UserPreamble {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{UserPreamble} = shift;
1N/A }
1N/A return $self->{UserPreamble};
1N/A}
1N/A
1N/A=item B<UserPostamble>
1N/A
1N/AUser supplied C<latex> postamble. Added after the pod translation
1N/Adata.
1N/A
1N/AIf set, the contents will be prepended to the output file after the translated
1N/Adata regardless of the value of C<AddPostamble>.
1N/AC<MakeIndex> will also be ignored.
1N/A
1N/A=cut
1N/A
1N/Asub UserPostamble {
1N/A my $self = shift;
1N/A if (@_) {
1N/A $self->{UserPostamble} = shift;
1N/A }
1N/A return $self->{UserPostamble};
1N/A}
1N/A
1N/A=begin __PRIVATE__
1N/A
1N/A=item B<Lists>
1N/A
1N/AContains details of the currently active lists.
1N/A The array contains C<Pod::List> objects. A new C<Pod::List>
1N/Aobject is created each time a list is encountered and it is
1N/Apushed onto this stack. When the list context ends, it
1N/Ais popped from the stack. The array will be empty if no
1N/Alists are active.
1N/A
1N/AReturns array of list information in list context
1N/AReturns array ref in scalar context
1N/A
1N/A=cut
1N/A
1N/A
1N/A
1N/Asub lists {
1N/A my $self = shift;
1N/A return @{ $self->{_Lists} } if wantarray();
1N/A return $self->{_Lists};
1N/A}
1N/A
1N/A=end __PRIVATE__
1N/A
1N/A=back
1N/A
1N/A=begin __PRIVATE__
1N/A
1N/A=head2 Subclassed methods
1N/A
1N/AThe following methods override methods provided in the C<Pod::Select>
1N/Abase class. See C<Pod::Parser> and C<Pod::Select> for more information
1N/Aon what these methods require.
1N/A
1N/A=over 4
1N/A
1N/A=cut
1N/A
1N/A######### END ACCESSORS ###################
1N/A
1N/A# Opening pod
1N/A
1N/A=item B<begin_pod>
1N/A
1N/AWrites the C<latex> preamble if requested.
1N/A
1N/A=cut
1N/A
1N/Asub begin_pod {
1N/A my $self = shift;
1N/A
1N/A # Get the pod identification
1N/A # This should really come from the '=head1 NAME' paragraph
1N/A
1N/A my $infile = $self->input_file;
1N/A my $class = ref($self);
1N/A my $date = gmtime(time);
1N/A
1N/A # Comment message to say where this came from
1N/A my $comment = << "__TEX_COMMENT__";
1N/A%% Latex generated from POD in document $infile
1N/A%% Using the perl module $class
1N/A%% Converted on $date
1N/A__TEX_COMMENT__
1N/A
1N/A # Write the preamble
1N/A # If the caller has supplied one then we just use that
1N/A
1N/A my $preamble = '';
1N/A if (defined $self->UserPreamble) {
1N/A
1N/A $preamble = $self->UserPreamble;
1N/A
1N/A # Add the description of where this came from
1N/A $preamble .= "\n$comment";
1N/A
1N/A
1N/A } elsif ($self->AddPreamble) {
1N/A # Write our own preamble
1N/A
1N/A # Code to initialise index making
1N/A # Use an array so that we can prepend comment if required
1N/A my @makeidx = (
1N/A '\usepackage{makeidx}',
1N/A '\makeindex',
1N/A );
1N/A
1N/A unless ($self->MakeIndex) {
1N/A foreach (@makeidx) {
1N/A $_ = '%% ' . $_;
1N/A }
1N/A }
1N/A my $makeindex = join("\n",@makeidx) . "\n";
1N/A
1N/A
1N/A # Table of contents
1N/A my $tableofcontents = '\tableofcontents';
1N/A
1N/A $tableofcontents = '%% ' . $tableofcontents
1N/A unless $self->TableOfContents;
1N/A
1N/A # Roll our own
1N/A $preamble = << "__TEX_HEADER__";
1N/A\\documentclass{article}
1N/A\\usepackage[T1]{fontenc}
1N/A\\usepackage{textcomp}
1N/A
1N/A$comment
1N/A
1N/A$makeindex
1N/A
1N/A\\begin{document}
1N/A
1N/A$tableofcontents
1N/A
1N/A__TEX_HEADER__
1N/A
1N/A }
1N/A
1N/A # Write the header (blank if none)
1N/A $self->_output($preamble);
1N/A
1N/A # Start on new page if requested
1N/A $self->_output("\\clearpage\n") if $self->StartWithNewPage;
1N/A
1N/A}
1N/A
1N/A
1N/A=item B<end_pod>
1N/A
1N/AWrite the closing C<latex> code.
1N/A
1N/A=cut
1N/A
1N/Asub end_pod {
1N/A my $self = shift;
1N/A
1N/A # End string
1N/A my $end = '';
1N/A
1N/A # Use the user version of the postamble if deinfed
1N/A if (defined $self->UserPostamble) {
1N/A $end = $self->UserPostamble;
1N/A
1N/A $self->_output($end);
1N/A
1N/A } elsif ($self->AddPostamble) {
1N/A
1N/A # Check for index
1N/A my $makeindex = '\printindex';
1N/A
1N/A $makeindex = '%% '. $makeindex unless $self->MakeIndex;
1N/A
1N/A $end = "$makeindex\n\n\\end{document}\n";
1N/A }
1N/A
1N/A
1N/A $self->_output($end);
1N/A
1N/A}
1N/A
1N/A=item B<command>
1N/A
1N/AProcess basic pod commands.
1N/A
1N/A=cut
1N/A
1N/Asub command {
1N/A my $self = shift;
1N/A my ($command, $paragraph, $line_num, $parobj) = @_;
1N/A
1N/A # return if we dont care
1N/A return if $command eq 'pod';
1N/A
1N/A # Store a copy of the raw text in case we are in a =for
1N/A # block and need to preserve the existing latex
1N/A my $rawpara = $paragraph;
1N/A
1N/A # Do the latex escapes
1N/A $paragraph = $self->_replace_special_chars($paragraph);
1N/A
1N/A # Interpolate pod sequences in paragraph
1N/A $paragraph = $self->interpolate($paragraph, $line_num);
1N/A $paragraph =~ s/\s+$//;
1N/A
1N/A # Replace characters that can only be done after
1N/A # interpolation of interior sequences
1N/A $paragraph = $self->_replace_special_chars_late($paragraph);
1N/A
1N/A # Now run the command
1N/A if ($command eq 'over') {
1N/A
1N/A $self->begin_list($paragraph, $line_num);
1N/A
1N/A } elsif ($command eq 'item') {
1N/A
1N/A $self->add_item($paragraph, $line_num);
1N/A
1N/A } elsif ($command eq 'back') {
1N/A
1N/A $self->end_list($line_num);
1N/A
1N/A } elsif ($command eq 'head1') {
1N/A
1N/A # Store the name of the section
1N/A $self->{_CURRENT_HEAD1} = $paragraph;
1N/A
1N/A # Print it
1N/A $self->head(1, $paragraph, $parobj);
1N/A
1N/A } elsif ($command eq 'head2') {
1N/A
1N/A $self->head(2, $paragraph, $parobj);
1N/A
1N/A } elsif ($command eq 'head3') {
1N/A
1N/A $self->head(3, $paragraph, $parobj);
1N/A
1N/A } elsif ($command eq 'head4') {
1N/A
1N/A $self->head(4, $paragraph, $parobj);
1N/A
1N/A } elsif ($command eq 'head5') {
1N/A
1N/A $self->head(5, $paragraph, $parobj);
1N/A
1N/A } elsif ($command eq 'head6') {
1N/A
1N/A $self->head(6, $paragraph, $parobj);
1N/A
1N/A } elsif ($command eq 'begin') {
1N/A
1N/A # pass through if latex
1N/A if ($paragraph =~ /^latex/i) {
1N/A # Make sure that subsequent paragraphs are not modfied before printing
1N/A $self->{_dont_modify_any_para} = 1;
1N/A
1N/A } else {
1N/A # Suppress all subsequent paragraphs unless
1N/A # it is explcitly intended for latex
1N/A $self->{_suppress_all_para} = 1;
1N/A }
1N/A
1N/A } elsif ($command eq 'for') {
1N/A
1N/A # =for latex
1N/A # some latex
1N/A
1N/A # With =for we will get the text for the full paragraph
1N/A # as well as the format name.
1N/A # We do not get an additional paragraph later on. The next
1N/A # paragraph is not governed by the =for
1N/A
1N/A # The first line contains the format and the rest is the
1N/A # raw code.
1N/A my ($format, $chunk) = split(/\n/, $rawpara, 2);
1N/A
1N/A # If we have got some latex code print it out immediately
1N/A # unmodified. Else do nothing.
1N/A if ($format =~ /^latex/i) {
1N/A # Make sure that next paragraph is not modfied before printing
1N/A $self->_output( $chunk );
1N/A
1N/A }
1N/A
1N/A } elsif ($command eq 'end') {
1N/A
1N/A # Reset suppression
1N/A $self->{_suppress_all_para} = 0;
1N/A $self->{_dont_modify_any_para} = 0;
1N/A
1N/A } elsif ($command eq 'pod') {
1N/A
1N/A # Do nothing
1N/A
1N/A } else {
1N/A carp "Command $command not recognised at line $line_num\n";
1N/A }
1N/A
1N/A}
1N/A
1N/A=item B<verbatim>
1N/A
1N/AVerbatim text
1N/A
1N/A=cut
1N/A
1N/Asub verbatim {
1N/A my $self = shift;
1N/A my ($paragraph, $line_num, $parobj) = @_;
1N/A
1N/A # Expand paragraph unless in =begin block
1N/A if ($self->{_dont_modify_any_para}) {
1N/A # Just print as is
1N/A $self->_output($paragraph);
1N/A
1N/A } else {
1N/A
1N/A return if $paragraph =~ /^\s+$/;
1N/A
1N/A # Clean trailing space
1N/A $paragraph =~ s/\s+$//;
1N/A
1N/A # Clean tabs. Routine taken from Tabs.pm
1N/A # by David Muir Sharnoff muir@idiom.com,
1N/A # slightly modified by hsmyers@sdragons.com 10/22/01
1N/A my @l = split("\n",$paragraph);
1N/A foreach (@l) {
1N/A 1 while s/(^|\n)([^\t\n]*)(\t+)/
1N/A $1. $2 . (" " x
1N/A (8 * length($3)
1N/A - (length($2) % 8)))
1N/A /sex;
1N/A }
1N/A $paragraph = join("\n",@l);
1N/A # End of change.
1N/A
1N/A
1N/A
1N/A $self->_output('\begin{verbatim}' . "\n$paragraph\n". '\end{verbatim}'."\n");
1N/A }
1N/A}
1N/A
1N/A=item B<textblock>
1N/A
1N/APlain text paragraph.
1N/A
1N/A=cut
1N/A
1N/Asub textblock {
1N/A my $self = shift;
1N/A my ($paragraph, $line_num, $parobj) = @_;
1N/A
1N/A # print Dumper($self);
1N/A
1N/A # Expand paragraph unless in =begin block
1N/A if ($self->{_dont_modify_any_para}) {
1N/A # Just print as is
1N/A $self->_output($paragraph);
1N/A
1N/A return;
1N/A }
1N/A
1N/A
1N/A # Escape latex special characters
1N/A $paragraph = $self->_replace_special_chars($paragraph);
1N/A
1N/A # Interpolate interior sequences
1N/A my $expansion = $self->interpolate($paragraph, $line_num);
1N/A $expansion =~ s/\s+$//;
1N/A
1N/A # Escape special characters that can not be done earlier
1N/A $expansion = $self->_replace_special_chars_late($expansion);
1N/A
1N/A # If we are replacing 'head1 NAME' with a section
1N/A # we need to look in the paragraph and rewrite things
1N/A # Need to make sure this is called only on the first paragraph
1N/A # following 'head1 NAME' and not on subsequent paragraphs that may be
1N/A # present.
1N/A if ($self->{_CURRENT_HEAD1} =~ /^NAME/i && $self->ReplaceNAMEwithSection()) {
1N/A
1N/A # Strip white space from start and end
1N/A $paragraph =~ s/^\s+//;
1N/A $paragraph =~ s/\s$//;
1N/A
1N/A # Split the string into 2 parts
1N/A my ($name, $purpose) = split(/\s+-\s+/, $expansion,2);
1N/A
1N/A # Now prevent this from triggering until a new head1 NAME is set
1N/A $self->{_CURRENT_HEAD1} = '_NAME';
1N/A
1N/A # Might want to clear the Label() before doing this (CHECK)
1N/A
1N/A # Print the heading
1N/A $self->head(1, $name, $parobj);
1N/A
1N/A # Set the labeling in case we want unique names later
1N/A $self->Label( $self->_create_label( $name, 1 ) );
1N/A
1N/A # Raise the Head1Level by one so that subsequent =head1 appear
1N/A # as subsections of the main name section unless we are already
1N/A # at maximum [Head1Level() could check this itself - CHECK]
1N/A $self->Head1Level( $self->Head1Level() + 1)
1N/A unless $self->Head1Level == $#LatexSections;
1N/A
1N/A # Now write out the new latex paragraph
1N/A $purpose = ucfirst($purpose);
1N/A $self->_output("\n\n$purpose\n\n");
1N/A
1N/A } else {
1N/A # Just write the output
1N/A $self->_output("\n\n$expansion\n\n");
1N/A }
1N/A
1N/A}
1N/A
1N/A=item B<interior_sequence>
1N/A
1N/AInterior sequence expansion
1N/A
1N/A=cut
1N/A
1N/Asub interior_sequence {
1N/A my $self = shift;
1N/A
1N/A my ($seq_command, $seq_argument, $pod_seq) = @_;
1N/A
1N/A if ($seq_command eq 'B') {
1N/A return "\\textbf{$seq_argument}";
1N/A
1N/A } elsif ($seq_command eq 'I') {
1N/A return "\\textit{$seq_argument}";
1N/A
1N/A } elsif ($seq_command eq 'E') {
1N/A
1N/A # If it is simply a number
1N/A if ($seq_argument =~ /^\d+$/) {
1N/A return chr($seq_argument);
1N/A # Look up escape in hash table
1N/A } elsif (exists $HTML_Escapes{$seq_argument}) {
1N/A return $HTML_Escapes{$seq_argument};
1N/A
1N/A } else {
1N/A my ($file, $line) = $pod_seq->file_line();
1N/A warn "Escape sequence $seq_argument not recognised at line $line of file $file\n";
1N/A return;
1N/A }
1N/A
1N/A } elsif ($seq_command eq 'Z') {
1N/A
1N/A # Zero width space
1N/A return '{}';
1N/A
1N/A } elsif ($seq_command eq 'C') {
1N/A return "\\texttt{$seq_argument}";
1N/A
1N/A } elsif ($seq_command eq 'F') {
1N/A return "\\emph{$seq_argument}";
1N/A
1N/A } elsif ($seq_command eq 'S') {
1N/A # non breakable spaces
1N/A my $nbsp = '~';
1N/A
1N/A $seq_argument =~ s/\s/$nbsp/g;
1N/A return $seq_argument;
1N/A
1N/A } elsif ($seq_command eq 'L') {
1N/A my $link = new Pod::Hyperlink($seq_argument);
1N/A
1N/A # undef on failure
1N/A unless (defined $link) {
1N/A carp $@;
1N/A return;
1N/A }
1N/A
1N/A # Handle internal links differently
1N/A my $type = $link->type;
1N/A my $page = $link->page;
1N/A
1N/A if ($type eq 'section' && $page eq '') {
1N/A # Use internal latex reference
1N/A my $node = $link->node;
1N/A
1N/A # Convert to a label
1N/A $node = $self->_create_label($node);
1N/A
1N/A return "\\S\\ref{$node}";
1N/A
1N/A } else {
1N/A # Use default markup for external references
1N/A # (although Starlink would use \xlabel)
1N/A my $markup = $link->markup;
1N/A my ($file, $line) = $pod_seq->file_line();
1N/A
1N/A return $self->interpolate($link->markup, $line);
1N/A }
1N/A
1N/A
1N/A
1N/A } elsif ($seq_command eq 'P') {
1N/A # Special markup for Pod::Hyperlink
1N/A # Replace :: with / - but not sure if I want to do this
1N/A # any more.
1N/A my $link = $seq_argument;
1N/A $link =~ s|::|/|g;
1N/A
1N/A my $ref = "\\emph{$seq_argument}";
1N/A return $ref;
1N/A
1N/A } elsif ($seq_command eq 'Q') {
1N/A # Special markup for Pod::Hyperlink
1N/A return "\\textsf{$seq_argument}";
1N/A
1N/A } elsif ($seq_command eq 'X') {
1N/A # Index entries
1N/A
1N/A # use \index command
1N/A # I will let '!' go through for now
1N/A # not sure how sub categories are handled in X<>
1N/A my $index = $self->_create_index($seq_argument);
1N/A return "\\index{$index}\n";
1N/A
1N/A } else {
1N/A carp "Unknown sequence $seq_command<$seq_argument>";
1N/A }
1N/A
1N/A}
1N/A
1N/A=back
1N/A
1N/A=head2 List Methods
1N/A
1N/AMethods used to handle lists.
1N/A
1N/A=over 4
1N/A
1N/A=item B<begin_list>
1N/A
1N/ACalled when a new list is found (via the C<over> directive).
1N/ACreates a new C<Pod::List> object and stores it on the
1N/Alist stack.
1N/A
1N/A $parser->begin_list($indent, $line_num);
1N/A
1N/A=cut
1N/A
1N/Asub begin_list {
1N/A my $self = shift;
1N/A my $indent = shift;
1N/A my $line_num = shift;
1N/A
1N/A # Indicate that a list should be started for the next item
1N/A # need to do this to work out the type of list
1N/A push ( @{$self->lists}, new Pod::List(-indent => $indent,
1N/A -start => $line_num,
1N/A -file => $self->input_file,
1N/A )
1N/A );
1N/A
1N/A}
1N/A
1N/A=item B<end_list>
1N/A
1N/ACalled when the end of a list is found (the C<back> directive).
1N/APops the C<Pod::List> object off the stack of lists and writes
1N/Athe C<latex> code required to close a list.
1N/A
1N/A $parser->end_list($line_num);
1N/A
1N/A=cut
1N/A
1N/Asub end_list {
1N/A my $self = shift;
1N/A my $line_num = shift;
1N/A
1N/A unless (defined $self->lists->[-1]) {
1N/A my $file = $self->input_file;
1N/A warn "No list is active at line $line_num (file=$file). Missing =over?\n";
1N/A return;
1N/A }
1N/A
1N/A # What to write depends on list type
1N/A my $type = $self->lists->[-1]->type;
1N/A
1N/A # Dont write anything if the list type is not set
1N/A # iomplying that a list was created but no entries were
1N/A # placed in it (eg because of a =begin/=end combination)
1N/A $self->_output("\\end{$type}\n")
1N/A if (defined $type && length($type) > 0);
1N/A
1N/A # Clear list
1N/A pop(@{ $self->lists});
1N/A
1N/A}
1N/A
1N/A=item B<add_item>
1N/A
1N/AAdd items to the list. The first time an item is encountered
1N/A(determined from the state of the current C<Pod::List> object)
1N/Athe type of list is determined (ordered, unnumbered or description)
1N/Aand the relevant latex code issued.
1N/A
1N/A $parser->add_item($paragraph, $line_num);
1N/A
1N/A=cut
1N/A
1N/Asub add_item {
1N/A my $self = shift;
1N/A my $paragraph = shift;
1N/A my $line_num = shift;
1N/A
1N/A unless (defined $self->lists->[-1]) {
1N/A my $file = $self->input_file;
1N/A warn "List has already ended by line $line_num of file $file. Missing =over?\n";
1N/A # Replace special chars
1N/A# $paragraph = $self->_replace_special_chars($paragraph);
1N/A $self->_output("$paragraph\n\n");
1N/A return;
1N/A }
1N/A
1N/A # If paragraphs printing is turned off via =begin/=end or whatver
1N/A # simply return immediately
1N/A return if $self->{_suppress_all_para};
1N/A
1N/A # Check to see whether we are starting a new lists
1N/A if (scalar($self->lists->[-1]->item) == 0) {
1N/A
1N/A # Examine the paragraph to determine what type of list
1N/A # we have
1N/A $paragraph =~ s/\s+$//;
1N/A $paragraph =~ s/^\s+//;
1N/A
1N/A my $type;
1N/A if (substr($paragraph, 0,1) eq '*') {
1N/A $type = 'itemize';
1N/A } elsif ($paragraph =~ /^\d/) {
1N/A $type = 'enumerate';
1N/A } else {
1N/A $type = 'description';
1N/A }
1N/A $self->lists->[-1]->type($type);
1N/A
1N/A $self->_output("\\begin{$type}\n");
1N/A
1N/A }
1N/A
1N/A my $type = $self->lists->[-1]->type;
1N/A
1N/A if ($type eq 'description') {
1N/A # Handle long items - long items do not wrap
1N/A # If the string is longer than 40 characters we split
1N/A # it into a real item header and some bold text.
1N/A my $maxlen = 40;
1N/A my ($hunk1, $hunk2) = $self->_split_delimited( $paragraph, $maxlen );
1N/A
1N/A # Print the first hunk
1N/A $self->_output("\n\\item[$hunk1] ");
1N/A
1N/A # and the second hunk if it is defined
1N/A if ($hunk2) {
1N/A $self->_output("\\textbf{$hunk2}");
1N/A } else {
1N/A # Not there so make sure we have a new line
1N/A $self->_output("\\mbox{}");
1N/A }
1N/A
1N/A } else {
1N/A # If the item was '* Something' or '\d+ something' we still need to write
1N/A # out the something. Also allow 1) and 1.
1N/A my $extra_info = $paragraph;
1N/A $extra_info =~ s/^(\*|\d+[\.\)]?)\s*//;
1N/A $self->_output("\n\\item $extra_info");
1N/A }
1N/A
1N/A # Store the item name in the object. Required so that
1N/A # we can tell if the list is new or not
1N/A $self->lists->[-1]->item($paragraph);
1N/A
1N/A}
1N/A
1N/A=back
1N/A
1N/A=head2 Methods for headings
1N/A
1N/A=over 4
1N/A
1N/A=item B<head>
1N/A
1N/APrint a heading of the required level.
1N/A
1N/A $parser->head($level, $paragraph, $parobj);
1N/A
1N/AThe first argument is the pod heading level. The second argument
1N/Ais the contents of the heading. The 3rd argument is a Pod::Paragraph
1N/Aobject so that the line number can be extracted.
1N/A
1N/A=cut
1N/A
1N/Asub head {
1N/A my $self = shift;
1N/A my $num = shift;
1N/A my $paragraph = shift;
1N/A my $parobj = shift;
1N/A
1N/A # If we are replace 'head1 NAME' with a section
1N/A # we return immediately if we get it
1N/A return
1N/A if ($self->{_CURRENT_HEAD1} =~ /^NAME/i && $self->ReplaceNAMEwithSection());
1N/A
1N/A # Create a label
1N/A my $label = $self->_create_label($paragraph);
1N/A
1N/A # Create an index entry
1N/A my $index = $self->_create_index($paragraph);
1N/A
1N/A # Work out position in the above array taking into account
1N/A # that =head1 is equivalent to $self->Head1Level
1N/A
1N/A my $level = $self->Head1Level() - 1 + $num;
1N/A
1N/A # Warn if heading to large
1N/A if ($num > $#LatexSections) {
1N/A my $line = $parobj->file_line;
1N/A my $file = $self->input_file;
1N/A warn "Heading level too large ($level) for LaTeX at line $line of file $file\n";
1N/A $level = $#LatexSections;
1N/A }
1N/A
1N/A # Check to see whether section should be unnumbered
1N/A my $star = ($level >= $self->LevelNoNum ? '*' : '');
1N/A
1N/A # Section
1N/A $self->_output("\\" .$LatexSections[$level] .$star ."{$paragraph\\label{".$label ."}\\index{".$index."}}\n");
1N/A
1N/A}
1N/A
1N/A
1N/A=back
1N/A
1N/A=end __PRIVATE__
1N/A
1N/A=begin __PRIVATE__
1N/A
1N/A=head2 Internal methods
1N/A
1N/AInternal routines are described in this section. They do not form part of the
1N/Apublic interface. All private methods start with an underscore.
1N/A
1N/A=over 4
1N/A
1N/A=item B<_output>
1N/A
1N/AOutput text to the output filehandle. This method must be always be called
1N/Ato output parsed text.
1N/A
1N/A $parser->_output($text);
1N/A
1N/ADoes not write anything if a =begin is active that should be
1N/Aignored.
1N/A
1N/A=cut
1N/A
1N/Asub _output {
1N/A my $self = shift;
1N/A my $text = shift;
1N/A
1N/A print { $self->output_handle } $text
1N/A unless $self->{_suppress_all_para};
1N/A
1N/A}
1N/A
1N/A
1N/A=item B<_replace_special_chars>
1N/A
1N/ASubroutine to replace characters that are special in C<latex>
1N/Awith the escaped forms
1N/A
1N/A $escaped = $parser->_replace_special_chars($paragraph);
1N/A
1N/ANeed to call this routine before interior_sequences are munged but not
1N/Aif verbatim. It must be called before interpolation of interior
1N/Asequences so that curly brackets and special latex characters inserted
1N/Aduring interpolation are not themselves escaped. This means that < and
1N/A> can not be modified here since the text still contains interior
1N/Asequences.
1N/A
1N/ASpecial characters and the C<latex> equivalents are:
1N/A
1N/A } \}
1N/A { \{
1N/A _ \_
1N/A $ \$
1N/A % \%
1N/A & \&
1N/A \ $\backslash$
1N/A ^ \^{}
1N/A ~ \~{}
1N/A # \#
1N/A
1N/A=cut
1N/A
1N/Asub _replace_special_chars {
1N/A my $self = shift;
1N/A my $paragraph = shift;
1N/A
1N/A # Replace a \ with $\backslash$
1N/A # This is made more complicated because the dollars will be escaped
1N/A # by the subsequent replacement. Easiest to add \backslash
1N/A # now and then add the dollars
1N/A $paragraph =~ s/\\/\\backslash/g;
1N/A
1N/A # Must be done after escape of \ since this command adds latex escapes
1N/A # Replace characters that can be escaped
1N/A $paragraph =~ s/([\$\#&%_{}])/\\$1/g;
1N/A
1N/A # Replace ^ characters with \^{} so that $^F works okay
1N/A $paragraph =~ s/(\^)/\\$1\{\}/g;
1N/A
1N/A # Replace tilde (~) with \texttt{\~{}}
1N/A $paragraph =~ s/~/\\texttt\{\\~\{\}\}/g;
1N/A
1N/A # Now add the dollars around each \backslash
1N/A $paragraph =~ s/(\\backslash)/\$$1\$/g;
1N/A return $paragraph;
1N/A}
1N/A
1N/A=item B<_replace_special_chars_late>
1N/A
1N/AReplace special characters that can not be replaced before interior
1N/Asequence interpolation. See C<_replace_special_chars> for a routine
1N/Ato replace special characters prior to interpolation of interior
1N/Asequences.
1N/A
1N/ADoes the following transformation:
1N/A
1N/A < $<$
1N/A > $>$
1N/A | $|$
1N/A
1N/A
1N/A=cut
1N/A
1N/Asub _replace_special_chars_late {
1N/A my $self = shift;
1N/A my $paragraph = shift;
1N/A
1N/A # < and >
1N/A $paragraph =~ s/(<|>)/\$$1\$/g;
1N/A
1N/A # Replace | with $|$
1N/A $paragraph =~ s'\|'$|$'g;
1N/A
1N/A
1N/A return $paragraph;
1N/A}
1N/A
1N/A
1N/A=item B<_create_label>
1N/A
1N/AReturn a string that can be used as an internal reference
1N/Ain a C<latex> document (i.e. accepted by the C<\label> command)
1N/A
1N/A $label = $parser->_create_label($string)
1N/A
1N/AIf UniqueLabels is true returns a label prefixed by Label()
1N/AThis can be suppressed with an optional second argument.
1N/A
1N/A $label = $parser->_create_label($string, $suppress);
1N/A
1N/AIf a second argument is supplied (of any value including undef)
1N/Athe Label() is never prefixed. This means that this routine can
1N/Abe called to create a Label() without prefixing a previous setting.
1N/A
1N/A=cut
1N/A
1N/Asub _create_label {
1N/A my $self = shift;
1N/A my $paragraph = shift;
1N/A my $suppress = (@_ ? 1 : 0 );
1N/A
1N/A # Remove latex commands
1N/A $paragraph = $self->_clean_latex_commands($paragraph);
1N/A
1N/A # Remove non alphanumerics from the label and replace with underscores
1N/A # want to protect '-' though so use negated character classes
1N/A $paragraph =~ s/[^-:\w]/_/g;
1N/A
1N/A # Multiple underscores will look unsightly so remove repeats
1N/A # This will also have the advantage of tidying up the end and
1N/A # start of string
1N/A $paragraph =~ s/_+/_/g;
1N/A
1N/A # If required need to make sure that the label is unique
1N/A # since it is possible to have multiple pods in a single
1N/A # document
1N/A if (!$suppress && $self->UniqueLabels() && defined $self->Label) {
1N/A $paragraph = $self->Label() .'_'. $paragraph;
1N/A }
1N/A
1N/A return $paragraph;
1N/A}
1N/A
1N/A
1N/A=item B<_create_index>
1N/A
1N/ASimilar to C<_create_label> except an index entry is created.
1N/AIf C<UniqueLabels> is true, the index entry is prefixed by
1N/Athe current C<Label> and an exclamation mark.
1N/A
1N/A $ind = $parser->_create_index($paragraph);
1N/A
1N/AAn exclamation mark is used by C<makeindex> to generate
1N/Asub-entries in an index.
1N/A
1N/A=cut
1N/A
1N/Asub _create_index {
1N/A my $self = shift;
1N/A my $paragraph = shift;
1N/A my $suppress = (@_ ? 1 : 0 );
1N/A
1N/A # Remove latex commands
1N/A $paragraph = $self->_clean_latex_commands($paragraph);
1N/A
1N/A # If required need to make sure that the index entry is unique
1N/A # since it is possible to have multiple pods in a single
1N/A # document
1N/A if (!$suppress && $self->UniqueLabels() && defined $self->Label) {
1N/A $paragraph = $self->Label() .'!'. $paragraph;
1N/A }
1N/A
1N/A # Need to replace _ with space
1N/A $paragraph =~ s/_/ /g;
1N/A
1N/A return $paragraph;
1N/A
1N/A}
1N/A
1N/A=item B<_clean_latex_commands>
1N/A
1N/ARemoves latex commands from text. The latex command is assumed to be of the
1N/Aform C<\command{ text }>. "C<text>" is retained
1N/A
1N/A $clean = $parser->_clean_latex_commands($text);
1N/A
1N/A=cut
1N/A
1N/Asub _clean_latex_commands {
1N/A my $self = shift;
1N/A my $paragraph = shift;
1N/A
1N/A # Remove latex commands of the form \text{ }
1N/A # and replace with the contents of the { }
1N/A # need to make this non-greedy so that it can handle
1N/A # "\text{a} and \text2{b}"
1N/A # without converting it to
1N/A # "a} and \text2{b"
1N/A # This match will still get into trouble if \} is present
1N/A # This is not vital since the subsequent replacement of non-alphanumeric
1N/A # characters will tidy it up anyway
1N/A $paragraph =~ s/\\\w+{(.*?)}/$1/g;
1N/A
1N/A return $paragraph
1N/A}
1N/A
1N/A=item B<_split_delimited>
1N/A
1N/ASplit the supplied string into two parts at approximately the
1N/Aspecified word boundary. Special care is made to make sure that it
1N/Adoes not split in the middle of some curly brackets.
1N/A
1N/Ae.g. "this text is \textbf{very bold}" would not be split into
1N/A"this text is \textbf{very" and " bold".
1N/A
1N/A ($hunk1, $hunk2) = $self->_split_delimited( $para, $length);
1N/A
1N/AThe length indicates the maximum length of hunk1.
1N/A
1N/A=cut
1N/A
1N/A# initially Supplied by hsmyers@sdragons.com
1N/A# 10/25/01, utility to split \hbox
1N/A# busting lines. Reformatted by TimJ to match module style.
1N/Asub _split_delimited {
1N/A my $self = shift;
1N/A my $input = shift;
1N/A my $limit = shift;
1N/A
1N/A # Return immediately if already small
1N/A return ($input, '') if length($input) < $limit;
1N/A
1N/A my @output;
1N/A my $s = '';
1N/A my $t = '';
1N/A my $depth = 0;
1N/A my $token;
1N/A
1N/A $input =~ s/\n/ /gm;
1N/A $input .= ' ';
1N/A foreach ( split ( //, $input ) ) {
1N/A $token .= $_;
1N/A if (/\{/) {
1N/A $depth++;
1N/A } elsif ( /}/ ) {
1N/A $depth--;
1N/A } elsif ( / / and $depth == 0) {
1N/A push @output, $token if ( $token and $token ne ' ' );
1N/A $token = '';
1N/A }
1N/A }
1N/A
1N/A foreach (@output) {
1N/A if (length($s) < $limit) {
1N/A $s .= $_;
1N/A } else {
1N/A $t .= $_;
1N/A }
1N/A }
1N/A
1N/A # Tidy up
1N/A $s =~ s/\s+$//;
1N/A $t =~ s/\s+$//;
1N/A return ($s,$t);
1N/A}
1N/A
1N/A=back
1N/A
1N/A=end __PRIVATE__
1N/A
1N/A=head1 NOTES
1N/A
1N/ACompatible with C<latex2e> only. Can not be used with C<latex> v2.09
1N/Aor earlier.
1N/A
1N/AA subclass of C<Pod::Select> so that specific pod sections can be
1N/Aconverted to C<latex> by using the C<select> method.
1N/A
1N/ASome HTML escapes are missing and many have not been tested.
1N/A
1N/A=head1 SEE ALSO
1N/A
1N/AL<Pod::Parser>, L<Pod::Select>, L<pod2latex>
1N/A
1N/A=head1 AUTHORS
1N/A
1N/ATim Jenness E<lt>t.jenness@jach.hawaii.eduE<gt>
1N/A
1N/ABug fixes and improvements have been received from: Simon Cozens
1N/AE<lt>simon@cozens.netE<gt>, Mark A. Hershberger
1N/AE<lt>mah@everybody.orgE<gt>, Marcel Grunauer
1N/AE<lt>marcel@codewerk.comE<gt>, Hugh S Myers
1N/AE<lt>hsmyers@sdragons.comE<gt>, Peter J Acklam
1N/AE<lt>jacklam@math.uio.noE<gt>, Sudhi Herle E<lt>sudhi@herle.netE<gt>
1N/Aand Ariel Scolnicov E<lt>ariels@compugen.co.ilE<gt>.
1N/A
1N/A
1N/A=head1 COPYRIGHT
1N/A
1N/ACopyright (C) 2000-2003 Tim Jenness. All Rights Reserved.
1N/A
1N/AThis program is free software; you can redistribute it and/or modify
1N/Ait under the same terms as Perl itself.
1N/A
1N/A=begin __PRIVATE__
1N/A
1N/A=head1 REVISION
1N/A
1N/A$Id: LaTeX.pm,v 1.17 2003/04/05 21:25:49 timj Exp $
1N/A
1N/A=end __PRIVATE__
1N/A
1N/A=cut
1N/A
1N/A1;