Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | #!/import/archperf/ws/devtools/4/amd64/bin/perl |
2 | eval 'exec /import/archperf/ws/devtools/4/amd64/bin/perl -S $0 ${1+"$@"}' | |
3 | if $running_under_some_shell; | |
4 | ||
5 | # pod2latex conversion program | |
6 | ||
7 | use strict; | |
8 | use Pod::LaTeX; | |
9 | use Pod::Find qw/ pod_find /; | |
10 | use Pod::Usage; | |
11 | use Getopt::Long; | |
12 | use File::Basename; | |
13 | use Symbol; | |
14 | ||
15 | my $VERSION = "1.01"; | |
16 | ||
17 | # return the entire contents of a text file | |
18 | # whose name is given as argument | |
19 | sub _get { | |
20 | my $fn = shift; | |
21 | my $infh = gensym; | |
22 | open $infh, $fn | |
23 | or die "Could not open file $fn: $!\n"; | |
24 | local $/; | |
25 | return <$infh>; | |
26 | } | |
27 | ||
28 | # Read command line arguments | |
29 | ||
30 | my %options = ( | |
31 | "help" => 0, | |
32 | "man" => 0, | |
33 | "sections" => [], | |
34 | "full" => 0, | |
35 | "out" => undef, | |
36 | "verbose" => 0, | |
37 | "modify" => 0, | |
38 | "h1level" => 1, # section is equivalent to H1 | |
39 | "preamble" => [], | |
40 | "postamble" => [], | |
41 | ); | |
42 | # "prefile" is just like "preamble", but the argument | |
43 | # comes from the file named by the argument | |
44 | $options{"prefile"} = sub { shift; push @{$options{"preamble"}}, _get(shift) }; | |
45 | # the same between "postfile" and "postamble" | |
46 | $options{"postfile"} = sub { shift; push @{$options{"postamble"}}, _get(shift) }; | |
47 | ||
48 | GetOptions(\%options, | |
49 | "help", | |
50 | "man", | |
51 | "verbose", | |
52 | "full", | |
53 | "sections=s@", | |
54 | "out=s", | |
55 | "modify", | |
56 | "h1level=i", | |
57 | "preamble=s@", | |
58 | "postamble=s@", | |
59 | "prefile=s", | |
60 | "postfile=s" | |
61 | ) || pod2usage(2); | |
62 | ||
63 | pod2usage(1) if ($options{help}); | |
64 | pod2usage(-verbose => 2) if ($options{man}); | |
65 | ||
66 | ||
67 | # Read all the files from the command line | |
68 | my @files = @ARGV; | |
69 | ||
70 | # Now find which ones are real pods and convert | |
71 | # directories to their contents. | |
72 | ||
73 | # Extract the pods from each arg since some of them might | |
74 | # be directories | |
75 | # This is not as efficient as using pod_find to search through | |
76 | # everything at once but it allows us to preserve the order | |
77 | # supplied by the user | |
78 | ||
79 | my @pods; | |
80 | foreach my $arg (@files) { | |
81 | my %pods = pod_find($arg); | |
82 | push(@pods, sort keys %pods); | |
83 | } | |
84 | ||
85 | # Abort if nothing to do | |
86 | if ($#pods == -1) { | |
87 | warn "None of the supplied Pod files actually exist\n"; | |
88 | exit; | |
89 | } | |
90 | ||
91 | # Only want to override the preamble and postamble if we have | |
92 | # been given values. | |
93 | my %User; | |
94 | $User{UserPreamble} = join("\n", @{$options{'preamble'}}) | |
95 | if ($options{preamble} && @{$options{preamble}}); | |
96 | $User{UserPostamble} = join("\n", @{$options{'postamble'}}) | |
97 | if ($options{postamble} && @{$options{postamble}}); | |
98 | ||
99 | ||
100 | ||
101 | # If $options{'out'} is set we are processing to a single output file | |
102 | my $multi_documents; | |
103 | if (exists $options{'out'} && defined $options{'out'}) { | |
104 | $multi_documents = 0; | |
105 | } else { | |
106 | $multi_documents = 1; | |
107 | } | |
108 | ||
109 | # If the output file is not specified it is assumed that | |
110 | # a single output file is required per input file using | |
111 | # a .tex extension rather than any exisiting extension | |
112 | ||
113 | if ($multi_documents) { | |
114 | ||
115 | # Case where we just generate one input per output | |
116 | ||
117 | foreach my $pod (@pods) { | |
118 | ||
119 | if (-f $pod) { | |
120 | ||
121 | my $output = $pod; | |
122 | $output = basename($output, '.pm', '.pod','.pl') . '.tex'; | |
123 | ||
124 | # Create a new parser object | |
125 | my $parser = new Pod::LaTeX( | |
126 | AddPreamble => $options{'full'}, | |
127 | AddPostamble => $options{'full'}, | |
128 | MakeIndex => $options{'full'}, | |
129 | TableOfContents => $options{'full'}, | |
130 | ReplaceNAMEwithSection => $options{'modify'}, | |
131 | UniqueLabels => $options{'modify'}, | |
132 | Head1Level => $options{'h1level'}, | |
133 | LevelNoNum => $options{'h1level'} + 1, | |
134 | %User, | |
135 | ); | |
136 | ||
137 | # Select sections if supplied | |
138 | $parser->select(@{ $options{'sections'}}) | |
139 | if @{$options{'sections'}}; | |
140 | ||
141 | # Derive the input file from the output file | |
142 | $parser->parse_from_file($pod, $output); | |
143 | ||
144 | print "Written output to $output\n" if $options{'verbose'}; | |
145 | ||
146 | } else { | |
147 | warn "File $pod not found\n"; | |
148 | } | |
149 | ||
150 | } | |
151 | } else { | |
152 | ||
153 | # Case where we want everything to be in a single document | |
154 | ||
155 | # Need to open the output file ourselves | |
156 | my $output = $options{'out'}; | |
157 | $output .= '.tex' unless $output =~ /\.tex$/; | |
158 | ||
159 | # Use auto-vivified file handle in perl 5.6 | |
160 | my $outfh = gensym; | |
161 | open ($outfh, ">$output") || die "Could not open output file: $!\n"; | |
162 | ||
163 | # Flag to indicate whether we have converted at least one file | |
164 | # indicates how many files have been converted | |
165 | my $converted = 0; | |
166 | ||
167 | # Loop over the input files | |
168 | foreach my $pod (@pods) { | |
169 | ||
170 | if (-f $pod) { | |
171 | ||
172 | warn "Converting $pod\n" if $options{'verbose'}; | |
173 | ||
174 | # Open the file (need the handle) | |
175 | # Use auto-vivified handle in perl 5.6 | |
176 | my $podfh = gensym; | |
177 | open ($podfh, "<$pod") || die "Could not open pod file $pod: $!\n"; | |
178 | ||
179 | # if this is the first file to be converted we may want to add | |
180 | # a preamble (controlled by command line option) | |
181 | my $preamble = 0; | |
182 | $preamble = 1 if ($converted == 0 && $options{'full'}); | |
183 | ||
184 | # if this is the last file to be converted may want to add | |
185 | # a postamble (controlled by command line option) | |
186 | # relies on a previous pass to check existence of all pods we | |
187 | # are converting. | |
188 | my $postamble = ( ($converted == $#pods && $options{'full'}) ? 1 : 0 ); | |
189 | ||
190 | # Open parser object | |
191 | # May want to start with a preamble for the first one and | |
192 | # end with an index for the last | |
193 | my $parser = new Pod::LaTeX( | |
194 | MakeIndex => $options{'full'}, | |
195 | TableOfContents => $preamble, | |
196 | ReplaceNAMEwithSection => $options{'modify'}, | |
197 | UniqueLabels => $options{'modify'}, | |
198 | StartWithNewPage => $options{'full'}, | |
199 | AddPreamble => $preamble, | |
200 | AddPostamble => $postamble, | |
201 | Head1Level => $options{'h1level'}, | |
202 | LevelNoNum => $options{'h1level'} + 1, | |
203 | %User | |
204 | ); | |
205 | ||
206 | # Store the file name for error messages | |
207 | # This is a kluge that breaks the data hiding of the object | |
208 | $parser->{_INFILE} = $pod; | |
209 | ||
210 | # Select sections if supplied | |
211 | $parser->select(@{ $options{'sections'}}) | |
212 | if @{$options{'sections'}}; | |
213 | ||
214 | # Parse it | |
215 | $parser->parse_from_filehandle($podfh, $outfh); | |
216 | ||
217 | # We have converted at least one file | |
218 | $converted++; | |
219 | ||
220 | } else { | |
221 | warn "File $pod not found\n"; | |
222 | } | |
223 | ||
224 | } | |
225 | ||
226 | # Should unlink the file if we didn't convert anything! | |
227 | # dont check for return status of unlink | |
228 | # since there is not a lot to be done if the unlink failed | |
229 | # and the program does not rely upon it. | |
230 | unlink "$output" unless $converted; | |
231 | ||
232 | # If verbose | |
233 | warn "Converted $converted files\n" if $options{'verbose'}; | |
234 | ||
235 | } | |
236 | ||
237 | exit; | |
238 | ||
239 | __END__ | |
240 | ||
241 | =head1 NAME | |
242 | ||
243 | pod2latex - convert pod documentation to latex format | |
244 | ||
245 | =head1 SYNOPSIS | |
246 | ||
247 | pod2latex *.pm | |
248 | ||
249 | pod2latex -out mytex.tex *.pod | |
250 | ||
251 | pod2latex -full -sections 'DESCRIPTION|NAME' SomeDir | |
252 | ||
253 | pod2latex -prefile h.tex -postfile t.tex my.pod | |
254 | ||
255 | =head1 DESCRIPTION | |
256 | ||
257 | C<pod2latex> is a program to convert POD format documentation | |
258 | (L<perlpod>) into latex. It can process multiple input documents at a | |
259 | time and either generate a latex file per input document or a single | |
260 | combined output file. | |
261 | ||
262 | =head1 OPTIONS AND ARGUMENTS | |
263 | ||
264 | This section describes the supported command line options. Minimum | |
265 | matching is supported. | |
266 | ||
267 | =over 4 | |
268 | ||
269 | =item B<-out> | |
270 | ||
271 | Name of the output file to be used. If there are multiple input pods | |
272 | it is assumed that the intention is to write all translated output | |
273 | into a single file. C<.tex> is appended if not present. If the | |
274 | argument is not supplied, a single document will be created for each | |
275 | input file. | |
276 | ||
277 | =item B<-full> | |
278 | ||
279 | Creates a complete C<latex> file that can be processed immediately | |
280 | (unless C<=for/=begin> directives are used that rely on extra packages). | |
281 | Table of contents and index generation commands are included in the | |
282 | wrapper C<latex> code. | |
283 | ||
284 | =item B<-sections> | |
285 | ||
286 | Specify pod sections to include (or remove if negated) in the | |
287 | translation. See L<Pod::Select/"SECTION SPECIFICATIONS"> for the | |
288 | format to use for I<section-spec>. This option may be given multiple | |
289 | times on the command line.This is identical to the similar option in | |
290 | the C<podselect()> command. | |
291 | ||
292 | =item B<-modify> | |
293 | ||
294 | This option causes the output C<latex> to be slightly | |
295 | modified from the input pod such that when a C<=head1 NAME> | |
296 | is encountered a section is created containing the actual | |
297 | pod name (rather than B<NAME>) and all subsequent C<=head1> | |
298 | directives are treated as subsections. This has the advantage | |
299 | that the description of a module will be in its own section | |
300 | which is helpful for including module descriptions in documentation. | |
301 | Also forces C<latex> label and index entries to be prefixed by the | |
302 | name of the module. | |
303 | ||
304 | =item B<-h1level> | |
305 | ||
306 | Specifies the C<latex> section that is equivalent to a C<H1> pod | |
307 | directive. This is an integer between 0 and 5 with 0 equivalent to a | |
308 | C<latex> chapter, 1 equivalent to a C<latex> section etc. The default | |
309 | is 1 (C<H1> equivalent to a latex section). | |
310 | ||
311 | =item B<-help> | |
312 | ||
313 | Print a brief help message and exit. | |
314 | ||
315 | =item B<-man> | |
316 | ||
317 | Print the manual page and exit. | |
318 | ||
319 | =item B<-verbose> | |
320 | ||
321 | Print information messages as each document is processed. | |
322 | ||
323 | =item B<-preamble> | |
324 | ||
325 | A user-supplied preamble for the LaTeX code. Multiple values | |
326 | are supported and appended in order separated by "\n". | |
327 | See B<-prefile> for reading the preamble from a file. | |
328 | ||
329 | =item B<-postamble> | |
330 | ||
331 | A user supplied postamble for the LaTeX code. Multiple values | |
332 | are supported and appended in order separated by "\n". | |
333 | See B<-postfile> for reading the postamble from a file. | |
334 | ||
335 | =item B<-prefile> | |
336 | ||
337 | A user-supplied preamble for the LaTeX code to be read from the | |
338 | named file. Multiple values are supported and appended in | |
339 | order. See B<-preamble>. | |
340 | ||
341 | =item B<-postfile> | |
342 | ||
343 | A user-supplied postamble for the LaTeX code to be read from the | |
344 | named file. Multiple values are supported and appended in | |
345 | order. See B<-postamble>. | |
346 | ||
347 | =back | |
348 | ||
349 | =head1 BUGS | |
350 | ||
351 | Known bugs are: | |
352 | ||
353 | =over 4 | |
354 | ||
355 | =item * | |
356 | ||
357 | Cross references between documents are not resolved when multiple | |
358 | pod documents are converted into a single output C<latex> file. | |
359 | ||
360 | =item * | |
361 | ||
362 | Functions and variables are not automatically recognized | |
363 | and they will therefore not be marked up in any special way | |
364 | unless instructed by an explicit pod command. | |
365 | ||
366 | =back | |
367 | ||
368 | =head1 SEE ALSO | |
369 | ||
370 | L<Pod::LaTeX> | |
371 | ||
372 | =head1 AUTHOR | |
373 | ||
374 | Tim Jenness E<lt>tjenness@cpan.orgE<gt> | |
375 | ||
376 | This program is free software; you can redistribute it | |
377 | and/or modify it under the same terms as Perl itself. | |
378 | ||
379 | Copyright (C) 2000, 2003, 2004 Tim Jenness. All Rights Reserved. | |
380 | ||
381 | =cut | |
382 |