1 1.1 christos #! @PATH_PERL@ -w 2 1.1 christos # 3 1.1 christos # html2man: Converts the NTP HTML documentation to man page format 4 1.1 christos # 5 1.1 christos # This file require the Perl HTML::TokeParser module: 6 1.1 christos # http://search.cpan.org/search?module=HTML::TokeParser 7 1.1 christos # 8 1.1 christos # Depending on where this is run from, you might need to modify $MANDIR below. 9 1.1 christos # 10 1.1 christos # Hacked together by Peter Boettcher <boettcher (at] ll.mit.edu> 11 1.1 christos # Last modified: <Mon Jan 28 17:24:38 2002 by pwb> 12 1.1 christos 13 1.1 christos require HTML::TokeParser; 14 1.1 christos 15 1.1 christos # use strict; # I can dream... 16 1.1 christos 17 1.1 christos $MANDIR = "./man"; 18 1.1 christos 19 1.1 christos # HTML files to convert. Also include per-file info here: 20 1.1 christos # name of man page, man section, 'see also' section 21 1.1 christos %manfiles = ( 22 1.1 christos 'ntpd' => ['ntpd', @NTPD_MS@, 'ntp.conf(5), ntpq(@NTPQ_MS@), ntpdc(@NTPDC_MS@)'], 23 1.1 christos 'ntpq' => ['ntpq', @NTPQ_MS@, 'ntp_decode(5), ntpd(@NTPD_MS@), ntpdc(@NTPDC_MS@)'], 24 1.1 christos 'ntpdate' => ['ntpdate', @NTPDATE_MS@, 'ntpd(@NTPD_MS@)'], 25 1.1 christos 'ntpdc' => ['ntpdc', @NTPDC_MS@, 'ntpd(@NTPD_MS@)'], 26 1.1 christos 'ntptime' => ['ntptime', @NTPTIME_MS@, 'ntpd(@NTPD_MS@), ntpdate(@NTPDATE_MS@)'], 27 1.1 christos 'ntptrace' => ['ntptrace', @NTPTRACE_MS@, 'ntpd(@NTPD_MS@)'], 28 1.1 christos 'ntp-wait' => ['ntp-wait', @NTP_WAIT_MS@, 'ntpd(@NTPD_MS@)'], 29 1.1 christos 'keygen' => ['ntp-keygen', @NTP_KEYGEN_MS@, 'ntpd(@NTPD_MS@), ntp_auth(5)'], 30 1.1 christos 'tickadj' => ['tickadj', @TICKADJ_MS@, 'ntpd(@NTPD_MS@)'], 31 1.1 christos 'confopt' => ['ntp.conf', 5, 'ntpd(@NTPD_MS@), ntp_auth(5), ntp_mon(5), ntp_acc(5), ntp_clock(5), ntp_misc(5)'], 32 1.1 christos 'authopt' => ['ntp_auth', 5, 'ntp.conf(5), ntpd(@NTPD_MS@)'], 33 1.1 christos 'monopt' => ['ntp_mon', 5, 'ntp.conf(5), ntp_decode(5)'], 34 1.1 christos 'accopt' => ['ntp_acc', 5, 'ntp.conf(5)'], 35 1.1 christos 'clockopt' => ['ntp_clock', 5, 'ntp.conf(5)'], 36 1.1 christos 'decode' => ['ntp_decode', 5, 'ntpq(@NTPQ_MS@), ntp_mon(5)'], 37 1.1 christos 'miscopt' => ['ntp_misc', 5, 'ntp.conf(5)']); 38 1.1 christos 39 1.1 christos %table_headers = ( 40 1.1 christos 'ntpd' => 'l l l l.', 41 1.1 christos 'ntpq' => 'l l.', 42 1.1 christos 'monopt' => 'l l l.', 43 1.1 christos 'decode' => 'l l l l.', 44 1.1 christos 'authopt' => 'c c c c c c.' 45 1.1 christos ); 46 1.1 christos 47 1.1 christos # Disclaimer to go in SEE ALSO section of the man page 48 1.1 christos $seealso_disclaimer = "The official HTML documentation.\n\n" . 49 1.1 christos "This file was automatically generated from HTML source.\n"; 50 1.1 christos 51 1.1 christos mkdir $MANDIR, 0777; 52 1.1 christos mkdir "$MANDIR/man8", 0777; 53 1.1 christos mkdir "$MANDIR/man5", 0777; 54 1.1 christos 55 1.1 christos # Do the actual processing 56 1.1 christos foreach $file (keys %manfiles) { 57 1.1 christos process($file); 58 1.1 christos } 59 1.1 christos # End of main function 60 1.1 christos 61 1.1 christos 62 1.1 christos 63 1.1 christos # Do the real work 64 1.1 christos sub process { 65 1.1 christos my($filename) = @_; 66 1.1 christos $fileinfo = $manfiles{$filename}; 67 1.1 christos 68 1.1 christos $p = HTML::TokeParser->new("$filename.html") || die "Can't open $filename.html: $!"; 69 1.1 christos $fileout = "$MANDIR/man$fileinfo->[1]/$fileinfo->[0].$fileinfo->[1]"; 70 1.1 christos open(MANOUT, ">$fileout") 71 1.1 christos || die "Can't open: $!"; 72 1.1 christos 73 1.1 christos $p->get_tag("title"); 74 1.1 christos $name = $p->get_text("/title"); 75 1.1 christos $p->get_tag("hr"); # Skip past image and quote, hopefully 76 1.1 christos 77 1.1 christos # Setup man header 78 1.1 christos print MANOUT ".TH " . $fileinfo->[0] . " " . $fileinfo->[1] . "\n"; 79 1.1 christos print MANOUT ".SH NAME\n"; 80 1.1 christos $pat = $fileinfo->[0]; 81 1.1 christos if ($name =~ /$pat/) { 82 1.1 christos } else { 83 1.1 christos # Add the manpage name, if not in the HTML title already 84 1.1 christos print MANOUT "$fileinfo->[0] - "; 85 1.1 christos } 86 1.1 christos print MANOUT "$name\n.SH \\ \n\n"; 87 1.1 christos 88 1.1 christos @fontstack = (); 89 1.1 christos $deflevel = 0; 90 1.1 christos $pre = 0; 91 1.1 christos $ignore = 0; 92 1.1 christos $first_td = 1; 93 1.1 christos # Now start scanning. We basically print everything after translating some tags. 94 1.1 christos # $token->[0] has "T", "S", "E" for Text, Start, End 95 1.1 christos # $token->[1] has the tag name, or text (for "T" case) 96 1.1 christos # Theres lots more in the world of tokens, but who cares? 97 1.1 christos while (my $token = $p->get_token) { 98 1.1 christos if($token->[0] eq "T") { 99 1.1 christos my $text = $token->[1]; 100 1.1 christos if (!$pre) { 101 1.1 christos if($tag) { 102 1.1 christos $text =~ s/^[\n\t ]*//; 103 1.1 christos } 104 1.1 christos $text =~ s/^[\n\t ][\n\t ]+$//; 105 1.1 christos $text =~ s/[\n\t ]+/ /g; 106 1.1 christos $text =~ s/ \;/ /g; 107 1.1 christos $text =~ s/>\;/>/g; 108 1.1 christos $text =~ s/<\;/</g; 109 1.1 christos $text =~ s/"\;/"/g; 110 1.1 christos $text =~ s/&\;/&/g; 111 1.1 christos $text =~ s/^\./\\[char46]/; 112 1.1 christos } 113 1.1 christos print MANOUT "$text"; 114 1.1 christos $tag = 0; 115 1.1 christos } 116 1.1 christos if($token->[0] eq "S") { 117 1.1 christos if($token->[1] eq "h4") { 118 1.1 christos my $text = uc($p->get_trimmed_text("/h4")); 119 1.1 christos # ignore these sections in ntpd.html 120 1.1 christos if ($filename eq "ntpd" && 121 1.1 christos ($text eq "CONFIGURATION OPTIONS")) { 122 1.1 christos $ignore = 1; 123 1.1 christos close(MANOUT); 124 1.1 christos open(MANOUT, ">/dev/null"); 125 1.1 christos } elsif ($ignore) { 126 1.1 christos $ignore = 0; 127 1.1 christos close(MANOUT); 128 1.1 christos open(MANOUT, ">>$fileout"); 129 1.1 christos } 130 1.1 christos print MANOUT "\n\n.SH $text\n"; 131 1.1 christos } 132 1.1 christos if($token->[1] eq "tt") { 133 1.1 christos push @fontstack, "tt"; 134 1.1 christos print MANOUT "\\fB"; 135 1.1 christos } 136 1.1 christos if($token->[1] eq "i") { 137 1.1 christos push @fontstack, "i"; 138 1.1 christos print MANOUT "\\fI"; 139 1.1 christos } 140 1.1 christos if($token->[1] eq "address") { 141 1.1 christos my $text = $p->get_trimmed_text("/address"); 142 1.1 christos print MANOUT "\n.SH AUTHOR\n$text\n"; 143 1.1 christos } 144 1.1 christos if($token->[1] eq "dt" || $token->[1] eq "br" && $deflevel > 0) { 145 1.1 christos print MANOUT "\n.TP 8\n"; 146 1.1 christos $tag = 1; 147 1.1 christos } 148 1.1 christos if($token->[1] eq "dd") { 149 1.1 christos print MANOUT "\n"; 150 1.1 christos $tag = 1; 151 1.1 christos } 152 1.1 christos if($token->[1] eq "dl") { 153 1.1 christos $deflevel+=1; 154 1.1 christos if ($deflevel > 0) { 155 1.1 christos print MANOUT "\n.RS ", $deflevel > 1 ? 8 : 0; 156 1.1 christos } 157 1.1 christos } 158 1.1 christos if($token->[1] eq "p") { 159 1.1 christos print MANOUT "\n"; 160 1.1 christos } 161 1.1 christos if($token->[1] eq "pre") { 162 1.1 christos print MANOUT "\n.nf"; 163 1.1 christos $pre = 1; 164 1.1 christos } 165 1.1 christos if($token->[1] eq "table") { 166 1.1 christos print MANOUT "\n.TS\n"; 167 1.1 christos print MANOUT "expand allbox tab(%);\n"; 168 1.1 christos print MANOUT $table_headers{$filename}; 169 1.1 christos print MANOUT "\n"; 170 1.1 christos } 171 1.1 christos if($token->[1] eq "td") { 172 1.1 christos if ($first_td == 0) { 173 1.1 christos print MANOUT " % "; 174 1.1 christos } 175 1.1 christos $first_td = 0; 176 1.1 christos } 177 1.1 christos } 178 1.1 christos elsif($token->[0] eq "E") { 179 1.1 christos if($token->[1] eq "h4") { 180 1.1 christos $tag = 1; 181 1.1 christos } 182 1.1 christos if($token->[1] eq "tt") { 183 1.1 christos $f = pop @fontstack; 184 1.1 christos if($f ne "tt") { 185 1.1 christos warn "Oops, mismatched font! Trying to continue\n"; 186 1.1 christos } 187 1.1 christos if ($#fontstack < 0) { $fontswitch = "\\fR"; } 188 1.1 christos elsif ($fontstack[$#fontstack] eq "tt") { $fontswitch = "\\fB"; } 189 1.1 christos else { $fontswitch = "\\fI"; } 190 1.1 christos print MANOUT "$fontswitch"; 191 1.1 christos } 192 1.1 christos if($token->[1] eq "i") { 193 1.1 christos $f = pop @fontstack; 194 1.1 christos if($f ne "i") { 195 1.1 christos warn "Oops, mismatched font! Trying to continue\n"; 196 1.1 christos } 197 1.1 christos if ($#fontstack < 0) { $fontswitch = "\\fR"; } 198 1.1 christos elsif ($fontstack[$#fontstack] eq "tt") { $fontswitch = "\\fB"; } 199 1.1 christos else { $fontswitch = "\\fI"; } 200 1.1 christos print MANOUT "$fontswitch"; 201 1.1 christos } 202 1.1 christos if($token->[1] eq "dl") { 203 1.1 christos if ($deflevel > 0) { 204 1.1 christos print MANOUT "\n.RE"; 205 1.1 christos } 206 1.1 christos print MANOUT "\n"; 207 1.1 christos $deflevel-=1; 208 1.1 christos } 209 1.1 christos if($token->[1] eq "p") { 210 1.1 christos print MANOUT "\n"; 211 1.1 christos $tag = 1; 212 1.1 christos } 213 1.1 christos if($token->[1] eq "pre") { 214 1.1 christos print MANOUT "\n.fi"; 215 1.1 christos $pre = 0; 216 1.1 christos } 217 1.1 christos if($token->[1] eq "table") { 218 1.1 christos print MANOUT ".TE\n"; 219 1.1 christos } 220 1.1 christos if($token->[1] eq "tr") { 221 1.1 christos print MANOUT "\n"; 222 1.1 christos $first_td = 1; 223 1.1 christos } 224 1.1 christos } 225 1.1 christos } 226 1.1 christos if ($ignore) { 227 1.1 christos close(MANOUT); 228 1.1 christos open(MANOUT, ">>$fileout"); 229 1.1 christos } 230 1.1 christos print MANOUT "\n.SH SEE ALSO\n\n"; 231 1.1 christos print MANOUT "$fileinfo->[2]\n\n"; 232 1.1 christos print MANOUT "$seealso_disclaimer\n"; 233 1.1 christos close(MANOUT); 234 1.1 christos } 235