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