1#!/usr/bin/perl -w 2 3use strict; 4use vars qw($Quiet); 5use File::Spec; 6use FindBin; 7use Text::Wrap; 8use Getopt::Long; 9 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 (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 '$a = shift; exit($a =~ 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 tr/\015//d; 210 if (s/^=head1 (NAME)\s*/=head2 /) { 211 unhead1(); 212 $OUT .= "\n\n=head2 "; 213 $_ = <$fh>; 214 # Remove svn keyword expansions from the Perl FAQ 215 s/ \(\$Revision: \d+ \$\)//g; 216 if ( /^\s*\Q$pod\E\b/ ) { 217 s/$pod\.pm/$pod/; # '.pm' in NAME !? 218 } else { 219 s/^/$pod, /; 220 } 221 } 222 elsif (s/^=head1 (.*)/=item $1/) { 223 unhead2(); 224 $OUT .= "=over 4\n\n" unless $inhead1; 225 $inhead1 = 1; 226 $_ .= "\n"; 227 } 228 elsif (s/^=head2 (.*)/=item $1/) { 229 unitem(); 230 $OUT .= "=over 4\n\n" unless $inhead2; 231 $inhead2 = 1; 232 $_ .= "\n"; 233 } 234 elsif (s/^=item ([^=].*)/$1/) { 235 next if $pod eq 'perldiag'; 236 s/^\s*\*\s*$// && next; 237 s/^\s*\*\s*//; 238 s/\n/ /g; 239 s/\s+$//; 240 next if /^[\d.]+$/; 241 next if $pod eq 'perlmodlib' && /^ftp:/; 242 $OUT .= ", " if $initem; 243 $initem = 1; 244 s/\.$//; 245 s/^-X\b/-I<X>/; 246 } 247 else { 248 unhead1() if /^=cut\s*\n/; 249 next; 250 } 251 $OUT .= $_; 252 } 253} 254 255sub unhead1 { 256 unhead2(); 257 if ($inhead1) { 258 $OUT .= "\n\n=back\n\n"; 259 } 260 $inhead1 = 0; 261} 262 263sub unhead2 { 264 unitem(); 265 if ($inhead2) { 266 $OUT .= "\n\n=back\n\n"; 267 } 268 $inhead2 = 0; 269} 270 271sub unitem { 272 if ($initem) { 273 $OUT .= "\n\n"; 274 } 275 $initem = 0; 276} 277 278# Local variables: 279# cperl-indent-level: 4 280# indent-tabs-mode: nil 281# End: 282# 283# ex: set ts=8 sts=4 sw=4 et: 284