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