diff --git a/build.tools/bsd2man b/build.tools/bsd2man new file mode 100755 index 0000000..fc9c590 --- /dev/null +++ b/build.tools/bsd2man @@ -0,0 +1,245 @@ +#! /usr/bin/perl +# +# Does a first approximation of converting a BSD man page into something +# suitable for GNO. Note that you still have to review the output of +# this filter -- no everything is handled, nor is everything handled +# correctly. +# +# $Id: bsd2man,v 1.1 1997/03/05 04:43:54 gdr Exp $ +# +# Devin Reade, December 1996 +# + +$last_nm = ''; # previously used function name +$title_printed = 0; # has the title line been printed? + +$chapterNames{'0'} = 'General Information'; +$chapterNames{'1'} = 'Commands and Applications'; +$chapterNames{'2'} = 'System Calls'; +$chapterNames{'3'} = 'Library Routines'; +$chapterNames{'4'} = 'Devices'; +$chapterNames{'5'} = 'File Formats'; +$chapterNames{'6'} = 'Games'; +$chapterNames{'7'} = 'Miscellaneous'; +$chapterNames{'8'} = 'System Administration'; +$chapterNames{'L'} = 'Local'; +$chapterNames{'N'} = 'New'; + +$authorCount = 0; + +while (<>) { + chop; + study; + + # ignore the following (no change in behavior) + # .sp + # .I + + if (/^.%A\s+(.*)$/) { # authors + $line = $1; + $line =~ s/\s+$//; + $authors[$authorCount++] = $line; + next; + + } else { + if ($authorCount > 0) { + printf("by\n"); + for ($i=0; $i<$authorCount-1; $i++) { + printf("%s,\n", $authors[$i]); + } + printf("%s.\n", $authors[$authorCount-1]); + $authorCount = 0; + } + } + + if (/^\.It\s+Bq\s+Er\s+(.*)$/) { # list item + $line = $1; + $line =~ s/\s+$//; + printf(".IP \\fB%s\\fR\n", $line); + + } elsif (/^\.(sp|I|\\\"|if)/) { # pass through verbatim + printf("%s\n", $_); + + } elsif (/^\.(Ar|Dv|El|Pp|Re|Rs|Sh|Va|%B|%T)/) { # simple replacement + $oldval = $1; + ($oldval eq 'Ar') && (s/$oldval/BR/); # argument + ($oldval eq 'Dv') && (s/$oldval/BR/); # macro value (approx) + ($oldval eq 'El') && (s/$oldval/RE/); # end list + ($oldval eq 'Pp') && (s/$oldval/LP/); # paragraph + ($oldval eq 'Re') && (s/$oldval/RE/); # relative indent end + ($oldval eq 'Rs') && (s/$oldval/RS/); # relative indent start + ($oldval eq 'Va') && (s/$oldval/IR/); # variable + ($oldval eq '%B') && (s/$oldval/B/); # programmer's sup docs + ($oldval eq '%T') && (s/$oldval/I/); # title + if ($oldval eq 'Sh') { # section header + if ($title_printed == 0) { + $title_printed++; + + printf(".TH %s %s %s %s \"%s\"\n", $pagename, $chapter, $date, + $os, defined($chapterNames{$chapter}) ? + $chapterNames{$chapter} : '(unlisted chapter)'); + } + s/$oldval/SH/; + } + printf("%s\n", $_); + + } elsif (/^\.Xr\s+(\S+)\s*(.*)$/) { # cross reference + $xref = $1; + $rest = $2; + if ($rest =~ /^\d+/) { + $section = int($&); + $rest = $'; + } else { + $section = -1; + } + $rest =~ s/\s+//g; + if ($section == -1) { + printf(".BR %s %s\n", $xref, $rest); + } else { + printf(".BR %s (%s)%s\n", $xref, $section, $rest); + } + + } elsif (/^\.(Nm)\s*$/) { # missing referent + $oldval = $1; + ($oldval eq 'Nm') && printf(".BR %s\n", $last_nm); + + } elsif (/^\.(Nm)\s+([\"\'][^\"\']*[\"\'])\s*(.*)$/) { + # quoted first argument + $oldval = $1; + $first = $2; + $rest = $3; + + if ($oldval eq 'Nm') { + $last_nm = $first; + $oldval = 'BR'; + } + if (($rest =~ /\s/) && !($rest =~ /[\"\']/)) { + printf(".%s %s \"%s\"\n", $oldval, $first, $rest); + } else { + printf(".%s %s %s\n", $oldval, $first, $rest); + } + + } elsif (/^\.(Nm)\s+(\S+)\s*(.*)$/) { + # unquoted first argument + $oldval = $1; + $first = $2; + $rest = $3; + + if ($oldval eq 'Nm') { + $last_nm = $first; + s/$oldval/BR/; + } + printf ("%s\n", $_); + + } elsif (/^\.Fd\s+(.*)$/) { # function define (?) + printf(".br\n%s\n", $1); + + } elsif (/^\.Ft\s+(.*)$/) { # function type + printf(".sp 1\n%s\n", $1); + + } elsif (/^\.Fn\s+(\S+)\s*(.*)$/) { # function name, perhaps with protos + $n = $1; + $rest = $2; + if ($rest =~ /[\"\']/) { + $rest =~ s/^\s*[\"\']/\(/; + $rest =~ s/\"\s+\"/, /g; + $rest =~ s/[\"\']\s*$/\);/; + printf ("%s %s\n", $n, $rest); + } else { + printf (".BR %s %s\n", $n, $rest); + } + + } elsif (/^\.Fa\s+(.*)$/) { # function argument + $line = $1; + $line =~ s/\s+$//; + if (($line =~ /^\S+$/) || ($line =~ /[\"\']([^\"\']+)[\"\']/)) { + printf(".I %s\n", $line); + } elsif ($line =~ /\(?(\S+)\)?/) { + printf(".RI ( %s )\n", $1); + } else { + printf(".IR %s\n", $line); + } + + } elsif (/^\.Em/) { + @line = split; + shift @line; + $line = ''; + $firstword = ''; + $word = shift @line; + if ($word =~ /([\'\"])/) { # get the emphasized part + $quote = $1; + $firstword .= $word; + do { + $word = shift @line; + $firstword .= ' ' . $word; + } while (($word ne '') && !($word =~ /$quote/)); + } else { + $firstword .= $word; + } + $skip_space = 1; + $quote = '"'; + foreach $w (@line) { + ($quote eq '"') && ($line .= ' '.$quote) && ($quote = ''); + ($w eq 'Ns') && ($skip_space = 1) && next; + ($w eq 'Ap') && ($skip_space = 1) && ($line .= "'") && next; + if ($skip_space == 1) { + $line .= $w; + $skip_space = 0; + } else { + $line .= ' ' . $w; + } + } + ($quote eq '') && ($line .= '"'); + if ($line =~ /^\s*"(\S+)"\s*$/) { # dump unecessary quotes + $line = $1; + } + printf(".IR %s %s\n", $firstword, $line); + + } elsif (/^\.Dd\s+[\"\']?([^\"\']+)[\"\']?/) { # date + $date = '"' . $1 . '"'; + + } elsif (/^\.Os\s+(.*)$/) { # specified operating system + $os = $1; + $os =~ s/\s+$//; + $os =~ s/[\"\']//g; + if (! $os =~ /\d+\.\d+/) { + $os =~ s/BSD\s+/BSD 4./; + } + $os = '"' . $os . '"'; + + } elsif (/^\.Os\s*$/) { # unspecified operating system + $os = '""'; + + } elsif (/^\.Dt\s+(.*)\s+(\d+[\S]*)\s*$/) { # name and section number + $pagename = $1; + $chapter = $2; + $chapter =~ /(\d+)/; + $chapternumber = $&; + if (($pagename =~ /\s/) && !($pagename =~ /[\"\']/)) { + $pagename = '"' . $pagename . '"'; + } + + } elsif (/^\.Nd\s+[\"\']?([^\"\']+)[\"\']?/) { # brief description + printf ("\\- %s\n", $1); + + } elsif (/^\.Bx\s+(\d+\.\d+)(.*)$/) { # BSD version + s/^\.Bx/BSD/; + s/\s+Reno\s+/ \(Reno\) /g; + s/\s+\.\s*$/./; + printf("%s\n", $_); + + } elsif (/^\.Bl\s+/) { # begin list + printf(".RS\n"); + + } elsif (/^(\.%N)/) { # volume number. See .%B above. + s/$1/volume/; + printf("%s\n", $_); + + } elsif (/^\./) { # catch unrecognised commands + printf(STDERR "Unknown command line %d: %s\n", $., $_); + printf("%s\n", $_); + + } else { # normal line + printf("%s\n", $_); + } +}