\nTo Table of Contents
\n\n"; $torefs = "To References
\n\n";
# the record separator is a newline followed by a dot
$/ = "\n\.";
# translate:
while( \n";
print $signature;
close(STDOUT);
}
# remove temporary file
unlink ($tempname);
}
sub handle_arguments {
if ($#ARGV < 0) {
die ($usage);
}
&NGetOpt("single", "soelim=s", "latin1", "mm", "ms", "dirgraph",
"table=s", "help");
if ($opt_help) {
print ($usage);
exit 0;
}
if ($opt_soelim) {
$soelim = $opt_soelim;
}
}
sub handle_record {
s/^\.//; # delete initial "." in first record
s/\n\.$//; # delete record separator
s/[ \t]+\n/\n/g; # delete trailing spaces and tabs
0 while s/\n\\\./\n./g; # unescape leading dots
s/^\\}$//m; # delete close of multi-line .if, .ie, and .el
# split input record
$last_cmd = $cmd if $cmd =~ /[A-Z][A-Z]/;
($cmd, $args, $text) = /^(\S+)[ \t]*(.*)\n?((.|\n)*)$/;
# we cannot just split $args, since "foo bar" is one argument
@args = &troffwords($args);
if ($opt_ms) {
&ms2html;
}
elsif ($opt_mm) {
&mm2html;
}
else {
&troff2html;
}
}
sub mm2html {
local($_) = $cmd;
# An attempt has been made to put these macros in order of
# frequency, with some consideration for parsing time.
# ??? - expand references into HTML links:
s/\[RF:(\d*)\]/[$1]<\/A>/g;
# paragraph
/^P$/ && do {
print " \n";
print &format($text), "\n";
return;
};
# space
# XXX
/^SP$/ && do {
local $i;
if ($args[0] !~ /^\d+$/) {
$args[0] = 1;
}
for (; $args[0] > 0; $args[0]--) {
print " [$FN2] " . &format($text) . "\n";
$FN2++;
warn("$prog: footnote number mismatch\n") if ($FN2 > $FN1);
return;
};
# footnote end
/^FE$/ && do {
print &format($text) . "\n";
select STDOUT;
close(FOOTNOTE);
return;
};
# displays
/^DS$/ && do {
print &format($text), "\n";
return;
};
# numbered header
/^H$/ && do {
local ($hlevel, $htext) = @args;
if ($#args < 1) {
die("$prog: `.H' must have at least two arguments\n");
}
# increment this HeaderLevel
$HeaderLevel[$hlevel - 1]++;
# zero any HeaderLevel elements greater than this one
for $i (($hlevel) .. $#HeaderLevel) {
$HeaderLevel[$i] = 0;
}
# set up ID
$HeaderID = "$HeaderLevel[0]";
for $i (1 .. ($hlevel - 1)) {
$HeaderID .= "." . $HeaderLevel[$i];
}
$name = "$HeaderID"; # unique anchor name
$num = "$HeaderID ";
$htext = &format($htext);
# table of contents
if ($hlevel <= $NR{'Cl'}) {
$pic = 0;
$eqn = 0;
$tbl = 0;
# output footnotes
if (-f "footnote.tmp") {
open(FOOTNOTE, "footnote.tmp");
while( \n";
open(TABLE, $basename);
while( \nTable $HeaderID.$tbl\n \n";
unlink($basename);
return;
}
# only expand strings in body of table
$_ = $text;
&ds2html;
# run groff
open(OUTPUT, "|groff -t -Tps -rN4 > $basename.ps");
print OUTPUT ".TS\n", $_, "\n.TE\n";
close(OUTPUT);
# convert PostScript to GIF
system "gs -r120 -q -sDEVICE=pbmraw -sOutputFile=$basename.pbm - < $basename.ps > /dev/null 2>&1";
system "pnmcrop -white $basename.pbm | pnmmargin -white 10 | ppmtogif > $basename.in.gif";
system "giftrans -t '#ffffff' $basename.in.gif > $basename.tbl.gif";
unlink "$basename.pbm", "$basename.ps", "$basename.in.gif";
print " \nTable $HeaderID.$tbl\n \n";
return;
};
/^PS$/ && do {
$pic++;
$basename = "picture.$HeaderID.$pic";
if ($opt_dirgraph) {
open(OUTPUT, "|tree2html > $basename");
print OUTPUT &format($text), "\n";
close(OUTPUT);
print " \n";
open(TABLE, $basename);
while( \nTree $HeaderID.$pic\n \n";
unlink($basename);
return;
}
# only expand strings in body of picture
$_ = $text;
&ds2html;
# run groff
open(OUTPUT, "|groff -p -Tps -rN4 > $basename.ps");
print OUTPUT ".PS\n", $_, "\n.PE\n";
close(OUTPUT);
# convert PostScript to GIF
system "gs -r120 -q -sDEVICE=pbmraw -sOutputFile=$basename.pbm - < $basename.ps > /dev/null 2>&1";
system "pnmcrop -white $basename.pbm | pnmmargin -white 10 | ppmtogif > $basename.gif";
system "giftrans -t '#ffffff' $basename.in.gif > $basename.pic.gif";
unlink "$basename.pbm", "$basename.ps", "$basename.in.gif";
print " \nFigure $HeaderID.$pic\n \n";
return;
};
/^TL$/ && do {
if ($text =~ m/(.*)(\\\(em|:)(.*)/) {
$title = $1;
$subtitle = $3;
$subtitle =~ s/<\S+>//g; # delete any HTML commands
$subtitle =~ s/^\s+//; # delete any leading whitespace
$subtitle =~ s/\s+$//; # delete any trailing whitespace
}
else {
$title = $text;
}
$title =~ s/<\S+>//g; # delete any HTML commands
$title =~ s/^\s+//; # delete any leading whitespace
$title =~ s/\s+$//; # delete any trailing whitespace
if ($subtitle =~ /\w/) {
&printtitle($subtitle);
}
else {
&printtitle("Title Page");
}
return;
};
# author or alternate format for 1st page
/^(AU|AF)$/ && do {
print "", &format($args[0]), "\n \n\n";
return;
};
# abstract start
/^AS$/ && do {
print "Abstract\n \n", &format($text), "\n \n";
return;
};
# ignored mm macros
# AE - abstract end
# EN - equation end
# DE - display end
# BE - block end
# MT - memorandum type and title
# ND - new date
# PE - picture end
# PF - page footer
# PH - page header
# S - point size & vertical spacing
# SA - right margin justification
# TC - table of contents
# TE - table end
# TM - number a technical memorandum
/^(AE|EN|DE|BE|MT|ND|PE|PF|PH|S|SA|TC|TE|TM)$/ && do {
print " \n";
print &format($text), "\n";
return;
};
# ignored groff mm macros
# COVEND - cover end
# COVER - cover start
# PGFORM - page form
# PGNH - no page header
/^(COVEND|COVER|PGFORM|PGNH)$/ && do {
print &format($text), "\n";
return;
};
# unknown mm macros
/^([A-Z]+)$/ && do {
warn("$prog: unknown mm macro, \"$cmd\"\n");
print &format($text), "\n";
return;
};
# troff requests
&troff2html;
}
sub ms2html {
# expand references into HTML links:
s/\[RF:(\d*)\]/[$1]<\/A>/g;
&popall unless
/^[LI][PL]/ || /^N[SN]$/ || /^BU[1234]/;
/^TL$/ && do {
$text =~ s/(.*) *\\\(em.*/$1/; # chop after emdash
$text =~ s/<\S+>//g; # delete any HTML commands
$title = $text;
$title =~ s/^\s+//; # delete any leading whitespace
$title =~ s/\s+$//; # delete any trailing whitespace
&printtitle("Title Page");
};
# ??? - from ms2html.
/^ST$/ && do {
print switch_font('B'), &format($text), switch_font('P');
return;
};
# author's institution
/^AI$/ && do {
print switch_font('I'), &format($text), switch_font('P'), " \n";
return;
};
# author's name
/^AU$/ && do {
print switch_font('B'), &format($text), switch_font('P'), " \n";
return;
};
# abstract begin
/^AB$/ && do {
print "Abstract\n \n", &format($text), "\n \n";
return;
};
# indented paragraph
/^PP$/ && do {
print " \n";
print &format($text), "\n";
return;
};
# ??? - from ms2html.
/^BH$/ && do {
print " \n", &format($text), "\n";
return;
};
# troff line breaks
/^br$/ && do {
# only insert a break if we need it
if ($opt_mm) {
if ($last_cmd !~ /^(HU?|P|SP|SK)$/) {
print " /g;
0 while s/\n\s*\n/\n \n/g;
0 while s/\n$/\n \n/g;
$_;
}
# Convert standard troff sequences into HTML.
sub troffize {
my ($end, $begin);
# want to convert troff special characters before we mangle any
# other elements into HTML format.
&troffescapes;
# HTML escapes
&htmlescapes;
# convert dead-key accents
s/\\AE/\Æ/g;
s/\\'([AEIOUYaeiouy])/\&$1acute;/g;
s/\\[<^]([AEIOUaeiou])/\&$1circ;/g;
s/\\`([AEIOUaeiou])/\&$1grave;/g;
s/\\o([Aa])/\&$1ring;/g;
s/\\~([ANOano])/\&$1tilde;/g;
s/\\[:"]([AEIOUYaeiouy])/\&$1uml;/g;
s/\\,([Cc])/\&$1cedil;/g;
s/\\\/([Oo])/\&$1slash;/g;
s/\\ss/\ß/g; # '
# escape sequences
s/\\%(\S+)/$1/g; # hyphenation indication
s/\\".*//g; # end of line comment "
# font changes
while (/\\f(\w|\(\w\w|\[\S+\])/) {
local $font = $1;
$font =~ s/^\((\w\w)/$1/; # \f(xx
$font =~ s/^\[(\S+)\]/$1/; # \f[xxx]
s/\\f(\w|\(\w\w|\[\S+\])/&switch_font($font)/e;
}
# number registers
while (/\\n(\w|\(\w\w|\[\S+\])/) {
local $nr = $1;
$nr =~ s/^\((\w\w)/$1/; # \n(xx
$nr =~ s/^\[(\S+)\]/$1/; # \n[xxx]
s/\\n(\w|\(\w\w|\[\S+\])/$NR{$nr}/e;
}
# size changes
s/\\s-[0-9]([\w\s\\]*)\\s0/$1/g; # ignore small text
s/\\s\+[1-9]([\w\s\\]*)\\s0/$1<\/STRONG>/g; # large
s/\\s\+[1-9]//g;
s/\\s0/<\/STRONG>/g;
}
# This should be called on any text from the document, except for
# titles, and before any other HTML commands have been inserted into
# the text.
sub htmlescapes {
s/&/&/g;
s/</g;
s/>/>/g;
}
# Convert troff escape sequences into HTML. Operates on $_.
#
# This should *only* be called from troffize
sub troffescapes {
# standard escapes
s/\\\(em/--/g; # 3/4 em dash
s/\\\(hy/-/g; # hyphen
s/\\-/-/g; # minus in current font
# bullet
if ($opt_latin1) {
s/\\\(bu/·/g;
}
else {
s/\\\(bu/o/g;
}
# square
while (s/\\\(sq/[]/) {
warn("$prog: using `[]' for `\\(sq'\n");
}
s/\\\(ru/_/g; # rule
s/\\\(14/¼/g; # 1/4
s/\\\(12/½/g; # 1/2
s/\\\(34/¾/g; # 3/4
s/\\\(fi/fi/g; # fi ligature
s/\\\(fl/fl/g; # fl ligature
s/\\\(Fi/ffi/g; # ffi ligature
s/\\\(Fl/ffl/g; # ffl ligature
# degree
if ($opt_latin1) {
s/\\\(de/°/g;
}
else {
s/\\\(de/o/g;
}
# dagger
while (s/\\\(dg/+/) {
warn("$prog: using `+' for `\\(dg'\n");
}
s/\\\(fm/'/g; #' # foot mark
# cent sign
if ($opt_latin1) {
s/\\\(ct/¢/g;
}
else {
s/\\\(ct/c/g;
}
s/\\\(rg/(R)/g; # registered
# copyright
if ($opt_latin1) {
s/\\\(co/©/g;
}
else {
s/\\\(co/(C)/g;
}
# miscellaneous characters
# section symbol
if ($opt_latin1) {
s/\\\(sc/§/g;
}
else {
s/\\\(sc/S/g;
}
s/\\\(aa/'/g; #' acute accent
s/\\\(ga/`/g; #` grave accent
s/\\\(ul/_/g; # underrule
s/\\\(->/->/g; # right arrow
s/\\\(<-/<-/g; # left arrow
s/\\\(ua/^/g; # up arrow
s/\\\(da/v/g; # down arrow
s/\\\(br/|/g; # box rule
# double dagger
while (s/\\\(dd/*/) {
warn("$prog: using `*' for \"\\(dd\"\n");
}
s/\\\(rh/=>/g; # right hand
s/\\\(lh/<=/g; # left hand
s/\\\(ci/O/g; # circle
s/\\\(vs/ /g; # visual space indicator
# mathematics symbols
s/\\\(pl/+/g; # math plus
s/\\\(mi/-/g; # math minus
s/\\\(eq/=/g; # math equals
s/\\\(\*\*/*/g; # math star
s/\\\(sl/\//g; # slash (matching backslash)
s/\\\(sr/\\\//g; # square root
s/\\\(rn//g; # root en extender
s/\\\(>=/>=/g; # greater than or equal
s/\\\(<=/<=/g; # less than or equal
s/\\\(==/==/g; # identically equal
s/\\\(~~/~~/g; # approximately equal
s/\\\(~=/~=/g; # ?
s/\\\(ap/~/g; # approximates
s/\\\(!=/!=/g; # not equal
s/\\\(mu/x/g; # multiply
s/\\\(di/\//g; # divide
s/\\\(\+-/+-/g; # plus-minus
s/\\\(cu/U/g; # cup (union)
s/\\\(ca/A/g; # cup (intersection)
s/\\\(sb/(=/g; # subset of
s/\\\(sp/=)/g; # superset of
s/\\\(ib/(_/g; # improper subset
s/\\\(ip/_)/g; # improper superset
s/\\\(if/oo/g; # infinity
s/\\\(pd/a/g; # partial derivative
s/\\\(gr/V/g; # gradient
s/\\\(no/~/g; # not
s/\\\(is/I/g; # integral sign
s/\\\(pt/oc/g; # proportional to
s/\\\(es/{}/g; # empty set
s/\\\(mo/E/g; # member of
s/\\\(or/|/g; # or
# greek charactters
if ($opt_latin1) {
s/\\\(\*b/ß/g;
s/\\\(\*m/µ/g;
}
else {
s/\\\(\*b/beta/g;
s/\\\(\*m/micro/g;
}
s/\\\(\*a/alpha/g;
# beta
s/\\\(\*g/gamma/g;
s/\\\(\*d/delta/g;
s/\\\(\*e/epsilon/g;
s/\\\(\*z/zeta/g;
s/\\\(\*y/eta/g;
s/\\\(\*h/theta/g;
s/\\\(\*i/iota/g;
s/\\\(\*k/kappa/g;
s/\\\(\*l/lambda/g;
# mu
s/\\\(\*n/nu/g;
s/\\\(\*c/xi/g;
s/\\\(\*o/omicron/g;
s/\\\(\*p/pi/g;
s/\\\(\*r/rho/g;
s/\\\(\*s/sigma/g;
s/\\\(ts/sigma/g; # terminal sigma
s/\\\(\*t/tau/g;
s/\\\(\*u/upsilon/g;
s/\\\(\*f/phi/g;
s/\\\(\*x/chi/g;
s/\\\(\*q/psi/g;
s/\\\(\*w/omega/g;
s/\\\(\*A/ALPHA/g;
s/\\\(\*B/BETA/g;
s/\\\(\*G/GAMMA/g;
s/\\\(\*D/DELTA/g;
s/\\\(\*E/EPSILON/g;
s/\\\(\*Z/ZETA/g;
s/\\\(\*Y/ETA/g;
s/\\\(\*H/THETA/g;
s/\\\(\*I/IOTA/g;
s/\\\(\*K/KAPPA/g;
s/\\\(\*L/LAMBDA/g;
s/\\\(\*M/MU/g;
s/\\\(\*N/NU/g;
s/\\\(\*C/XI/g;
s/\\\(\*O/OMICRON/g;
s/\\\(\*P/PI/g;
s/\\\(\*R/RHO/g;
s/\\\(\*S/SIGMA/g;
s/\\\(\*T/TAU/g;
s/\\\(\*U/UPSILON/g;
s/\\\(\*F/PHI/g;
s/\\\(\*X/CHI/g;
s/\\\(\*Q/PSI/g;
s/\\\(\*W/OMEGA/g;
# bracket-building symbols
s/\\\(lt/\{/g;
s/\\\(lb/\{/g;
s/\\\(rt/\}/g;
s/\\\(rb/\}/g;
s/\\\(lk/\{/g;
s/\\\(rk/\}/g;
s/\\\(bv/\|/g;
s/\\\(lf/\[/g;
s/\\\(rf/\]/g;
s/\\\(lc/\[/g;
s/\\\(rc/\]/g;
# delete characters that we cannot print
warn("$prog: deleting non-ASCII character `$1'\n") if s/(\\\(\S\S)//;
}
# Expand strings definitions. Operates on $_ and changes string
# definition escapes into the appropriate character sequence.
sub ds2html {
# \*F
while ($opt_mm && s/\\\*F/[footnote $FN1]<\/A>/) {
$FN1++;
}
# \*x
while (s/\\\*(\w)/$DS{$1}/) {
warn("$prog: warning: `$1' not defined\n") unless $DS{$1};
}
# \*(xx for a two character name
while (s/\\\*\((\w\w)/$DS{$1}/) {
warn("$prog: warning: `$1' not defined\n") unless $DS{$1};
}
# \*[xxx] for a name of arbitrary length (groff extension)
while (s/\\\*[(\w+)]/$DS{$1}/) {
warn("$prog: warning: `$1' not defined\n") unless $DS{$1};
}
}
# Based on `shellwords.pl' from the Perl 5 distribution.
#
# @words = &troffwords($line);
# @words = &troffwords(@lines);
# @words = &troffwords; # defaults to $_ (and clobbers it)
sub troffwords {
local($_) = join('', @_) if @_;
local(@words,$snippet,$field);
s/^\s+//;
/\001/ && die("$prog: bad characters in troffword: $_\n");
while ($_ ne '') {
$field = '';
s/\\ /\001/g; # escape all `\ ' to \001
for (;;) {
if (s/^"([^"]*)"//) {
$snippet = $1;
}
elsif (s/^"(.*)//) {
$snippet = $1;
}
elsif (s/^([^\s"]+)//) {
$snippet = $1;
}
else {
s/^\s+//;
last;
}
$snippet =~ s/\001/ /g; # replace \001 with a space
$field .= $snippet;
}
push(@words, $field);
}
@words;
}
Table of Contents
\n$toc\n";
if ($refs =~ /./) { print TOC $torefs; }
print TOC "
\n";
print TOC "\n";
print TOC $signature;
close(TOC);
# if there are references, print them out:
if ($refs =~ /./) {
&newpage($REFS);
&printtitle("References");
print "References
\n";
print "\n$refs\n
\n\n";
&up; print "
\n";
}
print &format($text), "\n";
return;
};
# list item
/^LI$/ && do {
print "
if there is following text. Otherwise, it
# really means that we are trying to reset the bottom block.
if ($text =~ /\S/) {
print "
\n";
}
print &format($text), "\n";
return;
};
# footnote start
/^FS$/ && do {
open(FOOTNOTE, ">> footnote.tmp");
select FOOTNOTE;
print "\n";
$TL++;
}
while ($TL > $hlevel) {
$toc .= "
\n";
$TL--;
}
if ($opt_single) {
print $totoc;
$toc .= "
\n";
}
print &format($text), "\n";
return;
};
/^TS$/ && do {
$tbl++;
$basename = "table.$HeaderID.$tbl";
if ($opt_table ne "none") {
if ($opt_table eq "break") {
open(OUTPUT, "|tbl2html --break > $basename");
}
else {
open(OUTPUT, "|tbl2html > $basename");
}
print OUTPUT &format($text), "\n";
close(OUTPUT);
print ") {
print;
}
close(TABLE);
print "
\n) {
print;
}
close(TABLE);
print "
\n
\n\n";
return;
};
# ??? - from ms2html.
/^BC$/ && do {
print "
\n\n";
return;
};
# footnote -- This should be fixed to create HTML 3.0 footnotes.
/^FS$/ && do {
print " (", &format($text), ") ";
return;
};
# # from ms2html
# /^FS$/ && do {
# print "
\n\n";
# return;
# };
# quoted paragraph
/^QP$/ && do {
print "\n", &format($text), "\n
\n";
return;
};
# displays
/^DS$/ && do {
print &format($text), "\n";
return;
};
#XXX # don't distinguish LP, LL & IP for nesting purposes:
/^LP$/ && do {
&listitem("LP"); print "
\n\n";
return;
};
/^MT$/ && do {
$mt++;
print "
\n\n";
return;
};
/^ML$/ && do {
$ml++;
print "
\n\n";
return;
};
/^MP$/ && do {
$mp++;
print "
\n\n";
return;
};
/^PR$/ && do {
print "
\n\n";
return;
};
if (/^([NS])H(\d)$/) {
# skip if this is the reference section:
if (($text eq "References") || ($text eq "Bibliography"))
{ return; };
$stype = $1; # numbered or unnumbered sections
$H = $2; # the header level
if ($H == 1) {
if ($stype =~ /N/) { $n1++; $n2 = $n3 = $n4 = 0; $id = "$n1"; }
else { $s1++; $s2 = $s3 = $s4 = 0; $id = "$s1"; }
}
elsif ($H == 2) {
if ($stype =~ /N/) { $n2++; $n3 = $n4 = 0; $id = "$n1.$n2"; }
else { $s2++; $s3 = $s4 = 0; $id = "$s1.$s2"; }
}
elsif ($H == 3) {
if ($stype =~ /N/) { $n3++; $n4 = 0; $id = "$n1.$n2.$n3"; }
else { $s3++; $s4 = 0; $id = "$s1.$s2.$s3"; }
}
elsif ($H == 4) {
if ($stype =~ /N/) { $n4++; $id = "$n1.$n2.$n3.$n4"; }
else { $s4++; $id = "$s1.$s2.$s3.$s4"; }
}
while ($TL < $H) { $toc .= "\n"; $TL++; }
while ($TL > $H) { $toc .= "
\n"; $TL--; }
$name = "${stype}-$id"; # unique anchor name
if ($stype =~ /N/) { $num = "$id "; }
else { $num = ""; }
# start a new page unless $opt_single was set
if (!$opt_single) {
$NEXT = "$BASE-$name.html" ;
&popall;
&newbody($NEXT);
&printtitle("${num}$text");
}
$inbody = 1;
print "\n", &format($text), "\n";
return;
};
# troff "fill mode"
/^fi$/ && do {
print "
\n", &format($text), "\n";
return;
};
# number registers
/^nr$/ && do {
$args[1] =~ s/^\\\\/\\/g;
$NR{$args[0]} = &format($args[1]);
print &format($text), "\n";
return;
};
# remove register
/^rr$/ && do {
undef($NR{$args[0]});
print &format($text), "\n";
return;
};
# set string definitions
/^ds$/ && do {
local($name);
$name = shift(@args);
$_ = join(' ', @args); # want every remaining argument
&troffize; # convert only troff escapes
s/\n$//; # don't want trailing newline
$DS{$name} = $_;
print &format($text), "\n";
return;
};
# troff spaces
/^sp$/ && do {
print "
\n";
}
}
else {
print "
\n";
}
print &format($text), "\n";
return;
};
# ignored troff requests
# lf - change line number
# nh - no hyphenation
# af - assign format to register
/^(lf|nh|af)$/ && do {
print &format($text), "\n";
return;
};
# empty command!?
/^$/ && do {
warn("$prog: empty command\n");
print &format($text), "\n";
return;
};
# ie XXX
/^ie$/ && do {
warn("$prog: .ie is false\n");
return;
};
# else XXX
/^el/ && do {
warn("$prog: .el is true\n");
print &format($text), "\n";
return;
};
# unknown troff commands
(/^[a-z]*$/) && do {
warn("$prog: unknown troff command, \"$cmd\"\n");
print &format($text), "\n";
return;
};
warn("$prog: unrecognized command, \"$cmd\"\n");
print &format($text), "\n";
}
# Close the current body page and open a new one.
sub newbody {
local($NEXT_LINK, $NEXT_TEXT) = @_;
$NEXT_TEXT =~ s/\s+$//;
&popall;
if ($inbody) {
print "
\n";
if (defined($PREV_TEXT)) {
print "\nPrevious: $PREV_TEXT
\n";
}
print "Next: $NEXT_TEXT
\n";
print "Up: Table of Contents\n";
print "
\n";
print $signature;
}
if (select != STDOUT) {
die("$prog: filehandle is not STDOUT\n");
}
close(STDOUT);
$PREV_LINK = $CURR;
$CURR = $NEXT_LINK;
$PREV_TEXT = $CURR_TEXT;
$CURR_TEXT = $NEXT_TEXT;
&newpage($CURR);
}
# terminate the last body page:
sub lastbody {
local($NEXT_LINK);
&popall;
if ($opt_mm) {
print "
";
if ($last_cmd !~ /^SK$/) {
print "
"
}
print "\n";
}
else {
print "
\n";
}
# pointer to next only if references exist:
if ($refs =~ /./) {
$NEXT_LINK = $REFS; &next;
};
if (! $opt_single) {
print "\nPrevious: $PREV_TEXT
\n";
# pointer to next only if references exist:
if ($refs =~ /./) {
print "Next: References
\n";
};
print "Up: Table of Contents\n";
print "
\n";
# clean up:
print $signature;
}
if (select != STDOUT) {
die("$prog: filehandle is not STDOUT\n");
}
close(STDOUT);
}
# open a new page
sub newpage {
local($PAGE) = @_;
if (select != STDOUT) {
die("$prog: filehandle is not STDOUT\n");
}
open(STDOUT, ">$PAGE") || die "fatal error: Can't create $PAGE";
print STDERR "Created $PAGE\n";
}
# start a new list
sub newlist_mm {
local($type) = @_; # type of list
if ($type eq "BL") { print "\n\n"; }
elsif ($type eq "DL") { print "\n
\n"; }
# this should never happen
else {
die("$prog: (poplist_mm) unknown list type `$type'\n");
}
}
# pop out of all remaining lists
sub popall {
while ($#lstack > 0) {
if ($opt_mm) {
&poplist_mm;
}
}
}
# yep, you guessed it!
sub printtitle {
local($name) = @_;
print <\n"; }
elsif ($type eq "ML") { print "\n
\n"; }
elsif ($type eq "AL") { print "\n"; }
elsif ($type eq "DL") { print "\n"; }
elsif ($type eq "VL") { print "\n
\n"; }
elsif ($type eq "VL") { print "\n"; }
elsif ($type eq "AL") { print "\n
\n"; }
elsif ($type eq "LB") { print "\n"; }
elsif ($type eq "ML") { print "\n"; }
elsif ($type eq "LB") { print "\n
\n"; }
# this should never happen
else {
die("$prog: (newlist_mm) unknown list type `$type'\n");
}
push(@lstack,$type);
}
# pop the current list
sub poplist_mm {
local($type);
$type = pop(@lstack);
if ($type eq "BL") { print "
$title - $name
\n\n";
}
else {
print "$title
\n\n";
}
}
# This function formats regions of troff text
sub format {
local($_) = join('',@_);
&troffize; # convert standard troff sequences
&ds2html; # convert string definitions
&html'href; #' change URLs into hypertext links
0 while s/\n\s*$/\n