DEVEL15-man-page-html-generation-hack-20080713
[openafs.git] / doc / man-pages / generate-html
1 #!/usr/bin/perl -w
2 package OpenAFS::HTML;
3
4 use strict;
5 use vars qw(@ISA);
6
7 use Pod::Simple::Search;
8 @ISA = qw(Pod::Simple::HTML);
9
10 sub do_man_link {
11     my ($self, $token) = @_;
12     my $page = $token->attr ('to');
13     my ($name, $section) = ($page =~ /^([^\(]+)\((\d+)\)$/);
14     return unless $name;
15     my @url = ('..', $section, $name);
16     return join ('/', map { $self->pagepath_url_escape ($_) } @url)
17         . $Pod::Simple::HTML::HTML_EXTENSION;
18 }
19
20 # Underscore isn't allowed in man page names in Pod::Simple 3.04, so links
21 # like L<fs_setacl(8)> show up as POD links.  Discover that case and dispatch
22 # everything else to the standard do_pod_link implementation.
23 sub do_pod_link {
24     my ($self, $token) = @_;
25     my $target = $token->attr ('to');
26     if ($target && $target =~ /^([^\s\(]+)\((\d+)\)$/) {
27         return $self->do_man_link ($token);
28     } else {
29         return $self->SUPER::do_pod_link ($token);
30     }
31 }
32
33 sub VERSION () { '1.1' }
34
35 $Pod::Simple::HTML::Tagmap{'item-bullet'} = '<li><p>';
36 $Pod::Simple::HTML::Tagmap{'/item-bullet'} = '</p></li>';
37 $Pod::Simple::HTML::Tagmap{'item-number'} = '<li><p>';
38 $Pod::Simple::HTML::Tagmap{'/item-number'} = '</p></li>';
39
40 # This horrific hack is required because Pod::Simple::HTMLBatch has no way
41 # of setting search options and we have to set laborious to true in order
42 # to pick up man pages like krb.conf(5).
43 package OpenAFS::Search;
44
45 use strict;
46 use vars qw(@ISA);
47
48 use Pod::Simple::Search;
49 @ISA = qw(Pod::Simple::HTML);
50
51 sub new {
52     my $class = shift;
53     my $object = Pod::Simple::Search->new;
54     $object->laborious (1);
55     return $object;
56 }
57
58 package main;
59
60 use strict;
61
62 use File::Copy;
63 use Pod::Simple::HTMLBatch;
64
65 # Override the search class to set laborious.
66 $Pod::Simple::HTMLBatch::SEARCH_CLASS = 'OpenAFS::Search';
67
68 our $HEADER = <<'EOH';
69 <html>
70 <head>
71   <title>OpenAFS Reference Manual</title>
72   <link rel="stylesheet" title="style" type="text/css" href="style.css" media="all">
73 </head>
74 <body class='contentspage'>
75 <h1>OpenAFS Reference Manual</h1>
76 EOH
77
78 our %HEADINGS = (1 => 'User Commands',
79                  5 => 'Configuration and Data Files',
80                  8 => 'Administrator Commands');
81
82 # Scan all of the POD files and build a list of section, name, and short
83 # description, returning that as an array.
84 sub scan_names {
85     my @index;
86     for my $dir (qw(pod1 pod5 pod8)) {
87         my $section = $dir;
88         $section =~ s/^pod//;
89         opendir (D, $dir) or die "Cannot open $dir: $!\n";
90         for my $file (sort grep { !/^\./ && !/CVS/ } readdir D) {
91             open (F, "$dir/$file") or die "Cannot open $dir/$file: $!\n";
92             my ($name, $desc);
93             local $_;
94             while (<F>) {
95                 last if /^=head1/ && !/^=head1\s+NAME\b/;
96                 next unless /\s+-\s+/;
97                 ($name, $desc) = split (/\s+-\s+/, $_, 2);
98             }
99             unless ($name) {
100                 warn "$dir/$file: cannot find NAME section, skipping\n";
101             }
102             $name =~ s/^(backup|bos|fs|fstrace|kas|pts|symlink|uss|vos)_/$1 /;
103             my $page = $file;
104             $page =~ s/\.pod$//;
105             push (@index, [ $section, $name, $page, $desc ]);
106         }
107         closedir D;
108     }
109     return @index;
110 }
111
112 unless (-d 'html') {
113     mkdir ('html', 0755) or die "Cannot create html directory: $!\n";
114 }
115 for my $dir (qw(pod1 pod5 pod8)) {
116     my $section = $dir;
117     $section =~ s/^pod//;
118     mkdir ("html/$section", 0755) unless -d "html/$section";
119
120     my $conv = Pod::Simple::HTMLBatch->new;
121     $conv->verbose (0);
122     $conv->index (undef);
123     $conv->contents_file (undef);
124     $conv->add_css ('../style.css', 1);
125     $conv->css_flurry (0);
126     $conv->javascript_flurry (0);
127     $conv->html_render_class ('OpenAFS::HTML');
128     $conv->batch_convert ($dir, "html/$section");
129 }
130 copy ('style.css', 'html/style.css') or die "Cannot copy style.css: $!\n";
131
132 open (INDEX, '> html/index.html')
133     or die "Cannot create html/index.html: $!\n";
134 print INDEX $HEADER;
135 print INDEX "<table>\n";
136 my @index = scan_names;
137 my $current;
138 for my $entry (@index) {
139     my ($section, $name, $page, $desc) = @$entry;
140     for ($name, $desc) {
141         s/&/&gt;/g;
142         s/</&lt;/g;
143         s/>/&gt;/g;
144     }
145     if (!$current || $section != $current) {
146         print INDEX qq(<tr><td>&nbsp;</td></tr>\n);
147         print INDEX qq(<tr class="heading"><th colspan="2">);
148         print INDEX qq($HEADINGS{$section}</th></tr>\n);
149         $current = $section;
150     }
151     print INDEX qq(<tr><td><a href="$section/$page.html">$name</a></td>);
152     print INDEX qq(<td>$desc</td></tr>\n);
153 }
154 print INDEX "</table>\n</body>\n</html>\n";