xref: /openbsd/gnu/usr.bin/perl/installhtml (revision eac174f2)
179cd0b9aSmillert#!./perl -Ilib -w
2ba47ec9dSmillert
3c5dcfd37Smillert# This file should really be extracted from a .PL file
4ba47ec9dSmillert
5*eac174f2Safresh1$| = 1;
679cd0b9aSmillertuse strict;
7ba47ec9dSmillertuse Config;		# for config options in the makefile
89f11ffb7Safresh1use File::Path qw(remove_tree);
9e9ce3842Safresh1use File::Spec::Functions qw(rel2abs no_upwards);
10ba47ec9dSmillertuse Getopt::Long;	# for command-line parsing
11ba47ec9dSmillertuse Cwd;
12*eac174f2Safresh1use Pod::Html 1.32;
13*eac174f2Safresh1use Pod::Html::Util 1.32 qw(anchorify relativize_url);
14ba47ec9dSmillert
15ba47ec9dSmillert=head1 NAME
16ba47ec9dSmillert
17ba47ec9dSmillertinstallhtml - converts a collection of POD pages to HTML format.
18ba47ec9dSmillert
19ba47ec9dSmillert=head1 SYNOPSIS
20ba47ec9dSmillert
21ba47ec9dSmillert  installhtml  [--help] [--podpath=<name>:...:<name>] [--podroot=<name>]
22ba47ec9dSmillert       [--htmldir=<name>] [--htmlroot=<name>]  [--norecurse] [--recurse]
23ba47ec9dSmillert       [--splithead=<name>,...,<name>]   [--splititem=<name>,...,<name>]
2448950c12Ssthen       [--ignore=<name>,...,<name>]  [--verbose]
25ba47ec9dSmillert
26ba47ec9dSmillert=head1 DESCRIPTION
27ba47ec9dSmillert
28ba47ec9dSmillertI<installhtml> converts a collection of POD pages to a corresponding
299f11ffb7Safresh1collection of HTML pages.  This is used to convert the pod pages found in the
309f11ffb7Safresh1perl distribution.  (It is not intended as a general-purpose
319f11ffb7Safresh1converter/installer of POD pages in HTML format.  See L<Pod::Html>.)
32ba47ec9dSmillert
33ba47ec9dSmillert=head1 OPTIONS
34ba47ec9dSmillert
35ba47ec9dSmillert=over 4
36ba47ec9dSmillert
37ba47ec9dSmillert=item B<--help> help
38ba47ec9dSmillert
39ba47ec9dSmillertDisplays the usage.
40ba47ec9dSmillert
41ba47ec9dSmillert=item B<--podroot> POD search path base directory
42ba47ec9dSmillert
43ba47ec9dSmillertThe base directory to search for all .pod and .pm files to be converted.
44ba47ec9dSmillertDefault is current directory.
45ba47ec9dSmillert
46ba47ec9dSmillert=item B<--podpath> POD search path
47ba47ec9dSmillert
48ba47ec9dSmillertThe list of directories to search for .pod and .pm files to be converted.
49*eac174f2Safresh1Default is 'podroot/lib'.
50ba47ec9dSmillert
51ba47ec9dSmillert=item B<--recurse> recurse on subdirectories
52ba47ec9dSmillert
53ba47ec9dSmillertWhether or not to convert all .pm and .pod files found in subdirectories
54ba47ec9dSmillerttoo.  Default is to not recurse.
55ba47ec9dSmillert
56ba47ec9dSmillert=item B<--htmldir> HTML destination directory
57ba47ec9dSmillert
58ba47ec9dSmillertThe base directory which all HTML files will be written to.  This should
59ba47ec9dSmillertbe a path relative to the filesystem, not the resulting URL.
60ba47ec9dSmillert
61ba47ec9dSmillert=item B<--htmlroot> URL base directory
62ba47ec9dSmillert
63ba47ec9dSmillertThe base directory which all resulting HTML files will be visible at in
647bfa9f44Smillerta URL.  The default is '/'.
65ba47ec9dSmillert
66ba47ec9dSmillert=item B<--splithead> POD files to split on =head directive
67ba47ec9dSmillert
68e2e5c5d3SmillertComma-separated list of pod files to split by the =head directive.  The
69ba47ec9dSmillert.pod suffix is optional. These files should have names specified
70ba47ec9dSmillertrelative to podroot.
71ba47ec9dSmillert
72ba47ec9dSmillert=item B<--splititem> POD files to split on =item directive
73ba47ec9dSmillert
749f11ffb7Safresh1Comma-separated list of all pod files to split by the =item directive.  The
759f11ffb7Safresh1.pod suffix is optional.  I<installhtml> does not do the actual split, rather
769f11ffb7Safresh1it invokes I<splitpod>, a separate program in the Perl 5 core distribution,
779f11ffb7Safresh1to do the dirty work.  As with --splithead, these files should have names
789f11ffb7Safresh1specified relative to podroot.
79ba47ec9dSmillert
80ba47ec9dSmillert=item B<--splitpod> Directory containing the splitpod program
81ba47ec9dSmillert
827bfa9f44SmillertThe directory containing the splitpod program. The default is 'podroot/pod'.
83ba47ec9dSmillert
84ad15181aSmillert=item B<--ignore> files to be ignored
85ad15181aSmillert
86ad15181aSmillertComma-separated of files that shouldn't be installed, given relative
87ad15181aSmillertto podroot.
88ad15181aSmillert
89ba47ec9dSmillert=item B<--verbose> verbose output
90ba47ec9dSmillert
91ba47ec9dSmillertSelf-explanatory.
92ba47ec9dSmillert
93ba47ec9dSmillert=back
94ba47ec9dSmillert
95ba47ec9dSmillert=head1 EXAMPLE
96ba47ec9dSmillert
97ba47ec9dSmillertThe following command-line is an example of the one we use to convert
98ba47ec9dSmillertperl documentation:
99ba47ec9dSmillert
100ba47ec9dSmillert    ./installhtml --podpath=lib:ext:pod:vms   \
101ba47ec9dSmillert			--podroot=/usr/src/perl     \
102ba47ec9dSmillert			--htmldir=/perl/nmanual     \
103ba47ec9dSmillert			--htmlroot=/perl/nmanual    \
104ba47ec9dSmillert			--splithead=pod/perlipc     \
105ba47ec9dSmillert			--splititem=pod/perlfunc    \
106ba47ec9dSmillert			--recurse \
107ba47ec9dSmillert			--verbose
108ba47ec9dSmillert
109ba47ec9dSmillert=head1 AUTHOR
110ba47ec9dSmillert
111ba47ec9dSmillertChris Hall E<lt>hallc@cs.colorado.eduE<gt>
112ba47ec9dSmillert
113ba47ec9dSmillert=cut
114ba47ec9dSmillert
11579cd0b9aSmillertmy $usage;
11679cd0b9aSmillert
117ba47ec9dSmillert$usage =<<END_OF_USAGE;
118ba47ec9dSmillertUsage: $0 --help --podpath=<name>:...:<name> --podroot=<name>
119ba47ec9dSmillert         --htmldir=<name> --htmlroot=<name> --norecurse --recurse
120ba47ec9dSmillert         --splithead=<name>,...,<name> --splititem=<name>,...,<name>
12148950c12Ssthen         --ignore=<name>,...,<name> --verbose
122ba47ec9dSmillert
123ba47ec9dSmillert    --help      - this message
124ba47ec9dSmillert    --podpath   - colon-separated list of directories containing .pod and
125*eac174f2Safresh1                  .pm files to be converted ('lib/' by default).
126ba47ec9dSmillert    --podroot   - filesystem base directory from which all relative paths in
127ba47ec9dSmillert                  podpath stem (default is .).
128ba47ec9dSmillert    --htmldir   - directory to store resulting html files in relative
129ba47ec9dSmillert                  to the filesystem (\$podroot/html by default).
130ba47ec9dSmillert    --htmlroot  - http-server base directory from which all relative paths
131ba47ec9dSmillert                  in podpath stem (default is /).
132ba47ec9dSmillert    --norecurse - don't recurse on those subdirectories listed in podpath.
133ba47ec9dSmillert                  (default behavior).
134ba47ec9dSmillert    --recurse   - recurse on those subdirectories listed in podpath
135ba47ec9dSmillert    --splithead - comma-separated list of .pod or .pm files to split.  will
136ba47ec9dSmillert                  split each file into several smaller files at every occurrence
137ba47ec9dSmillert                  of a pod =head[1-6] directive.
138ba47ec9dSmillert    --splititem - comma-separated list of .pod or .pm files to split using
139ba47ec9dSmillert                  splitpod.
140ba47ec9dSmillert    --splitpod  - directory where the program splitpod can be found
141ba47ec9dSmillert                  (\$podroot/pod by default).
142ad15181aSmillert    --ignore    - comma-separated list of files that shouldn't be installed.
143ba47ec9dSmillert    --verbose   - self-explanatory.
144ba47ec9dSmillert
145ba47ec9dSmillertEND_OF_USAGE
146ba47ec9dSmillert
14748950c12Ssthenmy (@podpath, $podroot, $htmldir, $htmlroot, $recurse, @splithead,
148ad15181aSmillert    @splititem, $splitpod, $verbose, $pod2html, @ignore);
14979cd0b9aSmillert
150*eac174f2Safresh1@podpath = ( "lib" );	# colon-separated list of directories containing .pod
151ba47ec9dSmillert			# and .pm files to be converted.
152ba47ec9dSmillert$podroot = ".";		# assume the pods we want are here
153ba47ec9dSmillert$htmldir = "";		# nothing for now...
154ba47ec9dSmillert$htmlroot = "/";	# default value
155ba47ec9dSmillert$recurse = 0;		# default behavior
156ba47ec9dSmillert@splithead = ();	# don't split any files by default
157ba47ec9dSmillert@splititem = ();	# don't split any files by default
158ba47ec9dSmillert$splitpod = "";		# nothing for now.
159ba47ec9dSmillert
160ba47ec9dSmillert$verbose = 0;		# whether or not to print debugging info
161ba47ec9dSmillert
162ba47ec9dSmillert$pod2html = "pod/pod2html";
163ba47ec9dSmillert
164ba47ec9dSmillertusage("") unless @ARGV;
165ba47ec9dSmillert
166e2e5c5d3Smillert# Overcome shell's p1,..,p8 limitation.
16748950c12Ssthen# See vms/descrip_mms.template -> descrip.mms for invocation.
168e2e5c5d3Smillertif ( $^O eq 'VMS' ) { @ARGV = split(/\s+/,$ARGV[0]); }
169e2e5c5d3Smillert
1709f11ffb7Safresh1our %Options;
17179cd0b9aSmillert
172ba47ec9dSmillert# parse the command-line
17379cd0b9aSmillertmy $result = GetOptions( \%Options, qw(
174ba47ec9dSmillert	help
175ba47ec9dSmillert	podpath=s
176ba47ec9dSmillert	podroot=s
177ba47ec9dSmillert	htmldir=s
178ba47ec9dSmillert	htmlroot=s
179ad15181aSmillert	ignore=s
180ba47ec9dSmillert	recurse!
181ba47ec9dSmillert	splithead=s
182ba47ec9dSmillert	splititem=s
183ba47ec9dSmillert	splitpod=s
184ba47ec9dSmillert	verbose
185ba47ec9dSmillert));
186ba47ec9dSmillertusage("invalid parameters") unless $result;
187ba47ec9dSmillertparse_command_line();
188ba47ec9dSmillert
189ba47ec9dSmillert
190ba47ec9dSmillert# set these variables to appropriate values if the user didn't specify
191ba47ec9dSmillert#  values for them.
192ba47ec9dSmillert$htmldir = "$htmlroot/html" unless $htmldir;
193ba47ec9dSmillert$splitpod = "$podroot/pod" unless $splitpod;
194ba47ec9dSmillert
195ba47ec9dSmillert
196ba47ec9dSmillert# make sure that the destination directory exists
197ba47ec9dSmillert(mkdir($htmldir, 0755) ||
198ba47ec9dSmillert	die "$0: cannot make directory $htmldir: $!\n") if ! -d $htmldir;
199ba47ec9dSmillert
200ba47ec9dSmillert
201ba47ec9dSmillert# the following array will eventually contain files that are to be
202ba47ec9dSmillert# ignored in the conversion process.  these are files that have been
203ba47ec9dSmillert# process by splititem or splithead and should not be converted as a
204ba47ec9dSmillert# result.
20579cd0b9aSmillertmy @splitdirs;
206ba47ec9dSmillert
207ad15181aSmillert# split pods. It's important to do this before convert ANY pods because
208ad15181aSmillert# it may affect some of the links
209ba47ec9dSmillert@splitdirs = ();    # files in these directories won't get an index
210ba47ec9dSmillertsplit_on_head($podroot, $htmldir, \@splitdirs, \@ignore, @splithead);
211ba47ec9dSmillertsplit_on_item($podroot,           \@splitdirs, \@ignore, @splititem);
212ba47ec9dSmillert
213ba47ec9dSmillert
214ba47ec9dSmillert# convert the pod pages found in @poddirs
215ba47ec9dSmillert#warn "converting files\n" if $verbose;
216ba47ec9dSmillert#warn "\@ignore\t= @ignore\n" if $verbose;
21779cd0b9aSmillertforeach my $dir (@podpath) {
218ba47ec9dSmillert    installdir($dir, $recurse, $podroot, \@splitdirs, \@ignore);
219ba47ec9dSmillert}
220ba47ec9dSmillert
221ba47ec9dSmillert
222ba47ec9dSmillert# now go through and create master indices for each pod we split
22379cd0b9aSmillertforeach my $dir (@splititem) {
224ba47ec9dSmillert    print "creating index $htmldir/$dir.html\n" if $verbose;
225ba47ec9dSmillert    create_index("$htmldir/$dir.html", "$htmldir/$dir");
226ba47ec9dSmillert}
227ba47ec9dSmillert
22879cd0b9aSmillertforeach my $dir (@splithead) {
229f64b279aSmillert    (my $pod = $dir) =~ s,^.*/,,;
230ba47ec9dSmillert    $dir .= ".pod" unless $dir =~ /(\.pod|\.pm)$/;
231ba47ec9dSmillert    # let pod2html create the file
232ba47ec9dSmillert    runpod2html($dir, 1);
233ba47ec9dSmillert
234ba47ec9dSmillert    # now go through and truncate after the index
235ba47ec9dSmillert    $dir =~ /^(.*?)(\.pod|\.pm)?$/sm;
23679cd0b9aSmillert    my $file = "$htmldir/$1";
237ba47ec9dSmillert    print "creating index $file.html\n" if $verbose;
238ba47ec9dSmillert
239ba47ec9dSmillert    # read in everything until what would have been the first =head
240ba47ec9dSmillert    # directive, patching the index as we go.
2419f11ffb7Safresh1    open(H, '<', "$file.html") ||
242ba47ec9dSmillert	die "$0: error opening $file.html for input: $!\n";
243ba47ec9dSmillert    $/ = "";
24479cd0b9aSmillert    my @data = ();
245ba47ec9dSmillert    while (<H>) {
2469f11ffb7Safresh1	last if m!<h1 id="NAME">NAME</h1>!;
247f64b279aSmillert	$_ =~ s{href="#(.*)">}{
2489f11ffb7Safresh1	    my $url = "$file/@{[anchorify(qq($1))]}.html" ;
2499f11ffb7Safresh1	    $url = relativize_url( $url, "$file.html" )
25079cd0b9aSmillert	    if ( ! defined $Options{htmlroot} || $Options{htmlroot} eq '' );
251f64b279aSmillert	    "href=\"$url\">" ;
252f64b279aSmillert	}egi;
253ba47ec9dSmillert	push @data, $_;
254ba47ec9dSmillert    }
255ba47ec9dSmillert    close(H);
256ba47ec9dSmillert
257ba47ec9dSmillert    # now rewrite the file
2589f11ffb7Safresh1    open(H, '>', "$file.html") ||
259ba47ec9dSmillert	die "$0: error opening $file.html for output: $!\n";
2609f11ffb7Safresh1    print H @data, "</body>\n\n</html>\n\n\n";
261ba47ec9dSmillert    close(H);
262ba47ec9dSmillert}
263ba47ec9dSmillert
2649f11ffb7Safresh1remove_tree(@splitdirs, {safe=>1});
2659f11ffb7Safresh1
266ba47ec9dSmillert##############################################################################
267ba47ec9dSmillert
268ba47ec9dSmillert
269ba47ec9dSmillertsub usage {
270ba47ec9dSmillert    warn "$0: @_\n" if @_;
271ba47ec9dSmillert    die $usage;
272ba47ec9dSmillert}
273ba47ec9dSmillert
274ba47ec9dSmillert
275ba47ec9dSmillertsub parse_command_line {
27679cd0b9aSmillert    usage() if defined $Options{help};
27779cd0b9aSmillert    $Options{help} = ""; 	    	    # make -w shut up
278ba47ec9dSmillert
279ba47ec9dSmillert    # list of directories
28079cd0b9aSmillert    @podpath   = split(":", $Options{podpath}) if defined $Options{podpath};
281ba47ec9dSmillert
282ba47ec9dSmillert    # lists of files
28379cd0b9aSmillert    @splithead = split(",", $Options{splithead}) if defined $Options{splithead};
28479cd0b9aSmillert    @splititem = split(",", $Options{splititem}) if defined $Options{splititem};
285ba47ec9dSmillert
28679cd0b9aSmillert    $htmldir  = $Options{htmldir}	    if defined $Options{htmldir};
28779cd0b9aSmillert    $htmlroot = $Options{htmlroot}	    if defined $Options{htmlroot};
28879cd0b9aSmillert    $podroot  = $Options{podroot}	    if defined $Options{podroot};
28979cd0b9aSmillert    $splitpod = $Options{splitpod}	    if defined $Options{splitpod};
290ba47ec9dSmillert
29179cd0b9aSmillert    $recurse  = $Options{recurse}	    if defined $Options{recurse};
29279cd0b9aSmillert    $verbose  = $Options{verbose}	    if defined $Options{verbose};
293ad15181aSmillert
294ad15181aSmillert    @ignore = map "$podroot/$_", split(",", $Options{ignore}) if defined $Options{ignore};
295ba47ec9dSmillert}
296ba47ec9dSmillert
297ba47ec9dSmillert
298ba47ec9dSmillertsub create_index {
299ba47ec9dSmillert    my($html, $dir) = @_;
300f64b279aSmillert    (my $pod = $dir) =~ s,^.*/,,;
301ba47ec9dSmillert
302ba47ec9dSmillert    # get the list of .html files in this directory
303ba47ec9dSmillert    opendir(DIR, $dir) ||
304ba47ec9dSmillert	die "$0: error opening directory $dir for reading: $!\n";
30548950c12Ssthen    my @files = sort(grep(/\.html?$/, readdir(DIR)));
306ba47ec9dSmillert    closedir(DIR);
307ba47ec9dSmillert
3089f11ffb7Safresh1    open(HTML, '>', $html) ||
309ba47ec9dSmillert	die "$0: error opening $html for output: $!\n";
310ba47ec9dSmillert
311ba47ec9dSmillert    # for each .html file in the directory, extract the index
312ba47ec9dSmillert    #	embedded in the file and throw it into the big index.
313ba47ec9dSmillert    print HTML "<DL COMPACT>\n";
31448950c12Ssthen    foreach my $file (@files) {
315ba47ec9dSmillert
31648950c12Ssthen	my $filedata = do {
3179f11ffb7Safresh1	    open(my $in, '<', "$dir/$file") ||
318ba47ec9dSmillert		die "$0: error opening $dir/$file for input: $!\n";
31948950c12Ssthen	    local $/ = undef;
32048950c12Ssthen	    <$in>;
32148950c12Ssthen	};
322ba47ec9dSmillert
323ba47ec9dSmillert	# pull out the NAME section
32448950c12Ssthen	my($lcp1, $lcp2) =
32548950c12Ssthen	    ($filedata =~
32648950c12Ssthen		m#<h1 id="NAME">NAME</h1>\s*<p>\s*(\S+)\s+-\s+(\S.*?\S)</p>#);
32748950c12Ssthen	defined $lcp1 or die "$0: can't find NAME section in $dir/$file\n";
32848950c12Ssthen
3299f11ffb7Safresh1	my $url= "$dir/$file" ;
33079cd0b9aSmillert	if ( ! defined $Options{htmlroot} || $Options{htmlroot} eq '' ) {
3319f11ffb7Safresh1	    $url = relativize_url( $url, $html ) ;
332e2e5c5d3Smillert	}
333e2e5c5d3Smillert
334f64b279aSmillert	print HTML qq(<DT><A HREF="$url">);
335f64b279aSmillert	print HTML "$lcp1</A></DT><DD>$lcp2</DD>\n";
336f64b279aSmillert    }
337ba47ec9dSmillert    print HTML "</DL>\n";
338ba47ec9dSmillert
339ba47ec9dSmillert    close(HTML);
340ba47ec9dSmillert}
341ba47ec9dSmillert
342ba47ec9dSmillert
343ba47ec9dSmillertsub split_on_head {
344ba47ec9dSmillert    my($podroot, $htmldir, $splitdirs, $ignore, @splithead) = @_;
345ba47ec9dSmillert    my($pod, $dirname, $filename);
346ba47ec9dSmillert
347ba47ec9dSmillert    # split the files specified in @splithead on =head[1-6] pod directives
348ba47ec9dSmillert    print "splitting files by head.\n" if $verbose && $#splithead >= 0;
349ba47ec9dSmillert    foreach $pod (@splithead) {
350ba47ec9dSmillert	# figure out the directory name and filename
351ba47ec9dSmillert	$pod      =~ s,^([^/]*)$,/$1,;
352f64b279aSmillert	$pod      =~ m,(.*)/(.*?)(\.pod)?$,;
353ba47ec9dSmillert	$dirname  = $1;
354ba47ec9dSmillert	$filename = "$2.pod";
355ba47ec9dSmillert
356ba47ec9dSmillert	# since we are splitting this file it shouldn't be converted.
357ba47ec9dSmillert	push(@$ignore, "$podroot/$dirname/$filename");
358ba47ec9dSmillert
359ba47ec9dSmillert	# split the pod
360ba47ec9dSmillert	splitpod("$podroot/$dirname/$filename", "$podroot/$dirname", $htmldir,
361ba47ec9dSmillert	    $splitdirs);
362ba47ec9dSmillert    }
363ba47ec9dSmillert}
364ba47ec9dSmillert
365ba47ec9dSmillert
366ba47ec9dSmillertsub split_on_item {
367ba47ec9dSmillert    my($podroot, $splitdirs, $ignore, @splititem) = @_;
368ba47ec9dSmillert    my($pwd, $dirname, $filename);
369ba47ec9dSmillert
370ba47ec9dSmillert    print "splitting files by item.\n" if $verbose && $#splititem >= 0;
371ba47ec9dSmillert    $pwd = getcwd();
372e9ce3842Safresh1    my $splitter = rel2abs("$splitpod/splitpod", $pwd);
373e9ce3842Safresh1    my $perl = rel2abs($^X, $pwd);
37479cd0b9aSmillert    foreach my $pod (@splititem) {
375ba47ec9dSmillert	# figure out the directory to split into
376ba47ec9dSmillert	$pod      =~ s,^([^/]*)$,/$1,;
377f64b279aSmillert	$pod      =~ m,(.*)/(.*?)(\.pod)?$,;
378ba47ec9dSmillert	$dirname  = "$1/$2";
379ba47ec9dSmillert	$filename = "$2.pod";
380ba47ec9dSmillert
381ba47ec9dSmillert	# since we are splitting this file it shouldn't be converted.
382ba47ec9dSmillert	push(@$ignore, "$podroot/$dirname.pod");
383ba47ec9dSmillert
384ba47ec9dSmillert	# split the pod
385ba47ec9dSmillert	push(@$splitdirs, "$podroot/$dirname");
3869f11ffb7Safresh1	-d "$podroot/$dirname" and remove_tree("$podroot/$dirname", {safe=>1});
387ba47ec9dSmillert	mkdir("$podroot/$dirname", 0755) ||
388ba47ec9dSmillert		    die "$0: error creating directory $podroot/$dirname: $!\n";
389ba47ec9dSmillert	chdir("$podroot/$dirname") ||
390ba47ec9dSmillert	    die "$0: error changing to directory $podroot/$dirname: $!\n";
391ba47ec9dSmillert	die "$splitter not found. Use '-splitpod dir' option.\n"
392ba47ec9dSmillert	    unless -f $splitter;
39309e75b67Smillert	system($perl, $splitter, "../$filename") &&
394ba47ec9dSmillert	    warn "$0: error running '$splitter ../$filename'"
395ba47ec9dSmillert		 ." from $podroot/$dirname";
396ba47ec9dSmillert    }
397ba47ec9dSmillert    chdir($pwd);
398ba47ec9dSmillert}
399ba47ec9dSmillert
400ba47ec9dSmillert
401ba47ec9dSmillert#
402ba47ec9dSmillert# splitpod - splits a .pod file into several smaller .pod files
403ba47ec9dSmillert#  where a new file is started each time a =head[1-6] pod directive
404ba47ec9dSmillert#  is encountered in the input file.
405ba47ec9dSmillert#
406ba47ec9dSmillertsub splitpod {
407ba47ec9dSmillert    my($pod, $poddir, $htmldir, $splitdirs) = @_;
408ba47ec9dSmillert    my(@poddata, @filedata, @heads);
409ba47ec9dSmillert    my($file, $i, $j, $prevsec, $section, $nextsec);
410ba47ec9dSmillert
411ba47ec9dSmillert    print "splitting $pod\n" if $verbose;
412ba47ec9dSmillert
413ba47ec9dSmillert    # read the file in paragraphs
414ba47ec9dSmillert    $/ = "";
4159f11ffb7Safresh1    open(SPLITIN, '<', $pod) ||
416ba47ec9dSmillert	die "$0: error opening $pod for input: $!\n";
417ba47ec9dSmillert    @filedata = <SPLITIN>;
418ba47ec9dSmillert    close(SPLITIN) ||
419ba47ec9dSmillert	die "$0: error closing $pod: $!\n";
420ba47ec9dSmillert
421ba47ec9dSmillert    # restore the file internally by =head[1-6] sections
422ba47ec9dSmillert    @poddata = ();
423ba47ec9dSmillert    for ($i = 0, $j = -1; $i <= $#filedata; $i++) {
424ba47ec9dSmillert	$j++ if ($filedata[$i] =~ /^\s*=head[1-6]/);
425ba47ec9dSmillert	if ($j >= 0) {
426ba47ec9dSmillert	    $poddata[$j]  = "" unless defined $poddata[$j];
427ba47ec9dSmillert	    $poddata[$j] .= "\n$filedata[$i]" if $j >= 0;
428ba47ec9dSmillert	}
429ba47ec9dSmillert    }
430ba47ec9dSmillert
431ba47ec9dSmillert    # create list of =head[1-6] sections so that we can rewrite
432ba47ec9dSmillert    #  L<> links as necessary.
43379cd0b9aSmillert    my %heads = ();
434ba47ec9dSmillert    foreach $i (0..$#poddata) {
435f64b279aSmillert	$heads{anchorify($1)} = 1 if $poddata[$i] =~ /=head[1-6]\s+(.*)/;
436ba47ec9dSmillert    }
437ba47ec9dSmillert
438ba47ec9dSmillert    # create a directory of a similar name and store all the
439ba47ec9dSmillert    #  files in there
440ba47ec9dSmillert    $pod =~ s,.*/(.*),$1,;	# get the last part of the name
44179cd0b9aSmillert    my $dir = $pod;
442ba47ec9dSmillert    $dir =~ s/\.pod//g;
443ba47ec9dSmillert    push(@$splitdirs, "$poddir/$dir");
4449f11ffb7Safresh1    -d "$poddir/$dir" and remove_tree("$poddir/$dir", {safe=>1});
445ba47ec9dSmillert    mkdir("$poddir/$dir", 0755) ||
4469f11ffb7Safresh1	die "$0: could not create directory $poddir/$dir: $!\n";
447ba47ec9dSmillert
448ba47ec9dSmillert    $poddata[0] =~ /^\s*=head[1-6]\s+(.*)/;
449ba47ec9dSmillert    $section    = "";
450ba47ec9dSmillert    $nextsec    = $1;
451ba47ec9dSmillert
452ba47ec9dSmillert    # for each section of the file create a separate pod file
453ba47ec9dSmillert    for ($i = 0; $i <= $#poddata; $i++) {
454ba47ec9dSmillert	# determine the "prev" and "next" links
455ba47ec9dSmillert	$prevsec = $section;
456ba47ec9dSmillert	$section = $nextsec;
457ba47ec9dSmillert	if ($i < $#poddata) {
458ba47ec9dSmillert	    $poddata[$i+1] =~ /^\s*=head[1-6]\s+(.*)/;
459ba47ec9dSmillert	    $nextsec       = $1;
460ba47ec9dSmillert	} else {
461ba47ec9dSmillert	    $nextsec = "";
462ba47ec9dSmillert	}
463ba47ec9dSmillert
464ba47ec9dSmillert	# determine an appropriate filename (this must correspond with
465ba47ec9dSmillert	#  what pod2html will try and guess)
466ba47ec9dSmillert	# $poddata[$i] =~ /^\s*=head[1-6]\s+(.*)/;
467f64b279aSmillert	$file = "$dir/" . anchorify($section) . ".pod";
468ba47ec9dSmillert
469ba47ec9dSmillert	# create the new .pod file
470ba47ec9dSmillert	print "\tcreating $poddir/$file\n" if $verbose;
4719f11ffb7Safresh1	open(SPLITOUT, '>', "$poddir/$file") ||
472ba47ec9dSmillert	    die "$0: error opening $poddir/$file for output: $!\n";
473ba47ec9dSmillert	$poddata[$i] =~ s,L<([^<>]*)>,
474f64b279aSmillert			defined $heads{anchorify($1)} ? "L<$dir/$1>" : "L<$1>"
475ba47ec9dSmillert		     ,ge;
476ba47ec9dSmillert	print SPLITOUT $poddata[$i]."\n\n";
477ba47ec9dSmillert	print SPLITOUT "=over 4\n\n";
478ba47ec9dSmillert	print SPLITOUT "=item *\n\nBack to L<$dir/\"$prevsec\">\n\n" if $prevsec;
479ba47ec9dSmillert	print SPLITOUT "=item *\n\nForward to L<$dir/\"$nextsec\">\n\n" if $nextsec;
480ba47ec9dSmillert	print SPLITOUT "=item *\n\nUp to L<$dir>\n\n";
481ba47ec9dSmillert	print SPLITOUT "=back\n\n";
482ba47ec9dSmillert	close(SPLITOUT) ||
483ba47ec9dSmillert	    die "$0: error closing $poddir/$file: $!\n";
484ba47ec9dSmillert    }
485ba47ec9dSmillert}
486ba47ec9dSmillert
487ba47ec9dSmillert
488ba47ec9dSmillert#
489ba47ec9dSmillert# installdir - takes care of converting the .pod and .pm files in the
490ba47ec9dSmillert#  current directory to .html files and then installing those.
491ba47ec9dSmillert#
492ba47ec9dSmillertsub installdir {
493ba47ec9dSmillert    my($dir, $recurse, $podroot, $splitdirs, $ignore) = @_;
494ba47ec9dSmillert
495e9ce3842Safresh1    my @dirlist; # directories to recurse on
496e9ce3842Safresh1    my @podlist; # .pod files to install
497e9ce3842Safresh1    my @pmlist;  # .pm files to install
498ba47ec9dSmillert
499ba47ec9dSmillert    # should files in this directory get an index?
500e9ce3842Safresh1    my $doindex = (grep($_ eq "$podroot/$dir", @$splitdirs) ? 0 : 1);
501ba47ec9dSmillert
502ba47ec9dSmillert    opendir(DIR, "$podroot/$dir")
503ba47ec9dSmillert	|| die "$0: error opening directory $podroot/$dir: $!\n";
504ba47ec9dSmillert
505e9ce3842Safresh1    while(readdir DIR) {
506e9ce3842Safresh1	no_upwards($_) or next;
507e9ce3842Safresh1	my $is_dir = -d "$podroot/$dir/$_";
508e9ce3842Safresh1	next if $is_dir and not $recurse;
509b8851fccSafresh1	my $target
510b8851fccSafresh1	    = $is_dir    ? \@dirlist
511b8851fccSafresh1	    : s/\.pod$// ? \@podlist
512b8851fccSafresh1	    : s/\.pm$//  ? \@pmlist
513b8851fccSafresh1	    : undef
514b8851fccSafresh1	    ;
515e9ce3842Safresh1	push @$target, "$dir/$_" if $target;
516e9ce3842Safresh1    }
517ba47ec9dSmillert
518ba47ec9dSmillert    closedir(DIR);
519ba47ec9dSmillert
520e9ce3842Safresh1    if ($^O eq 'VMS') { s/\.dir$//i for @dirlist }
521e9ce3842Safresh1
522ba47ec9dSmillert    # recurse on all subdirectories we kept track of
523ba47ec9dSmillert    foreach $dir (@dirlist) {
524ba47ec9dSmillert	installdir($dir, $recurse, $podroot, $splitdirs, $ignore);
525ba47ec9dSmillert    }
526ba47ec9dSmillert
527ba47ec9dSmillert    # install all the pods we found
52879cd0b9aSmillert    foreach my $pod (@podlist) {
529ba47ec9dSmillert	# check if we should ignore it.
530ad15181aSmillert	next if $pod =~ m(/t/); # comes from a test file
531ad15181aSmillert	next if grep($_ eq "$pod.pod", @$ignore);
532ba47ec9dSmillert
533ba47ec9dSmillert	# check if a .pm files exists too
534f64b279aSmillert	if (grep($_ eq $pod, @pmlist)) {
5357bfa9f44Smillert	    print  "$0: Warning both '$podroot/$pod.pod' and "
5367bfa9f44Smillert		. "'$podroot/$pod.pm' exist, using pod\n";
537ba47ec9dSmillert	    push(@ignore, "$pod.pm");
538ba47ec9dSmillert	}
539ba47ec9dSmillert	runpod2html("$pod.pod", $doindex);
540ba47ec9dSmillert    }
541ba47ec9dSmillert
542ba47ec9dSmillert    # install all the .pm files we found
54379cd0b9aSmillert    foreach my $pm (@pmlist) {
544ba47ec9dSmillert	# check if we should ignore it.
545ad15181aSmillert	next if $pm =~ m(/t/); # comes from a test file
546ba47ec9dSmillert	next if grep($_ eq "$pm.pm", @ignore);
547ba47ec9dSmillert
548ba47ec9dSmillert	runpod2html("$pm.pm", $doindex);
549ba47ec9dSmillert    }
550ba47ec9dSmillert}
551ba47ec9dSmillert
552ba47ec9dSmillert
553ba47ec9dSmillert#
554ba47ec9dSmillert# runpod2html - invokes pod2html to convert a .pod or .pm file to a .html
555ba47ec9dSmillert#  file.
556ba47ec9dSmillert#
557ba47ec9dSmillertsub runpod2html {
558ba47ec9dSmillert    my($pod, $doindex) = @_;
559ba47ec9dSmillert    my($html, $i, $dir, @dirs);
560ba47ec9dSmillert
561ba47ec9dSmillert    $html = $pod;
562ba47ec9dSmillert    $html =~ s/\.(pod|pm)$/.html/g;
563ba47ec9dSmillert
564ba47ec9dSmillert    # make sure the destination directories exist
565ba47ec9dSmillert    @dirs = split("/", $html);
566ba47ec9dSmillert    $dir  = "$htmldir/";
567ba47ec9dSmillert    for ($i = 0; $i < $#dirs; $i++) {
568ba47ec9dSmillert	if (! -d "$dir$dirs[$i]") {
569ba47ec9dSmillert	    mkdir("$dir$dirs[$i]", 0755) ||
570ba47ec9dSmillert		die "$0: error creating directory $dir$dirs[$i]: $!\n";
571ba47ec9dSmillert	}
572ba47ec9dSmillert	$dir .= "$dirs[$i]/";
573ba47ec9dSmillert    }
574ba47ec9dSmillert
575ba47ec9dSmillert    # invoke pod2html
576ba47ec9dSmillert    print "$podroot/$pod => $htmldir/$html\n" if $verbose;
577f64b279aSmillert    Pod::Html::pod2html(
578e2e5c5d3Smillert        "--htmldir=$htmldir",
579ba47ec9dSmillert	"--htmlroot=$htmlroot",
580ba47ec9dSmillert	"--podpath=".join(":", @podpath),
58148950c12Ssthen	"--podroot=$podroot",
582c5dcfd37Smillert	"--header",
583ba47ec9dSmillert	($doindex ? "--index" : "--noindex"),
584ba47ec9dSmillert	"--" . ($recurse ? "" : "no") . "recurse",
585ba47ec9dSmillert	"--infile=$podroot/$pod", "--outfile=$htmldir/$html");
586ba47ec9dSmillert    die "$0: error running $pod2html: $!\n" if $?;
587ba47ec9dSmillert}
588