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> \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"><<</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"><<</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