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