1b39c5158Smillert
2b39c5158Smillertrequire 5;
3b39c5158Smillertpackage Pod::Simple::HTMLBatch;
4b39c5158Smillertuse strict;
5b39c5158Smillertuse vars qw( $VERSION $HTML_RENDER_CLASS $HTML_EXTENSION
6b39c5158Smillert $CSS $JAVASCRIPT $SLEEPY $SEARCH_CLASS @ISA
7b39c5158Smillert);
8*eac174f2Safresh1$VERSION = '3.43';
9b39c5158Smillert@ISA = ();  # Yup, we're NOT a subclass of Pod::Simple::HTML!
10b39c5158Smillert
11b39c5158Smillert# TODO: nocontents stylesheets. Strike some of the color variations?
12b39c5158Smillert
13b39c5158Smillertuse Pod::Simple::HTML ();
14b39c5158SmillertBEGIN {*esc = \&Pod::Simple::HTML::esc }
15b39c5158Smillertuse File::Spec ();
16b39c5158Smillert
17b39c5158Smillertuse Pod::Simple::Search;
18b39c5158Smillert$SEARCH_CLASS ||= 'Pod::Simple::Search';
19b39c5158Smillert
20b39c5158SmillertBEGIN {
21b39c5158Smillert  if(defined &DEBUG) { } # no-op
22b39c5158Smillert  elsif( defined &Pod::Simple::DEBUG ) { *DEBUG = \&Pod::Simple::DEBUG }
23b39c5158Smillert  else { *DEBUG = sub () {0}; }
24b39c5158Smillert}
25b39c5158Smillert
26b39c5158Smillert$SLEEPY = 1 if !defined $SLEEPY and $^O =~ /mswin|mac/i;
27b39c5158Smillert# flag to occasionally sleep for $SLEEPY - 1 seconds.
28b39c5158Smillert
29b39c5158Smillert$HTML_RENDER_CLASS ||= "Pod::Simple::HTML";
30b39c5158Smillert
31b39c5158Smillert#
32b39c5158Smillert# Methods beginning with "_" are particularly internal and possibly ugly.
33b39c5158Smillert#
34b39c5158Smillert
35b39c5158SmillertPod::Simple::_accessorize( __PACKAGE__,
36b39c5158Smillert 'verbose', # how verbose to be during batch conversion
37b39c5158Smillert 'html_render_class', # what class to use to render
38b39c5158Smillert 'search_class', # what to use to search for POD documents
39b39c5158Smillert 'contents_file', # If set, should be the name of a file (in current directory)
40b39c5158Smillert                  # to write the list of all modules to
41b39c5158Smillert 'index', # will set $htmlpage->index(...) to this (true or false)
42b39c5158Smillert 'progress', # progress object
43b39c5158Smillert 'contents_page_start',  'contents_page_end',
44b39c5158Smillert
45b39c5158Smillert 'css_flurry', '_css_wad', 'javascript_flurry', '_javascript_wad',
46b39c5158Smillert 'no_contents_links', # set to true to suppress automatic adding of << links.
47b39c5158Smillert '_contents',
48b39c5158Smillert);
49b39c5158Smillert
50b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
51b39c5158Smillert# Just so we can run from the command line more easily
52b39c5158Smillertsub go {
53b39c5158Smillert  @ARGV == 2 or die sprintf(
54b39c5158Smillert    "Usage: perl -M%s -e %s:go indirs outdir\n  (or use \"\@INC\" for indirs)\n",
55b39c5158Smillert    __PACKAGE__, __PACKAGE__,
56b39c5158Smillert  );
57b39c5158Smillert
58b39c5158Smillert  if(defined($ARGV[1]) and length($ARGV[1])) {
59b39c5158Smillert    my $d = $ARGV[1];
60b39c5158Smillert    -e $d or die "I see no output directory named \"$d\"\nAborting";
61b39c5158Smillert    -d $d or die "But \"$d\" isn't a directory!\nAborting";
62b39c5158Smillert    -w $d or die "Directory \"$d\" isn't writeable!\nAborting";
63b39c5158Smillert  }
64b39c5158Smillert
65b39c5158Smillert  __PACKAGE__->batch_convert(@ARGV);
66b39c5158Smillert}
67b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
68b39c5158Smillert
69b39c5158Smillert
70b39c5158Smillertsub new {
71b39c5158Smillert  my $new = bless {}, ref($_[0]) || $_[0];
72b39c5158Smillert  $new->html_render_class($HTML_RENDER_CLASS);
73b39c5158Smillert  $new->search_class($SEARCH_CLASS);
74b39c5158Smillert  $new->verbose(1 + DEBUG);
75b39c5158Smillert  $new->_contents([]);
76b39c5158Smillert
77b39c5158Smillert  $new->index(1);
78b39c5158Smillert
79b39c5158Smillert  $new->       _css_wad([]);         $new->css_flurry(1);
80b39c5158Smillert  $new->_javascript_wad([]);  $new->javascript_flurry(1);
81b39c5158Smillert
82b39c5158Smillert  $new->contents_file(
83b39c5158Smillert    'index' . ($HTML_EXTENSION || $Pod::Simple::HTML::HTML_EXTENSION)
84b39c5158Smillert  );
85b39c5158Smillert
86b39c5158Smillert  $new->contents_page_start( join "\n", grep $_,
87b39c5158Smillert    $Pod::Simple::HTML::Doctype_decl,
88b39c5158Smillert    "<html><head>",
89b39c5158Smillert    "<title>Perl Documentation</title>",
90b39c5158Smillert    $Pod::Simple::HTML::Content_decl,
91b39c5158Smillert    "</head>",
92b39c5158Smillert    "\n<body class='contentspage'>\n<h1>Perl Documentation</h1>\n"
93b39c5158Smillert  ); # override if you need a different title
94b39c5158Smillert
95b39c5158Smillert
96b39c5158Smillert  $new->contents_page_end( sprintf(
97*eac174f2Safresh1    "\n\n<p class='contentsfooty'>Generated by %s v%s under Perl v%s\n<br >At %s GMT.</p>\n\n</body></html>\n",
98b39c5158Smillert    esc(
99b39c5158Smillert      ref($new),
100b39c5158Smillert      eval {$new->VERSION} || $VERSION,
101*eac174f2Safresh1      $], scalar(gmtime($ENV{SOURCE_DATE_EPOCH} || time)),
102b39c5158Smillert  )));
103b39c5158Smillert
104b39c5158Smillert  return $new;
105b39c5158Smillert}
106b39c5158Smillert
107b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
108b39c5158Smillert
109b39c5158Smillertsub muse {
110b39c5158Smillert  my $self = shift;
111b39c5158Smillert  if($self->verbose) {
112b39c5158Smillert    print 'T+', int(time() - $self->{'_batch_start_time'}), "s: ", @_, "\n";
113b39c5158Smillert  }
114b39c5158Smillert  return 1;
115b39c5158Smillert}
116b39c5158Smillert
117b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
118b39c5158Smillert
119b39c5158Smillertsub batch_convert {
120b39c5158Smillert  my($self, $dirs, $outdir) = @_;
121b39c5158Smillert  $self ||= __PACKAGE__; # tolerate being called as an optionless function
122b39c5158Smillert  $self = $self->new unless ref $self; # tolerate being used as a class method
123b39c5158Smillert
124b39c5158Smillert  if(!defined($dirs)  or  $dirs eq ''  or  $dirs eq '@INC' ) {
125b39c5158Smillert    $dirs = '';
126b39c5158Smillert  } elsif(ref $dirs) {
127b39c5158Smillert    # OK, it's an explicit set of dirs to scan, specified as an arrayref.
128b39c5158Smillert  } else {
129b39c5158Smillert    # OK, it's an explicit set of dirs to scan, specified as a
130b39c5158Smillert    #  string like "/thing:/also:/whatever/perl" (":"-delim, as usual)
131b39c5158Smillert    #  or, under MSWin, like "c:/thing;d:/also;c:/whatever/perl" (";"-delim!)
132b39c5158Smillert    require Config;
133b39c5158Smillert    my $ps = quotemeta( $Config::Config{'path_sep'} || ":" );
134b39c5158Smillert    $dirs = [ grep length($_), split qr/$ps/, $dirs ];
135b39c5158Smillert  }
136b39c5158Smillert
137b39c5158Smillert  $outdir = $self->filespecsys->curdir
138b39c5158Smillert   unless defined $outdir and length $outdir;
139b39c5158Smillert
140b39c5158Smillert  $self->_batch_convert_main($dirs, $outdir);
141b39c5158Smillert}
142b39c5158Smillert
143b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
144b39c5158Smillert
145b39c5158Smillertsub _batch_convert_main {
146b39c5158Smillert  my($self, $dirs, $outdir) = @_;
147b39c5158Smillert  # $dirs is either false, or an arrayref.
148b39c5158Smillert  # $outdir is a pathspec.
149b39c5158Smillert
150b39c5158Smillert  $self->{'_batch_start_time'} ||= time();
151b39c5158Smillert
152b39c5158Smillert  $self->muse( "= ", scalar(localtime) );
153b39c5158Smillert  $self->muse( "Starting batch conversion to \"$outdir\"" );
154b39c5158Smillert
155b39c5158Smillert  my $progress = $self->progress;
156b39c5158Smillert  if(!$progress and $self->verbose > 0 and $self->verbose() <= 5) {
157b39c5158Smillert    require Pod::Simple::Progress;
158b39c5158Smillert    $progress = Pod::Simple::Progress->new(
159b39c5158Smillert        ($self->verbose  < 2) ? () # Default omission-delay
160b39c5158Smillert      : ($self->verbose == 2) ? 1  # Reduce the omission-delay
161b39c5158Smillert                              : 0  # Eliminate the omission-delay
162b39c5158Smillert    );
163b39c5158Smillert    $self->progress($progress);
164b39c5158Smillert  }
165b39c5158Smillert
166b39c5158Smillert  if($dirs) {
167b39c5158Smillert    $self->muse(scalar(@$dirs), " dirs to scan: @$dirs");
168b39c5158Smillert  } else {
169b39c5158Smillert    $self->muse("Scanning \@INC.  This could take a minute or two.");
170b39c5158Smillert  }
171b39c5158Smillert  my $mod2path = $self->find_all_pods($dirs ? $dirs : ());
172b39c5158Smillert  $self->muse("Done scanning.");
173b39c5158Smillert
174b39c5158Smillert  my $total = keys %$mod2path;
175b39c5158Smillert  unless($total) {
176b39c5158Smillert    $self->muse("No pod found.  Aborting batch conversion.\n");
177b39c5158Smillert    return $self;
178b39c5158Smillert  }
179b39c5158Smillert
180b39c5158Smillert  $progress and $progress->goal($total);
181b39c5158Smillert  $self->muse("Now converting pod files to HTML.",
182b39c5158Smillert    ($total > 25) ? "  This will take a while more." : ()
183b39c5158Smillert  );
184b39c5158Smillert
185b39c5158Smillert  $self->_spray_css(        $outdir );
186b39c5158Smillert  $self->_spray_javascript( $outdir );
187b39c5158Smillert
188b39c5158Smillert  $self->_do_all_batch_conversions($mod2path, $outdir);
189b39c5158Smillert
190b39c5158Smillert  $progress and $progress->done(sprintf (
191b39c5158Smillert    "Done converting %d files.",  $self->{"__batch_conv_page_count"}
192b39c5158Smillert  ));
193b39c5158Smillert  return $self->_batch_convert_finish($outdir);
194b39c5158Smillert  return $self;
195b39c5158Smillert}
196b39c5158Smillert
197b39c5158Smillert
198b39c5158Smillertsub _do_all_batch_conversions {
199b39c5158Smillert  my($self, $mod2path, $outdir) = @_;
200b39c5158Smillert  $self->{"__batch_conv_page_count"} = 0;
201b39c5158Smillert
202b39c5158Smillert  foreach my $module (sort {lc($a) cmp lc($b)} keys %$mod2path) {
203b39c5158Smillert    $self->_do_one_batch_conversion($module, $mod2path, $outdir);
204b39c5158Smillert    sleep($SLEEPY - 1) if $SLEEPY;
205b39c5158Smillert  }
206b39c5158Smillert
207b39c5158Smillert  return;
208b39c5158Smillert}
209b39c5158Smillert
210b39c5158Smillertsub _batch_convert_finish {
211b39c5158Smillert  my($self, $outdir) = @_;
212b39c5158Smillert  $self->write_contents_file($outdir);
213b39c5158Smillert  $self->muse("Done with batch conversion.  $$self{'__batch_conv_page_count'} files done.");
214b39c5158Smillert  $self->muse( "= ", scalar(localtime) );
215b39c5158Smillert  $self->progress and $self->progress->done("All done!");
216b39c5158Smillert  return;
217b39c5158Smillert}
218b39c5158Smillert
219b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
220b39c5158Smillert
221b39c5158Smillertsub _do_one_batch_conversion {
222b39c5158Smillert  my($self, $module, $mod2path, $outdir, $outfile) = @_;
223b39c5158Smillert
224b39c5158Smillert  my $retval;
225b39c5158Smillert  my $total    = scalar keys %$mod2path;
226b39c5158Smillert  my $infile   = $mod2path->{$module};
227b39c5158Smillert  my @namelets = grep m/\S/, split "::", $module;
228b39c5158Smillert        # this can stick around in the contents LoL
229b39c5158Smillert  my $depth    = scalar @namelets;
230b39c5158Smillert  die "Contentless thingie?! $module $infile" unless @namelets; #sanity
231b39c5158Smillert
232b39c5158Smillert  $outfile  ||= do {
233b39c5158Smillert    my @n = @namelets;
234b39c5158Smillert    $n[-1] .= $HTML_EXTENSION || $Pod::Simple::HTML::HTML_EXTENSION;
235b39c5158Smillert    $self->filespecsys->catfile( $outdir, @n );
236b39c5158Smillert  };
237b39c5158Smillert
238b39c5158Smillert  my $progress = $self->progress;
239b39c5158Smillert
240b39c5158Smillert  my $page = $self->html_render_class->new;
241b39c5158Smillert  if(DEBUG > 5) {
242b39c5158Smillert    $self->muse($self->{"__batch_conv_page_count"} + 1, "/$total: ",
243b39c5158Smillert      ref($page), " render ($depth) $module => $outfile");
244b39c5158Smillert  } elsif(DEBUG > 2) {
245b39c5158Smillert    $self->muse($self->{"__batch_conv_page_count"} + 1, "/$total: $module => $outfile")
246b39c5158Smillert  }
247b39c5158Smillert
248b39c5158Smillert  # Give each class a chance to init the converter:
249b39c5158Smillert  $page->batch_mode_page_object_init($self, $module, $infile, $outfile, $depth)
250b39c5158Smillert   if $page->can('batch_mode_page_object_init');
251b39c5158Smillert  # Init for the index (TOC), too.
252b39c5158Smillert  $self->batch_mode_page_object_init($page, $module, $infile, $outfile, $depth)
253b39c5158Smillert   if $self->can('batch_mode_page_object_init');
254b39c5158Smillert
255b39c5158Smillert  # Now get busy...
256b39c5158Smillert  $self->makepath($outdir => \@namelets);
257b39c5158Smillert
258b39c5158Smillert  $progress and $progress->reach($self->{"__batch_conv_page_count"}, "Rendering $module");
259b39c5158Smillert
260b39c5158Smillert  if( $retval = $page->parse_from_file($infile, $outfile) ) {
261b39c5158Smillert    ++ $self->{"__batch_conv_page_count"} ;
262b39c5158Smillert    $self->note_for_contents_file( \@namelets, $infile, $outfile );
263b39c5158Smillert  } else {
264b39c5158Smillert    $self->muse("Odd, parse_from_file(\"$infile\", \"$outfile\") returned false.");
265b39c5158Smillert  }
266b39c5158Smillert
267b39c5158Smillert  $page->batch_mode_page_object_kill($self, $module, $infile, $outfile, $depth)
268b39c5158Smillert   if $page->can('batch_mode_page_object_kill');
269b39c5158Smillert  # The following isn't a typo.  Note that it switches $self and $page.
270b39c5158Smillert  $self->batch_mode_page_object_kill($page, $module, $infile, $outfile, $depth)
271b39c5158Smillert   if $self->can('batch_mode_page_object_kill');
272b39c5158Smillert
273b8851fccSafresh1  DEBUG > 4 and printf STDERR "%s %sb < $infile %s %sb\n",
274b39c5158Smillert     $outfile, -s $outfile, $infile, -s $infile
275b39c5158Smillert  ;
276b39c5158Smillert
277b39c5158Smillert  undef($page);
278b39c5158Smillert  return $retval;
279b39c5158Smillert}
280b39c5158Smillert
281b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
282b39c5158Smillertsub filespecsys { $_[0]{'_filespecsys'} || 'File::Spec' }
283b39c5158Smillert
284b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
285b39c5158Smillert
286b39c5158Smillertsub note_for_contents_file {
287b39c5158Smillert  my($self, $namelets, $infile, $outfile) = @_;
288b39c5158Smillert
289b39c5158Smillert  # I think the infile and outfile parts are never used. -- SMB
290b39c5158Smillert  # But it's handy to have them around for debugging.
291b39c5158Smillert
292b39c5158Smillert  if( $self->contents_file ) {
293b39c5158Smillert    my $c = $self->_contents();
294b39c5158Smillert    push @$c,
295b39c5158Smillert     [ join("::", @$namelets), $infile, $outfile, $namelets ]
296b39c5158Smillert     #            0               1         2         3
297b39c5158Smillert    ;
298b8851fccSafresh1    DEBUG > 3 and print STDERR "Noting @$c[-1]\n";
299b39c5158Smillert  }
300b39c5158Smillert  return;
301b39c5158Smillert}
302b39c5158Smillert
303b39c5158Smillert#_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
304b39c5158Smillert
305b39c5158Smillertsub write_contents_file {
306b39c5158Smillert  my($self, $outdir) = @_;
307b39c5158Smillert  my $outfile  = $self->_contents_filespec($outdir) || return;
308b39c5158Smillert
309b39c5158Smillert  $self->muse("Preparing list of modules for ToC");
310b39c5158Smillert
311b39c5158Smillert  my($toplevel,           # maps  toplevelbit => [all submodules]
312b39c5158Smillert     $toplevel_form_freq, # ends up being  'foo' => 'Foo'
313b39c5158Smillert    ) = $self->_prep_contents_breakdown;
314b39c5158Smillert
315b39c5158Smillert  my $Contents = eval { $self->_wopen($outfile) };
316b39c5158Smillert  if( $Contents ) {
317b39c5158Smillert    $self->muse( "Writing contents file $outfile" );
318b39c5158Smillert  } else {
319b39c5158Smillert    warn "Couldn't write-open contents file $outfile: $!\nAbort writing to $outfile at all";
320b39c5158Smillert    return;
321b39c5158Smillert  }
322b39c5158Smillert
323b39c5158Smillert  $self->_write_contents_start(  $Contents, $outfile, );
324b39c5158Smillert  $self->_write_contents_middle( $Contents, $outfile, $toplevel, $toplevel_form_freq );
325b39c5158Smillert  $self->_write_contents_end(    $Contents, $outfile, );
326b39c5158Smillert  return $outfile;
327b39c5158Smillert}
328b39c5158Smillert
329b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
330b39c5158Smillert
331b39c5158Smillertsub _write_contents_start {
332b39c5158Smillert  my($self, $Contents, $outfile) = @_;
333b39c5158Smillert  my $starter = $self->contents_page_start || '';
334b39c5158Smillert
335b39c5158Smillert  {
336b39c5158Smillert    my $css_wad = $self->_css_wad_to_markup(1);
337b39c5158Smillert    if( $css_wad ) {
338b39c5158Smillert      $starter =~ s{(</head>)}{\n$css_wad\n$1}i;  # otherwise nevermind
339b39c5158Smillert    }
340b39c5158Smillert
341b39c5158Smillert    my $javascript_wad = $self->_javascript_wad_to_markup(1);
342b39c5158Smillert    if( $javascript_wad ) {
343b39c5158Smillert      $starter =~ s{(</head>)}{\n$javascript_wad\n$1}i;   # otherwise nevermind
344b39c5158Smillert    }
345b39c5158Smillert  }
346b39c5158Smillert
347b39c5158Smillert  unless(print $Contents $starter, "<dl class='superindex'>\n" ) {
348b39c5158Smillert    warn "Couldn't print to $outfile: $!\nAbort writing to $outfile at all";
349b39c5158Smillert    close($Contents);
350b39c5158Smillert    return 0;
351b39c5158Smillert  }
352b39c5158Smillert  return 1;
353b39c5158Smillert}
354b39c5158Smillert
355b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
356b39c5158Smillert
357b39c5158Smillertsub _write_contents_middle {
358b39c5158Smillert  my($self, $Contents, $outfile, $toplevel2submodules, $toplevel_form_freq) = @_;
359b39c5158Smillert
360b39c5158Smillert  foreach my $t (sort keys %$toplevel2submodules) {
361b39c5158Smillert    my @downlines = sort {$a->[-1] cmp $b->[-1]}
362b39c5158Smillert                          @{ $toplevel2submodules->{$t} };
363b39c5158Smillert
364b39c5158Smillert    printf $Contents qq[<dt><a name="%s">%s</a></dt>\n<dd>\n],
365b39c5158Smillert      esc( $t, $toplevel_form_freq->{$t} )
366b39c5158Smillert    ;
367b39c5158Smillert
368b39c5158Smillert    my($path, $name);
369b39c5158Smillert    foreach my $e (@downlines) {
370b39c5158Smillert      $name = $e->[0];
371b39c5158Smillert      $path = join( "/", '.', esc( @{$e->[3]} ) )
372b39c5158Smillert        . ($HTML_EXTENSION || $Pod::Simple::HTML::HTML_EXTENSION);
373b39c5158Smillert      print $Contents qq{  <a href="$path">}, esc($name), "</a>&nbsp;&nbsp;\n";
374b39c5158Smillert    }
375b39c5158Smillert    print $Contents "</dd>\n\n";
376b39c5158Smillert  }
377b39c5158Smillert  return 1;
378b39c5158Smillert}
379b39c5158Smillert
380b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
381b39c5158Smillert
382b39c5158Smillertsub _write_contents_end {
383b39c5158Smillert  my($self, $Contents, $outfile) = @_;
384b39c5158Smillert  unless(
385b39c5158Smillert    print $Contents "</dl>\n",
386b39c5158Smillert      $self->contents_page_end || '',
387b39c5158Smillert  ) {
388b39c5158Smillert    warn "Couldn't write to $outfile: $!";
389b39c5158Smillert  }
390b39c5158Smillert  close($Contents) or warn "Couldn't close $outfile: $!";
391b39c5158Smillert  return 1;
392b39c5158Smillert}
393b39c5158Smillert
394b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
395b39c5158Smillert
396b39c5158Smillertsub _prep_contents_breakdown {
397b39c5158Smillert  my($self) = @_;
398b39c5158Smillert  my $contents = $self->_contents;
399b39c5158Smillert  my %toplevel; # maps  lctoplevelbit => [all submodules]
400b39c5158Smillert  my %toplevel_form_freq; # ends up being  'foo' => 'Foo'
401b39c5158Smillert                               # (mapping anycase forms to most freq form)
402b39c5158Smillert
403b39c5158Smillert  foreach my $entry (@$contents) {
404b39c5158Smillert    my $toplevel =
405b39c5158Smillert      $entry->[0] =~ m/^perl\w*$/ ? 'perl_core_docs'
406b39c5158Smillert          # group all the perlwhatever docs together
407b39c5158Smillert      : $entry->[3][0] # normal case
408b39c5158Smillert    ;
409b39c5158Smillert    ++$toplevel_form_freq{ lc $toplevel }{ $toplevel };
410b39c5158Smillert    push @{ $toplevel{ lc $toplevel } }, $entry;
411b39c5158Smillert    push @$entry, lc($entry->[0]); # add a sort-order key to the end
412b39c5158Smillert  }
413b39c5158Smillert
414b39c5158Smillert  foreach my $toplevel (sort keys %toplevel) {
415b39c5158Smillert    my $fgroup = $toplevel_form_freq{$toplevel};
416b39c5158Smillert    $toplevel_form_freq{$toplevel} =
417b39c5158Smillert    (
418b39c5158Smillert      sort { $fgroup->{$b} <=> $fgroup->{$a}  or  $a cmp $b }
419b39c5158Smillert        keys %$fgroup
420b39c5158Smillert      # This hash is extremely unlikely to have more than 4 members, so this
421b39c5158Smillert      # sort isn't so very wasteful
422b39c5158Smillert    )[0];
423b39c5158Smillert  }
424b39c5158Smillert
425b39c5158Smillert  return(\%toplevel, \%toplevel_form_freq) if wantarray;
426b39c5158Smillert  return \%toplevel;
427b39c5158Smillert}
428b39c5158Smillert
429b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
430b39c5158Smillert
431b39c5158Smillertsub _contents_filespec {
432b39c5158Smillert  my($self, $outdir) = @_;
433b39c5158Smillert  my $outfile = $self->contents_file;
434b39c5158Smillert  return unless $outfile;
435b39c5158Smillert  return $self->filespecsys->catfile( $outdir, $outfile );
436b39c5158Smillert}
437b39c5158Smillert
438b39c5158Smillert#_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
439b39c5158Smillert
440b39c5158Smillertsub makepath {
441b39c5158Smillert  my($self, $outdir, $namelets) = @_;
442b39c5158Smillert  return unless @$namelets > 1;
443b39c5158Smillert  for my $i (0 .. ($#$namelets - 1)) {
444b39c5158Smillert    my $dir = $self->filespecsys->catdir( $outdir, @$namelets[0 .. $i] );
445b39c5158Smillert    if(-e $dir) {
446b39c5158Smillert      die "$dir exists but not as a directory!?" unless -d $dir;
447b39c5158Smillert      next;
448b39c5158Smillert    }
449b8851fccSafresh1    DEBUG > 3 and print STDERR "  Making $dir\n";
450b39c5158Smillert    mkdir $dir, 0777
451b39c5158Smillert     or die "Can't mkdir $dir: $!\nAborting"
452b39c5158Smillert    ;
453b39c5158Smillert  }
454b39c5158Smillert  return;
455b39c5158Smillert}
456b39c5158Smillert
457b39c5158Smillert#_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
458b39c5158Smillert
459b39c5158Smillertsub batch_mode_page_object_init {
460b39c5158Smillert  my $self = shift;
461b39c5158Smillert  my($page, $module, $infile, $outfile, $depth) = @_;
462b39c5158Smillert
463b39c5158Smillert  # TODO: any further options to percolate onto this new object here?
464b39c5158Smillert
465b39c5158Smillert  $page->default_title($module);
466b39c5158Smillert  $page->index( $self->index );
467b39c5158Smillert
468b39c5158Smillert  $page->html_css(        $self->       _css_wad_to_markup($depth) );
469b39c5158Smillert  $page->html_javascript( $self->_javascript_wad_to_markup($depth) );
470b39c5158Smillert
471b39c5158Smillert  $self->add_header_backlink($page, $module, $infile, $outfile, $depth);
472b39c5158Smillert  $self->add_footer_backlink($page, $module, $infile, $outfile, $depth);
473b39c5158Smillert
474b39c5158Smillert
475b39c5158Smillert  return $self;
476b39c5158Smillert}
477b39c5158Smillert
478b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
479b39c5158Smillert
480b39c5158Smillertsub add_header_backlink {
481b39c5158Smillert  my $self = shift;
482b39c5158Smillert  return if $self->no_contents_links;
483b39c5158Smillert  my($page, $module, $infile, $outfile, $depth) = @_;
484b39c5158Smillert  $page->html_header_after_title( join '',
485b39c5158Smillert    $page->html_header_after_title || '',
486b39c5158Smillert
487b39c5158Smillert    qq[<p class="backlinktop"><b><a name="___top" href="],
488b39c5158Smillert    $self->url_up_to_contents($depth),
489b39c5158Smillert    qq[" accesskey="1" title="All Documents">&lt;&lt;</a></b></p>\n],
490b39c5158Smillert  )
491b39c5158Smillert   if $self->contents_file
492b39c5158Smillert  ;
493b39c5158Smillert  return;
494b39c5158Smillert}
495b39c5158Smillert
496b39c5158Smillertsub add_footer_backlink {
497b39c5158Smillert  my $self = shift;
498b39c5158Smillert  return if $self->no_contents_links;
499b39c5158Smillert  my($page, $module, $infile, $outfile, $depth) = @_;
500b39c5158Smillert  $page->html_footer( join '',
501b39c5158Smillert    qq[<p class="backlinkbottom"><b><a name="___bottom" href="],
502b39c5158Smillert    $self->url_up_to_contents($depth),
503b39c5158Smillert    qq[" title="All Documents">&lt;&lt;</a></b></p>\n],
504b39c5158Smillert
505b39c5158Smillert    $page->html_footer || '',
506b39c5158Smillert  )
507b39c5158Smillert   if $self->contents_file
508b39c5158Smillert  ;
509b39c5158Smillert  return;
510b39c5158Smillert}
511b39c5158Smillert
512b39c5158Smillertsub url_up_to_contents {
513b39c5158Smillert  my($self, $depth) = @_;
514b39c5158Smillert  --$depth;
515b39c5158Smillert  return join '/', ('..') x $depth, esc($self->contents_file);
516b39c5158Smillert}
517b39c5158Smillert
518b39c5158Smillert#_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
519b39c5158Smillert
520b39c5158Smillertsub find_all_pods {
521b39c5158Smillert  my($self, $dirs) = @_;
522b39c5158Smillert  # You can override find_all_pods in a subclass if you want to
523b39c5158Smillert  #  do extra filtering or whatnot.  But for the moment, we just
524b39c5158Smillert  #  pass to modnames2paths:
525b39c5158Smillert  return $self->modnames2paths($dirs);
526b39c5158Smillert}
527b39c5158Smillert
528b39c5158Smillert#_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
529b39c5158Smillert
530b39c5158Smillertsub modnames2paths { # return a hashref mapping modulenames => paths
531b39c5158Smillert  my($self, $dirs) = @_;
532b39c5158Smillert
533b39c5158Smillert  my $m2p;
534b39c5158Smillert  {
535b39c5158Smillert    my $search = $self->search_class->new;
536b8851fccSafresh1    DEBUG and print STDERR "Searching via $search\n";
537b39c5158Smillert    $search->verbose(1) if DEBUG > 10;
538b39c5158Smillert    $search->progress( $self->progress->copy->goal(0) ) if $self->progress;
539b39c5158Smillert    $search->shadows(0);  # don't bother noting shadowed files
540b39c5158Smillert    $search->inc(     $dirs ? 0      :  1 );
541b39c5158Smillert    $search->survey(  $dirs ? @$dirs : () );
542b39c5158Smillert    $m2p = $search->name2path;
543b39c5158Smillert    die "What, no name2path?!" unless $m2p;
544b39c5158Smillert  }
545b39c5158Smillert
546b39c5158Smillert  $self->muse("That's odd... no modules found!") unless keys %$m2p;
547b39c5158Smillert  if( DEBUG > 4 ) {
548b8851fccSafresh1    print STDERR "Modules found (name => path):\n";
549b39c5158Smillert    foreach my $m (sort {lc($a) cmp lc($b)} keys %$m2p) {
550b8851fccSafresh1      print STDERR "  $m  $$m2p{$m}\n";
551b39c5158Smillert    }
552b8851fccSafresh1    print STDERR "(total ",     scalar(keys %$m2p), ")\n\n";
553b39c5158Smillert  } elsif( DEBUG ) {
554b8851fccSafresh1    print STDERR      "Found ", scalar(keys %$m2p), " modules.\n";
555b39c5158Smillert  }
556b39c5158Smillert  $self->muse( "Found ", scalar(keys %$m2p), " modules." );
557b39c5158Smillert
558b39c5158Smillert  # return the Foo::Bar => /whatever/Foo/Bar.pod|pm hashref
559b39c5158Smillert  return $m2p;
560b39c5158Smillert}
561b39c5158Smillert
562b39c5158Smillert#===========================================================================
563b39c5158Smillert
564b39c5158Smillertsub _wopen {
565b39c5158Smillert  # this is abstracted out so that the daemon class can override it
566b39c5158Smillert  my($self, $outpath) = @_;
567b39c5158Smillert  require Symbol;
568b39c5158Smillert  my $out_fh = Symbol::gensym();
569b8851fccSafresh1  DEBUG > 5 and print STDERR "Write-opening to $outpath\n";
570b39c5158Smillert  return $out_fh if open($out_fh, "> $outpath");
571b39c5158Smillert  require Carp;
572b39c5158Smillert  Carp::croak("Can't write-open $outpath: $!");
573b39c5158Smillert}
574b39c5158Smillert
575b39c5158Smillert#==========================================================================
576b39c5158Smillert
577b39c5158Smillertsub add_css {
578b39c5158Smillert  my($self, $url, $is_default, $name, $content_type, $media, $_code) = @_;
579b39c5158Smillert  return unless $url;
580b39c5158Smillert  unless($name) {
581b39c5158Smillert    # cook up a reasonable name based on the URL
582b39c5158Smillert    $name = $url;
583b39c5158Smillert    if( $name !~ m/\?/ and $name =~ m{([^/]+)$}s ) {
584b39c5158Smillert      $name = $1;
585b39c5158Smillert      $name =~ s/\.css//i;
586b39c5158Smillert    }
587b39c5158Smillert  }
588b39c5158Smillert  $media        ||= 'all';
589b39c5158Smillert  $content_type ||= 'text/css';
590b39c5158Smillert
591b39c5158Smillert  my $bunch = [$url, $name, $content_type, $media, $_code];
592b39c5158Smillert  if($is_default) { unshift @{ $self->_css_wad }, $bunch }
593b39c5158Smillert  else            { push    @{ $self->_css_wad }, $bunch }
594b39c5158Smillert  return;
595b39c5158Smillert}
596b39c5158Smillert
597b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
598b39c5158Smillert
599b39c5158Smillertsub _spray_css {
600b39c5158Smillert  my($self, $outdir) = @_;
601b39c5158Smillert
602b39c5158Smillert  return unless $self->css_flurry();
603b39c5158Smillert  $self->_gen_css_wad();
604b39c5158Smillert
605b39c5158Smillert  my $lol = $self->_css_wad;
606b39c5158Smillert  foreach my $chunk (@$lol) {
607b39c5158Smillert    my $url = $chunk->[0];
608b39c5158Smillert    my $outfile;
609b39c5158Smillert    if( ref($chunk->[-1]) and $url =~ m{^(_[-a-z0-9_]+\.css$)} ) {
610b39c5158Smillert      $outfile = $self->filespecsys->catfile( $outdir, "$1" );
611b8851fccSafresh1      DEBUG > 5 and print STDERR "Noting $$chunk[0] as a file I'll create.\n";
612b39c5158Smillert    } else {
613b8851fccSafresh1      DEBUG > 5 and print STDERR "OK, noting $$chunk[0] as an external CSS.\n";
614b39c5158Smillert      # Requires no further attention.
615b39c5158Smillert      next;
616b39c5158Smillert    }
617b39c5158Smillert
618b39c5158Smillert    #$self->muse( "Writing autogenerated CSS file $outfile" );
619b39c5158Smillert    my $Cssout = $self->_wopen($outfile);
620b39c5158Smillert    print $Cssout ${$chunk->[-1]}
621b39c5158Smillert     or warn "Couldn't print to $outfile: $!\nAbort writing to $outfile at all";
622b39c5158Smillert    close($Cssout);
623b8851fccSafresh1    DEBUG > 5 and print STDERR "Wrote $outfile\n";
624b39c5158Smillert  }
625b39c5158Smillert
626b39c5158Smillert  return;
627b39c5158Smillert}
628b39c5158Smillert
629b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
630b39c5158Smillert
631b39c5158Smillertsub _css_wad_to_markup {
632b39c5158Smillert  my($self, $depth) = @_;
633b39c5158Smillert
634b39c5158Smillert  my @css  = @{ $self->_css_wad || return '' };
635b39c5158Smillert  return '' unless @css;
636b39c5158Smillert
637b39c5158Smillert  my $rel = 'stylesheet';
638b39c5158Smillert  my $out = '';
639b39c5158Smillert
640b39c5158Smillert  --$depth;
641b39c5158Smillert  my $uplink = $depth ? ('../' x $depth) : '';
642b39c5158Smillert
643b39c5158Smillert  foreach my $chunk (@css) {
644b39c5158Smillert    next unless $chunk and @$chunk;
645b39c5158Smillert
646b39c5158Smillert    my( $url1, $url2, $title, $type, $media) = (
647b39c5158Smillert      $self->_maybe_uplink( $chunk->[0], $uplink ),
648b39c5158Smillert      esc(grep !ref($_), @$chunk)
649b39c5158Smillert    );
650b39c5158Smillert
651b39c5158Smillert    $out .= qq{<link rel="$rel" title="$title" type="$type" href="$url1$url2" media="$media" >\n};
652b39c5158Smillert
653b39c5158Smillert    $rel = 'alternate stylesheet'; # alternates = all non-first iterations
654b39c5158Smillert  }
655b39c5158Smillert  return $out;
656b39c5158Smillert}
657b39c5158Smillert
658b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
659b39c5158Smillertsub _maybe_uplink {
660b39c5158Smillert  # if the given URL looks relative, return the given uplink string --
661b39c5158Smillert  # otherwise return emptystring
662b39c5158Smillert  my($self, $url, $uplink) = @_;
663b39c5158Smillert  ($url =~ m{^\./} or $url !~ m{[/\:]} )
664b39c5158Smillert    ? $uplink
665b39c5158Smillert    : ''
666b39c5158Smillert    # qualify it, if/as needed
667b39c5158Smillert}
668b39c5158Smillert
669b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
670b39c5158Smillertsub _gen_css_wad {
671b39c5158Smillert  my $self = $_[0];
672b39c5158Smillert  my $css_template = $self->_css_template;
673b39c5158Smillert  foreach my $variation (
674b39c5158Smillert
675b39c5158Smillert   # Commented out for sake of concision:
676b39c5158Smillert   #
677b39c5158Smillert   #  011n=black_with_red_on_white
678b39c5158Smillert   #  001n=black_with_yellow_on_white
679b39c5158Smillert   #  101n=black_with_green_on_white
680b39c5158Smillert   #  110=white_with_yellow_on_black
681b39c5158Smillert   #  010=white_with_green_on_black
682b39c5158Smillert   #  011=white_with_blue_on_black
683b39c5158Smillert   #  100=white_with_red_on_black
684b39c5158Smillert    '110n=blkbluw',  # black_with_blue_on_white
685b39c5158Smillert    '010n=blkmagw',  # black_with_magenta_on_white
686b39c5158Smillert    '100n=blkcynw',  # black_with_cyan_on_white
687b39c5158Smillert    '101=whtprpk',   # white_with_purple_on_black
688b39c5158Smillert    '001=whtnavk',   # white_with_navy_blue_on_black
689b39c5158Smillert    '010a=grygrnk',  # grey_with_green_on_black
690b39c5158Smillert    '010b=whtgrng',  # white_with_green_on_grey
691b39c5158Smillert    '101an=blkgrng', # black_with_green_on_grey
692b39c5158Smillert    '101bn=grygrnw', # grey_with_green_on_white
693b39c5158Smillert  ) {
694b39c5158Smillert
695b39c5158Smillert    my $outname = $variation;
696b39c5158Smillert    my($flipmode, @swap) = ( ($4 || ''), $1,$2,$3)
697b39c5158Smillert      if $outname =~ s/^([012])([012])([[012])([a-z]*)=?//s;
698b39c5158Smillert    @swap = () if '010' eq join '', @swap; # 010 is a swop-no-op!
699b39c5158Smillert
700b39c5158Smillert    my $this_css =
701b39c5158Smillert      "/* This file is autogenerated.  Do not edit.  $variation */\n\n"
702b39c5158Smillert      . $css_template;
703b39c5158Smillert
704b39c5158Smillert    # Only look at three-digitty colors, for now at least.
705b39c5158Smillert    if( $flipmode =~ m/n/ ) {
706b39c5158Smillert      $this_css =~ s/(#[0-9a-fA-F]{3})\b/_color_negate($1)/eg;
707b39c5158Smillert      $this_css =~ s/\bthin\b/medium/g;
708b39c5158Smillert    }
709b39c5158Smillert    $this_css =~ s<#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])\b>
710b39c5158Smillert                  < join '', '#', ($1,$2,$3)[@swap] >eg   if @swap;
711b39c5158Smillert
712b39c5158Smillert    if(   $flipmode =~ m/a/)
713b39c5158Smillert       { $this_css =~ s/#fff\b/#999/gi } # black -> dark grey
714b39c5158Smillert    elsif($flipmode =~ m/b/)
715b39c5158Smillert       { $this_css =~ s/#000\b/#666/gi } # white -> light grey
716b39c5158Smillert
717b39c5158Smillert    my $name = $outname;
718b39c5158Smillert    $name =~ tr/-_/  /;
719b39c5158Smillert    $self->add_css( "_$outname.css", 0, $name, 0, 0, \$this_css);
720b39c5158Smillert  }
721b39c5158Smillert
722b39c5158Smillert  # Now a few indexless variations:
72356d68f1eSafresh1  for (my ($outfile, $variation) = each %{{
72456d68f1eSafresh1      blkbluw => 'black_with_blue_on_white',
72556d68f1eSafresh1      whtpurk => 'white_with_purple_on_black',
72656d68f1eSafresh1      whtgrng => 'white_with_green_on_grey',
72756d68f1eSafresh1      grygrnw => 'grey_with_green_on_white',
72856d68f1eSafresh1  }}) {
729b39c5158Smillert    my $this_css = join "\n",
73056d68f1eSafresh1      "/* This file is autogenerated.  Do not edit.  $outfile */\n",
731b39c5158Smillert      "\@import url(\"./_$variation.css\");",
732b39c5158Smillert      ".indexgroup { display: none; }",
733b39c5158Smillert      "\n",
734b39c5158Smillert    ;
73556d68f1eSafresh1    my $name = $outfile;
736b39c5158Smillert    $name =~ tr/-_/  /;
73756d68f1eSafresh1    $self->add_css( "_$outfile.css", 0, $name, 0, 0, \$this_css);
738b39c5158Smillert  }
739b39c5158Smillert
740b39c5158Smillert  return;
741b39c5158Smillert}
742b39c5158Smillert
743b39c5158Smillertsub _color_negate {
744b39c5158Smillert  my $x = lc $_[0];
745b39c5158Smillert  $x =~ tr[0123456789abcdef]
746b39c5158Smillert          [fedcba9876543210];
747b39c5158Smillert  return $x;
748b39c5158Smillert}
749b39c5158Smillert
750b39c5158Smillert#===========================================================================
751b39c5158Smillert
752b39c5158Smillertsub add_javascript {
753b39c5158Smillert  my($self, $url, $content_type, $_code) = @_;
754b39c5158Smillert  return unless $url;
755b39c5158Smillert  push  @{ $self->_javascript_wad }, [
756b39c5158Smillert    $url, $content_type || 'text/javascript', $_code
757b39c5158Smillert  ];
758b39c5158Smillert  return;
759b39c5158Smillert}
760b39c5158Smillert
761b39c5158Smillertsub _spray_javascript {
762b39c5158Smillert  my($self, $outdir) = @_;
763b39c5158Smillert  return unless $self->javascript_flurry();
764b39c5158Smillert  $self->_gen_javascript_wad();
765b39c5158Smillert
766b39c5158Smillert  my $lol = $self->_javascript_wad;
767b39c5158Smillert  foreach my $script (@$lol) {
768b39c5158Smillert    my $url = $script->[0];
769b39c5158Smillert    my $outfile;
770b39c5158Smillert
771b39c5158Smillert    if( ref($script->[-1]) and $url =~ m{^(_[-a-z0-9_]+\.js$)} ) {
772b39c5158Smillert      $outfile = $self->filespecsys->catfile( $outdir, "$1" );
773b8851fccSafresh1      DEBUG > 5 and print STDERR "Noting $$script[0] as a file I'll create.\n";
774b39c5158Smillert    } else {
775b8851fccSafresh1      DEBUG > 5 and print STDERR "OK, noting $$script[0] as an external JavaScript.\n";
776b39c5158Smillert      next;
777b39c5158Smillert    }
778b39c5158Smillert
779b39c5158Smillert    #$self->muse( "Writing JavaScript file $outfile" );
780b39c5158Smillert    my $Jsout = $self->_wopen($outfile);
781b39c5158Smillert
782b39c5158Smillert    print $Jsout ${$script->[-1]}
783b39c5158Smillert     or warn "Couldn't print to $outfile: $!\nAbort writing to $outfile at all";
784b39c5158Smillert    close($Jsout);
785b8851fccSafresh1    DEBUG > 5 and print STDERR "Wrote $outfile\n";
786b39c5158Smillert  }
787b39c5158Smillert
788b39c5158Smillert  return;
789b39c5158Smillert}
790b39c5158Smillert
791b39c5158Smillertsub _gen_javascript_wad {
792b39c5158Smillert  my $self = $_[0];
793b39c5158Smillert  my $js_code = $self->_javascript || return;
794b39c5158Smillert  $self->add_javascript( "_podly.js", 0, \$js_code);
795b39c5158Smillert  return;
796b39c5158Smillert}
797b39c5158Smillert
798b39c5158Smillertsub _javascript_wad_to_markup {
799b39c5158Smillert  my($self, $depth) = @_;
800b39c5158Smillert
801b39c5158Smillert  my @scripts  = @{ $self->_javascript_wad || return '' };
802b39c5158Smillert  return '' unless @scripts;
803b39c5158Smillert
804b39c5158Smillert  my $out = '';
805b39c5158Smillert
806b39c5158Smillert  --$depth;
807b39c5158Smillert  my $uplink = $depth ? ('../' x $depth) : '';
808b39c5158Smillert
809b39c5158Smillert  foreach my $s (@scripts) {
810b39c5158Smillert    next unless $s and @$s;
811b39c5158Smillert
812b39c5158Smillert    my( $url1, $url2, $type, $media) = (
813b39c5158Smillert      $self->_maybe_uplink( $s->[0], $uplink ),
814b39c5158Smillert      esc(grep !ref($_), @$s)
815b39c5158Smillert    );
816b39c5158Smillert
817b39c5158Smillert    $out .= qq{<script type="$type" src="$url1$url2"></script>\n};
818b39c5158Smillert  }
819b39c5158Smillert  return $out;
820b39c5158Smillert}
821b39c5158Smillert
822b39c5158Smillert#===========================================================================
823b39c5158Smillert
824b39c5158Smillertsub _css_template { return $CSS }
825b39c5158Smillertsub _javascript   { return $JAVASCRIPT }
826b39c5158Smillert
827b39c5158Smillert$CSS = <<'EOCSS';
828b39c5158Smillert/* For accessibility reasons, never specify text sizes in px/pt/pc/in/cm/mm */
829b39c5158Smillert
830b39c5158Smillert@media all { .hide { display: none; } }
831b39c5158Smillert
832b39c5158Smillert@media print {
833b39c5158Smillert  .noprint, div.indexgroup, .backlinktop, .backlinkbottom { display: none }
834b39c5158Smillert
835b39c5158Smillert  * {
836b39c5158Smillert    border-color: black !important;
837b39c5158Smillert    color: black !important;
838b39c5158Smillert    background-color: transparent !important;
839b39c5158Smillert    background-image: none !important;
840b39c5158Smillert  }
841b39c5158Smillert
842b39c5158Smillert  dl.superindex > dd  {
843b39c5158Smillert    word-spacing: .6em;
844b39c5158Smillert  }
845b39c5158Smillert}
846b39c5158Smillert
847b39c5158Smillert@media aural, braille, embossed {
848b39c5158Smillert  div.indexgroup  { display: none; }  /* Too noisy, don't you think? */
849b39c5158Smillert  dl.superindex > dt:before { content: "Group ";  }
850b39c5158Smillert  dl.superindex > dt:after  { content: " contains:"; }
851b39c5158Smillert  .backlinktop    a:before  { content: "Back to contents"; }
852b39c5158Smillert  .backlinkbottom a:before  { content: "Back to contents"; }
853b39c5158Smillert}
854b39c5158Smillert
855b39c5158Smillert@media aural {
856b39c5158Smillert  dl.superindex > dt  { pause-before: 600ms; }
857b39c5158Smillert}
858b39c5158Smillert
859b39c5158Smillert@media screen, tty, tv, projection {
860b39c5158Smillert  .noscreen { display: none; }
861b39c5158Smillert
862b39c5158Smillert  a:link    { color: #7070ff; text-decoration: underline; }
863b39c5158Smillert  a:visited { color: #e030ff; text-decoration: underline; }
864b39c5158Smillert  a:active  { color: #800000; text-decoration: underline; }
865b39c5158Smillert  body.contentspage a            { text-decoration: none; }
866b39c5158Smillert  a.u { color: #fff !important; text-decoration: none; }
867b39c5158Smillert
868b39c5158Smillert  body.pod {
869b39c5158Smillert    margin: 0 5px;
870b39c5158Smillert    color:            #fff;
871b39c5158Smillert    background-color: #000;
872b39c5158Smillert  }
873b39c5158Smillert
874*eac174f2Safresh1  body.pod h1, body.pod h2, body.pod h3,
875*eac174f2Safresh1  body.pod h4, body.pod h5, body.pod h6  {
876b39c5158Smillert    font-family: Tahoma, Verdana, Helvetica, Arial, sans-serif;
877b39c5158Smillert    font-weight: normal;
878b39c5158Smillert    margin-top: 1.2em;
879b39c5158Smillert    margin-bottom: .1em;
880b39c5158Smillert    border-top: thin solid transparent;
881b39c5158Smillert    /* margin-left: -5px;  border-left: 2px #7070ff solid;  padding-left: 3px; */
882b39c5158Smillert  }
883b39c5158Smillert
884b39c5158Smillert  body.pod h1  { border-top-color: #0a0; }
885b39c5158Smillert  body.pod h2  { border-top-color: #080; }
886b39c5158Smillert  body.pod h3  { border-top-color: #040; }
887b39c5158Smillert  body.pod h4  { border-top-color: #010; }
888*eac174f2Safresh1  body.pod h5  { border-top-color: #010; }
889*eac174f2Safresh1  body.pod h6  { border-top-color: #010; }
890b39c5158Smillert
891b39c5158Smillert  p.backlinktop + h1 { border-top: none; margin-top: 0em;  }
892b39c5158Smillert  p.backlinktop + h2 { border-top: none; margin-top: 0em;  }
893b39c5158Smillert  p.backlinktop + h3 { border-top: none; margin-top: 0em;  }
894b39c5158Smillert  p.backlinktop + h4 { border-top: none; margin-top: 0em;  }
895*eac174f2Safresh1  p.backlinktop + h5 { border-top: none; margin-top: 0em;  }
896*eac174f2Safresh1  p.backlinktop + h6 { border-top: none; margin-top: 0em;  }
897b39c5158Smillert
898b39c5158Smillert  body.pod dt {
899b39c5158Smillert    font-size: 105%; /* just a wee bit more than normal */
900b39c5158Smillert  }
901b39c5158Smillert
902b39c5158Smillert  .indexgroup { font-size: 80%; }
903b39c5158Smillert
904b39c5158Smillert  .backlinktop,   .backlinkbottom    {
905b39c5158Smillert    margin-left:  -5px;
906b39c5158Smillert    margin-right: -5px;
907b39c5158Smillert    background-color:         #040;
908b39c5158Smillert    border-top:    thin solid #050;
909b39c5158Smillert    border-bottom: thin solid #050;
910b39c5158Smillert  }
911b39c5158Smillert
912b39c5158Smillert  .backlinktop a, .backlinkbottom a  {
913b39c5158Smillert    text-decoration: none;
914b39c5158Smillert    color: #080;
915b39c5158Smillert    background-color:  #000;
916b39c5158Smillert    border: thin solid #0d0;
917b39c5158Smillert  }
918b39c5158Smillert  .backlinkbottom { margin-bottom: 0; padding-bottom: 0; }
919b39c5158Smillert  .backlinktop    { margin-top:    0; padding-top:    0; }
920b39c5158Smillert
921b39c5158Smillert  body.contentspage {
922b39c5158Smillert    color:            #fff;
923b39c5158Smillert    background-color: #000;
924b39c5158Smillert  }
925b39c5158Smillert
926b39c5158Smillert  body.contentspage h1  {
927b39c5158Smillert    color:            #0d0;
928b39c5158Smillert    margin-left: 1em;
929b39c5158Smillert    margin-right: 1em;
930b39c5158Smillert    text-indent: -.9em;
931b39c5158Smillert    font-family: Tahoma, Verdana, Helvetica, Arial, sans-serif;
932b39c5158Smillert    font-weight: normal;
933b39c5158Smillert    border-top:    thin solid #fff;
934b39c5158Smillert    border-bottom: thin solid #fff;
935b39c5158Smillert    text-align: center;
936b39c5158Smillert  }
937b39c5158Smillert
938b39c5158Smillert  dl.superindex > dt  {
939b39c5158Smillert    font-family: Tahoma, Verdana, Helvetica, Arial, sans-serif;
940b39c5158Smillert    font-weight: normal;
941b39c5158Smillert    font-size: 90%;
942b39c5158Smillert    margin-top: .45em;
943b39c5158Smillert    /* margin-bottom: -.15em; */
944b39c5158Smillert  }
945b39c5158Smillert  dl.superindex > dd  {
946b39c5158Smillert    word-spacing: .6em;    /* most important rule here! */
947b39c5158Smillert  }
948b39c5158Smillert  dl.superindex > a:link  {
949b39c5158Smillert    text-decoration: none;
950b39c5158Smillert    color: #fff;
951b39c5158Smillert  }
952b39c5158Smillert
953b39c5158Smillert  .contentsfooty {
954b39c5158Smillert    border-top: thin solid #999;
955b39c5158Smillert    font-size: 90%;
956b39c5158Smillert  }
957b39c5158Smillert
958b39c5158Smillert}
959b39c5158Smillert
960b39c5158Smillert/* The End */
961b39c5158Smillert
962b39c5158SmillertEOCSS
963b39c5158Smillert
964b39c5158Smillert#==========================================================================
965b39c5158Smillert
966b39c5158Smillert$JAVASCRIPT = <<'EOJAVASCRIPT';
967b39c5158Smillert
968b39c5158Smillert// From http://www.alistapart.com/articles/alternate/
969b39c5158Smillert
970b39c5158Smillertfunction setActiveStyleSheet(title) {
971b39c5158Smillert  var i, a, main;
972b39c5158Smillert  for(i=0  ;  (a = document.getElementsByTagName("link")[i])  ;  i++) {
973b39c5158Smillert    if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
974b39c5158Smillert      a.disabled = true;
975b39c5158Smillert      if(a.getAttribute("title") == title) a.disabled = false;
976b39c5158Smillert    }
977b39c5158Smillert  }
978b39c5158Smillert}
979b39c5158Smillert
980b39c5158Smillertfunction getActiveStyleSheet() {
981b39c5158Smillert  var i, a;
982b39c5158Smillert  for(i=0  ;  (a = document.getElementsByTagName("link")[i])  ;  i++) {
983b39c5158Smillert    if(   a.getAttribute("rel").indexOf("style") != -1
984b39c5158Smillert       && a.getAttribute("title")
985b39c5158Smillert       && !a.disabled
986b39c5158Smillert       ) return a.getAttribute("title");
987b39c5158Smillert  }
988b39c5158Smillert  return null;
989b39c5158Smillert}
990b39c5158Smillert
991b39c5158Smillertfunction getPreferredStyleSheet() {
992b39c5158Smillert  var i, a;
993b39c5158Smillert  for(i=0  ;  (a = document.getElementsByTagName("link")[i])  ;  i++) {
994b39c5158Smillert    if(   a.getAttribute("rel").indexOf("style") != -1
995b39c5158Smillert       && a.getAttribute("rel").indexOf("alt") == -1
996b39c5158Smillert       && a.getAttribute("title")
997b39c5158Smillert       ) return a.getAttribute("title");
998b39c5158Smillert  }
999b39c5158Smillert  return null;
1000b39c5158Smillert}
1001b39c5158Smillert
1002b39c5158Smillertfunction createCookie(name,value,days) {
1003b39c5158Smillert  if (days) {
1004b39c5158Smillert    var date = new Date();
1005b39c5158Smillert    date.setTime(date.getTime()+(days*24*60*60*1000));
1006b39c5158Smillert    var expires = "; expires="+date.toGMTString();
1007b39c5158Smillert  }
1008b39c5158Smillert  else expires = "";
1009b39c5158Smillert  document.cookie = name+"="+value+expires+"; path=/";
1010b39c5158Smillert}
1011b39c5158Smillert
1012b39c5158Smillertfunction readCookie(name) {
1013b39c5158Smillert  var nameEQ = name + "=";
1014b39c5158Smillert  var ca = document.cookie.split(';');
1015b39c5158Smillert  for(var i=0  ;  i < ca.length  ;  i++) {
1016b39c5158Smillert    var c = ca[i];
1017b39c5158Smillert    while (c.charAt(0)==' ') c = c.substring(1,c.length);
1018b39c5158Smillert    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
1019b39c5158Smillert  }
1020b39c5158Smillert  return null;
1021b39c5158Smillert}
1022b39c5158Smillert
1023b39c5158Smillertwindow.onload = function(e) {
1024b39c5158Smillert  var cookie = readCookie("style");
1025b39c5158Smillert  var title = cookie ? cookie : getPreferredStyleSheet();
1026b39c5158Smillert  setActiveStyleSheet(title);
1027b39c5158Smillert}
1028b39c5158Smillert
1029b39c5158Smillertwindow.onunload = function(e) {
1030b39c5158Smillert  var title = getActiveStyleSheet();
1031b39c5158Smillert  createCookie("style", title, 365);
1032b39c5158Smillert}
1033b39c5158Smillert
1034b39c5158Smillertvar cookie = readCookie("style");
1035b39c5158Smillertvar title = cookie ? cookie : getPreferredStyleSheet();
1036b39c5158SmillertsetActiveStyleSheet(title);
1037b39c5158Smillert
1038b39c5158Smillert// The End
1039b39c5158Smillert
1040b39c5158SmillertEOJAVASCRIPT
1041b39c5158Smillert
1042b39c5158Smillert# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1043b39c5158Smillert1;
1044b39c5158Smillert__END__
1045b39c5158Smillert
1046b39c5158Smillert
1047b39c5158Smillert=head1 NAME
1048b39c5158Smillert
1049b39c5158SmillertPod::Simple::HTMLBatch - convert several Pod files to several HTML files
1050b39c5158Smillert
1051b39c5158Smillert=head1 SYNOPSIS
1052b39c5158Smillert
1053b39c5158Smillert  perl -MPod::Simple::HTMLBatch -e 'Pod::Simple::HTMLBatch::go' in out
1054b39c5158Smillert
1055b39c5158Smillert
1056b39c5158Smillert=head1 DESCRIPTION
1057b39c5158Smillert
1058b39c5158SmillertThis module is used for running batch-conversions of a lot of HTML
1059b39c5158Smillertdocuments
1060b39c5158Smillert
1061b39c5158SmillertThis class is NOT a subclass of Pod::Simple::HTML
1062b39c5158Smillert(nor of bad old Pod::Html) -- although it uses
1063b39c5158SmillertPod::Simple::HTML for doing the conversion of each document.
1064b39c5158Smillert
1065b39c5158SmillertThe normal use of this class is like so:
1066b39c5158Smillert
1067b39c5158Smillert  use Pod::Simple::HTMLBatch;
1068b39c5158Smillert  my $batchconv = Pod::Simple::HTMLBatch->new;
1069b39c5158Smillert  $batchconv->some_option( some_value );
1070b39c5158Smillert  $batchconv->some_other_option( some_other_value );
1071b39c5158Smillert  $batchconv->batch_convert( \@search_dirs, $output_dir );
1072b39c5158Smillert
1073b39c5158Smillert=head2 FROM THE COMMAND LINE
1074b39c5158Smillert
1075b39c5158SmillertNote that this class also provides
1076b39c5158Smillert(but does not export) the function Pod::Simple::HTMLBatch::go.
1077b39c5158SmillertThis is basically just a shortcut for C<<
1078b39c5158SmillertPod::Simple::HTMLBatch->batch_convert(@ARGV) >>.
1079b39c5158SmillertIt's meant to be handy for calling from the command line.
1080b39c5158Smillert
1081b39c5158SmillertHowever, the shortcut requires that you specify exactly two command-line
1082b39c5158Smillertarguments, C<indirs> and C<outdir>.
1083b39c5158Smillert
1084b39c5158SmillertExample:
1085b39c5158Smillert
1086b39c5158Smillert  % mkdir out_html
1087b39c5158Smillert  % perl -MPod::Simple::HTMLBatch -e Pod::Simple::HTMLBatch::go @INC out_html
1088b39c5158Smillert      (to convert the pod from Perl's @INC
1089898184e3Ssthen       files under the directory ./out_html)
1090b39c5158Smillert
1091b39c5158Smillert(Note that the command line there contains a literal atsign-I-N-C.  This
1092b39c5158Smillertis handled as a special case by batch_convert, in order to save you having
1093b39c5158Smillertto enter the odd-looking "" as the first command-line parameter when you
1094b39c5158Smillertmean "just use whatever's in @INC".)
1095b39c5158Smillert
1096b39c5158SmillertExample:
1097b39c5158Smillert
1098b39c5158Smillert  % mkdir ../seekrut
1099b39c5158Smillert  % chmod og-rx ../seekrut
110091f110e0Safresh1  % perl -MPod::Simple::HTMLBatch -e Pod::Simple::HTMLBatch::go . ../seekrut
1101b39c5158Smillert      (to convert the pod under the current dir into HTML
1102898184e3Ssthen       files under the directory ./seekrut)
1103b39c5158Smillert
1104b39c5158SmillertExample:
1105b39c5158Smillert
1106b39c5158Smillert  % perl -MPod::Simple::HTMLBatch -e Pod::Simple::HTMLBatch::go happydocs .
1107b39c5158Smillert      (to convert all pod from happydocs into the current directory)
1108b39c5158Smillert
1109b39c5158Smillert
1110b39c5158Smillert
1111b39c5158Smillert=head1 MAIN METHODS
1112b39c5158Smillert
1113b39c5158Smillert=over
1114b39c5158Smillert
1115b39c5158Smillert=item $batchconv = Pod::Simple::HTMLBatch->new;
1116b39c5158Smillert
111756d68f1eSafresh1This creates a new batch converter.  The method doesn't take parameters.
111856d68f1eSafresh1To change the converter's attributes, use the L<"/ACCESSOR METHODS">
111956d68f1eSafresh1below.
1120b39c5158Smillert
1121b39c5158Smillert=item $batchconv->batch_convert( I<indirs>, I<outdir> );
1122b39c5158Smillert
112356d68f1eSafresh1This searches the directories given in I<indirs> and writes
112456d68f1eSafresh1HTML files for each of these to a corresponding directory
112556d68f1eSafresh1in I<outdir>.  The directory I<outdir> must exist.
1126b39c5158Smillert
1127b39c5158Smillert=item $batchconv->batch_convert( undef    , ...);
1128b39c5158Smillert
1129b39c5158Smillert=item $batchconv->batch_convert( q{@INC}, ...);
1130b39c5158Smillert
1131b39c5158SmillertThese two values for I<indirs> specify that the normal Perl @INC
1132b39c5158Smillert
1133b39c5158Smillert=item $batchconv->batch_convert( \@dirs , ...);
1134b39c5158Smillert
1135b39c5158SmillertThis specifies that the input directories are the items in
1136b39c5158Smillertthe arrayref C<\@dirs>.
1137b39c5158Smillert
1138b39c5158Smillert=item $batchconv->batch_convert( "somedir" , ...);
1139b39c5158Smillert
1140b39c5158SmillertThis specifies that the director "somedir" is the input.
1141b39c5158Smillert(This can be an absolute or relative path, it doesn't matter.)
1142b39c5158Smillert
1143b39c5158SmillertA common value you might want would be just "." for the current
1144b39c5158Smillertdirectory:
1145b39c5158Smillert
1146b39c5158Smillert     $batchconv->batch_convert( "." , ...);
1147b39c5158Smillert
1148b39c5158Smillert
1149b39c5158Smillert=item $batchconv->batch_convert( 'somedir:someother:also' , ...);
1150b39c5158Smillert
1151898184e3SsthenThis specifies that you want the dirs "somedir", "someother", and "also"
1152b39c5158Smillertscanned, just as if you'd passed the arrayref
1153b39c5158SmillertC<[qw( somedir someother also)]>.  Note that a ":"-separator is normal
1154b39c5158Smillertunder Unix, but Under MSWin, you'll need C<'somedir;someother;also'>
1155b39c5158Smillertinstead, since the pathsep on MSWin is ";" instead of ":".  (And
1156b39c5158SmillertI<that> is because ":" often comes up in paths, like
1157b39c5158SmillertC<"c:/perl/lib">.)
1158b39c5158Smillert
1159b39c5158Smillert(Exactly what separator character should be used, is gotten from
1160b39c5158SmillertC<$Config::Config{'path_sep'}>, via the L<Config> module.)
1161b39c5158Smillert
1162b39c5158Smillert=item $batchconv->batch_convert( ... , undef );
1163b39c5158Smillert
1164b39c5158SmillertThis specifies that you want the HTML output to go into the current
1165b39c5158Smillertdirectory.
1166b39c5158Smillert
1167b39c5158Smillert(Note that a missing or undefined value means a different thing in
1168b39c5158Smillertthe first slot than in the second.  That's so that C<batch_convert()>
1169b39c5158Smillertwith no arguments (or undef arguments) means "go from @INC, into
1170b39c5158Smillertthe current directory.)
1171b39c5158Smillert
1172b39c5158Smillert=item $batchconv->batch_convert( ... , 'somedir' );
1173b39c5158Smillert
1174b39c5158SmillertThis specifies that you want the HTML output to go into the
1175b39c5158Smillertdirectory 'somedir'.
1176b39c5158Smillert(This can be an absolute or relative path, it doesn't matter.)
1177b39c5158Smillert
1178b39c5158Smillert=back
1179b39c5158Smillert
1180b39c5158Smillert
1181b39c5158SmillertNote that you can also call C<batch_convert> as a class method,
1182b39c5158Smillertlike so:
1183b39c5158Smillert
1184b39c5158Smillert  Pod::Simple::HTMLBatch->batch_convert( ... );
1185b39c5158Smillert
1186b39c5158SmillertThat is just short for this:
1187b39c5158Smillert
1188b39c5158Smillert  Pod::Simple::HTMLBatch-> new-> batch_convert(...);
1189b39c5158Smillert
1190b39c5158SmillertThat is, it runs a conversion with default options, for
1191b39c5158Smillertwhatever inputdirs and output dir you specify.
1192b39c5158Smillert
1193b39c5158Smillert
1194b39c5158Smillert=head2 ACCESSOR METHODS
1195b39c5158Smillert
1196b39c5158SmillertThe following are all accessor methods -- that is, they don't do anything
1197b39c5158Smillerton their own, but just alter the contents of the conversion object,
1198b39c5158Smillertwhich comprises the options for this particular batch conversion.
1199b39c5158Smillert
1200b39c5158SmillertWe show the "put" form of the accessors below (i.e., the syntax you use
1201b39c5158Smillertfor setting the accessor to a specific value).  But you can also
1202b39c5158Smillertcall each method with no parameters to get its current value.  For
1203b39c5158Smillertexample, C<< $self->contents_file() >> returns the current value of
1204b39c5158Smillertthe contents_file attribute.
1205b39c5158Smillert
1206b39c5158Smillert=over
1207b39c5158Smillert
1208b39c5158Smillert
1209b39c5158Smillert=item $batchconv->verbose( I<nonnegative_integer> );
1210b39c5158Smillert
1211b39c5158SmillertThis controls how verbose to be during batch conversion, as far as
1212b39c5158Smillertnotes to STDOUT (or whatever is C<select>'d) about how the conversion
1213b39c5158Smillertis going.  If 0, no progress information is printed.
1214b39c5158SmillertIf 1 (the default value), some progress information is printed.
1215b39c5158SmillertHigher values print more information.
1216b39c5158Smillert
1217b39c5158Smillert
1218b39c5158Smillert=item $batchconv->index( I<true-or-false> );
1219b39c5158Smillert
1220b39c5158SmillertThis controls whether or not each HTML page is liable to have a little
1221b39c5158Smillerttable of contents at the top (which we call an "index" for historical
1222b39c5158Smillertreasons).  This is true by default.
1223b39c5158Smillert
1224b39c5158Smillert
1225b39c5158Smillert=item $batchconv->contents_file( I<filename> );
1226b39c5158Smillert
1227b39c5158SmillertIf set, should be the name of a file (in the output directory)
1228b39c5158Smillertto write the HTML index to.  The default value is "index.html".
1229b39c5158SmillertIf you set this to a false value, no contents file will be written.
1230b39c5158Smillert
1231b39c5158Smillert=item $batchconv->contents_page_start( I<HTML_string> );
1232b39c5158Smillert
1233b39c5158SmillertThis specifies what string should be put at the beginning of
1234b39c5158Smillertthe contents page.
1235b39c5158SmillertThe default is a string more or less like this:
1236b39c5158Smillert
1237b39c5158Smillert  <html>
1238b39c5158Smillert  <head><title>Perl Documentation</title></head>
1239b39c5158Smillert  <body class='contentspage'>
1240b39c5158Smillert  <h1>Perl Documentation</h1>
1241b39c5158Smillert
1242b39c5158Smillert=item $batchconv->contents_page_end( I<HTML_string> );
1243b39c5158Smillert
1244b39c5158SmillertThis specifies what string should be put at the end of the contents page.
1245b39c5158SmillertThe default is a string more or less like this:
1246b39c5158Smillert
1247b39c5158Smillert  <p class='contentsfooty'>Generated by
1248b39c5158Smillert  Pod::Simple::HTMLBatch v3.01 under Perl v5.008
1249b39c5158Smillert  <br >At Fri May 14 22:26:42 2004 GMT,
1250b39c5158Smillert  which is Fri May 14 14:26:42 2004 local time.</p>
1251b39c5158Smillert
1252b39c5158Smillert
1253b39c5158Smillert
1254b39c5158Smillert=item $batchconv->add_css( $url );
1255b39c5158Smillert
1256b39c5158SmillertTODO
1257b39c5158Smillert
1258b39c5158Smillert=item $batchconv->add_javascript( $url );
1259b39c5158Smillert
1260b39c5158SmillertTODO
1261b39c5158Smillert
1262b39c5158Smillert=item $batchconv->css_flurry( I<true-or-false> );
1263b39c5158Smillert
1264b39c5158SmillertIf true (the default value), we autogenerate some CSS files in the
1265b39c5158Smillertoutput directory, and set our HTML files to use those.
1266b39c5158SmillertTODO: continue
1267b39c5158Smillert
1268b39c5158Smillert=item $batchconv->javascript_flurry( I<true-or-false> );
1269b39c5158Smillert
1270b39c5158SmillertIf true (the default value), we autogenerate a JavaScript in the
1271b39c5158Smillertoutput directory, and set our HTML files to use it.  Currently,
1272b39c5158Smillertthe JavaScript is used only to get the browser to remember what
1273b39c5158Smillertstylesheet it prefers.
1274b39c5158SmillertTODO: continue
1275b39c5158Smillert
1276b39c5158Smillert=item $batchconv->no_contents_links( I<true-or-false> );
1277b39c5158Smillert
1278b39c5158SmillertTODO
1279b39c5158Smillert
1280b39c5158Smillert=item $batchconv->html_render_class( I<classname> );
1281b39c5158Smillert
1282b39c5158SmillertThis sets what class is used for rendering the files.
1283b39c5158SmillertThe default is "Pod::Simple::HTML".  If you set it to something else,
1284b39c5158Smillertit should probably be a subclass of Pod::Simple::HTML, and you should
1285b39c5158SmillertC<require> or C<use> that class so that's it's loaded before
1286b39c5158SmillertPod::Simple::HTMLBatch tries loading it.
1287b39c5158Smillert
1288b39c5158Smillert=item $batchconv->search_class( I<classname> );
1289b39c5158Smillert
1290b39c5158SmillertThis sets what class is used for searching for the files.
1291b39c5158SmillertThe default is "Pod::Simple::Search".  If you set it to something else,
1292b39c5158Smillertit should probably be a subclass of Pod::Simple::Search, and you should
1293b39c5158SmillertC<require> or C<use> that class so that's it's loaded before
1294b39c5158SmillertPod::Simple::HTMLBatch tries loading it.
1295b39c5158Smillert
1296b39c5158Smillert=back
1297b39c5158Smillert
1298b39c5158Smillert
1299b39c5158Smillert
1300b39c5158Smillert
1301b39c5158Smillert=head1 NOTES ON CUSTOMIZATION
1302b39c5158Smillert
1303b39c5158SmillertTODO
1304b39c5158Smillert
1305b39c5158Smillert  call add_css($someurl) to add stylesheet as alternate
1306b39c5158Smillert  call add_css($someurl,1) to add as primary stylesheet
1307b39c5158Smillert
1308b39c5158Smillert  call add_javascript
1309b39c5158Smillert
1310b39c5158Smillert  subclass Pod::Simple::HTML and set $batchconv->html_render_class to
1311b39c5158Smillert    that classname
1312b39c5158Smillert  and maybe override
1313b39c5158Smillert    $page->batch_mode_page_object_init($self, $module, $infile, $outfile, $depth)
1314b39c5158Smillert  or maybe override
1315b39c5158Smillert    $batchconv->batch_mode_page_object_init($page, $module, $infile, $outfile, $depth)
1316b39c5158Smillert  subclass Pod::Simple::Search and set $batchconv->search_class to
1317b39c5158Smillert    that classname
1318b39c5158Smillert
1319b39c5158Smillert
1320b39c5158Smillert=head1 SEE ALSO
1321b39c5158Smillert
1322b39c5158SmillertL<Pod::Simple>, L<Pod::Simple::HTMLBatch>, L<perlpod>, L<perlpodspec>
1323b39c5158Smillert
1324b39c5158Smillert=head1 SUPPORT
1325b39c5158Smillert
1326b39c5158SmillertQuestions or discussion about POD and Pod::Simple should be sent to the
1327b39c5158Smillertpod-people@perl.org mail list. Send an empty email to
1328b39c5158Smillertpod-people-subscribe@perl.org to subscribe.
1329b39c5158Smillert
1330b39c5158SmillertThis module is managed in an open GitHub repository,
1331b8851fccSafresh1L<https://github.com/perl-pod/pod-simple/>. Feel free to fork and contribute, or
1332b8851fccSafresh1to clone L<git://github.com/perl-pod/pod-simple.git> and send patches!
1333b39c5158Smillert
1334b39c5158SmillertPatches against Pod::Simple are welcome. Please send bug reports to
1335b39c5158Smillert<bug-pod-simple@rt.cpan.org>.
1336b39c5158Smillert
1337b39c5158Smillert=head1 COPYRIGHT AND DISCLAIMERS
1338b39c5158Smillert
1339b39c5158SmillertCopyright (c) 2002 Sean M. Burke.
1340b39c5158Smillert
1341b39c5158SmillertThis library is free software; you can redistribute it and/or modify it
1342b39c5158Smillertunder the same terms as Perl itself.
1343b39c5158Smillert
1344b39c5158SmillertThis program is distributed in the hope that it will be useful, but
1345b39c5158Smillertwithout any warranty; without even the implied warranty of
1346b39c5158Smillertmerchantability or fitness for a particular purpose.
1347b39c5158Smillert
1348b39c5158Smillert=head1 AUTHOR
1349b39c5158Smillert
1350b39c5158SmillertPod::Simple was created by Sean M. Burke <sburke@cpan.org>.
1351b39c5158SmillertBut don't bother him, he's retired.
1352b39c5158Smillert
1353b39c5158SmillertPod::Simple is maintained by:
1354b39c5158Smillert
1355b39c5158Smillert=over
1356b39c5158Smillert
1357b39c5158Smillert=item * Allison Randal C<allison@perl.org>
1358b39c5158Smillert
1359b39c5158Smillert=item * Hans Dieter Pearcey C<hdp@cpan.org>
1360b39c5158Smillert
1361b39c5158Smillert=item * David E. Wheeler C<dwheeler@cpan.org>
1362b39c5158Smillert
1363b39c5158Smillert=back
1364b39c5158Smillert
1365b39c5158Smillert=cut
1366