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