3 package Local::MkManPages;
7 use File::Basename qw(basename);
9 use Getopt::Long qw(GetOptionsFromArray);
10 use Pod::Usage qw(pod2usage);
11 use Pod::Simple::XHTML;
13 __PACKAGE__->run(@ARGV);
15 sub Dirs { return (qw(apps crypto ssl
16 man1 man3 man5 man7)) }
17 sub Dir2Section { return ( apps => "man1", crypto => "man3", ssl => "man3" ) }
20 my ( $class, @argv ) = @_;
21 my $opt = $class->process_options(@argv);
22 exit $class->main( $opt->{SrcDir}, $opt->{WwwDir}, $opt->{RelVer} );
26 my ( $class, $srcdir, $wwwdir, $release ) = @_;
28 foreach my $subdir ( $class->Dirs ) {
29 my $dir = File::Spec->catfile( $srcdir, $subdir );
30 if ( opendir( my $dh, $dir ) ) {
31 while ( my $ent = readdir($dh) ) {
32 next if $ent =~ /^\./;
33 next if $ent !~ /\.pod$/;
35 my $origbase = basename( $ent, ".pod" );
36 my $title = $origbase;
37 my $tmp_sect = { $class->Dir2Section }->{$subdir} // $subdir;
38 (my $tmp_sectnum = $tmp_sect) =~ s|^man||;
39 # In addition to what getdata() gives us, we add a few
40 # defaults of our own:
43 # subdir => "..." # The original subdir
44 # sectnum => n # Default section number
49 sectnum => $tmp_sectnum,
50 $class->getdata( File::Spec->catfile ( $dir, $ent ) )
52 # These are for display
53 my $podfile = File::Spec->catfile( $subdir, $ent );
54 my $incfile = File::Spec->catfile( "man$data{sectnum}",
56 # These are files we're actually manipulating
57 my $inpod = File::Spec->catfile( $srcdir, $podfile );
58 my $outinc = File::Spec->catfile( $wwwdir, $incfile );
60 # Get main HTML output
61 my $out = $class->geninc( $release, $inpod, %data );
62 open( my $fh, ">", $outinc )
63 or $class->die("Can't open $outinc: $!");
64 print $fh $out or $class->die("Can't print $outinc: $!");
65 close($fh) or $class->die("Can't close $outinc: $!");
68 map { (my $x = $_) =~ s|/|-|g; $x } @{$data{names}};
69 # Older OpenSSL pods have file names that do not correspond
70 # to any of the names in the NAME section.
71 # Strictly speaking, we shouldn't use that name, but HTML
72 # pages with that name have been produced in the past, so
73 # we keep doing so as long as it's relevant.
74 if (! grep { $_ eq $origbase } @htmlnames) {
75 push @htmlnames, $origbase;
77 foreach my $htmlname (@htmlnames) {
78 my $htmlfile = File::Spec->catdir( "man$data{sectnum}",
80 my $outhtml = File::Spec->catfile( $wwwdir, $htmlfile );
81 $out = $class->genhtml( $release, $title, $origbase,
83 open( $fh, ">", $outhtml )
84 or $class->die("Can't open $outhtml: $!");
85 print $fh $out or $class->die("Can't print $outhtml: $!");
86 close($fh) or $class->die("Can't close $outhtml: $!");
93 # Generate manpag HTML wrapper
95 my ( $class, $release, $title, $origbase, $htmlbase, %data ) = @_;
99 <!-- OSSL: original subdir: $data{subdir} -->
100 <!-- OSSL: subdir: man$data{sectnum} -->
101 <!-- OSSL: section: $data{sectnum} -->
102 <!-- OSSL: description: $data{description} -->
103 <!--#include virtual="/inc/head.shtml" -->
105 <!--#include virtual="/inc/banner.shtml" -->
108 <div class="blog-index">
110 <header><h2>$title</h2></header>
111 <div class="entry-content">
113 <!--#include virtual="$origbase.inc" -->
117 You are here: <a href="/">Home</a>
118 : <a href="/docs">Docs</a>
119 : <a href="/docs/manpages.html">Manpages</a>
120 : <a href="/docs/man$release/">$release</a>
121 : <a href="/docs/man$release/man$data{sectnum}">man$data{sectnum}</a>
122 : <a href="/docs/man$release/man$data{sectnum}/$htmlbase.html">$htmlbase</a>
123 <br/><a href="/sitemap.txt">Sitemap</a>
127 <aside class="sidebar">
129 <h1><a href="/docs/man$release/">$release manpages</a></h1>
131 <li><a href="../man1">Commands</a></li>
132 <li><a href="../man3">Libraries</a></li>
133 <li><a href="../man5">File Formats</a></li>
134 <li><a href="../man7">Overviews</a></li>
137 <!--#include virtual="$htmlbase.cross" -->
141 <!--#include virtual="/inc/footer.shtml" -->
147 # Generate manpage content
149 my ( $class, $release, $filename, %data ) = @_;
151 open( my $fh, $filename ) or $class->die("Can't open $filename: $!");
152 my $infile = do { local $/; <$fh>; };
156 my $pod = Pod::Simple::XHTML->new;
157 $pod->html_h_level(3);
158 $pod->perldoc_url_prefix("/docs/man$release/man$data{sectnum}/");
159 $pod->perldoc_url_postfix(".html");
160 $pod->man_url_prefix("/docs/man$release/man");
161 $pod->man_url_postfix(".html");
162 $pod->html_header('');
163 $pod->html_footer('');
164 $pod->output_string( \$out );
165 $pod->parse_string_document($infile);
169 # Return diverse data from a manpage if available, currently:
171 # names => [ ... ] # list of all OTHER names
172 # description => "text" # the short description from NAME
173 # section => n # the section number
176 my ( $class, $infile ) = @_;
178 open( my $fh, "<", $infile ) or $class->die("Can't open $infile: $!");
185 if (/^=for (?:comment|openssl) openssl_manual_section:\s*(\d+)/) {
186 $data{sectnum} = "$1";
188 elsif (/^=head1\s/) {
193 $data{description} = $';
200 push @{$data{names}}, split ',';
203 if (/^=head1\s+NAME\s*$/) {
219 my $prog = basename($0);
220 warn("$prog: $_\n") for @_;
223 sub process_options {
224 my ( $class, @argv ) = @_;
227 GetOptionsFromArray( \@argv, \%opt, "help", "man" )
228 or pod2usage( -verbose => 0 );
230 pod2usage( -verbose => 1 ) if ( $opt{help} or @argv != 3 );
231 pod2usage( -verbose => 2 ) if ( $opt{man} );
233 # <src/dir> <rel.ver> <www/dir>
234 my @argkeys = qw(SrcDir RelVer WwwDir);
235 @opt{@argkeys} = @argv;
237 # no empty values, directories must exist
239 foreach my $key (@argkeys) {
240 push( @err, "Invalid $key argument '$opt{$key}'" )
241 if ( $opt{$key} =~ /^\s*$/ );
242 push( @err, "Directory '$opt{$key}': $!" )
243 if ( $key =~ /Dir$/ and !-d $opt{$key} );
245 $class->die(@err) if @err;
247 # each source dir has a set of subdirs with documentation
249 my $docdir = File::Spec->catfile( $opt{SrcDir} );
250 foreach my $subdir ( $class->Dirs ) {
251 my $dir = File::Spec->catfile( $docdir, $subdir );
252 push @found_dirs, $dir if -d $dir;
254 push( @err, "No documentation directories in $docdir" )
255 unless ( @found_dirs );
266 mk-manpages - htmlize man pages from POD for the OpenSSL website
270 mk-manpages [options] <SrcDir> <RelVer> <WwwDir>
272 <SrcDir> doc directory of release <RelVer>, example 'OpenSSL_1_0_2-stable/doc'
273 <RelVer> version number associated with <SrcDir>, example '1.0.2'
274 <WwwDir> top level directory beneath which generated html is stored, example 'web'
276 --help display a brief help message
277 --man display full documentation
281 This utility is run on a web server generate the htmlized version of
282 OpenSSL documentation from the original POD. The resultant directory
283 structure may look something like the following (where the contents of
284 index.html do not come from this tool):
286 $ ls some/path/to/web
287 man1.0.2 man1.1.0 manmaster
288 $ ls some/path/to/web/man1.0.2
289 apps crypto index.html ssl
290 $ ls some/path/to/web/man1.0.2/apps