"Fossies" - the Fresh Open Source Software Archive

Member "perl-5.32.1/installhtml" (18 Dec 2020, 17805 Bytes) of package /linux/misc/perl-5.32.1.tar.xz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

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