1package Pod::Tree::PerlPod; 2use 5.006; 3use strict; 4use warnings; 5use File::Find; 6use HTML::Stream; 7use IO::File; 8use Pod::Tree::HTML; 9use Pod::Tree::PerlUtil; 10 11our $VERSION = '1.31'; 12 13use base qw(Pod::Tree::PerlUtil); 14 15sub new { 16 my ( $class, $perl_dir, $html_dir, $link_map, %options ) = @_; 17 18 my %defaults = ( 19 col_width => 20, 20 bgcolor => '#ffffff', 21 text => '#000000' 22 ); 23 24 my $options = { %defaults, %options, link_map => $link_map }; 25 26 my %special = map { $_ => 1 } qw(pod/perl pod/perlfunc); 27 28 my $perl_pod = { 29 perl_dir => $perl_dir, 30 html_dir => $html_dir, 31 top_page => 'pod.html', 32 special => \%special, 33 options => $options 34 }; 35 36 bless $perl_pod, $class; 37} 38 39sub scan { 40 my $perl_pod = shift; 41 $perl_pod->report1("scan"); 42 my $perl_dir = $perl_pod->{perl_dir}; 43 44 File::Find::find( 45 { 46 wanted => sub { $perl_pod->_scan }, # Perl rocks! 47 no_chdir => 1 48 }, 49 $perl_dir 50 ); 51} 52 53sub _scan { 54 my $perl_pod = shift; 55 my $source = $File::Find::name; 56 my $dest = $source; 57 my $perl_dir = $perl_pod->{perl_dir}; 58 my $html_dir = $perl_pod->{html_dir}; 59 $dest =~ s(^$perl_dir)($html_dir); 60 61 -d $source and $perl_pod->_scan_dir($dest); 62 -f $source and $perl_pod->_scan_file( $source, $dest ); 63} 64 65sub _scan_dir { 66 my ( $perl_pod, $dir ) = @_; 67 68 $dir =~ m(/ext$) and do # extensions are handled by Pod::Tree::PerlLib 69 { 70 $File::Find::prune = 1; 71 return; 72 }; 73 74 -d $dir 75 or mkdir $dir, 0755 76 or die "Pod::Tree::PerlPod::_scan_dir: Can't mkdir $dir: $!\n"; 77} 78 79sub _scan_file { 80 my ( $perl_pod, $source, $dest ) = @_; 81 82 $source =~ m( (\w+)\.pod$ )x or return; 83 84 my $link = $source; 85 my $perl_dir = $perl_pod->{perl_dir}; 86 $link =~ s(^$perl_dir/)(); 87 $link =~ s( \.pod$ )()x; 88 $perl_pod->report2($link); 89 90 my $name = ( split m(/), $link )[-1]; 91 my $desc = $perl_pod->get_description($source); 92 93 $dest =~ s( \.\w+$ )(.html)x; 94 95 my $pod = { 96 name => $name, # perldata 97 desc => $desc, # Perl data types 98 link => $link, # pod/perldata 99 source => $source, # .../perl5.5.650/pod/perldata.pod 100 dest => $dest 101 }; # .../public_html/perl/pod/perldata.html 102 103 $perl_pod->{pods}{$link} = $pod; 104 $perl_pod->{options}{link_map}->add_page( $name, $link ); 105} 106 107sub index { 108 my $perl_pod = shift; 109 $perl_pod->report1("index"); 110 my $html_dir = $perl_pod->{html_dir}; 111 my $top_page = $perl_pod->{top_page}; 112 my $dest = "$html_dir/$top_page"; 113 114 my $fh = IO::File->new(">$dest"); 115 defined $fh or die "Pod::Tree::PerlPod::index: Can't open $dest: $!\n"; 116 my $stream = HTML::Stream->new($fh); 117 118 my $options = $perl_pod->{options}; 119 my $bgcolor = $options->{bgcolor}; 120 my $text = $options->{text}; 121 my $title = "Perl PODs"; 122 123 $stream->HTML->HEAD; 124 $stream->TITLE->text($title)->_TITLE; 125 $stream->_HEAD->BODY( BGCOLOR => $bgcolor, TEXT => $text ); 126 $stream->H1->t($title)->_H1; 127 128 $perl_pod->_emit_entries($stream); 129 130 $stream->_BODY->_HTML; 131} 132 133sub get_top_entry { 134 my $perl_dist = shift; 135 136 +{ 137 URL => $perl_dist->{top_page}, 138 description => 'PODs' 139 }; 140} 141 142sub _emit_entries { 143 my ( $perl_pod, $stream ) = @_; 144 my $pods = $perl_pod->{pods}; 145 my $options = $perl_pod->{options}; 146 my $col_width = $options->{col_width}; 147 148 $stream->PRE; 149 150 $pods = $perl_pod->{pods}; 151 for my $link ( sort keys %$pods ) { 152 my $pad = $col_width - length $link; 153 $stream->A( HREF => "$link.html" )->t($link)->_A; 154 155 $pad < 1 and do { 156 $stream->nl; 157 $pad = $col_width; 158 }; 159 160 $stream->t( ' ' x $pad, $pods->{$link}{desc} )->nl; 161 } 162 163 $stream->_PRE; 164} 165 166sub translate { 167 my $perl_pod = shift; 168 $perl_pod->report1("translate"); 169 my $pods = $perl_pod->{pods}; 170 my $special = $perl_pod->{special}; 171 172 for my $link ( sort keys %$pods ) { 173 $special->{$link} and next; 174 $perl_pod->report2($link); 175 $perl_pod->_translate($link); 176 } 177} 178 179sub _translate { 180 my ( $perl_pod, $link ) = @_; 181 182 my $pod = $perl_pod->{pods}{$link}; 183 my $source = $pod->{source}; 184 my $dest = $pod->{dest}; 185 my $options = $perl_pod->{options}; 186 187 my @path = split m(\/), $link; 188 my $depth = @path - 1; 189 $options->{link_map}->set_depth($depth); 190 191 my $html = Pod::Tree::HTML->new( $source, $dest, %$options ); 192 $html->translate; 193} 194 1951 196 197__END__ 198 199=head1 NAME 200 201Pod::Tree::PerlPod - translate Perl PODs to HTML 202 203=head1 SYNOPSIS 204 205 $perl_map = Pod::Tree::PerlMap->new; 206 $perl_pod = Pod::Tree::PerlPod->new( $perl_dir, $HTML_dir, $perl_map, %opts ); 207 208 $perl_pod->scan; 209 $perl_pod->index; 210 $perl_pod->translate; 211 212 $top = $perl_pod->get_top_entry; 213 214=head1 DESCRIPTION 215 216C<Pod::Tree::PerlPod> translates Perl PODs to HTML. 217It does a recursive subdirectory search through I<$perl_dir> to find PODs. 218 219C<Pod::Tree::PerlPod> generates a top-level index of all the PODs 220that it finds, and writes it to I<HTML_dir>C</pod.html>. 221 222C<Pod::Tree::PerlPod> generates and uses an index of the PODs 223that it finds to construct HTML links. 224Other modules can also use this index. 225 226=head1 METHODS 227 228=over 4 229 230=item I<$perl_pod> = C<new> C<Pod::Tree::PerlPod> I<$perl_dir>, 231I<$HTML_dir>, I<$perl_map>, I<%options> 232 233Creates and returns a new C<Pod::Tree::PerlPod> object. 234 235I<$perl_dir> is the root of the Perl source tree. 236 237I<$HTML_dir> is the directory where HTML files will be written. 238 239I<$perl_map> maps POD names to URLs. 240 241I<%options> are passed through to C<Pod::Tree::HTML>. 242 243=item I<$perl_pod>->C<scan>; 244 245Does a recursive subdirectory search through I<$perl_dir> to 246locate PODs. Each POD that is located is entered into I<$perl_map>. 247 248=item I<$perl_pod>->C<index> 249 250Generates a top-level index of all the PODs. 251The index is written to I<HTML_dir>C</pod.html>. 252 253=item I<$perl_pod>->C<translate> 254 255Translates each POD found by C<scan> to HTML. 256The HTML pages are written to I<HTML_dir>, 257in a subdirectory hierarchy that mirrors the 258the Perl source distribution. 259 260=item I<$perl_pod>->C<get_top_entry> 261 262Returns a hash reference of the form 263 264 { URL => $URL, 265 description => $description } 266 267C<Pod::Tree::PerlTop> uses this to build a top-level index of all the 268Perl PODs. 269 270=back 271 272=head1 LINKING 273 274C<Pod::Tree::PerlPod> indexes PODs by the base name of the POD file. 275To link to F<perlsub.pod>, write 276 277 L<perlsub> 278 279=head1 REQUIRES 280 281 5.005; 282 File::Find; 283 HTML::Stream; 284 IO::File; 285 Pod::Tree::HTML; 286 Pod::Tree::PerlUtil; 287 288=head1 EXPORTS 289 290Nothing. 291 292=head1 SEE ALSO 293 294L<C<Pod::Tree::HTML>>, L<C<Pod::Tree::PerlMap>>, 295 296=head1 AUTHOR 297 298Steven McDougall, swmcd@world.std.com 299 300=head1 COPYRIGHT 301 302Copyright (c) 2000 by Steven McDougall. This module is free software; 303you can redistribute it and/or modify it under the same terms as Perl. 304