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