This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Retract #12284.
[perl5.git] / lib / Pod / LaTeX.pm
1 package Pod::LaTeX;
2
3 # Copyright (C) 2000 by Tim Jenness <t.jenness@jach.hawaii.edu>
4 # All Rights Reserved.
5
6 =head1 NAME
7
8 Pod::LaTeX - Convert Pod data to formatted Latex
9
10 =head1 SYNOPSIS
11
12   use Pod::LaTeX;
13   my $parser = Pod::LaTeX->new ( );
14
15   $parser->parse_from_filehandle;
16
17   $parser->parse_from_file ('file.pod', 'file.tex');
18
19 =head1 DESCRIPTION
20
21 C<Pod::LaTeX> is a module to convert documentation in the Pod format
22 into Latex. The L<B<pod2latex>|pod2latex> X<pod2latex> command uses
23 this module for translation.
24
25 C<Pod::LaTeX> is a derived class from L<Pod::Select|Pod::Select>.
26
27 =cut
28
29
30 use strict;
31 require Pod::ParseUtils;
32 use base qw/ Pod::Select /;
33
34 # use Data::Dumper; # for debugging
35 use Carp;
36
37 use vars qw/ $VERSION %HTML_Escapes @LatexSections /;
38
39 $VERSION = '0.53';
40
41 # Definitions of =headN -> latex mapping
42 @LatexSections = (qw/
43                   chapter
44                   section
45                   subsection
46                   subsubsection
47                   paragraph
48                   subparagraph
49                   /);
50
51 # Standard escape sequences converted to Latex
52 # Up to "yuml" these are taken from the original pod2latex
53 # command written by Taro Kawagish (kawagish@imslab.co.jp)
54
55 %HTML_Escapes = (
56     'amp'       =>      '&',      #   ampersand
57     'lt'        =>      '$<$',    #   ' left chevron, less-than
58     'gt'        =>      '$>$',    #   ' right chevron, greater-than
59     'quot'      =>      '"',      #   double quote
60     'sol'       =>      '/',
61     'verbar'    =>      '$|$',
62
63     "Aacute"    =>      "\\'{A}",       #   capital A, acute accent
64     "aacute"    =>      "\\'{a}",       #   small a, acute accent
65     "Acirc"     =>      "\\^{A}",       #   capital A, circumflex accent
66     "acirc"     =>      "\\^{a}",       #   small a, circumflex accent
67     "AElig"     =>      '\\AE',         #   capital AE diphthong (ligature)
68     "aelig"     =>      '\\ae',         #   small ae diphthong (ligature)
69     "Agrave"    =>      "\\`{A}",       #   capital A, grave accent
70     "agrave"    =>      "\\`{a}",       #   small a, grave accent
71     "Aring"     =>      '\\u{A}',       #   capital A, ring
72     "aring"     =>      '\\u{a}',       #   small a, ring
73     "Atilde"    =>      '\\~{A}',       #   capital A, tilde
74     "atilde"    =>      '\\~{a}',       #   small a, tilde
75     "Auml"      =>      '\\"{A}',       #   capital A, dieresis or umlaut mark
76     "auml"      =>      '\\"{a}',       #   small a, dieresis or umlaut mark
77     "Ccedil"    =>      '\\c{C}',       #   capital C, cedilla
78     "ccedil"    =>      '\\c{c}',       #   small c, cedilla
79     "Eacute"    =>      "\\'{E}",       #   capital E, acute accent
80     "eacute"    =>      "\\'{e}",       #   small e, acute accent
81     "Ecirc"     =>      "\\^{E}",       #   capital E, circumflex accent
82     "ecirc"     =>      "\\^{e}",       #   small e, circumflex accent
83     "Egrave"    =>      "\\`{E}",       #   capital E, grave accent
84     "egrave"    =>      "\\`{e}",       #   small e, grave accent
85     "ETH"       =>      '\\OE',         #   capital Eth, Icelandic
86     "eth"       =>      '\\oe',         #   small eth, Icelandic
87     "Euml"      =>      '\\"{E}',       #   capital E, dieresis or umlaut mark
88     "euml"      =>      '\\"{e}',       #   small e, dieresis or umlaut mark
89     "Iacute"    =>      "\\'{I}",       #   capital I, acute accent
90     "iacute"    =>      "\\'{i}",       #   small i, acute accent
91     "Icirc"     =>      "\\^{I}",       #   capital I, circumflex accent
92     "icirc"     =>      "\\^{i}",       #   small i, circumflex accent
93     "Igrave"    =>      "\\`{I}",       #   capital I, grave accent
94     "igrave"    =>      "\\`{i}",       #   small i, grave accent
95     "Iuml"      =>      '\\"{I}',       #   capital I, dieresis or umlaut mark
96     "iuml"      =>      '\\"{i}',       #   small i, dieresis or umlaut mark
97     "Ntilde"    =>      '\\~{N}',       #   capital N, tilde
98     "ntilde"    =>      '\\~{n}',       #   small n, tilde
99     "Oacute"    =>      "\\'{O}",       #   capital O, acute accent
100     "oacute"    =>      "\\'{o}",       #   small o, acute accent
101     "Ocirc"     =>      "\\^{O}",       #   capital O, circumflex accent
102     "ocirc"     =>      "\\^{o}",       #   small o, circumflex accent
103     "Ograve"    =>      "\\`{O}",       #   capital O, grave accent
104     "ograve"    =>      "\\`{o}",       #   small o, grave accent
105     "Oslash"    =>      "\\O",          #   capital O, slash
106     "oslash"    =>      "\\o",          #   small o, slash
107     "Otilde"    =>      "\\~{O}",       #   capital O, tilde
108     "otilde"    =>      "\\~{o}",       #   small o, tilde
109     "Ouml"      =>      '\\"{O}',       #   capital O, dieresis or umlaut mark
110     "ouml"      =>      '\\"{o}',       #   small o, dieresis or umlaut mark
111     "szlig"     =>      '\\ss{}',       #   small sharp s, German (sz ligature)
112     "THORN"     =>      '\\L',          #   capital THORN, Icelandic
113     "thorn"     =>      '\\l',,         #   small thorn, Icelandic
114     "Uacute"    =>      "\\'{U}",       #   capital U, acute accent
115     "uacute"    =>      "\\'{u}",       #   small u, acute accent
116     "Ucirc"     =>      "\\^{U}",       #   capital U, circumflex accent
117     "ucirc"     =>      "\\^{u}",       #   small u, circumflex accent
118     "Ugrave"    =>      "\\`{U}",       #   capital U, grave accent
119     "ugrave"    =>      "\\`{u}",       #   small u, grave accent
120     "Uuml"      =>      '\\"{U}',       #   capital U, dieresis or umlaut mark
121     "uuml"      =>      '\\"{u}',       #   small u, dieresis or umlaut mark
122     "Yacute"    =>      "\\'{Y}",       #   capital Y, acute accent
123     "yacute"    =>      "\\'{y}",       #   small y, acute accent
124     "yuml"      =>      '\\"{y}',       #   small y, dieresis or umlaut mark
125
126     # Added by TimJ
127
128     "iexcl"  =>   '!`',           # inverted exclamation mark
129 #    "cent"   =>   ' ',        # cent sign
130     "pound"  =>   '\pounds',      # (UK) pound sign
131 #    "curren" =>   ' ',        # currency sign
132 #    "yen"    =>   ' ',        # yen sign
133 #    "brvbar" =>   ' ',        # broken vertical bar
134     "sect"   =>   '\S',           # section sign
135     "uml"    =>   '\"{}',        # diaresis
136     "copy"   =>   '\copyright',   # Copyright symbol
137 #    "ordf"   =>   ' ',        # feminine ordinal indicator
138     "laquo"  =>   '$\ll$',      # ' # left pointing double angle quotation mark
139     "not"    =>   '$\neg$',       # '  # not sign
140     "shy"    =>   '-',            # soft hyphen
141 #    "reg"    =>   ' ',        # registered trademark
142     "macr"   =>   '$^-$',         # ' # macron, overline
143     "deg"    =>   '$^\circ$',     # '  # degree sign
144     "plusmn" =>   '$\pm$',        # ' # plus-minus sign
145     "sup2"   =>   '$^2$',         # ' # superscript 2
146     "sup3"   =>   '$^3$',         # ' # superscript 3
147     "acute"  =>   "\\'{}",        # acute accent
148     "micro"  =>   '$\mu$',        # micro sign
149     "para"   =>   '\P',           # pilcrow sign = paragraph sign
150     "middot" =>   '$\cdot$',      # middle dot = Georgian comma
151     "cedil"  =>   '\c{}',        # cedilla
152     "sup1"   =>   '$^1$',         # ' # superscript 1
153 #    "ordm"   =>   ' ',        # masculine ordinal indicator
154     "raquo"  =>   '$\gg$',     # ' # right pointing double angle quotation mark
155     "frac14" =>   '$\frac{1}{4}$',   # ' # vulgar fraction one quarter
156     "frac12" =>   '$\frac{1}{2}$',   # ' # vulgar fraction one half
157     "frac34" =>   '$\frac{3}{4}$',   # ' # vulgar fraction three quarters
158     "iquest" =>   "?'",              # inverted question mark
159     "times"  =>   '$\times$',        # ' # multiplication sign
160     "divide" =>   '$\div$',          # division sign
161
162     # Greek letters using HTML codes
163     "alpha"  =>   '$\alpha$',   # '
164     "beta"   =>   '$\beta$',    # '
165     "gamma"  =>   '$\gamma$',   # '
166     "delta"  =>   '$\delta$',   # '
167     "epsilon"=>   '$\epsilon$', # '
168     "zeta"   =>   '$\zeta$',    # '
169     "eta"    =>   '$\eta$',     # '
170     "theta"  =>   '$\theta$',   # '
171     "iota"   =>   '$\iota$',    # '
172     "kappa"  =>   '$\kappa$',   # '
173     "lambda" =>   '$\lambda$',  # '
174     "mu"     =>   '$\mu$',      # '
175     "nu"     =>   '$\nu$',      # '
176     "xi"     =>   '$\xi$',      # '
177     "omicron"=>   '$o$',        # '
178     "pi"     =>   '$\pi$',      # '
179     "rho"    =>   '$\rho$',     # '
180     "sigma"  =>   '$\sigma$',   # '
181     "tau"    =>   '$\tau$',     # '
182     "upsilon"=>   '$\upsilon$', # '
183     "phi"    =>   '$\phi$',     # '
184     "chi"    =>   '$\chi$',     # '
185     "psi"    =>   '$\psi$',     # '
186     "omega"  =>   '$\omega$',   # '
187
188     "Alpha"  =>   '$A$',   # '
189     "Beta"   =>   '$B$',    # '
190     "Gamma"  =>   '$\Gamma$',   # '
191     "Delta"  =>   '$\Delta$',   # '
192     "Epsilon"=>   '$E$', # '
193     "Zeta"   =>   '$Z$',    # '
194     "Eta"    =>   '$H$',     # '
195     "Theta"  =>   '$\Theta$',   # '
196     "Iota"   =>   '$I$',    # '
197     "Kappa"  =>   '$K$',   # '
198     "Lambda" =>   '$\Lambda$',  # '
199     "Mu"     =>   '$M$',      # '
200     "Nu"     =>   '$N$',      # '
201     "Xi"     =>   '$\Xi$',      # '
202     "Omicron"=>   '$O$',        # '
203     "Pi"     =>   '$\Pi$',      # '
204     "Rho"    =>   '$R$',     # '
205     "Sigma"  =>   '$\Sigma$',   # '
206     "Tau"    =>   '$T$',     # '
207     "Upsilon"=>   '$\Upsilon$', # '
208     "Phi"    =>   '$\Phi$',     # '
209     "Chi"    =>   '$X$',     # '
210     "Psi"    =>   '$\Psi$',     # '
211     "Omega"  =>   '$\Omega$',   # '
212
213
214 );
215
216
217 =head1 OBJECT METHODS
218
219 The following methods are provided in this module. Methods inherited
220 from C<Pod::Select> are not described in the public interface.
221
222 =over 4
223
224 =begin __PRIVATE__
225
226 =item C<initialize>
227
228 Initialise the object. This method is subclassed from C<Pod::Parser>.
229 The base class method is invoked. This method defines the default
230 behaviour of the object unless overridden by supplying arguments to
231 the constructor. 
232
233 Internal settings are defaulted as well as the public instance data.
234 Internal hash values are accessed directly (rather than through
235 a method) and start with an underscore.
236
237 This method should not be invoked by the user directly.
238
239 =end __PRIVATE__
240
241 =cut
242
243
244
245 #   - An array for nested lists
246
247 # Arguments have already been read by this point
248
249 sub initialize {
250   my $self = shift;
251
252   # print Dumper($self);
253
254   # Internals
255   $self->{_Lists} = [];             # For nested lists
256   $self->{_suppress_all_para}  = 0; # For =begin blocks
257   $self->{_suppress_next_para} = 0; # For =for blocks
258   $self->{_dont_modify_any_para}=0; # For =begin blocks
259   $self->{_dont_modify_next_para}=0; # For =for blocks
260   $self->{_CURRENT_HEAD1}   = '';   # Name of current HEAD1 section
261
262   # Options - only initialise if not already set
263
264   # Cause the '=head1 NAME' field to be treated specially
265   # The contents of the NAME paragraph will be converted
266   # to a section title. All subsequent =head1 will be converted
267   # to =head2 and down. Will not affect =head1's prior to NAME 
268   # Assumes:  'Module - purpose' format
269   # Also creates a purpose field
270   # The name is used for Labeling of the subsequent subsections
271   $self->{ReplaceNAMEwithSection} = 0
272     unless exists $self->{ReplaceNAMEwithSection};
273   $self->{AddPreamble}      = 1    # make full latex document
274     unless exists $self->{AddPreamble};
275   $self->{StartWithNewPage} = 0    # Start new page for pod section
276     unless exists $self->{StartWithNewPage};
277   $self->{TableOfContents}  = 0    # Add table of contents
278     unless exists $self->{TableOfContents};  # only relevent if AddPreamble=1
279    $self->{AddPostamble}     = 1          # Add closing latex code at end
280     unless exists $self->{AddPostamble}; #  effectively end{document} and index
281   $self->{MakeIndex}        = 1         # Add index (only relevant AddPostamble
282     unless exists $self->{MakeIndex};   # and AddPreamble)
283
284   $self->{UniqueLabels}     = 1          # Use label unique for each pod
285     unless exists $self->{UniqueLabels}; # either based on the filename
286                                          # or supplied
287
288   # Control the level of =head1. default is \section
289   # 
290   $self->{Head1Level}     = 1   # Offset in latex sections
291     unless exists $self->{Head1Level}; # 0 is chapter, 2 is subsection
292
293   # Control at which level numbering of sections is turned off
294   # ie subsection becomes subsection*
295   # The numbering is relative to the latex sectioning commands
296   # and is independent of Pod heading level
297   # default is to number \section but not \subsection
298   $self->{LevelNoNum} = 2
299     unless exists $self->{LevelNoNum};
300
301   # Label to be used as prefix to all internal section names
302   # If not defined will attempt to derive it from the filename
303   # This can not happen when running parse_from_filehandle though
304   # hence the ability to set the label externally
305   # The label could then be Pod::Parser_DESCRIPTION or somesuch
306
307   $self->{Label}            = undef # label to be used as prefix
308     unless exists $self->{Label};   # to all internal section names
309
310   # These allow the caller to add arbritrary latex code to
311   # start and end of document. AddPreamble and AddPostamble are ignored
312   # if these are set.
313   # Also MakeIndex and TableOfContents are also ignored.
314   $self->{UserPreamble}     = undef # User supplied start (AddPreamble =1)
315     unless exists $self->{Label};
316   $self->{UserPostamble}    = undef # Use supplied end    (AddPostamble=1)
317     unless exists $self->{Label};
318
319   # Run base initialize
320   $self->SUPER::initialize;
321
322 }
323
324 =back
325
326 =head2 Data Accessors
327
328 The following methods are provided for accessing instance data. These
329 methods should be used for accessing configuration parameters rather
330 than assuming the object is a hash.
331
332 Default values can be supplied by using these names as keys to a hash
333 of arguments when using the C<new()> constructor.
334
335 =over 4
336
337 =item B<AddPreamble>
338
339 Logical to control whether a C<latex> preamble is to be written.
340 If true, a valid C<latex> preamble is written before the pod data is written.
341 This is similar to:
342
343   \documentclass{article}
344   \begin{document}
345
346 but will be more complicated if table of contents and indexing are required.
347 Can be used to set or retrieve the current value.
348
349   $add = $parser->AddPreamble();
350   $parser->AddPreamble(1);
351
352 If used in conjunction with C<AddPostamble> a full latex document will
353 be written that could be immediately processed by C<latex>.
354
355 =cut
356
357 sub AddPreamble {
358    my $self = shift;
359    if (@_) {
360      $self->{AddPreamble} = shift;
361    }
362    return $self->{AddPreamble};
363 }
364
365 =item B<AddPostamble>
366
367 Logical to control whether a standard C<latex> ending is written to the output
368 file after the document has been processed.
369 In its simplest form this is simply:
370
371   \end{document}
372
373 but can be more complicated if a index is required.
374 Can be used to set or retrieve the current value.
375
376   $add = $parser->AddPostamble();
377   $parser->AddPostamble(1);
378
379 If used in conjunction with C<AddPreaamble> a full latex document will
380 be written that could be immediately processed by C<latex>.
381
382 =cut
383
384 sub AddPostamble {
385    my $self = shift;
386    if (@_) {
387      $self->{AddPostamble} = shift;
388    }
389    return $self->{AddPostamble};
390 }
391
392 =item B<Head1Level>
393
394 The C<latex> sectioning level that should be used to correspond to
395 a pod C<=head1> directive. This can be used, for example, to turn
396 a C<=head1> into a C<latex> C<subsection>. This should hold a number
397 corresponding to the required position in an array containing the
398 following elements:
399
400  [0] chapter
401  [1] section
402  [2] subsection
403  [3] subsubsection
404  [4] paragraph
405  [5] subparagraph
406
407 Can be used to set or retrieve the current value:
408
409   $parser->Head1Level(2);
410   $sect = $parser->Head1Level;
411
412 Setting this number too high can result in sections that may not be reproducible
413 in the expected way. For example, setting this to 4 would imply that C<=head3>
414 do not have a corresponding C<latex> section (C<=head1> would correspond to
415 a C<paragraph>).
416
417 A check is made to ensure that the supplied value is an integer in the
418 range 0 to 5.
419
420 Default is for a value of 1 (i.e. a C<section>).
421
422 =cut
423
424 sub Head1Level {
425    my $self = shift;
426    if (@_) {
427      my $arg = shift;
428      if ($arg =~ /^\d$/ && $arg <= $#LatexSections) {
429        $self->{Head1Level} = $arg;
430      } else {
431        carp "Head1Level supplied ($arg) must be integer in range 0 to ".$#LatexSections . "- Ignoring\n";
432      }
433    }
434    return $self->{Head1Level};
435 }
436
437 =item B<Label>
438
439 This is the label that is prefixed to all C<latex> label and index
440 entries to make them unique. In general, pods have similarly titled
441 sections (NAME, DESCRIPTION etc) and a C<latex> label will be multiply
442 defined if more than one pod document is to be included in a single
443 C<latex> file. To overcome this, this label is prefixed to a label
444 whenever a label is required (joined with an underscore) or to an
445 index entry (joined by an exclamation mark which is the normal index
446 separator). For example, C<\label{text}> becomes C<\label{Label_text}>.
447
448 Can be used to set or retrieve the current value:
449
450   $label = $parser->Label;
451   $parser->Label($label);
452
453 This label is only used if C<UniqueLabels> is true.
454 Its value is set automatically from the C<NAME> field
455 if C<ReplaceNAMEwithSection> is true. If this is not the case
456 it must be set manually before starting the parse.
457
458 Default value is C<undef>.
459
460 =cut
461
462 sub Label {
463    my $self = shift;
464    if (@_) {
465      $self->{Label} = shift;
466    }
467    return $self->{Label};
468 }
469
470 =item B<LevelNoNum>
471
472 Control the point at which C<latex> section numbering is turned off.
473 For example, this can be used to make sure that C<latex> sections
474 are numbered but subsections are not.
475
476 Can be used to set or retrieve the current value:
477
478   $lev = $parser->LevelNoNum;
479   $parser->LevelNoNum(2);
480
481 The argument must be an integer between 0 and 5 and is the same as the
482 number described in C<Head1Level> method description. The number has
483 nothing to do with the pod heading number, only the C<latex> sectioning.
484
485 Default is 2. (i.e. C<latex> subsections are written as C<subsection*>
486 but sections are numbered).
487
488 =cut
489
490 sub LevelNoNum {
491    my $self = shift;
492    if (@_) {
493      $self->{LevelNoNum} = shift;
494    }
495    return $self->{LevelNoNum};
496 }
497
498 =item B<MakeIndex>
499
500 Controls whether C<latex> commands for creating an index are to be inserted
501 into the preamble and postamble
502
503   $makeindex = $parser->MakeIndex;
504   $parser->MakeIndex(0);
505
506 Irrelevant if both C<AddPreamble> and C<AddPostamble> are false (or equivalently,
507 C<UserPreamble> and C<UserPostamble> are set).
508
509 Default is for an index to be created.
510
511 =cut
512
513 sub MakeIndex {
514    my $self = shift;
515    if (@_) {
516      $self->{MakeIndex} = shift;
517    }
518    return $self->{MakeIndex};
519 }
520
521 =item B<ReplaceNAMEwithSection>
522
523 This controls whether the C<NAME> section in the pod is to be translated
524 literally or converted to a slightly modified output where the section
525 name is the pod name rather than "NAME".
526
527 If true, the pod segment
528
529   =head1 NAME
530
531   pod::name - purpose
532
533   =head1 SYNOPSIS
534
535 is converted to the C<latex>
536
537   \section{pod::name\label{pod_name}\index{pod::name}}
538
539   Purpose
540
541   \subsection*{SYNOPSIS\label{pod_name_SYNOPSIS}%
542                \index{pod::name!SYNOPSIS}}
543
544 (dependent on the value of C<Head1Level> and C<LevelNoNum>). Note that
545 subsequent C<head1> directives translate to subsections rather than
546 sections and that the labels and index now include the pod name (dependent
547 on the value of C<UniqueLabels>).
548
549 The C<Label> is set from the pod name regardless of any current value
550 of C<Label>.
551
552   $mod = $parser->ReplaceNAMEwithSection;
553   $parser->ReplaceNAMEwithSection(0);
554
555 Default is to translate the pod literally.
556
557 =cut
558
559 sub ReplaceNAMEwithSection {
560    my $self = shift;
561    if (@_) {
562      $self->{ReplaceNAMEwithSection} = shift;
563    }
564    return $self->{ReplaceNAMEwithSection};
565 }
566
567 =item B<StartWithNewPage>
568
569 If true, each pod translation will begin with a C<latex>
570 C<\clearpage>.
571
572   $parser->StartWithNewPage(1);
573   $newpage = $parser->StartWithNewPage;
574
575 Default is false.
576
577 =cut
578
579 sub StartWithNewPage {
580    my $self = shift;
581    if (@_) {
582      $self->{StartWithNewPage} = shift;
583    }
584    return $self->{StartWithNewPage};
585 }
586
587 =item B<TableOfContents>
588
589 If true, a table of contents will be created.
590 Irrelevant if C<AddPreamble> is false or C<UserPreamble>
591 is set.
592
593   $toc = $parser->TableOfContents;
594   $parser->TableOfContents(1);
595
596 Default is false.
597
598 =cut
599
600 sub TableOfContents {
601    my $self = shift;
602    if (@_) {
603      $self->{TableOfContents} = shift;
604    }
605    return $self->{TableOfContents};
606 }
607
608 =item B<UniqueLabels>
609
610 If true, the translator will attempt to make sure that
611 each C<latex> label or index entry will be uniquely identified
612 by prefixing the contents of C<Label>. This allows
613 multiple documents to be combined without clashing 
614 common labels such as C<DESCRIPTION> and C<SYNOPSIS>
615
616   $parser->UniqueLabels(1);
617   $unq = $parser->UniqueLabels;
618
619 Default is true.
620
621 =cut
622
623 sub UniqueLabels {
624    my $self = shift;
625    if (@_) {
626      $self->{UniqueLabels} = shift;
627    }
628    return $self->{UniqueLabels};
629 }
630
631 =item B<UserPreamble>
632
633 User supplied C<latex> preamble. Added before the pod translation
634 data. 
635
636 If set, the contents will be prepended to the output file before the translated 
637 data regardless of the value of C<AddPreamble>.
638 C<MakeIndex> and C<TableOfContents> will also be ignored.
639
640 =cut
641
642 sub UserPreamble {
643    my $self = shift;
644    if (@_) {
645      $self->{UserPreamble} = shift;
646    }
647    return $self->{UserPreamble};
648 }
649
650 =item B<UserPostamble>
651
652 User supplied C<latex> postamble. Added after the pod translation
653 data. 
654
655 If set, the contents will be prepended to the output file after the translated 
656 data regardless of the value of C<AddPostamble>.
657 C<MakeIndex> will also be ignored.
658
659 =cut
660
661 sub UserPostamble {
662    my $self = shift;
663    if (@_) {
664      $self->{UserPostamble} = shift;
665    }
666    return $self->{UserPostamble};
667 }
668
669 =begin __PRIVATE__
670
671 =item B<Lists>
672
673 Contains details of the currently active lists.
674   The array contains C<Pod::List> objects. A new C<Pod::List>
675 object is created each time a list is encountered and it is
676 pushed onto this stack. When the list context ends, it 
677 is popped from the stack. The array will be empty if no
678 lists are active.
679
680 Returns array of list information in list context
681 Returns array ref in scalar context
682
683 =cut
684
685
686
687 sub lists {
688   my $self = shift;
689   return @{ $self->{_Lists} } if wantarray();
690   return $self->{_Lists};
691 }
692
693 =end __PRIVATE__
694
695 =back
696
697 =begin __PRIVATE__
698
699 =head2 Subclassed methods
700
701 The following methods override methods provided in the C<Pod::Select>
702 base class. See C<Pod::Parser> and C<Pod::Select> for more information
703 on what these methods require.
704
705 =over 4
706
707 =cut
708
709 ######### END ACCESSORS ###################
710
711 # Opening pod
712
713 =item B<begin_pod>
714
715 Writes the C<latex> preamble if requested.
716
717 =cut
718
719 sub begin_pod {
720   my $self = shift;
721
722   # Get the pod identification
723   # This should really come from the '=head1 NAME' paragraph
724
725   my $infile = $self->input_file;
726   my $class = ref($self);
727   my $date = gmtime(time);
728
729   # Comment message to say where this came from
730   my $comment = << "__TEX_COMMENT__";
731 %%  Latex generated from POD in document $infile
732 %%  Using the perl module $class
733 %%  Converted on $date
734 __TEX_COMMENT__
735
736   # Write the preamble
737   # If the caller has supplied one then we just use that
738
739   my $preamble = '';
740   if (defined $self->UserPreamble) {
741
742     $preamble = $self->UserPreamble;
743
744     # Add the description of where this came from
745     $preamble .=  "\n$comment";
746     
747
748   } elsif ($self->AddPreamble) {
749     # Write our own preamble
750
751     # Code to initialise index making
752     # Use an array so that we can prepend comment if required
753     my @makeidx = (
754                    '\usepackage{makeidx}',
755                    '\makeindex',
756                   );
757
758     unless ($self->MakeIndex) {
759       foreach (@makeidx) {
760         $_ = '%% ' . $_;
761       }
762     }
763     my $makeindex = join("\n",@makeidx) . "\n";
764
765
766     # Table of contents
767     my $tableofcontents = '\tableofcontents';
768     
769     $tableofcontents = '%% ' . $tableofcontents
770       unless $self->TableOfContents;
771
772     # Roll our own
773     $preamble = << "__TEX_HEADER__";
774 \\documentclass{article}
775
776 $comment
777
778 $makeindex
779
780 \\begin{document}
781
782 $tableofcontents
783
784 __TEX_HEADER__
785
786   }
787
788   # Write the header (blank if none)
789   $self->_output($preamble);
790
791   # Start on new page if requested
792   $self->_output("\\clearpage\n") if $self->StartWithNewPage;
793
794 }
795
796
797 =item B<end_pod>
798
799 Write the closing C<latex> code.
800
801 =cut
802
803 sub end_pod {
804   my $self = shift;
805
806   # End string
807   my $end = '';
808
809   # Use the user version of the postamble if deinfed
810   if (defined $self->UserPostamble) {
811     $end = $self->UserPostamble;
812
813     $self->_output($end);
814
815   } elsif ($self->AddPostamble) {
816
817     # Check for index
818     my $makeindex = '\printindex';
819
820     $makeindex = '%% '. $makeindex  unless $self->MakeIndex;
821
822     $end = "$makeindex\n\n\\end{document}\n";
823   }
824
825
826   $self->_output($end);
827
828 }
829
830 =item B<command>
831
832 Process basic pod commands.
833
834 =cut
835
836 sub command {
837   my $self = shift;
838   my ($command, $paragraph, $line_num, $parobj) = @_;
839
840   # return if we dont care
841   return if $command eq 'pod';
842
843   $paragraph = $self->_replace_special_chars($paragraph);
844
845   # Interpolate pod sequences in paragraph
846   $paragraph = $self->interpolate($paragraph, $line_num);
847
848   $paragraph =~ s/\s+$//;
849
850   # Now run the command
851   if ($command eq 'over') {
852
853     $self->begin_list($paragraph, $line_num);
854
855   } elsif ($command eq 'item') {
856
857     $self->add_item($paragraph, $line_num);
858
859   } elsif ($command eq 'back') {
860
861     $self->end_list($line_num);
862
863   } elsif ($command eq 'head1') {
864
865     # Store the name of the section
866     $self->{_CURRENT_HEAD1} = $paragraph;
867
868     # Print it
869     $self->head(1, $paragraph, $parobj);
870
871   } elsif ($command eq 'head2') {
872
873     $self->head(2, $paragraph, $parobj);
874
875   } elsif ($command eq 'head3') {
876
877     $self->head(3, $paragraph, $parobj);
878
879   } elsif ($command eq 'head4') {
880
881     $self->head(4, $paragraph, $parobj);
882
883   } elsif ($command eq 'head5') {
884
885     $self->head(5, $paragraph, $parobj);
886
887   } elsif ($command eq 'head6') {
888
889     $self->head(6, $paragraph, $parobj);
890
891   } elsif ($command eq 'begin') {
892
893     # pass through if latex
894     if ($paragraph =~ /^latex/i) {
895       # Make sure that subsequent paragraphs are not modfied before printing
896       $self->{_dont_modify_any_para} = 1;
897
898     } else {
899       # Suppress all subsequent paragraphs unless 
900       # it is explcitly intended for latex
901       $self->{_suppress_all_para} = 1;
902     }
903
904   } elsif ($command eq 'for') {
905
906     # pass through if latex
907     if ($paragraph =~ /^latex/i) {
908       # Make sure that next paragraph is not modfied before printing
909       $self->{_dont_modify_next_para} = 1;
910
911     } else {
912       # Suppress the next paragraph unless it is latex
913       $self->{_suppress_next_para} = 1
914     }
915
916   } elsif ($command eq 'end') {
917
918     # Reset suppression
919     $self->{_suppress_all_para} = 0;
920     $self->{_dont_modify_any_para} = 0;
921
922   } elsif ($command eq 'pod') {
923
924     # Do nothing
925
926   } else {
927     carp "Command $command not recognised at line $line_num\n";
928   }
929
930 }
931
932 =item B<verbatim>
933
934 Verbatim text
935
936 =cut
937
938 sub verbatim {
939   my $self = shift;
940   my ($paragraph, $line_num, $parobj) = @_;
941
942   # Expand paragraph unless in =for or =begin block
943   if ($self->{_dont_modify_any_para} || $self->{_dont_modify_next_para}) {
944     # Just print as is
945     $self->_output($paragraph);
946
947     # Reset flag if in =for
948     $self->{_dont_modify_next_para} = 0;
949
950   } else {
951
952     return if $paragraph =~ /^\s+$/;
953
954     # Clean trailing space
955     $paragraph =~ s/\s+$//;
956
957     # Clean tabs
958     $paragraph =~ s/\t/        /g;
959
960     $self->_output('\begin{verbatim}' . "\n$paragraph\n". '\end{verbatim}'."\n");
961   }
962 }
963
964 =item B<textblock>
965
966 Plain text paragraph.
967
968 =cut
969
970 sub textblock {
971   my $self = shift;
972   my ($paragraph, $line_num, $parobj) = @_;
973
974   # print Dumper($self);
975   
976   # Expand paragraph unless in =for or =begin block
977   if ($self->{_dont_modify_any_para} || $self->{_dont_modify_next_para}) {
978     # Just print as is
979     $self->_output($paragraph);
980
981     # Reset flag if in =for
982     $self->{_dont_modify_next_para} = 0;
983
984     return;
985   } 
986
987   
988   # Escape latex special characters
989   $paragraph = $self->_replace_special_chars($paragraph);
990
991   # Interpolate interior sequences
992   my $expansion = $self->interpolate($paragraph, $line_num);
993   $expansion =~ s/\s+$//;
994
995
996   # If we are replacing 'head1 NAME' with a section
997   # we need to look in the paragraph and rewrite things
998   # Need to make sure this is called only on the first paragraph
999   # following 'head1 NAME' and not on subsequent paragraphs that may be
1000   # present.
1001   if ($self->{_CURRENT_HEAD1} =~ /^NAME/i && $self->ReplaceNAMEwithSection()) {
1002
1003     # Strip white space from start and end
1004     $paragraph =~ s/^\s+//;
1005     $paragraph =~ s/\s$//;
1006
1007     # Split the string into 2 parts
1008     my ($name, $purpose) = split(/\s+-\s+/, $expansion,2);
1009
1010     # Now prevent this from triggering until a new head1 NAME is set
1011     $self->{_CURRENT_HEAD1} = '_NAME';
1012
1013     # Might want to clear the Label() before doing this (CHECK)
1014
1015     # Print the heading
1016     $self->head(1, $name, $parobj);
1017
1018     # Set the labeling in case we want unique names later
1019     $self->Label( $self->_create_label( $name, 1 ) );
1020
1021     # Raise the Head1Level by one so that subsequent =head1 appear
1022     # as subsections of the main name section unless we are already
1023     # at maximum [Head1Level() could check this itself - CHECK]
1024     $self->Head1Level( $self->Head1Level() + 1)
1025       unless $self->Head1Level == $#LatexSections;
1026
1027     # Now write out the new latex paragraph
1028     $purpose = ucfirst($purpose);
1029     $self->_output("\n\n$purpose\n\n");
1030
1031   } else {
1032     # Just write the output
1033     $self->_output("\n\n$expansion\n\n");
1034   }
1035
1036 }
1037
1038 =item B<interior_sequence>
1039
1040 Interior sequence expansion
1041
1042 =cut
1043
1044 sub interior_sequence {
1045   my $self = shift;
1046
1047   my ($seq_command, $seq_argument, $pod_seq) = @_;
1048
1049   if ($seq_command eq 'B') {
1050     return "\\textbf{$seq_argument}";
1051
1052   } elsif ($seq_command eq 'I') {
1053     return "\\textit{$seq_argument}";
1054
1055   } elsif ($seq_command eq 'E') {
1056
1057     # If it is simply a number
1058     if ($seq_argument =~ /^\d+$/) {
1059       return chr($seq_argument);
1060     # Look up escape in hash table
1061     } elsif (exists $HTML_Escapes{$seq_argument}) {
1062       return $HTML_Escapes{$seq_argument};
1063
1064     } else {
1065       my ($file, $line) = $pod_seq->file_line();
1066       warn "Escape sequence $seq_argument not recognised at line $line of file $file\n";
1067       return;
1068     }
1069
1070   } elsif ($seq_command eq 'Z') {
1071
1072     # Zero width space
1073     return '$\!$'; # '
1074
1075   } elsif ($seq_command eq 'C') {
1076     return "\\texttt{$seq_argument}";
1077
1078   } elsif ($seq_command eq 'F') {
1079     return "\\emph{$seq_argument}";
1080
1081   } elsif ($seq_command eq 'S') {
1082     # non breakable spaces
1083     my $nbsp = '$\:$'; #'
1084
1085     $seq_argument =~ s/\s/$nbsp/g;
1086     return $seq_argument;
1087
1088   } elsif ($seq_command eq 'L') {
1089
1090     my $link = new Pod::Hyperlink($seq_argument);
1091
1092     # undef on failure
1093     unless (defined $link) {
1094       carp $@;
1095       return;
1096     }
1097
1098     # Handle internal links differently
1099     my $type = $link->type;
1100     my $page = $link->page;
1101
1102     if ($type eq 'section' && $page eq '') {
1103       # Use internal latex reference 
1104       my $node = $link->node;
1105
1106       # Convert to a label
1107       $node = $self->_create_label($node);
1108
1109       return "\\S\\ref{$node}";
1110
1111     } else {
1112       # Use default markup for external references
1113       # (although Starlink would use \xlabel)
1114       my $markup = $link->markup;
1115
1116       my ($file, $line) = $pod_seq->file_line();
1117
1118       return $self->interpolate($link->markup, $line);
1119     }
1120
1121
1122
1123   } elsif ($seq_command eq 'P') {
1124     # Special markup for Pod::Hyperlink
1125     # Replace :: with /
1126     my $link = $seq_argument;
1127     $link =~ s/::/\//g;
1128
1129     my $ref = "\\emph{$seq_argument}";
1130     return $ref;
1131
1132   } elsif ($seq_command eq 'Q') {
1133     # Special markup for Pod::Hyperlink
1134     return "\\textsf{$seq_argument}\n";
1135
1136   } elsif ($seq_command eq 'X') {
1137     # Index entries
1138
1139     # use \index command
1140     # I will let '!' go through for now
1141     # not sure how sub categories are handled in X<>
1142     my $index = $self->_create_index($seq_argument);
1143     return "\\index{$index}\n";
1144
1145   } else {
1146     carp "Unknown sequence $seq_command<$seq_argument>";
1147   }
1148
1149 }
1150
1151 =back
1152
1153 =head2 List Methods
1154
1155 Methods used to handle lists.
1156
1157 =over 4
1158
1159 =item B<begin_list>
1160
1161 Called when a new list is found (via the C<over> directive).
1162 Creates a new C<Pod::List> object and stores it on the 
1163 list stack.
1164
1165   $parser->begin_list($indent, $line_num);
1166
1167 =cut
1168
1169 sub begin_list {
1170   my $self = shift;
1171   my $indent = shift;
1172   my $line_num = shift;
1173
1174   # Indicate that a list should be started for the next item
1175   # need to do this to work out the type of list
1176   push ( @{$self->lists}, new Pod::List(-indent => $indent, 
1177                                         -start => $line_num,
1178                                         -file => $self->input_file,
1179                                        )         
1180        );
1181
1182 }
1183
1184 =item B<end_list>
1185
1186 Called when the end of a list is found (the C<back> directive).
1187 Pops the C<Pod::List> object off the stack of lists and writes
1188 the C<latex> code required to close a list.
1189
1190   $parser->end_list($line_num);
1191
1192 =cut
1193
1194 sub end_list {
1195   my $self = shift;
1196   my $line_num = shift;
1197
1198   unless (defined $self->lists->[-1]) {
1199     my $file = $self->input_file;
1200     warn "No list is active at line $line_num (file=$file). Missing =over?\n";
1201     return;
1202   }
1203
1204   # What to write depends on list type
1205   my $type = $self->lists->[-1]->type;
1206
1207   # Dont write anything if the list type is not set
1208   # iomplying that a list was created but no entries were
1209   # placed in it (eg because of a =begin/=end combination)
1210   $self->_output("\\end{$type}\n")
1211     if (defined $type && length($type) > 0);
1212   
1213   # Clear list
1214   pop(@{ $self->lists});
1215
1216 }
1217
1218 =item B<add_item>
1219
1220 Add items to the list. The first time an item is encountered 
1221 (determined from the state of the current C<Pod::List> object)
1222 the type of list is determined (ordered, unnumbered or description)
1223 and the relevant latex code issued.
1224
1225   $parser->add_item($paragraph, $line_num);
1226
1227 =cut
1228
1229 sub add_item {
1230   my $self = shift;
1231   my $paragraph = shift;
1232   my $line_num = shift;
1233
1234   unless (defined $self->lists->[-1]) {
1235     my $file = $self->input_file;
1236     warn "List has already ended by line $line_num of file $file. Missing =over?\n";
1237     # Replace special chars
1238 #    $paragraph = $self->_replace_special_chars($paragraph);
1239     $self->_output("$paragraph\n\n");
1240     return;
1241   }
1242
1243   # If paragraphs printing is turned off via =begin/=end or whatver
1244   # simply return immediately
1245   return if ($self->{_suppress_all_para} || $self->{_suppress_next_para});
1246
1247   # Check to see whether we are starting a new lists
1248   if (scalar($self->lists->[-1]->item) == 0) {
1249
1250     # Examine the paragraph to determine what type of list
1251     # we have
1252     $paragraph =~ s/\s+$//;
1253     $paragraph =~ s/^\s+//;
1254
1255     my $type;
1256     if (substr($paragraph, 0,1) eq '*') {
1257       $type = 'itemize';
1258     } elsif ($paragraph =~ /^\d/) {
1259       $type = 'enumerate';
1260     } else {
1261       $type = 'description';
1262     }
1263     $self->lists->[-1]->type($type);
1264
1265     $self->_output("\\begin{$type}\n");
1266
1267   }
1268
1269   my $type = $self->lists->[-1]->type;
1270
1271   if ($type eq 'description') {
1272     # Handle long items - long items do not wrap
1273     if (length($paragraph) < 40) {
1274       # A real description list item
1275       $self->_output("\\item[$paragraph] \\mbox{}");
1276     } else {
1277       # The item is now simply bold text
1278       $self->_output(qq{\\item \\textbf{$paragraph}});
1279     }
1280
1281   } else {
1282     # If the item was '* Something' we still need to write
1283     # out the something
1284     my $extra_info = $paragraph;
1285     $extra_info =~ s/^\*\s*//;
1286     $self->_output("\\item $extra_info");
1287   }
1288
1289   # Store the item name in the object. Required so that 
1290   # we can tell if the list is new or not
1291   $self->lists->[-1]->item($paragraph);
1292
1293 }
1294
1295 =back
1296
1297 =head2 Methods for headings
1298
1299 =over 4
1300
1301 =item B<head>
1302
1303 Print a heading of the required level.
1304
1305   $parser->head($level, $paragraph, $parobj);
1306
1307 The first argument is the pod heading level. The second argument
1308 is the contents of the heading. The 3rd argument is a Pod::Paragraph
1309 object so that the line number can be extracted.
1310
1311 =cut
1312
1313 sub head {
1314   my $self = shift;
1315   my $num = shift;
1316   my $paragraph = shift;
1317   my $parobj = shift;
1318
1319   # If we are replace 'head1 NAME' with a section
1320   # we return immediately if we get it
1321   return 
1322     if ($self->{_CURRENT_HEAD1} =~ /^NAME/i && $self->ReplaceNAMEwithSection());
1323
1324   # Create a label
1325   my $label = $self->_create_label($paragraph);
1326
1327   # Create an index entry
1328   my $index = $self->_create_index($paragraph);
1329
1330   # Work out position in the above array taking into account
1331   # that =head1 is equivalent to $self->Head1Level
1332
1333   my $level = $self->Head1Level() - 1 + $num;
1334
1335   # Warn if heading to large
1336   if ($num > $#LatexSections) {
1337     my $line = $parobj->file_line;
1338     my $file = $self->input_file;
1339     warn "Heading level too large ($level) for LaTeX at line $line of file $file\n";
1340     $level = $#LatexSections;
1341   }
1342
1343   # Check to see whether section should be unnumbered
1344   my $star = ($level >= $self->LevelNoNum ? '*' : '');
1345
1346   # Section
1347   $self->_output("\\" .$LatexSections[$level] .$star ."{$paragraph\\label{".$label ."}\\index{".$index."}}");
1348
1349 }
1350
1351
1352 =back
1353
1354 =end __PRIVATE__
1355
1356 =begin __PRIVATE__
1357
1358 =head2 Internal methods
1359
1360 Internal routines are described in this section. They do not form part of the
1361 public interface. All private methods start with an underscore.
1362
1363 =over 4
1364
1365 =item B<_output>
1366
1367 Output text to the output filehandle. This method must be always be called
1368 to output parsed text.
1369
1370    $parser->_output($text);
1371
1372 Does not write anything if a =begin or =for is active that should be
1373 ignored.
1374
1375 =cut
1376
1377 sub _output { 
1378   my $self = shift;
1379   my $text = shift;
1380
1381   print { $self->output_handle } $text 
1382     unless $self->{_suppress_all_para} ||
1383       $self->{_suppress_next_para};
1384
1385   # Reset pargraph stuff for =for
1386   $self->{_suppress_next_para} = 0
1387     if $self->{_suppress_next_para};
1388 }
1389
1390
1391 =item B<_replace_special_chars>
1392
1393 Subroutine to replace characters that are special in C<latex>
1394 with the escaped forms
1395
1396   $escaped = $parser->_replace_special_chars($paragraph);
1397
1398 Need to call this routine before interior_sequences are munged but
1399 not if verbatim.
1400
1401 Special characters and the C<latex> equivalents are:
1402
1403   }     \}
1404   {     \{
1405   _     \_
1406   $     \$
1407   %     \%
1408   &     \&
1409   \     $\backslash$
1410   ^     \^{}
1411   ~     \~{}
1412   |     $|$
1413
1414 =cut
1415
1416 sub _replace_special_chars {
1417   my $self = shift;
1418   my $paragraph = shift;
1419
1420   # Replace a \ with $\backslash$
1421   # This is made more complicated because the dollars will be escaped
1422   # by the subsequent replacement. Easiest to add \backslash 
1423   # now and then add the dollars
1424   $paragraph =~ s/\\/\\backslash/g;
1425
1426   # Must be done after escape of \ since this command adds latex escapes
1427   # Replace characters that can be escaped
1428   $paragraph =~ s/([\$\#&%_{}])/\\$1/g;
1429
1430   # Replace ^ characters with \^{} so that $^F works okay
1431   $paragraph =~ s/(\^)/\\$1\{\}/g;
1432
1433   # Replace tilde (~) with \texttt{\~{}}
1434   $paragraph =~ s/~/\\texttt\{\\~\{\}\}/g;
1435
1436   # Replace | with $|$
1437   $paragraph =~ s'\|'$|$'g;
1438
1439   # Now add the dollars around each \backslash
1440   $paragraph =~ s/(\\backslash)/\$$1\$/g;
1441
1442   return $paragraph;
1443 }
1444
1445
1446 =item B<_create_label>
1447
1448 Return a string that can be used as an internal reference
1449 in a C<latex> document (i.e. accepted by the C<\label> command)
1450
1451  $label = $parser->_create_label($string)
1452
1453 If UniqueLabels is true returns a label prefixed by Label()
1454 This can be suppressed with an optional second argument.
1455
1456  $label = $parser->_create_label($string, $suppress);
1457
1458 If a second argument is supplied (of any value including undef)
1459 the Label() is never prefixed. This means that this routine can
1460 be called to create a Label() without prefixing a previous setting.
1461
1462 =cut
1463
1464 sub _create_label {
1465   my $self = shift;
1466   my $paragraph = shift;
1467   my $suppress = (@_ ? 1 : 0 );
1468
1469   # Remove latex commands
1470   $paragraph = $self->_clean_latex_commands($paragraph);
1471
1472   # Remove non alphanumerics from the label and replace with underscores
1473   # want to protect '-' though so use negated character classes 
1474   $paragraph =~ s/[^-:\w]/_/g;
1475
1476   # Multiple underscores will look unsightly so remove repeats
1477   # This will also have the advantage of tidying up the end and
1478   # start of string
1479   $paragraph =~ s/_+/_/g;
1480
1481   # If required need to make sure that the label is unique
1482   # since it is possible to have multiple pods in a single
1483   # document
1484   if (!$suppress && $self->UniqueLabels() && defined $self->Label) {
1485     $paragraph = $self->Label() .'_'. $paragraph;
1486   }
1487
1488   return $paragraph;
1489 }
1490
1491
1492 =item B<_create_index>
1493
1494 Similar to C<_create_label> except an index entry is created.
1495 If C<UniqueLabels> is true, the index entry is prefixed by 
1496 the current C<Label> and an exclamation mark.
1497
1498   $ind = $parser->_create_index($paragraph);
1499
1500 An exclamation mark is used by C<makeindex> to generate 
1501 sub-entries in an index.
1502
1503 =cut
1504
1505 sub _create_index {
1506   my $self = shift;
1507   my $paragraph = shift;
1508   my $suppress = (@_ ? 1 : 0 );
1509
1510   # Remove latex commands
1511   $paragraph = $self->_clean_latex_commands($paragraph);
1512
1513   # If required need to make sure that the index entry is unique
1514   # since it is possible to have multiple pods in a single
1515   # document
1516   if (!$suppress && $self->UniqueLabels() && defined $self->Label) {
1517     $paragraph = $self->Label() .'!'. $paragraph;
1518   }
1519
1520   # Need to replace _ with space
1521   $paragraph =~ s/_/ /g;
1522
1523   return $paragraph;
1524
1525 }
1526
1527 =item B<_clean_latex_commands>
1528
1529 Removes latex commands from text. The latex command is assumed to be of the
1530 form C<\command{ text }>. "C<text>" is retained
1531
1532   $clean = $parser->_clean_latex_commands($text);
1533
1534 =cut
1535
1536 sub _clean_latex_commands {
1537   my $self = shift;
1538   my $paragraph = shift;
1539
1540   # Remove latex commands of the form \text{ }
1541   # and replace with the contents of the { }
1542   # need to make this non-greedy so that it can handle
1543   #  "\text{a} and \text2{b}"
1544   # without converting it to
1545   #  "a} and \text2{b"
1546   # This match will still get into trouble if \} is present 
1547   # This is not vital since the subsequent replacement of non-alphanumeric
1548   # characters will tidy it up anyway
1549   $paragraph =~ s/\\\w+{(.*?)}/$1/g;
1550
1551   return $paragraph
1552 }
1553
1554 =back
1555
1556 =end __PRIVATE__
1557
1558 =head1 NOTES
1559
1560 Compatible with C<latex2e> only. Can not be used with C<latex> v2.09
1561 or earlier.
1562
1563 A subclass of C<Pod::Select> so that specific pod sections can be
1564 converted to C<latex> by using the C<select> method.
1565
1566 Some HTML escapes are missing and many have not been tested.
1567
1568 =head1 SEE ALSO
1569
1570 L<Pod::Parser>, L<Pod::Select>, L<pod2latex>
1571
1572 =head1 AUTHORS
1573
1574 Tim Jenness E<lt>t.jenness@jach.hawaii.eduE<gt>
1575
1576 =head1 COPYRIGHT
1577
1578 Copyright (C) 2000 Tim Jenness. All Rights Reserved.
1579
1580 This program is free software; you can redistribute it and/or modify it
1581 under the same terms as Perl itself.
1582
1583 =begin __PRIVATE__
1584
1585 =head1 REVISION
1586
1587 $Id: LaTeX.pm,v 1.6 2000/08/21 09:05:03 timj Exp $
1588
1589 =end __PRIVATE__
1590
1591 =cut