Commit | Line | Data |
076c2fc0 |
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 | |
4d4a0c66 |
39 | $VERSION = '0.53'; |
076c2fc0 |
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 |
4d4a0c66 |
60 | 'sol' => '/', |
61 | 'verbar' => '$|$', |
076c2fc0 |
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 | |
91e74348 |
680 | Returns array of list information in list context |
076c2fc0 |
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 | |
4d4a0c66 |
957 | # Clean tabs |
958 | $paragraph =~ s/\t/ /g; |
959 | |
076c2fc0 |
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; |
4d4a0c66 |
1256 | if (substr($paragraph, 0,1) eq '*') { |
076c2fc0 |
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') { |
4d4a0c66 |
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 | } |
076c2fc0 |
1280 | |
076c2fc0 |
1281 | } else { |
4d4a0c66 |
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"); |
076c2fc0 |
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 | ^ \^{} |
4d4a0c66 |
1411 | ~ \~{} |
1412 | | $|$ |
076c2fc0 |
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 | |
4d4a0c66 |
1433 | # Replace tilde (~) with \texttt{\~{}} |
1434 | $paragraph =~ s/~/\\texttt\{\\~\{\}\}/g; |
1435 | |
1436 | # Replace | with $|$ |
1437 | $paragraph =~ s'\|'$|$'g; |
1438 | |
076c2fc0 |
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 | |
4d4a0c66 |
1587 | $Id: LaTeX.pm,v 1.6 2000/08/21 09:05:03 timj Exp $ |
076c2fc0 |
1588 | |
1589 | =end __PRIVATE__ |
1590 | |
1591 | =cut |