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