gno/build.tools/bsd2man

247 lines
6.1 KiB
Perl
Executable File

#! /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.2 1997/10/30 04:21:56 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 (/^\.(RI|PP|SH|sp|ft|I|nf|fi|br|TH|\\\"|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", $_);
}
}