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