#!/usr/bin/perl -w =pod =head1 NAME cvspod - Extract POD from cvs =head1 SYNOPSIS cvspod [B<-v>] [B<-d> CVSROOT] I I =head1 DESCRIPTION cvspod will checkout the specified I from cvs, and produce HTML formatted documentation for each file in the module which contains POD markup. The HTML will be in the form of a tree, rooted at I. An index file will also be produced. =head1 OPTIONS =over 4 =item B<-v> Run in verbose mode. =item B<-d> Specify the path to the CVSROOT. May be used in lieu of a CVSROOT environment variable. =back =head1 SEE ALSO cvs(1), pod2html(1). =head1 AUTHOR Dominic Mitchell Edom@happygiraffe.netE. =head1 VERSION @(#) $Id: cvspod.pl,v 1.1 2001/07/30 21:29:50 dom Exp $ =head1 BUGS =over 4 =item * Does not ignore .pm files for which a .pod file exists. =back =cut use strict; use File::Path; use Getopt::Std; use Pod::Html; my ($me) = $0 =~ m/([^\/]+)$/; my %opt; my $tmpdir; #----------------------------------------------------------------------- sub usage { die "usage: $me [-v] [-d CVSROOT] module destdir\n"; } sub cleanup { rmtree $tmpdir if $tmpdir; } # Pull this cvs module out and return the list of files it has # extracted. sub getmodule { my $module = shift; my @files; open CVS, "cvs -d $opt{d} get $module |" or die "popen(cvs): $!\n"; while () { chomp; push @files, (split)[1]; } close CVS; return @files; } # Which of the files that cvs returned actually contain pod directives? sub findpods { my @files = @_; my %pods; foreach my $f (@files) { my @podlines; open F, $f or die "open($f): $!\n"; @podlines = grep { m/^=(head1|pod)/ } ; close F; $pods{$f} = @podlines ? 1 : 0; } return %pods; } # Create a HTML file in $destdir for each pod. sub makepods { my ($destdir, %pods) = @_; $| = 1 if $opt{v}; foreach my $p (grep { $pods{$_} } keys %pods) { my ($path) = ($p =~ m/(.*)\//); $path = "$destdir/$path"; mkpath $path, 0, 0755 unless -d $path; print ">" if $opt{v}; pod2html( "--infile" => $p, "--outfile" => "$destdir/$p.html", "--noindex"); } print "\n" if $opt{v}; } # Create a html table of the list, in $cols columns. sub maketable { my ($cols, @data) = @_; my $table = "\n"; my @tuple; while (@tuple = splice(@data, 0, $cols)) { @tuple = map { "" } @tuple; $table .= "@tuple\n"; } $table .= "
$_
\n"; return $table; } # Create an index.html file of all pods in $module. sub makeindex { my ($module, $destdir, %pods) = @_; my @htmllist; my @podfiles = sort grep { $pods{$_} } keys %pods; my @nonpodfiles = sort grep { ! $pods{$_} } keys %pods; foreach my $p (@podfiles) { my $outp = "$p.html"; push @htmllist, "
  • $p
  • \n"; } # Produce a 1 column table of non-pod files. 3 cols was too big. :( my $table = maketable(1, @nonpodfiles); open INDEX, "> $destdir/index.html" or die "open($destdir/index.html): $!\n"; print INDEX < Documentation for $module

    Documentation for $module

      @htmllist

    The following files had no POD documentation:

    $table EOF close INDEX; } #----------------------------------------------------------------------- $opt{d} = $ENV{CVSROOT}; getopts("dv", \%opt) or usage; die "CVSROOT not set\n" unless $opt{d}; usage unless @ARGV == 2; #----------------------------------------------------------------------- $tmpdir = $ENV{TMPDIR} || "/tmp"; $tmpdir .= "/$me.$$"; mkdir $tmpdir, 0700 or die "mkdir($tmpdir): $!\n"; chdir $tmpdir; # Ensure we don't leave crap behind. END { cleanup } # Not sure if END gets called if we get a signal, so... $SIG{HUP} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = \&cleanup; #----------------------------------------------------------------------- my ($module, $destdir) = @ARGV; if (-d $destdir) { rmtree $destdir; mkdir $destdir, 0755 or die "mkdir($destdir): $!\n"; } print "===> Extracting $module from cvs...\n" if $opt{v}; my @files = getmodule $module; print "===> Finding files containing POD markup...\n" if $opt{v}; my %pods = findpods @files; print "===> Creating HTML files from POD files...\n" if $opt{v}; makepods $destdir, %pods; print "===> Creating index HTML file...\n" if $opt{v}; makeindex $module, $destdir, %pods; #----------------------------------------------------------------------- # vim: set ai sw=4 et :