sophuwu.site > manhttpd
forgot to push for a while but made a server
sophuwu sophie@skisiel.com
Fri, 29 Dec 2023 19:17:54 +0100
commit

2819aed3caf5778288da866279ecfd9ae588be45

7 files changed, 1492 insertions(+), 0 deletions(-)

jump to
A .gitignore

@@ -0,0 +1,2 @@

+.idea +build/
A go.mod

@@ -0,0 +1,3 @@

+module manpages + +go 1.21.5
A main.go

@@ -0,0 +1,40 @@

+package main + +import ( + "bytes" + "log" + "net/http" + "os/exec" + "path/filepath" + "strings" +) + +func main() { + http.HandleFunc("/cgi-bin/man/", handleWIS) + log.Println("Starting server on http://localhost:1234") + log.Fatal(http.ListenAndServe(":1234", nil)) +} + +func handleWIS(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html") + exe := filepath.Base(r.URL.Path) + if !(exe == "man2html" || exe == "mansearch" || exe == "mansec" || exe == "manwhatis") { + http.Error(w, "Not found", http.StatusNotFound) + return + } + q := "" + if strings.Contains(r.URL.String(), "?") { + q = strings.SplitN(r.URL.String(), "?", 2)[1] + } + cmd := exec.Command("/usr/lib/cgi-bin/man/"+exe, "-bare") + var buff bytes.Buffer + cmd.Env = append(cmd.Env, "QUERY_STRING="+q, "REQUEST_METHOD="+r.Method, "SERVER_NAME=localhost:1234") + // cmd.Env = append(cmd.Env, "MANPATH=/usr/man:/usr/share/man:/usr/local/man:/usr/local/share/man:/usr/X11R6/man:/opt/man:/snap/man") + cmd.Stdout = &buff + err := cmd.Run() + if err != nil { + http.Redirect(w, r, "/cgi-bin/man/man2html", http.StatusTemporaryRedirect) + return + } + buff.WriteTo(w) +}
A one/help.sh

@@ -0,0 +1,1 @@

+man ../share/man/man1/man2html.1.gz | ./man2html -botm 0 -cgiurl '/page/$section/$title' -leftm 0 -noheads -topm 0 > man2.html
A one/man.cgi

@@ -0,0 +1,404 @@

+#!/usr/bin/perl +##---------------------------------------------------------------------------## +## File: +## @(#) man.cgi 1.2 97/08/12 12:58:26 @(#) +## Author: +## Earl Hood ehood@medusa.acs.uci.edu +## Description: +## man.cgi is a CGI program for viewing Unix manpages. The +## program man2html, +## <URL:http://www.oac.uci.edu/indiv/ehood/man2html.html>, +## is used to convert the output from man(1) to html. +## +## If man.cgi is invoked with no input data, it will output a +## form for the user to select a manpage to view. +## man.cgi can handle POST and GET methods. +## +## The code section "Configureable Globals" is designed to +## allow you to modify man.cgi to work with your particular +## system configuration. +##---------------------------------------------------------------------------## +## Copyright (C) 1995-1997, Earl Hood, ehood@medusa.acs.uci.edu +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +## 02111-1307, USA +##---------------------------------------------------------------------------## + +######################################################################## +## Configureable Globals +######################################################################## +## Change the value of these variables to reflect your +## system configuration. +######################################################################## + +## "English" name for program + +$ProgName = "Manpage Viewer"; + +## cgi-bin directory as accessed by a URL. + +$CgiBin = "/cgi-bin"; + +## man program (should be a full pathname) + +$ManPrg = '/usr/bin/man'; + +## man(1) option to specify a section. "-s" is used for Solaris +## systems. If using Tom Christiansen's Perl man program, than +## define use "". + +#$SectOpt = ""; +$SectOpt = "-s"; + +## man2html program (needs to be a full pathname) + +$ManConvPrg = '/usr/bin/man2html'; + +## Flag if the -cgiurl option should be used + +$DoCgiurl = 1; + +## System specific arguments to man2html: +## HP => ("-leftm", "1", "-topm", "8") +## Sun => ("-sun") +## See man2html documentation for more information. + +#@ConvArgs = ("-compress"); +#@ConvArgs = ("-compress", "-leftm", "1", "-topm", "8"); +@ConvArgs = ("-compress", "-sun"); + +## Keyword search processing arguments for man2html. Normally, +## '-k' is adequate. However, if on a Solaris system, the +## '-solaris' option should be specified with '-k'. See +## man2html documentation on information about the '-solaris' option. + +#@KeyWArgs = ("-k"); # Normal +@KeyWArgs = ("-k", "-solaris"); # For Solaris + +## Possible manual sections. This array is used to determine the +## the choices available in an option menu. + +@Sections = ( + '1', '1F', '1M', + '2', + '3', '3C', '3F', '3G', '3I', '3N', '3S', '3X', + '4', + '5', + '6', + '7', + '8', + '9', '9F', +); + +## Form method. The value is either 'GET' or 'POST'. 'GET' is +## recommended since the URL sent by the client also contains +## the argument information. This allows a client's "Reload" function +## to reprocess a currently viewed manpage. + +$FormMethod = 'GET'; + +## Argument separator for CGI URL links. As clients become more +## SGML conformant, the simple use of '&' conflicts with +## SGML syntax. You can set this variable to control what is +## used as the separator. Possibilities: +## &amp; +## &#38; +## ; +## + +$ArgSep = '&'; + +## Man directories. Add paths to the list you want man(1) to +## know about + +@ManPath = qw( + /usr/man + /usr/openwin/man + /usr/man +); + +## PATH setting. Modify as see fit. Once useful modification +## is to have groff utils first in path since its nroff would +## be invoked over the systems nroff when man formats a manpage. + +@Path = qw( + /opt/FSFgroff/bin + /bin + /usr/bin +); + +######################################################################## +## END!!!! Configureable Globals section +######################################################################## + +######################################################################## +## Globals +######################################################################## + +($PROG = $0) =~ s/.*\///; # Name of program +$VERSION = '2.0.1'; # Version +%FORM = (); # Hash to hold form contents +$Error = ''; # Error string +$ENV{'MANPATH'} = join(":", @ManPath); +$ENV{'PATH'} = join(":", @Path); + +######################################################################## +## Main block +{ + # Set unbuffered I/O. Prevents buffering problems with + # "system()" calls. + select((select(STDOUT), $| = 1)[0]); + + # Print content-type header + printouttype("text/html"); + + # Print man form if called w/no arguments + printform() if noarg(); + + # If reached here, there is input to process + error("CGI input error") unless parseinput(); + printform() unless $FORM{'topic'}; + doit(); + exit 0; +} +######################################################################## +## Subroutines +######################################################################## + +#----------------------------------------------------------------------- +# printform outputs the man selection form to the client. +# +sub printform { + printhead($ProgName); + print STDOUT <<EndOfForm; +<p>The following form allows you to view a manpage on this system. +Please fill out the following fields and select <strong>Submit</strong> +to view a manpage. +</p> +<form method="$FormMethod" action="$CgiBin/man.cgi"> +<table border=0> +<tr> +<td align=right>Section:</td> +<td><select name=section> +<option value="all">All Sections</option> +<option value="keyword">Keyword Search</option> +EndOfForm + + # Print out possible section choices + local($section); + foreach $section (@Sections) { + print STDOUT qq|<option value="$section">Section $section</option>\n|; + } + +print STDOUT <<EndOfForm; +</select> +</td> +</tr> +<tr> +<td align=right>Topic:</td> +<td><input type="TEXT" name="topic"></td> +</tr> +<tr> +<td></td><td><input type="SUBMIT" value="Submit"><td> +</tr> +</table> +</form> +EndOfForm + printend(); + exit 0; +} + +#----------------------------------------------------------------------- +# doit does the conversion +# +sub doit { + my($section, $topic, $manexec, $manout, $tmp); + $manout = ''; + + # Get section and topic from input + #--------------------------------- + $section = $FORM{'section'}; + $topic = $FORM{'topic'}; + error("Questionable characters in topic") if isquestionable($topic); + + # Determine command arguments for man and man2html + #------------------------------------------------- + @ARGV = (); + @manargs = (); + $manexec = $ManPrg; + if ($section =~ /keyword/) { + $manexec .= " -k $topic"; + push(@manargs, "-k", $topic); + push(@ARGV, @KeyWArgs, + "-title", qq{Keyword search: "$topic"}); + } else { + error("No topic entered") unless $topic; + if ($section !~ /all/) { + push(@manargs, $SectOpt) if $SectOpt; + push(@manargs, $section); + } + push(@manargs, $topic); + $manexec .= " $section" if $section !~ /all/; + $manexec .= " $topic"; + $tmp = $topic; + $tmp .= "($section)" if $section !~ /all/; + push(@ARGV, @ConvArgs, + "-title", $tmp); + } + + # Check if doing man xref detection + #---------------------------------- + if ($DoCgiurl) { + push(@ARGV, "-cgiurl", + join('', $CgiBin, '/man.cgi?', + 'section=${section}${subsection}', + $ArgSep, + 'topic=${title}')); + } + + # Convert output from man to html + #-------------------------------- + close(STDERR); + open(MANPRG, "-|") or exec($ManPrg, @manargs); + $Man2Html::InFH = \*MANPRG; # set input filehandle + require $ManConvPrg or + error("Problem executing man->HTML converter"); +} + +######################################################################## +## Generic subroutines for CGI use +######################################################################## + +#----------------------------------------------------------------------- +# noarg returns true if no arguments were passed to script. +# +sub noarg { + $ENV{"REQUEST_METHOD"} eq "GET" && $ENV{"QUERY_STRING"} =~ /^\s*$/; +} + +#----------------------------------------------------------------------- +# parseinput converts the input data into the %FORM array +# +sub parseinput { + my($method) = ($ENV{"REQUEST_METHOD"}); + my($data); + if ($method eq "GET") { + $data = $ENV{"QUERY_STRING"}; + } elsif ($method eq "POST") { + read(STDIN, $data, $ENV{"CONTENT_LENGTH"}); + } else { + $Error = "Unrecgonized request method : $method"; + return 0; + } + my(@pairs, $name, $value); + if ($data ne '') { + @pairs = split(/&/, $data); + foreach (@pairs) { + ($name, $value) = split(/=/); + $name = expandstr($name); + $value = expandstr($value); + $FORM{$name} = $value; + } + } + 1; +} + +#----------------------------------------------------------------------- +# printouttype prints out specified content-type header back +# to client +# +sub printouttype { + my($type) = shift; + print STDOUT "Content-type: $type\r\n\r\n"; +} + +#----------------------------------------------------------------------- +# printhead outputs html prematter +# +sub printhead { + my($title, $h1) = @_; + $h1 = $title unless $h1; + + print STDOUT <<ENDOFHEAD; +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML//EN"> +<HTML> +<HEAD> +<TITLE>$title</TITLE> +</HEAD> +<BODY> +<H1>$h1</H1> +ENDOFHEAD +} + +#----------------------------------------------------------------------- +# printend outputs html postmatter +# +sub printend { + print STDOUT <<ENDOFEND; +<HR> +<ADDRESS> +Manpage viewer available with the +<a href="http://www.oac.uci.edu/indiv/ehood/man2html.html">man2html</a> +package. +</ADDRESS> +</BODY> +</HTML> +ENDOFEND +} + +#----------------------------------------------------------------------- +# error prints an error out to the client. +# +sub error { + my($str) = htmlize(shift); + printhead("$ProgName Error"); + $str .= ":" if $Error && $str; + $str .= " $Error"; + print STDOUT "<p>$str</p>"; + printend(); + exit 0; +} + +#----------------------------------------------------------------------- +# htmlize translates special characters to enitity refs. +# +sub htmlize { + my($str) = shift; + $str =~ s/&/\&amp;/g; + $str =~ s/</\&lt;/g; + $str =~ s/>/\&gt;/g; + $str; +} + +#----------------------------------------------------------------------- +# expandstr translates hex codes to characters +# +sub expandstr { + my($str) = shift; + $str =~ tr/+/ /; + $str =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/ge; + $str; +} + +#----------------------------------------------------------------------- +# isquestionable determines if $str contains questionable +# characters if $str is used in a subshell invocation. +# +sub isquestionable { + my($str) = shift; + $str !~ /^[a-zA-Z0-9_\-+ \t\/@%\.]+$/; +} + +########################################################################
A one/man.html

@@ -0,0 +1,433 @@

+<HTML> +<HEAD> +<TITLE>man</TITLE> +</HEAD> +<BODY> +<H1>man</H1> +<HR> +<PRE> +<!-- Manpage converted by man2html 3.0.1 --> +<B><A HREF="/page/1/MAN2HTML">MAN2HTML(1)</A></B> General Commands Manual <B><A HREF="/page/1/MAN2HTML">MAN2HTML(1)</A></B> + +NAME + man2html - convert UNIX <B><A HREF="/page/1/nroff">nroff(1)</A></B> manual pages to HTML format + +SYNOPSIS + man2html [-bare] [-belem name] [-botm lines] [-cgiurl string] + [-cgiurlexp expr] [-compress] [-headmap mapfile] [-help] [-k] + [-leftm chars] [-nodepage] [-noheads] [-pgsize lines] + [-seealso] [-solaris] [-sun] [-title string] [-topm lines] + [-uelem name] + + Typical Usage: + + man2html [-options] &lt; infile &gt; outfile + + man topic | man2html [-options] &gt; outfile + +DESCRIPTION + The man2html filter reads formatted nroff text from standard input + (stdin) and writes a HTML document to standard output (stdout). + + The formatted nroff output is surrounded with &lt;PRE&gt; tags with the fol‐ + lowing exceptions/additions: + + • Section heads are wrapped in HTML header tags. See the SEC‐ + TION HEAD MAP FILE section below for additional information. The + -noheads option can be used to disable this feature. + + • Bold words designated by a "&lt;char&gt;&lt;bs&gt;&lt;char&gt;" sequences are wrapped + in &lt;B&gt; tags (or the element specified via the -belem option). + + • Underlined words designated by a "_&lt;bs&gt;&lt;char&gt;" sequences are + wrapped in &lt;I&gt; tags (or the element specified via the -uelem op‐ + tion). + +OPTIONS + -bare + This option will eliminate HTML &lt;HEAD&gt; and &lt;BODY&gt; tags from the + output. This is useful when you wish to incorporate the output + into another HTML document. + + -belem name + Use name as the name of the element to wrap overstriken charac‐ + ters. The default is B. + + -botm lines + The lines argument specifies the number of lines representing the + bottom margin of the formatted nroff input. The line count in‐ + cludes any running footers. The default value is 7. + + -cgiurl string + The string argument specifies a template URL for creating links to + other manpages. See the LINKING TO OTHER MANPAGES section below + for additional information. + + -cgiurlexp expr + The expr argument specifies a Perl expression evaluting to a URL + for creating links to other manpages. See the LINK‐ + ING TO OTHER MANPAGES section below for additional information. + + -compress + Compress consecutive blank lines into a single line. + + -headmap mapfile + The mapfile argument is read to determine which HTML header tags + are to be used for various section heading in the manpage. See + the SECTION HEAD MAP FILE section below for information on the + format of the map file. + + -help + Print out a short usage message and then exit immediately. + + -k Process input resulting from a manpage keyword search (man -k). + See the KEYWORD SEARCH section below for additional information. + + -leftm chars + The chars argument specifies the width of the number of characters + making up the left margin of the formatted nroff input. The de‐ + fault value is 0. + + -nodepage + By default, man2html merges multi-page formatted nroff into a sin‐ + gle page. This option may be used to disable depagination, caus‐ + ing running headers and footers in the formatted nroff input to be + carried over into the HTML output. + + -noheads + By default, man2html wraps section heads in HTML header tags. See + the SECTION HEAD MAP FILE section below for additional informa‐ + tion. This option may be specified to disabled this feature. + + -pgsize lines + The lines argument specifies the number of lines making up the + page size (length) of the formatted nroff input. The default + value is 66. + + -seealso + If the -cgiurl option has been specified, then this option re‐ + stricts the creation of links to other manual pages to the + SEE ALSO section only. + + -solaris + If the -k option has been specified, then this option modifies its + operation to process the alternate manual page keyword search for‐ + mat produced by the <B><A HREF="/page/1/man">man(1)</A></B> utility on systems running Solaris. + See the KEYWORD SEARCH section below for additional information. + + -sun Do not require a section head to have bold overstriking in the + formatted nroff input. The option is called sun because it was on + a Sun workstation that section heads in manpages were found to not + be overstruck. + + -title string + By default, man2html does not generate a HTML title (&lt;TITLE&gt;). + This option sets the title of the HTML output to the specified + string. + + -topm lines + The lines argument specifies number number of lines representing + the top margin of the formatted nroff input. The line count in‐ + cludes any running headers. The default value is 7. + + -uelem name + Use name as the name of the element to wrap underscored charac‐ + ters. The default is I. + +SECTION HEAD MAP FILE + The -headmap option may be used to customize which HTML header tags, + &lt;H1&gt; ... &lt;H6&gt;, are used in manpage section headings. Normally, + man2html treats lines that are flush to the left margin (-leftm), and + contain overstriking (overstrike check is canceled with the -sun op‐ + tion), as section heads. However, you can augment/override what HTML + header tags are used for any given section head. + + In order to write a section head map file, you will need to know about + <B><A HREF="/page/1/perl">perl(1)</A></B> associative arrays. You do not need to be an expert in perl to + write a map file, however, having knowledge of perl allows you to be + more clever. + + Augmenting the Default Map + To add to the default mapping defined by man2html, your map file will + contain lines with the following syntax: + + $SectionHead{'&lt;section head text&gt;'} = '&lt;html header tag&gt;'; + + where + + &lt;section head text&gt; + is the text of the manpage section head. For example: SYNOPSIS + or DESCRIPTION. + + &lt;html header tag&gt; + is the HTML header tag to wrap the section head in. Legal val‐ + ues are: &lt;H1&gt;, &lt;H2&gt;, &lt;H3&gt;, &lt;H4&gt;, &lt;H5&gt;, &lt;H6&gt;. + + Overriding the Default Map + To override the default mapping with your own, then your map file will + have the following syntax: + + %SectionHead = ( + '&lt;section head text&gt;', '&lt;html header tag&gt;', + '&lt;section head text&gt;', '&lt;html header tag&gt;', + # ... More section head/tag pairs + '&lt;section head text&gt;', '&lt;html header tag&gt;', + ); + + The Default Map + As of this writing, this is the default map used by man2html: + + %SectionHead = ( + '\S.*OPTIONS.*' =&gt; '&lt;H2&gt;', + 'AUTHORS?' =&gt; '&lt;H2&gt;', + 'BUGS' =&gt; '&lt;H2&gt;', + 'COMPATIBILITY' =&gt; '&lt;H2&gt;', + 'DEPENDENCIES' =&gt; '&lt;H2&gt;', + 'DESCRIPTION' =&gt; '&lt;H2&gt;', + 'DIAGNOSTICS' =&gt; '&lt;H2&gt;', + 'ENVIRONMENT' =&gt; '&lt;H2&gt;', + 'ERRORS' =&gt; '&lt;H2&gt;', + 'EXAMPLES' =&gt; '&lt;H2&gt;', + 'EXTERNAL INFLUENCES' =&gt; '&lt;H2&gt;', + 'FILES' =&gt; '&lt;H2&gt;', + 'LIMITATIONS' =&gt; '&lt;H2&gt;', + 'NAME' =&gt; '&lt;H2&gt;', + 'NOTES?' =&gt; '&lt;H2&gt;', + 'OPTIONS' =&gt; '&lt;H2&gt;', + 'REFERENCES' =&gt; '&lt;H2&gt;', + 'RETURN VALUE' =&gt; '&lt;H2&gt;', + 'SECTION.*:' =&gt; '&lt;H2&gt;', + 'SEE ALSO' =&gt; '&lt;H2&gt;', + 'STANDARDS CONFORMANCE' =&gt; '&lt;H2&gt;', + 'STYLE CONVENTION' =&gt; '&lt;H2&gt;', + 'SYNOPSIS' =&gt; '&lt;H2&gt;', + 'SYNTAX' =&gt; '&lt;H2&gt;', + 'WARNINGS' =&gt; '&lt;H2&gt;', + '\s+Section.*:' =&gt; '&lt;H3&gt;', + ); + $HeadFallback = '&lt;H2&gt;'; # Fallback tag if above is not found. + + Check the perl source code of man2html for the latest default mapping. + + You can reassign the $HeadFallback variable to a different value if you + choose. This value is used as the header tag of a section head if no + matches are found in the %SectionHead map. + + Using Regular Expressions in the Map File + You may have noticed unusual characters in the default map file, like + "\s" or "*". The man2html utility actual treats the + &lt;section head text&gt; as a perl regular expression. If you are comfort‐ + able with perl regular expressions, then you have their full power to + use in your map file. + + Caution: The man2html utility already anchors the regular expression to + the beginning of the line with left margin spacing specified by the + -leftm option. Therefore, do not use the `^' character to anchor your + regular expression to the beginning. However, you may end your expres‐ + sion with a `$' to anchor it to the end of the line. + + Since the &lt;section head text&gt; is actually a regular expression, you + will have to be careful of special characters if you want them to be + treated literally. Any of the characters `[ ] ( ) . ^ { } $ * ? + |' + should be escaped by prefixing them by the `\' character if you want + perl to treat them "as is". + + Caution: One should use single quotes instead of double quotes to de‐ + limit &lt;section head text&gt;. This will preserve any `\' characters for + character escaping or when the `\' is used for special perl character + matching sequences (e.g., \s, \w, \S). + + Other Tid-bits on the Map File + Comments can be inserted in the map file by using the '#' character. + Anything after, and including, the '#' character is ignored, up to the + end of line. + + You might be thinking that the above is quite-a-bit-of-stuff just for + doing manpage section heads. However, you will be surprised how much + better the HTML output looks with header tags, even though, everything + else is in a &lt;PRE&gt; tag. + +LINKING TO OTHER MANPAGES + The man2html utility allows the ability to link to other manpage refer‐ + ences. If the -cgiurl option is specified, man2html will create an‐ + chors that link to other manpages. + + The URL entered with the -cgiurl option is actually a template that de‐ + termines the actual URL used to link to other manpages. The following + variables are defined during run time that may be used in the template + string: + + $title The title of the manual page referenced. + + $section + The section number of the manual page referenced. + + $subsection + The subsection of the manual page referenced. + + Any other text in the template is preserved "as is". + + Caution: The man2html utility evaluates the template string as a perl + string expression. Therefore, one might need to surround the variable + names with '{}' (e.g., ${title}) so that man2html properly recognizes + the variable. + + Note: If a CGI program calling man2html is actually a shell script or a + perl program, make sure to properly escape the '$' character in the URL + template to avoid variable interpolation by the CGI program. + + Normally, the URL calls a CGI program (hence the option name), but the + URL can easily link to statically converted documents. + + Example1: + The following template string is specified to call a CGI program to re‐ + trieve the appropriate manpage linked to: + + /cgi-bin/man.cgi?section=${section}${subsection}&amp;topic=${title} + + If the <B><A HREF="/page/1/ls">ls(1)</A></B> manpage is referenced in the SEE ALSO section, the above + template will translate to the following URL: + + /cgi-bin/man.cgi?section=1&amp;topic=ls + + The actual HTML markup will look like the following: + + &lt;A HREF="/cgi-bin/man.cgi?section=1&amp;topic=ls"&gt;<B><A HREF="/page/1/ls">ls(1)</A></B>&lt;/A&gt; + + Example2: + The following template string is specified to retrieve pre-converted + manpages: + + http://foo.org/man$section/$title.$section$subsection.html + + If the <B><A HREF="/page/1/mount">mount(1M)</A></B> manpage is referenced, the above template will trans‐ + late to the following URL: + + http://foo.org/man1/mount.1M.html + + The actual HTML markup will look like the following: + + &lt;A HREF="http://foo.org/man1/mount.1M.html"&gt;<B><A HREF="/page/1/mount">mount(1M)</A></B>&lt;/A&gt; + + -cgiurlexp + The option -cgiurlexp is a more general form of the -cgiurl option. + -cgiurlexp allows one to specify a general Perl expression. For exam‐ + ple: + + $title=~/^db_/i?"$title.html":"/cgi-bin/man?$title+$section" + + A -cgiurl string can be expressed as follows with -cgiurlexp: + + return "string" + +KEYWORD SEARCH + The man2html utility has the ability to process keyword search output + generated by the man -k or apropos commands, through the use of the -k + option. The man2html utility will generate an HTML document of the + keyword search input having the following format: + + • All manpage references are listed by section. + + • Within each section listing, the manpage references are sorted al‐ + phabetically (case-sensitive) in a &lt;DL&gt; tag. The manpage refer‐ + ences are listed in the &lt;DT&gt; section, and the summary text is + listed in the &lt;DD&gt; section. + + • Each manpage reference listed is a hyperlink to the actual manpage + as specified by the -cgiurl option. + + This ability to process keyword searches gives nice added functionality + to a WWW forms interface to <B><A HREF="/page/1/man">man(1)</A></B>. Even if you have statically con‐ + verted manpages to HTML via another man-&gt;HTML program, you can use + man2html and "man -k" to provide keyword search capabilities easily for + your HTML manpages. + + Processing Keyword Search Results + Unfortunately, there is no standard controlling the format of keyword + search results. The man2html utility tries it best to handle all the + variations. However, the keyword search results generated by the So‐ + laris operating system is different enough from other systems that a + special command-line option (-solaris) must be specified to handle its + output. + + Example of raw Solaris-type keyword search results: + strcpy strcpy (9f) - copy a string from one location to another. + strcpy string (3c) - string operations + strncpy strcpy (9f) - copy a string from one location to another. + strncpy string (3c) - string operations + + If keyword search results on your systems appear in the following for‐ + mat: + + &lt;topic&gt; &lt;actual_manpage&gt; (#) - Description + + then you need to specify the -solaris option in addition to the -k op‐ + tion. + +ADDITIONAL NOTES + Different systems format manpages differently. Here is a list of rec‐ + ommended command-line options for certain systems: + + Convex: &lt;defaults should be okay&gt; + HP: -leftm 1 -topm 8 + Sun: -sun (and -solaris when using -k) + + Some line spacing gets lost in the formatted nroff since the spacing + would occur in the middle of a page break. This can cause text to be + merged that shouldn't be merged when man2html depaginates the text. To + avoid this problem, man2html keeps track of the margin indent right be‐ + fore and after a page break. If the margin width of the line after the + page break is less than the line before the page break, then man2html + inserts a blank line in the HTML output. + + A manpage cross-reference is detected by the following pseudo expres‐ + sion: [A-z.-+_]+([0-9][A-z]?) + + The man2html utility only recognizes lines with " - " (the normal sepa‐ + rator between manpage references and summary text) while in keyword + search mode. + + The man2html utility can be hooked in a CGI script/program to convert + manpages on the fly. This is the reason for the -cgiurl option. + +LIMITATIONS + The order that section head mapping is searched is not defined. There‐ + fore, if two or more &lt;section head text&gt; can match a give manpage sec‐ + tion, there is no way to determine which map tag is chosen. + + If -seealso is specified, all xrefs are detected after the SEE ALSO + heading. In other words, sections after SEE ALSO may contain hyper‐ + linked xrefs. + +BUGS + Text that is flush to the left margin, but is not actually a section + head, can be mistaken for a section head. This mistake is more likely + when the -sun option is in affect. + +VERSION + This documentation describes man2html version 3.0.1 + +SEE ALSO + <B><A HREF="/page/1/man">man(1)</A></B>, <B><A HREF="/page/1/nroff">nroff(1)</A></B>, <B><A HREF="/page/1/perl">perl(1)</A></B> + + http://www.oac.uci.edu/indiv/ehood/man2html.html + +AUTHOR + Earl Hood + ehood@medusa.acs.uci.edu + +ERRORS AND OMISSIONS + Troff version of this document initially created for version 2.1.0 by + C. Jeffery Small (jeff@cjsa.com) by copying, reformatting, rearranging + and partially rewriting the contents of the ascii text file + doc/man2html.txt. + + 97/08/12 <B><A HREF="/page/1/MAN2HTML">MAN2HTML(1)</A></B> +</PRE> +<HR> +<ADDRESS> +Man(1) output converted with +<a href="http://www.oac.uci.edu/indiv/ehood/man2html.html">man2html</a> +</ADDRESS> +</BODY> +</HTML>
A one/man2html

@@ -0,0 +1,609 @@

+#!/usr/bin/perl +use lib qw(/usr/share/perl5/site_perl); +#!/usr/local/bin/perl +##---------------------------------------------------------------------------## +## File: +## @(#) man2html 1.2 97/08/12 12:57:30 @(#) +## Author: +## Earl Hood, ehood@medusa.acs.uci.edu +## Description: +## man2html is a Perl program to convert formatted nroff output +## to HTML. +## +## Recommend command-line options based on platform: +## +## Platform Options +## --------------------------------------------------------------------- +## c2mp <None, the defaults should be okay> +## hp9000s700/800 -leftm 1 -topm 8 +## sun4 -sun +## --------------------------------------------------------------------- +## +##---------------------------------------------------------------------------## +## Copyright (C) 1995-1997 Earl Hood, ehood@medusa.acs.uci.edu +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +## 02111-1307, USA +##---------------------------------------------------------------------------## + +package Man2Html; + +use Getopt::Long; + +($PROG = $0) =~ s/.*\///; +$VERSION = "3.0.1"; + +## Input and outputs filehandles +$InFH = \*STDIN unless $InFH; +$OutFH = \*STDOUT unless $OutFH; + +## Backspace character: Used in overstriking detection +*bs = \"\b"; + +## Hash of section titles and their HTML tag wrapper. +## This list allows customization of what HTML tag is used for +## a given section head. +## +## The section title can be a regular expression. Therefore, one must +## be careful about quoting special characters. +## +%SectionHead = ( + + '\S.*OPTIONS.*' => '<H2>', + 'AUTHORS?' => '<H2>', + 'BUGS' => '<H2>', + 'COMPATIBILITY' => '<H2>', + 'DEPENDENCIES' => '<H2>', + 'DESCRIPTION' => '<H2>', + 'DIAGNOSTICS' => '<H2>', + 'ENVIRONMENT' => '<H2>', + 'ERRORS' => '<H2>', + 'EXAMPLES' => '<H2>', + 'EXTERNAL INFLUENCES' => '<H2>', + 'FILES' => '<H2>', + 'LIMITATIONS' => '<H2>', + 'NAME' => '<H2>', + 'NOTES?' => '<H2>', + 'OPTIONS' => '<H2>', + 'REFERENCES' => '<H2>', + 'RETURN VALUE' => '<H2>', + 'SECTION.*:' => '<H2>', + 'SEE ALSO' => '<H2>', + 'STANDARDS CONFORMANCE' => '<H2>', + 'STYLE CONVENTION' => '<H2>', + 'SYNOPSIS' => '<H2>', + 'SYNTAX' => '<H2>', + 'WARNINGS' => '<H2>', + '\s+Section.*:' => '<H3>', + +); + +## Fallback tag if above is not found +$HeadFallback = '<H2>'; + +## Other gobals + +$Bare = 0; # Skip printing HTML head/foot flag +$BTag = 'B'; # Overstrike tag +$CgiUrl = ''; # CGI URL expression +$Compress = 0; # Do blank line compression flag +$K = 0; # Do keyword search processing flag +$NoDepage = 0; # Do not strip page information +$NoHeads = 0; # Do no header detection flag +$SeeAlso = 0; # Do only SEE ALSO xrefs flag +$Solaris = 0; # Solaris keyword search processing flag +$Sun = 0; # Headers not overstriken flag +$Title = ''; # Title +$UTag = 'I'; # Underline tag +$ftsz = 7; # Bottome margin size +$hdsz = 7; # Top margin size +$leftm = ''; # Left margin pad +$leftmsz = 0; # Left margin size +$pgsz = 66; # Size of page size +$txsz = 52; # Text body length size + +############################################################################# +## Main Block +############################################################################# +{ + if (get_cli_opts()) { + if ($K) { + man_k(); + } else { + do_it(); + } + } else { + usage(); + } +} + +############################################################################# +## Subroutines +############################################################################# + +sub do_it { + + ## Define while loop and then eval it when used. The reason + ## is to avoid the regular expression reevaulation in the + ## section head detection code. + + $doitcode =<<'EndOfDoItCode'; + + my($line, $tmp, $i, $head, $preindent, $see_also, $do); + + $see_also = !$SeeAlso; + print $OutFH "<!-- Manpage converted by man2html $VERSION -->\n"; + LOOP: while(!eof($InFH)) { + $blank = 0; + for ($i=0; $i < $hdsz; $i++) { + last LOOP unless defined($_ = <$InFH>); + } + for ($i=0; $i < $txsz; $i++) { + last LOOP unless defined($_ = <$InFH>); + + ## Check if compress consecutive blank lines + if ($Compress and !/\S/) { + if ($blank) { next; } else { $blank = 1; } + } else { + $blank = 0; + } + + ## Try to check if line space is needed at page boundaries ## + if (!$NoDepage && ($i==0 || $i==($txsz-1)) && !/^\s*$/) { + /^(\s*)/; $tmp = length($1); + if ($do) { + if ($tmp < $preindent) { print $OutFH "\n"; } + } else { + $do = 1; + } + $preindent = $tmp; + } else { + $do = 0; $preindent = 0; + } + + ## Interpret line + $line = $_; + entitize(\$_); # Convert [$<>] to entity references + + ## Check for 'SEE ALSO' link only + if (!$see_also && $CgiUrl && $SeeAlso) { + ($tmp = $line) =~ s/.\010//go; + if ($tmp =~ /^\s*SEE\s+ALSO\s*$/o) { $see_also = 1; } + else { $see_also = 0; } + } + + ## Create anchor links for manpage references + s/((((.\010)+)?[\+_\.\w-])+\(((.\010)+)? + \d((.\010)+)?\w?\)) + /make_xref($1) + /geox if $see_also; + + ## Emphasize underlined words + # s/((_\010[^_])+[\.\(\)_]?(_\010[^_])+\)?)/emphasize($1)/oge; + # s/((_\010[^_])+([\.\(\)_]?(_\010[^_])+)?)/emphasize($1)/oge; + # + # The previous expressions were trying to be clever about + # detecting underlined text which contain non-alphanumeric + # characters. nroff will not underline non-alphanumeric + # characters in an underlined phrase, and the above was trying + # to detect that. It does not work all the time, and it + # screws up other text, so a simplified expression is used. + + s/((_\010[^_])+)/emphasize($1)/oge; + + $secth = 0; + ## Check for strong text and headings + if ($Sun || /.\010./o) { + if (!$NoHeads) { + $line =~ s/.\010//go; + $tmp = $HeadFallback; +EndOfDoItCode + + ## Create switch statement for detecting a heading + ## + $doitcode .= "HEADSW: {\n"; + foreach $head (keys %SectionHead) { + $doitcode .= join("", "\$tmp = '$SectionHead{$head}', ", + "\$secth = 1, last HEADSW ", + "if \$line =~ /^$leftm$head/o;\n"); + } + $doitcode .= "}\n"; + + ## Rest of routine + ## + $doitcode .=<<'EndOfDoItCode'; + if ($secth || $line =~ /^$leftm\S/o) { + chop $line; + $_ = $tmp . $line . $tmp; + s%<([^>]*)>$%</$1>%; + $_ = "\n</PRE>\n" . $_ . "<PRE>\n"; + } else { + s/(((.\010)+.)+)/strongize($1)/oge; + } + } else { + s/(((.\010)+.)+)/strongize($1)/oge; + } + } + print $OutFH $_; + } + + for ($i=0; $i < $ftsz; $i++) { + last LOOP unless defined($_ = <$InFH>); + } + } +EndOfDoItCode + + + ## Perform processing. + + printhead() unless $Bare; + print $OutFH "<PRE>\n"; + eval $doitcode; # $doitcode defined above + print $OutFH "</PRE>\n"; + printtail() unless $Bare; +} + +##--------------------------------------------------------------------------- +## +sub get_cli_opts { + return 0 unless + GetOptions( + "bare", # Leave out HTML, HEAD, BODY tags. + "belem=s", # HTML Element for overstriked text (def: "B") + "botm=i", # Number of lines for bottom margin (def: 7) + "cgiurl=s", # CGI URL for linking to other manpages + "cgiurlexp=s", # CGI URL Perl expr for linking to other manpages + "compress", # Compress consecutive blank lines + "headmap=s", # Filename of user section head map file + "k", # Process input from 'man -k' output. + "leftm=i", # Character width of left margin (def: 0) + "nodepage", # Do not remove pagination lines + "noheads", # Do not detect for section heads + "pgsize=i", # Number of lines in a page (def: 66) + "seealso", # Link to other manpages only in the SEE ALSO section + "solaris", # Parse 'man -k' output from a solaris system + "sun", # Section heads are not overstriked in input + "title=s", # Title of manpage (def: Not defined) + "topm=i", # Number of lines for top margin (def: 7) + "uelem=s", # HTML Element for underlined text (def: "I") + + "help" # Short usage message + ); + return 0 if defined($opt_help); + + $pgsz = $opt_pgsize || $pgsz; + if (defined($opt_nodepage)) { + $hdsz = 0; + $ftsz = 0; + } else { + $hdsz = $opt_topm if defined($opt_topm); + $ftsz = $opt_botm if defined($opt_botm); + } + $txsz = $pgsz - ($hdsz + $ftsz); + $leftmsz = $opt_leftm if defined($opt_leftm); + $leftm = ' ' x $leftmsz; + + $Bare = defined($opt_bare); + $Compress = defined($opt_compress); + $K = defined($opt_k); + $NoDepage = defined($opt_nodepage); + $NoHeads = defined($opt_noheads); + $SeeAlso = defined($opt_seealso); + $Solaris = defined($opt_solaris); + $Sun = defined($opt_sun); + + $Title = $opt_title || $Title; + $CgiUrl = $opt_cgiurlexp || + ($opt_cgiurl ? qq{return "$opt_cgiurl"} : ''); + + $BTag = $opt_belem || $BTag; + $UTag = $opt_uelem || $UTag; + $BTag =~ s/[<>]//g; + $UTag =~ s/[<>]//g; + + if (defined($opt_headmap)) { + require $opt_headmap or warn "Unable to read $opt_headmap\n"; + } + 1; +} + +##--------------------------------------------------------------------------- +sub printhead { + print $OutFH "<HTML>\n"; + print $OutFH "<HEAD>\n", + "<TITLE>$Title</TITLE>\n", + "</HEAD>\n" if $Title; + print $OutFH "<BODY>\n"; + print $OutFH "<H1>$Title</H1>\n", + "<HR>\n" if $Title; +} + +##--------------------------------------------------------------------------- +sub printtail { + print $OutFH <<EndOfRef; +<HR> +<ADDRESS> +Man(1) output converted with +<a href="http://www.oac.uci.edu/indiv/ehood/man2html.html">man2html</a> +</ADDRESS> +</BODY> +</HTML> +EndOfRef +} + +##--------------------------------------------------------------------------- +sub emphasize { + my($txt) = shift; + $txt =~ s/.\010//go; + $txt = "<$UTag>$txt</$UTag>"; + $txt; +} + +##--------------------------------------------------------------------------- +sub strongize { + my($txt) = shift; + $txt =~ s/.\010//go; + $txt = "<$BTag>$txt</$BTag>"; + $txt; +} + +##--------------------------------------------------------------------------- +sub entitize { + my($txt) = shift; + + ## Check for special characters in overstrike text ## + $$txt =~ s/_\010\&/strike('_', '&')/geo; + $$txt =~ s/_\010</strike('_', '<')/geo; + $$txt =~ s/_\010>/strike('_', '>')/geo; + + $$txt =~ s/(\&\010)+\&/strike('&', '&')/geo; + $$txt =~ s/(<\010)+</strike('<', '<')/geo; + $$txt =~ s/(>\010)+>/strike('>', '>')/geo; + + ## Check for special characters in regular text. Must be careful + ## to check before/after character in expression because it might be + ## a special character. + $$txt =~ s/([^\010]\&[^\010])/htmlize2($1)/geo; + $$txt =~ s/([^\010]<[^\010])/htmlize2($1)/geo; + $$txt =~ s/([^\010]>[^\010])/htmlize2($1)/geo; +} + +##--------------------------------------------------------------------------- +## escape special characters in a string, in-place +## +sub htmlize { + my($str) = shift; + $$str =~ s/&/\&amp;/g; + $$str =~ s/</\&lt;/g; + $$str =~ s/>/\&gt;/g; + $$str; +} + +##--------------------------------------------------------------------------- +## htmlize2() is used by entitize. +## +sub htmlize2 { + my($str) = shift; + $str =~ s/&/\&amp;/g; + $str =~ s/</\&lt;/g; + $str =~ s/>/\&gt;/g; + $str; +} + +##--------------------------------------------------------------------------- +## strike converts HTML special characters in overstriked text +## into entity references. The entities are overstriked so +## strongize() and emphasize() will recognize the entity to be +## wrapped in tags. +## +sub strike { + my($w, $char) = @_; + my($ret); + if ($w eq '_') { + if ($char eq '&') { + $ret = "_$bs\&_${bs}a_${bs}m_${bs}p_${bs};"; + } elsif ($char eq '<') { + $ret = "_$bs\&_${bs}l_${bs}t_${bs};"; + } elsif ($char eq '>') { + $ret = "_$bs\&_${bs}g_${bs}t_${bs};"; + } else { + warn qq|Unrecognized character, "$char", passed to strike()\n|; + } + } else { + if ($char eq '&') { + $ret = "\&$bs\&a${bs}am${bs}mp${bs}p;${bs};"; + } elsif ($char eq '<') { + $ret = "\&$bs\&l${bs}lt${bs}t;${bs};"; + } elsif ($char eq '>') { + $ret = "\&$bs\&g${bs}gt${bs}t;${bs};"; + } else { + warn qq|Unrecognized character, "$char", passed to strike()\n|; + } + } + $ret; +} + +##--------------------------------------------------------------------------- +## make_xref() converts a manpage crossreference into a hyperlink. +## +sub make_xref { + my $str = shift; + $str =~ s/.\010//go; # Remove overstriking + + if ($CgiUrl) { + my($title,$section,$subsection) = + ($str =~ /([\+_\.\w-]+)\((\d)(\w?)\)/); + + $title =~ s/\+/%2B/g; + my($href) = (eval $CgiUrl); + qq|<B><A HREF="$href">$str</A></B>|; + } else { + qq|<B>$str</B>|; + } +} + +##--------------------------------------------------------------------------- +## man_k() process a keyword search. The problem we have is there +## is no standard for keyword search results from man. Solaris +## systems have a different enough format to warrent dealing +## with it as a special case. For other cases, we try our best. +## Unfortunately, there are some lines of results that may be +## skipped. +## +sub man_k { + my($line,$refs,$section,$subsection,$desc,$i, + %Sec1, %Sec1sub, %Sec2, %Sec2sub, %Sec3, %Sec3sub, + %Sec4, %Sec4sub, %Sec5, %Sec5sub, %Sec6, %Sec6sub, + %Sec7, %Sec7sub, %Sec8, %Sec8sub, %Sec9, %Sec9sub, + %SecN, %SecNsub, %SecNsec); + + printhead() unless $Bare; + print $OutFH "<!-- Man keyword results converted by ", + "man2html $VERSION -->\n"; + + while ($line = <$InFH>) { + next if $line !~ /\(\d\w?\)\s+-\s/; # check if line can be handled + ($refs,$section,$subsection,$desc) = + $line =~ /^\s*(.*)\((\d)(\w?)\)\s*-\s*(.*)$/; + + if ($Solaris) { + $refs =~ s/^\s*([\+_\.\w-]+)\s+([\+_\.\w-]+)\s*$/$1/; + # <topic> <manpage> + } else { + $refs =~ s/\s(and|or)\s/,/gi; # Convert and/or to commas + $refs =~ s/^[^:\s]:\s*//; # Remove prefixed whatis path + } + $refs =~ s/\s//g; # Remove all whitespace + $refs =~ s/,/, /g; # Put space after comma + htmlize(\$desc); # Check for special chars in desc + $desc =~ s/^(.)/\U$1/; # Uppercase first letter in desc + + if ($section eq '1') { + $Sec1{$refs} = $desc; $Sec1sub{$refs} = $subsection; + } elsif ($section eq '2') { + $Sec2{$refs} = $desc; $Sec2sub{$refs} = $subsection; + } elsif ($section eq '3') { + $Sec3{$refs} = $desc; $Sec3sub{$refs} = $subsection; + } elsif ($section eq '4') { + $Sec4{$refs} = $desc; $Sec4sub{$refs} = $subsection; + } elsif ($section eq '5') { + $Sec5{$refs} = $desc; $Sec5sub{$refs} = $subsection; + } elsif ($section eq '6') { + $Sec6{$refs} = $desc; $Sec6sub{$refs} = $subsection; + } elsif ($section eq '7') { + $Sec7{$refs} = $desc; $Sec7sub{$refs} = $subsection; + } elsif ($section eq '8') { + $Sec8{$refs} = $desc; $Sec8sub{$refs} = $subsection; + } elsif ($section eq '9') { + $Sec9{$refs} = $desc; $Sec9sub{$refs} = $subsection; + } else { # Catch all + $SecN{$refs} = $desc; $SecNsec{$refs} = $section; + $SecNsub{$refs} = $subsection; + } + } + print_mank_sec(\%Sec1, 1, \%Sec1sub); + print_mank_sec(\%Sec2, 2, \%Sec2sub); + print_mank_sec(\%Sec3, 3, \%Sec3sub); + print_mank_sec(\%Sec4, 4, \%Sec4sub); + print_mank_sec(\%Sec5, 5, \%Sec5sub); + print_mank_sec(\%Sec6, 6, \%Sec6sub); + print_mank_sec(\%Sec7, 7, \%Sec7sub); + print_mank_sec(\%Sec8, 8, \%Sec8sub); + print_mank_sec(\%Sec9, 9, \%Sec9sub); + print_mank_sec(\%SecN, 'N', \%SecNsub, \%SecNsec); + + printtail() unless $Bare; +} +##--------------------------------------------------------------------------- +## print_mank_sec() prints out manpage cross-refs of a specific section. +## +sub print_mank_sec { + my($sec, $sect, $secsub, $secsec) = @_; + my(@array, @refs, $href, $item, $title, $subsection, $i, $section, + $xref); + $section = $sect; + + @array = sort keys %$sec; + if ($#array >= 0) { + print $OutFH "<H2>Section $section</H2>\n", + "<DL COMPACT>\n"; + foreach $item (@array) { + @refs = split(/,/, $item); + $section = $secsec->{$item} if $sect eq 'N'; + $subsection = $secsub->{$item}; + if ($CgiUrl) { + ($title = $refs[0]) =~ s/\(\)//g; # watch out for extra ()'s + $xref = eval $CgiUrl; + } + print $OutFH "<DT>\n"; + $i = 0; + foreach (@refs) { + if ($CgiUrl) { + print $OutFH qq|<B><A HREF="$xref">$_</A></B>|; + } else { + print $OutFH $_; + } + print $OutFH ", " if $i < $#refs; + $i++; + } + print $OutFH " ($section$subsection)\n", + "</DT><DD>\n", + $sec->{$item}, "</DD>\n"; + } + print $OutFH "</DL>\n"; + } +} + +##--------------------------------------------------------------------------- +## +sub usage { + print $OutFH <<EndOfUsage; +Usage: $PROG [ options ] < infile > outfile +Options: + -bare : Do not put in HTML, HEAD, BODY tags + -belem <elem> : HTML Element for overstriked text (def: "B") + -botm <#> : Number of lines for bottom margin (def: 7) + -cgiurl <url> : URL for linking to other manpages + -cgiurlexp <url> : Perl expression URL for linking to other manpages + -compress : Compress consective blank lines + -headmap <file> : Filename of user section head map file + -help : This message + -k : Process a keyword search result + -leftm <#> : Character width of left margin (def: 0) + -nodepage : Do not remove pagination lines + -noheads : Turn off section head detection + -pgsize <#> : Number of lines in a page (def: 66) + -seealso : Link to other manpages only in the SEE ALSO section + -solaris : Process keyword search result in Solaris format + -sun : Section heads are not overstriked in input + -title <string> : Title of manpage (def: Not defined) + -topm <#> : Number of lines for top margin (def: 7) + -uelem <elem> : HTML Element for underlined text (def: "I") + +Description: + $PROG takes formatted manpages from STDIN and converts it to HTML sent + to STDOUT. The -topm and -botm arguments are the number of lines to the + main body text and NOT to the running headers/footers. + +Version: + $VERSION + Copyright (C) 1995-1997 Earl Hood, ehood\@medusa.acs.uci.edu + $PROG comes with ABSOLUTELY NO WARRANTY and $PROG may be copied only + under the terms of the GNU General Public License, which may be found in + the $PROG distribution. + +EndOfUsage + exit 0; +}