Apache2-PodBrowser
view release on metacpan or search on metacpan
lib/Apache2/PodBrowser.pm view on Meta::CPAN
# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
package Apache2::PodBrowser;
use 5.008008;
use strict;
{our $VERSION = '0.08'}
use Apache2::RequestRec ();
use Apache2::RequestUtil ();
use Apache2::RequestIO ();
use Apache2::Response ();
use Apache2::URI ();
use Apache2::Log ();
use APR::Finfo ();
use APR::Table ();
use Apache2::Const -compile => qw/OK DECLINED REDIRECT NOT_FOUND SERVER_ERROR/;
use APR::Const -compile => qw/FINFO_NORM FILETYPE_DIR FILETYPE_REG
FILETYPE_NOFILE SUCCESS ENOENT/;
use Pod::Find;
use Pod::Simple::HTML;
use constant {
INDEX_NORMAL=>0,
INDEX_PODINDEX=>1,
INDEX_PODCACHED=>10,
INDEX_FUNCINDEX=>2,
};
sub _indexlink {
("<div class=\"uplink\">\n".
join( '', map {
" <a href=\"$_->[1]\">$_->[0]</a>\n";
} ($_[0] ==INDEX_PODINDEX ? (['Function and Variable Index', './??'])
: $_[0]==INDEX_PODCACHED ? (['Function and Variable Index', './??'],
['Update POD Cache', './-'])
: $_[0]==INDEX_FUNCINDEX ? (['Pod Index', './'])
: (['Pod Index', './'], ['Function and Variable Index', './??']))).
"</div>\n");
}
sub _header {
my ($kind, $style)=@_;
my ($title, $uplink)=
($kind==INDEX_PODINDEX ? ('POD Index', _indexlink($kind))
:$kind==INDEX_PODCACHED ? ('POD Index', _indexlink($kind))
:$kind==INDEX_FUNCINDEX ? ('Function and Variable Index',
_indexlink($kind))
:());
<<"EOF";
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><title>$title</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" >
<link rel="stylesheet" type="text/css" title="pod_stylesheet" href="$style">
</head>
<body class='podindex'>
$uplink<h1>$title</h1>
EOF
}
sub _footer {"</body></html>\n"}
{
my ($current, @index);
my %html=('"'=>'"', '<'=>'<', '>'=>'>', '&'=>'&');
sub _reset_link_generator { ($current, @index)=('') }
sub _link {
my ($name, $linkprefix)=@_;
my $prefix='';
my $firstchar=substr($name, 0, 1);
unless( $firstchar eq $current ) {
push @index, $firstchar;
$prefix="<h2><a name=\"$firstchar\">$firstchar</a></h2>\n";
$current=$firstchar;
}
my $display;
if( length $name>35 ) {
$display='...'.substr($name, -32);
} else {
$display=$name;
}
my $title=$name;
$name=~s{([^A-Za-z0-9\-_.!~*'()/:\$@&=+,;?\\\]\[^`|<>{}])}
{sprintf("%%%02X",ord($1))}eg;
for my $x ($title, $display) {
$x=~s/(["<>&])/$html{$1}/ge;
}
$prefix."<a href=\"./$linkprefix$name\" title=\"$title\">$display</a>";
}
sub _gen_index {
"<div class=\"indexgroup\"><div>\n ".join("\n ", map {
"<a href=\"#$_\">$_</a>";
} @index)."\n</div></div>\n";
}
}
sub _stylesheet {
my ($r)=@_;
my $stylesheet=$r->dir_config('STYLESHEET') || '';
if ($stylesheet=~/^auto$/i) {
$stylesheet='./auto.css';
} elsif ($stylesheet=~/^fancy$/i) {
$stylesheet='./fancy.css';
}
return $stylesheet;
lib/Apache2/PodBrowser.pm view on Meta::CPAN
|http://httpd.apache.org/docs/2.2/mod/mod_deflate.html#recommended> for
more information
PerlSetVar GZIP 1
By default, this is off.
=head3 PODDIR
This variable is useful only in perldoc mode.
It declares additional directories to look for PODs. This can be given multiple
times. Directories given this way are searched B<before> C<@INC>.
PerlAddVar PODDIR /path/to/project1
PerlAddVar PODDIR /path/to/project2
=head3 NOINC
In perldoc mode POD files are normally looked up in C<@INC> plus in the
directories given by C<PODDIR>. If C<NOINC> is set then the C<@INC> search
is skipped. That means only the directories specifed in F<httpd.conf>
are scanned:
PerlAddVar NOINC 1
For documentation requests for perl functions via
L<http://localhost/perldoc/?functionname> C<@INC> is used nevertheless
to locate C<perlfunc.pod> if it is not found in one of the given directories.
In direct mode this variable is ignored.
=head3 CACHE
When in perldoc mode C<Apache2::PodBrowser> uses
L<Pod::Find::pod_find>
to generate a list of available POD files. This may take quite a while
depending upon the number of directories and files to scan for POD.
To avoid to repeat this for each POD index request one can set up a cache.
PerlSetVar CACHE /path/to/cache.mmdb
The cache file itself is created on the first access to the index. The POD
index page then contains a link to update the cache. So, if a POD file
is added or removed from the system this link is to be clicked to keep
the POD index page up to date.
The cache file itself is a L<MMapDB> object. If this module is not available
you'll probably get a C<404 - NOT FOUND> response the next time the POD index
page is requested if C<CACHE> is set.
The directory containing the cache file must be writable by the C<httpd>.
=head3 CONTENTTYPE
You'll probably need that only for plain text output with the
L<Pod::Simple::Text> parser. Here one can set the content type
of the output.
PerlSetVar CONTENTTYPE "text/plain; charset=UTF-8"
=head3 PARSER and LINKBASE
C<PARSER> sets the POD-to-HTML converter class that is used. It should
support at least the interface that L<Pod::Simple::Text> provides.
The L<Pod::Simple::Text> parser gives you plain text.
If L<Pod::Simple::HTML> is used as parser one gets almost usable output
except for the missing C<DOCTYPE> HTML header and the broken linkage
to other modules.
The default C<PARSER> is C<Apache2::PodBrowser::Formatter> and is
suitable for perldoc mode. It derives
from L<Pod::Simple::HTML> but overrides the constructor C<new> to
provide a C<DOCTYPE> and C<resolve_pod_page_link> to fix the linkage.
If C<LINKBASE> is not set or empty C<resolve_pod_page_link> creates
relative links to other modules of the type:
./Other::Module
If C<LINKBASE> is set it is prepended before C<Other::Module> instead
of C<./>. For example you could set
PerlSetVar LINKBASE http://search.cpan.org/perldoc?
to generate links to CPAN.
For perldoc mode an empty C<LINKBASE> is best choice.
In direct mode an other parser C<Apache2::PodBrowser::DirectMode> should
be used. It derives from C<Apache2::PodBrowser::Formatter> but overrides
C<resolve_pod_page_link>.
This time the link generator searches for the link destination POD by
the module name with one of the following extensions appended: C<.pod>,
C<.pm> and C<.pl>. If none is found it resorts to its base class. And
now C<LINKBASE> makes sense.
If you know of a C<Apache2::PodBrowser> running in perldoc mode you can
point C<LINKBASE> to that address. This way modules that does not exist
in the local tree would be looked up there or on CPAN if C<LINKBASE>
points there.
If all that is unsuitable for you you can implement your own C<PARSER>
class. Have a look at the source code of this module. It is quite straight
forward regarding the 2 parser classes.
=head2 The Fixup Handler
If you use your own stylesheet or teach apache to find one of the
provided styles in the file system you don't need the fixup handler.
It simply does the file lookup for you.
If you don't like it just find the style sheet in your file system:
find $(perl -e 'print "@INC"') -type f -name fancy.css
( run in 2.770 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )