1#!/usr/bin/perl -w 2 3use strict; 4use File::Spec; 5use FindBin; 6use Text::Wrap; 7use Getopt::Long; 8 9our $Quiet; 10no locale; 11 12# Assumption is that we're either already being run from the top level (*nix, 13# VMS), or have absolute paths in @INC (Win32, pod/Makefile) 14BEGIN { 15 my $Top = File::Spec->catdir($FindBin::Bin, File::Spec->updir); 16 chdir $Top or die "Can't chdir to $Top: $!"; 17 require './Porting/pod_lib.pl'; 18} 19 20die "$0: Usage: $0 [--quiet]\n" 21 unless GetOptions ('q|quiet' => \$Quiet) && !@ARGV; 22 23my $state = get_pod_metadata(0, sub { warn @_ if @_ }, 'pod/perltoc.pod'); 24 25my $found = pods_to_install(); 26 27my_die "Can't find any pods!\n" unless %$found; 28 29# Accumulating everything into a lexical before writing to disk dates from the 30# time when this script also provided the functionality of regen/pod_rules.pl 31# and this code was in a subroutine do_toc(). In turn, the use of a file scoped 32# lexical instead of a parameter or return value is because the code dates back 33# further still, and used *only* to create pod/perltoc.pod by printing direct 34 35my $OUT; 36my $roffitall; 37 38($_= <<"EOPOD2B") =~ s/^\t//gm and $OUT .= $_; 39 40 # !!!!!!! DO NOT EDIT THIS FILE !!!!!!! 41 # This file is autogenerated by buildtoc from all the other pods. 42 # Edit those files and run $0 to effect changes. 43 44 =encoding UTF-8 45 46 =head1 NAME 47 48 perltoc - perl documentation table of contents 49 50 =head1 DESCRIPTION 51 52 This page provides a brief table of contents for the rest of the Perl 53 documentation set. It is meant to be scanned quickly or grepped 54 through to locate the proper section you're looking for. 55 56 =head1 BASIC DOCUMENTATION 57 58EOPOD2B 59 60# All the things in the master list that happen to be pod filenames 61foreach (grep {!$_->[2]{toc_omit}} @{$state->{master}}) { 62 $roffitall .= " \$mandir/$_->[0].1 \\\n"; 63 podset($_->[0], $_->[1]); 64} 65 66foreach my $type (qw(PRAGMA MODULE)) { 67 ($_= <<"EOPOD2B") =~ s/^\t//gm and $OUT .= $_; 68 69 70 71 =head1 $type DOCUMENTATION 72 73EOPOD2B 74 75 foreach my $name (sort keys %{$found->{$type}}) { 76 $roffitall .= " \$libdir/$name.3 \\\n"; 77 podset($name, $found->{$type}{$name}); 78 } 79} 80 81$_= <<"EOPOD2B"; 82 83 84 =head1 AUXILIARY DOCUMENTATION 85 86 Here should be listed all the extra programs' documentation, but they 87 don't all have manual pages yet: 88 89 =over 4 90 91EOPOD2B 92 93$_ .= join "\n", map {"\t=item $_\n"} @{$state->{aux}}; 94$_ .= <<"EOPOD2B" ; 95 96 =back 97 98 =head1 AUTHOR 99 100 Larry Wall <F<larry\@wall.org>>, with the help of oodles 101 of other folks. 102 103 104EOPOD2B 105 106s/^\t//gm; 107$OUT .= "$_\n"; 108 109$OUT =~ s/\n\s+\n/\n\n/gs; 110$OUT =~ s/\n{3,}/\n\n/g; 111 112$OUT =~ s/([^\n]+)/wrap('', '', $1)/ge; 113 114write_or_die('pod/perltoc.pod', $OUT); 115 116write_or_die('pod/roffitall', <<'EOH' . $roffitall . <<'EOT'); 117#!/bin/sh 118# 119# Usage: roffitall [-nroff|-psroff|-groff] 120# 121# Authors: Tom Christiansen, Raphael Manfredi 122 123me=roffitall 124tmp=. 125 126if test -f ../config.sh; then 127 . ../config.sh 128fi 129 130mandir=$installman1dir 131libdir=$installman3dir 132 133test -d $mandir || mandir=/usr/new/man/man1 134test -d $libdir || libdir=/usr/new/man/man3 135 136case "$1" in 137-nroff) cmd="nroff -man"; ext='txt';; 138-psroff) cmd="psroff -t"; ext='ps';; 139-groff) cmd="groff -man"; ext='ps';; 140*) 141 echo "Usage: roffitall [-nroff|-psroff|-groff]" >&2 142 exit 1 143 ;; 144esac 145 146toroff=` 147 echo \ 148EOH 149 | perl -ne 'map { -r && print "$_ " } split'` 150 151 # Bypass internal shell buffer limit -- can't use case 152 if perl -e '$x = shift; exit($x =~ m|/|)' $toroff; then 153 echo "$me: empty file list -- did you run install?" >&2 154 exit 1 155 fi 156 157 #psroff -t -man -rC1 -rD1 -rF1 > $tmp/PerlDoc.ps 2>$tmp/PerlTOC.raw 158 #nroff -man -rC1 -rD1 -rF1 > $tmp/PerlDoc.txt 2>$tmp/PerlTOC.nr.raw 159 160 # First, create the raw data 161 run="$cmd -rC1 -rD1 -rF1 >$tmp/PerlDoc.$ext 2>$tmp/PerlTOC.$ext.raw" 162 echo "$me: running $run" 163 eval $run $toroff 164 165 #Now create the TOC 166 echo "$me: parsing TOC" 167 perl rofftoc $tmp/PerlTOC.$ext.raw > $tmp/PerlTOC.tmp.man 168 run="$cmd $tmp/PerlTOC.tmp.man >$tmp/PerlTOC.$ext" 169 echo "$me: running $run" 170 eval $run 171 172 # Finally, recreate the Doc, without the blank page 0 173 run="$cmd -rC1 -rD1 >$tmp/PerlDoc.$ext 2>$tmp/PerlTOC.$ext.raw" 174 echo "$me: running $run" 175 eval $run $toroff 176 rm -f $tmp/PerlTOC.tmp.man $tmp/PerlTOC.$ext.raw 177 echo "$me: leaving you with $tmp/PerlDoc.$ext and $tmp/PerlTOC.$ext" 178EOT 179 180exit(0); 181 182# Below are all the auxiliary routines for generating perltoc.pod 183 184my ($inhead1, $inhead2, $initem); 185 186sub podset { 187 my ($pod, $file) = @_; 188 189 open my $fh, '<:', $file or my_die "Can't open file '$file' for $pod: $!"; 190 191 local *_; 192 my $found_pod; 193 while (<$fh>) { 194 if (/^=head1\s+NAME\b/) { 195 ++$found_pod; 196 last; 197 } 198 } 199 200 unless ($found_pod) { 201 warn "$0: NOTE: cannot find '=head1 NAME' in:\n $file\n" unless $Quiet; 202 return; 203 } 204 205 seek $fh, 0, 0 or my_die "Can't rewind file '$file': $!"; 206 local $/ = ''; 207 208 while(<$fh>) { 209 s/\r$//; 210 if (s/^=head1 (NAME)\s*/=head2 /) { 211 unhead1(); 212 $OUT .= "\n\n=head2 "; 213 $_ = <$fh>; 214 last unless defined $_; 215 # Remove svn keyword expansions from the Perl FAQ 216 s/ \(\$Revision: \d+ \$\)//g; 217 if ( /^\s*\Q$pod\E\b/ ) { 218 s/$pod\.pm/$pod/; # '.pm' in NAME !? 219 } else { 220 s/^/$pod, /; 221 } 222 } 223 elsif (s/^=head1 (.*)/=item $1/) { 224 unhead2(); 225 $OUT .= "=over 4\n\n" unless $inhead1; 226 $inhead1 = 1; 227 $_ .= "\n"; 228 } 229 elsif (s/^=head2 (.*)/=item $1/) { 230 unitem(); 231 $OUT .= "=over 4\n\n" unless $inhead2; 232 $inhead2 = 1; 233 $_ .= "\n"; 234 } 235 elsif (s/^=item ([^=].*)/$1/) { 236 next if $pod eq 'perldiag'; 237 s/^\s*\*\s*$// && next; 238 s/^\s*\*\s*//; 239 s/\n/ /g; 240 s/\s+$//; 241 # make sure inner links include the target page 242 s{L<(?:[^|>]+\|)?\K/}{$pod/}g; 243 next if /^[\d.]+$/; 244 next if $pod eq 'perlmodlib' && /^ftp:/; 245 $OUT .= ", " if $initem; 246 $initem = 1; 247 s/\.$//; 248 s/^-X\b/-I<X>/; 249 } 250 else { 251 unhead1() if /^=cut\s*\n/; 252 next; 253 } 254 $OUT .= $_; 255 } 256} 257 258sub unhead1 { 259 unhead2(); 260 if ($inhead1) { 261 $OUT .= "\n\n=back\n\n"; 262 } 263 $inhead1 = 0; 264} 265 266sub unhead2 { 267 unitem(); 268 if ($inhead2) { 269 $OUT .= "\n\n=back\n\n"; 270 } 271 $inhead2 = 0; 272} 273 274sub unitem { 275 if ($initem) { 276 $OUT .= "\n\n"; 277 } 278 $initem = 0; 279} 280 281=head1 NAME 282 283pod/buildtoc - Generate table of contents 284 285=head1 DESCRIPTION 286 287This program generates a table of contents for the documentation included in the Perl core distribution. This table of contents takes two forms: 288 289=over 4 290 291=item 1 F<pod/perltoc.pod> 292 293A file in Perl's Plain Old Documentation (POD) format found in the F<pod/> directory in the core distribution. Once Perl is installed, this file becomes accessible system-wide via C<perldoc perltoc>. 294 295=item 2 F<pod/roffitall> 296 297A shell script originally written by Tom Christiansen and Raphael Manfredi, also found in the F<pod/> directory, which can be used to translate Perl documentation into F<man> pages. 298 299=back 300 301=head1 USAGE 302 303This program will typically B<not> need to be called directly by a user. Rather, it is one of the last commands invoked during C<make test_prep>: 304 305 ./perl -Ilib -I. -f pod/buildtoc -q 306 307The only command-line switch is C<-q|--quiet>, which quiets some non-critical warnings. 308 309=head2 Diagnosing Problems 310 311This program C<require>s F<Porting/pod_lib.pl> and makes use of several subroutines found in that file: C<get_pod_metadata()> and C<pods_to_install()> in particular. Consequently, any warnings or exceptions you see when this program is running may be being passed through from those subroutines. You may have to (a) examine those subroutines and/or (b) run that program from the command-line to fully understand what is causing such warnings or exceptions. 312 313=head2 AUTHORS and MAINTENANCE 314 315This program was introduced into the Perl 5 core distribution by Andy Dougherty, based on earlier work by Tom Christiansen. It is maintained by the Perl 5 Porters. 316 317=cut 318 319# ex: set ts=8 sts=4 sw=4 et: 320