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