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