# Crunch option documentation from CWEB/TeX .w format
# to (more or less) TROFF format for a manual page.
# by John Walker -- October 2002
# perl cwebtex2man.pl input_file.w output_file.1
# This is not remotely general; it assumes the precise
# format used by the documentation of this program
# and still requires some manual fix-up.
if ($#ARGV != 1) {
print(STDERR "Usage: perl cwebtex2man.pl input_file.w output_file.1\n");
exit(2);
}
$ifname = $ARGV[0];
$ofname = $ARGV[1];
$product = 'annoyance-filter';
open(FI, "<$ifname") || die("Cannot open input file $ifname");
$indent = ' 10'; # Indentation for first .TP command
$prevpp = $lastpp = 0;
open(OF, ">$ofname") || die("Cannot create output file $ofname");
while ($l = <FI>) {
$l =~ s/\s+$//;
if ($l =~ m/^%/) {
next; # Line with % in column is comment--ignore
}
if (length($l) == 0) {
if ($lastpp == 0) {
print(OF ".PP\n"); # Input blank line is paragraph break
$lastpp = 1;
}
next;
}
$prevpp = $lastpp;
$lastpp = 0;
# print "L: $l\n";
if ($l =~ m/^\\opt\{/) {
# print("Opt: $l\n");
print(OF ".TP$indent\n");
$indent = '';
$l =~ s/\{\\rm, \}/,/;
#print("Lmod: ($l)\n");
$l =~ s/\\opt\{([^\s\}]+)//;
$oname = $1;
#print("Oname: ($oname) L = ($l)\n");
$l =~ s/^\s+//; # Strip leading spaces
undef $optarg;
if ($l =~ s/\{\\it ([^\}]+)\}//) {
$optarg = $1;
#print("Optarg = ($optarg)\n");
}
$l =~ s/^\}\{//;
#print("Rline: ($l)\n");
# Emit option line for single or variant options
$oname =~ s/-/\\-/g; # Convert hyphens to TROFF dashes
$twopts = 0;
if ($oname =~ m/,/) {
$twopts = 1;
if (defined $optarg) {
$oname =~ s/,/, /; # Insert space after comma
$oname = "\"$oname\""; # Quote entire option
} else {
$oname =~ s/,/ ", " /; # Expand to use with .BR
}
}
# Now we're ready to generate the option line
#print("ONAME: ($oname)\n");
if (defined $optarg) {
print(OF ".BI $oname \" $optarg\"\n");
} else {
if ($twopts) {
print(OF ".BR $oname\n");
} else {
print(OF ".B $oname\n");
}
}
&xform;
if (length($l) > 0) {
print(OF "$l\n"); # Copy on balance of \opt line, if any
}
} else {
&xform;
if (length($l) > 0) {
print(OF "$l\n"); # Body copy line
}
}
}
close(OF);
# Transform body copy, converting control sequences
sub xform {
$pl = '[\(`]+$'; # Punctuation subsumed at left
$pr = '^[\'\),\.]+'; # Punctuation subsumed at right
while ($l =~ m/\\([^\s\{]+)/) {
$before = $l;
$texcmd = $1;
#print("Texcmd = ($texcmd)\n");
# Handle \bigskip escape
if ($texcmd eq 'bigskip') {
$l =~ m/(^[^\\]*)\\([^\s\{]+)(.*)$/;
$left = $1;
$arg = $2;
$right = $3;
if (length($left) > 0) {
print(OF "$left\n");
}
$l = $right;
if ((length($left) == 0) && (length($right) == 0)) {
$lastpp = $prevpp;
}
# Handle \.{text} escape
} elsif ($texcmd eq '.') {
#print("Dot escape\n");
$l =~ m/^([^\\]*)\\\.\{([^\}]*)\}(.*)$/;
#print ("Dot escape ($1) : ($2) : ($3)\n");
# Store parsed left, command, and right into variables
$left = $1;
$arg = $2;
$right = $3;
$arg =~ s/-/\\-/g; # Convert hyphens to TROFF dashes
$fcmd = 'B';
&subsume;
# Handle {\it text} sequence
} elsif ($texcmd eq 'it') {
$l =~ m/(^[^\{]*)\{\\it\s+([^\}]*)\}(.*)$/;
# Store parsed left, command, and right into variables
$left = $1;
$arg = $2;
$right = $3;
$fcmd = 'I';
&subsume;
# Handle \UNIX/ macro
} elsif ($texcmd eq 'UNIX/') {
$l =~ m/(^[^\\]*)\\([^\s\{]+)(.*)$/;
$left = $1;
$arg = 'Unix';
$right = $3;
$fcmd = 'B';
&subsume;
# Handle \aletter{c}{description} sequence.
# This is even more of a special case than the
# ones above.
} elsif ($texcmd eq 'aletter') {
#print("aletter ($l)\n");
$l =~ m/^([^\\]*)\\aletter\{([^\}]*)\}\{([^\}]*)\}(.*)$/;
$left = $1;
$arg1 = $2;
$arg2 = $3;
$right = $4;
#print("aletter ($left) ($arg1) ($arg2) ($arg3)\n");
$left =~ s/\s+$//;
$right =~ s/^\s+//;
if (length($left) > 0) {
print(OF "$left\n");
}
print(OF ".br\n");
print(OF ".BR \" $arg1 \" \"$arg2\"\n");
$l = $right;
} else {
print(STDERR "!! Undefined command ($texcmd) in ($l)\n");
$l =~ m/(^[^\\]*)\\([^\s\{]+)(.*)$/;
$left = $1;
$arg = $2;
$right = $3;
$left .= "(***$arg***)";
print(OF "$left\n");
$l = $right;
}
#print("Before: >>$before<<\n");
#print("After: Left: >>$left<< Arg: >>$arg<< Right: >>$right<<\n");
}
# Check for trailing right bracket marking end of
# option description text and delete.
$l =~ s/\s*\}$//;
# Translate em-dashes
$l =~ s/---/\\\(em/g;
}
# Subsume adjacent punctuation into sequence
sub subsume {
$pl = '[\(`]+$'; # Punctuation subsumed at left
$pr = '^[\'\),\.]+'; # Punctuation subsumed at right
# Strip white space from bleeding ends of left and right parts
$left =~ s/\s+$//;
$right =~ s/^\s+//;
# Check for and subsume parentheses and quotes around literal text
$lp = $rp = '';
if (($left =~ m/$pl/) || ($right =~ m/$pr/)) {
$fcmd = "R$fcmd";
if ($left =~ s/($pl)//) {
$lp = $1;
$left =~ s/\s+$//;
}
if ($right =~ s/($pr)//) {
$rp = $1;
$right =~ s/^\s+//;
}
#print("RI lp = ($lp) left = ($left) rp = ($rp) right = ($right)\n");
}
if (length($left) > 0) {
print(OF "$left\n");
}
$arg =~ s/\\\$/\$/g;
if (length($fcmd) == 2) {
printf(OF ".$fcmd \"$lp\" \"$arg\" \"$rp\"\n");
} else {
print(OF ".$fcmd \"$arg\"\n");
}
#print("I2 = ($left) A = ($arg) R = ($right)\n");
$l = $right;
}
syntax highlighted by Code2HTML, v. 0.9.1