#!/usr/local/bin/perl
use strict;
my %Options = (bgcolor => '#ffffff',
text => '#000000',
hr => 1,
toc => 1 );
my $ok = GetOptions(\%Options, "base:s",
"css:s",
"bgcolor:s",
"empty",
"index:s",
"module",
"text:s",
"toc!",
"hr:i");
$ok or die "Bad command line options\n";
my %Index;
my @Dirs;
my($PodDir, $HTMLDir) = @ARGV;
$HTMLDir or die "pods2html PodDir HTMLDir\n";
$PodDir = canonpath File::Spec $PodDir;
$HTMLDir = rel2abs File::Spec $HTMLDir;
mkpath($HTMLDir);
umask 0022;
find({ wanted => \&Translate,
no_chdir => 1 }, $PodDir);
Index () if $Options{index};
Cleanup() unless $Options{empty};
sub Translate
{
-d and &Translate_Dir;
-f and &Translate_POD;
}
sub MkDir
{
my $dir = shift;
-d $dir and return;
mkdir $dir, 0755 or die "Can't mkdir $dir: $!\n";
push @Dirs, $dir;
}
sub Translate_Dir
{
my $dir = $File::Find::name;
if ($HTMLDir eq rel2abs File::Spec $dir)
{
$File::Find::prune = 1;
return;
}
if ($Options{module} and ( m(/t$) or m(/blib$) ) )
{
$File::Find::prune = 1;
return;
}
$dir =~ s/^$PodDir/$HTMLDir/o;
-d $dir or MkDir $dir;
print "$File::Find::name\n";
}
sub Translate_POD
{
m( \.(pm|pod)$ )x or return;
my $source = $File::Find::name;
Hidden($source) and return;
print "$source\n";
my $dest = $source;
$dest =~ s/^$PodDir/$HTMLDir/;
$dest =~ s( \.\w+$ )(.html)x;
my $depth = Depth($source);
my $pod = $source;
$pod =~ s(^$PodDir/)();
$pod =~ s( \.\w+$ )()x;
$Index{$pod} = 1;
my $html = new Pod::Tree::HTML $source, $dest, %Options;
$html->set_options(depth => $depth);
$html->translate;
}
sub Hidden
{
my $source = shift;
$source =~ m(\.pm$) or return 0;
$source =~ s(\.pm$)(.pod);
-e $source
}
sub Depth
{
my $source = shift;
my $tree = new Pod::Tree;
$tree->load_file($source);
my $children = $tree->get_root->get_children;
my @pod = grep { is_pod $_ } @$children;
my $node1 = $pod[1];
$node1 or return '';
my $text = $node1->get_deep_text;
my($name) = split m(\s+-+\s+), $text;
$name =~ s(^\s+)();
my @name = split /::/, $name;
@name-1
}
sub Index
{
my $index = "$HTMLDir/index.html";
my $fh = new IO::File ">$index";
defined $fh or die "Can't open $index: $!\n";
my $stream = new HTML::Stream $fh;
my $title = $Options{index};
my $bgcolor = $Options{bgcolor};
my $text = $Options{text};
$stream-> HTML->HEAD;
$stream-> TITLE->text($title)->_TITLE;
$stream->_HEAD
-> BODY(BGCOLOR => $bgcolor, TEXT => $text);
$stream->H1->t($title)->_H1;
Emit_Entries($stream);
$stream->_BODY->_HTML;
}
sub Emit_Entries
{
my $stream = shift;
$stream->UL;
for my $entry (sort keys %Index)
{
$stream->LI
->A(HREF => "$entry.html")
->t($entry)
->_A
->_LI;
}
$stream->_UL;
}
sub Cleanup
{
while (@Dirs)
{
my $dir = pop @Dirs;
rmdir $dir; # does nothing unless $dir is empty
}
}
__END__
=head1 NAME
pods2html - translate a tree of PODs to HTML
=head1 SYNOPSIS
C<pods2html>
[C<--base> I<url>]
[C<--css> I<url>]
[C<--empty>]
[C<--index> I<title>]
[C<--module>]
[C<-->[C<no>]C<toc>] [C<--hr> I<level>]
[C<--bgcolor> I<#rrggbb>] [C<--text> I<#rrggbb>]
I<PODdir> I<HTMLdir>
=head1 DESCRIPTION
C<pods2html> finds all the F<.pod> and F<.pm> files in the
directory tree rooted at I<PODdir>.
It translates each POD to HTML,
and writes it to a parallel directory tree rooted at I<HTMLdir>
It makes the HTML files world-readable.
=head1 OPTIONS
=over 4
=item C<--base> I<url>
Specifies a base URL for HTML links.
=item C<--css> I<url>
Specifies a Cascanding Style Sheet for the generated HTML pages.
=item C<--empty>
Creates HTML files for empty PODs.
If this options is not provided, then no HTML file is created for empty PODs.
=item C<--index> I<title>
Writes an index of all the HTML files to I<HTMLDir>F</index.html>.
I<title> is used as the title of the index page.
=item C<--module>
Ignores files in directories named F<t/> and F<blib/>.
Useful for translating PODs in a module development directory.
=item C<-->[C<no>]C<toc>
Includes or omits the table of contents.
Default is to include the TOC.
=item C<--hr> I<level>
Controls the profusion of horizontal lines in the output, as follows:
level horizontal lines
0 none
1 between TOC and body
2 after each =head1
3 after each =head1 and =head2
Default is level 1.
=item C<--bgcolor> I<#rrggbb>
Set the background color to I<#rrggbb>.
Default is white.
=item C<--text> I<#rrggbb>
Set the text color to I<#rrggbb>.
Default is black.
=back
=head1 REQUIRES
L<C<Pod::Tree::HTML>>,
L<C<HTML::Stream>>
=head1 BUGS
The recursion check doesn't work on Win32.
This means that the program will enter an infinite recursion
if I<HTMLdir> is a subdirectory of I<PODdir>.
=head1 SEE ALSO
L<C<pod2html>>,
L<C<Pod::Tree::HTML>>
=head1 AUTHOR
Steven McDougall, <swmcd@world.std.com>
=head1 COPYRIGHT
Copyright (c) 1999-2006 by Steven McDougall. This program is free software;
you can redistribute it and/or modify it under the same terms as Perl.