xref: /freebsd/contrib/tcsh/tcsh.man2html (revision 9122aeeaa60ee2a1381ea935d749194b32940e7a)
16767bd61SMark Peek: # -*- perl -*-
2c80476e4SDavid E. O'Brien
3c80476e4SDavid E. O'Brien# tcsh.man2html, Dave Schweisguth <dcs@proton.chem.yale.edu>
4c80476e4SDavid E. O'Brien#
5c80476e4SDavid E. O'Brien# Notes:
6c80476e4SDavid E. O'Brien#
7c80476e4SDavid E. O'Brien# Always puts all files in the directory tcsh.html, creating it if necessary.
8c80476e4SDavid E. O'Brien# tcsh.html/top.html is the entry point, and tcsh.html/index.html is a symlink
9c80476e4SDavid E. O'Brien# to tcsh.html/top.html so one needn't specify a file at all if working through
10c80476e4SDavid E. O'Brien# a typically configured server.
11c80476e4SDavid E. O'Brien#
12c80476e4SDavid E. O'Brien# Designed for tcsh manpage. Guaranteed not to work on manpages not written
13c80476e4SDavid E. O'Brien# in the exact same style of nroff -man, i.e. any other manpage.
14c80476e4SDavid E. O'Brien#
15c80476e4SDavid E. O'Brien# Makes links FROM items which are both a) in particular sections (see
16c80476e4SDavid E. O'Brien# Configuration) and b) marked with .B or .I. Makes links TO items which
17c80476e4SDavid E. O'Brien# are marked with \fB ... \fR or \fI ... \fR.
18c80476e4SDavid E. O'Brien#
19c80476e4SDavid E. O'Brien# Designed with X Mosaic in mind and tested lightly with lynx. I've punted on
20c80476e4SDavid E. O'Brien# HTML's lack of a .PD equivalent and lynx's different <menu> handling.
21c80476e4SDavid E. O'Brien
22c80476e4SDavid E. O'Brien# Emulate #!/usr/local/bin/perl on systems without #!
23c80476e4SDavid E. O'Brien
24dc86a98eSDavid E. O'Brieneval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
25dc86a98eSDavid E. O'Brien& eval 'exec perl -S $0 $argv:q' if 0;
26c80476e4SDavid E. O'Brien
27c80476e4SDavid E. O'Brien### Constants
28c80476e4SDavid E. O'Brien
29c80476e4SDavid E. O'Brien# Setup
30c80476e4SDavid E. O'Brien
31c80476e4SDavid E. O'Brien($whatami = $0)	=~ s|.*/||;	# `basename $0`
32c80476e4SDavid E. O'Brien$isatty		= -t STDIN;
33c80476e4SDavid E. O'Brien
34c80476e4SDavid E. O'Brien# Configuration
35c80476e4SDavid E. O'Brien
36c80476e4SDavid E. O'Brien$index		= 0;		# Don't make a searchable index CGI script
37c80476e4SDavid E. O'Brien$cgibin		= 0;		# Look for $cgifile in $dir, not $cgibindir
38c80476e4SDavid E. O'Brien$shortfiles	= 0;		# Use long filenames
39c80476e4SDavid E. O'Brien$single		= 0;		# Make single page instead of top and sections
40c80476e4SDavid E. O'Brien
41c80476e4SDavid E. O'Brien$host		= '';		# host:port part of server URL ***
42c80476e4SDavid E. O'Brien$updir		= '';		# Directories between $host and $dir ***
43c80476e4SDavid E. O'Brien$dir		= 'tcsh';	# Directory in which to put the pieces *
44c80476e4SDavid E. O'Brien$cgifile	= 'tcsh.cgi';	# CGI script name **
45c80476e4SDavid E. O'Brien$cgibindir	= 'cgi-bin';	# CGI directory ***
46c80476e4SDavid E. O'Brien$headerfile	= 'header';	# HTML file for initial comments *
47c80476e4SDavid E. O'Brien$indexfile	= 'index';	# Symlink to $topfile *
48c80476e4SDavid E. O'Brien$listsfile	= 'lists';	# Mailing list description HTML file *
49c80476e4SDavid E. O'Brien$outfile	= 'tcsh.man';	# Default input file and copy of input file
50c80476e4SDavid E. O'Brien$script		= $whatami;	# Copy of script; filename length must be OK
51c80476e4SDavid E. O'Brien$topfile	= 'top';	# Top-level HTML file *
52c80476e4SDavid E. O'Brien
53c80476e4SDavid E. O'Brien# *   .htm or .html suffix added later
54c80476e4SDavid E. O'Brien# **  Only used with -i or -c
55c80476e4SDavid E. O'Brien# *** Only used with -c
56c80476e4SDavid E. O'Brien
57c80476e4SDavid E. O'Brien# Sections to inline in the top page
58c80476e4SDavid E. O'Brien
59c80476e4SDavid E. O'Brien%inline_me	= ('NAME',	1,
60c80476e4SDavid E. O'Brien		   'SYNOPSIS',	1);
61c80476e4SDavid E. O'Brien
62c80476e4SDavid E. O'Brien# Sections in which to put name anchors and the font in which to look for
63c80476e4SDavid E. O'Brien# links to those anchors
64c80476e4SDavid E. O'Brien
65c80476e4SDavid E. O'Brien%link_me	= ('Editor commands',		'I',
66c80476e4SDavid E. O'Brien		   'Builtin commands',		'I',
67c80476e4SDavid E. O'Brien		   'Special aliases',		'I',
68c80476e4SDavid E. O'Brien		   'Special shell variables',	'B',
69c80476e4SDavid E. O'Brien		   'ENVIRONMENT',		'B',
70c80476e4SDavid E. O'Brien		   'FILES',			'I');
71c80476e4SDavid E. O'Brien
72c80476e4SDavid E. O'Brien### Arguments and error-checking
73c80476e4SDavid E. O'Brien
74c80476e4SDavid E. O'Brien# Parse args
75c80476e4SDavid E. O'Brien
76c80476e4SDavid E. O'Brienwhile ($#ARGV > -1 && (($first, $rest) = ($ARGV[0] =~ /^-(.)(.*)/))) {
77c80476e4SDavid E. O'Brien    # Perl 5 lossage alert
78c80476e4SDavid E. O'Brien    if ($first =~ /[CdDGh]/) {	# Switches with arguments
79c80476e4SDavid E. O'Brien    	shift;
80c80476e4SDavid E. O'Brien    	$arg = $rest ne '' ? $rest : $ARGV[0] ne '' ? shift :
81c80476e4SDavid E. O'Brien      	    &usage("$whatami: -$first requires an argument.\n");
82c80476e4SDavid E. O'Brien    } elsif ($rest ne '') {
83c80476e4SDavid E. O'Brien    	$ARGV[0] = "-$rest";
84c80476e4SDavid E. O'Brien    } else {
85c80476e4SDavid E. O'Brien	shift;
86c80476e4SDavid E. O'Brien    }
87c80476e4SDavid E. O'Brien    if	  ($first eq '1')   { $single = 1; }
88c80476e4SDavid E. O'Brien    elsif ($first eq 'c')   { $cgibin = 1; }
89c80476e4SDavid E. O'Brien    elsif ($first eq 'C')   { $cgibindir = $arg; }
90c80476e4SDavid E. O'Brien    elsif ($first eq 'd')   { $updir = $arg; }
91c80476e4SDavid E. O'Brien    elsif ($first eq 'D')   { $dir = $arg; }
92c80476e4SDavid E. O'Brien    elsif ($first eq 'G')   { $cgifile = $arg; }
93c80476e4SDavid E. O'Brien    elsif ($first eq 'h')   { $host = $arg; }
94c80476e4SDavid E. O'Brien    elsif ($first eq 'i')   { $index = 1; }
95c80476e4SDavid E. O'Brien    elsif ($first eq 's')   { $shortfiles = 1; }
96c80476e4SDavid E. O'Brien    elsif ($first eq 'u')   { &usage(0); }
97c80476e4SDavid E. O'Brien    else		    { &usage("$whatami: -$first is not an option.\n"); }
98c80476e4SDavid E. O'Brien}
99c80476e4SDavid E. O'Brien
100c80476e4SDavid E. O'Brienif (@ARGV == 0) {
101c80476e4SDavid E. O'Brien    if ($isatty) {
102c80476e4SDavid E. O'Brien        $infile = $outfile;		# Default input file if interactive
103c80476e4SDavid E. O'Brien    } else {
104c80476e4SDavid E. O'Brien	$infile = 'STDIN';		# Read STDIN if no args and not a tty
105c80476e4SDavid E. O'Brien    }
106c80476e4SDavid E. O'Brien} elsif (@ARGV == 1) {
107c80476e4SDavid E. O'Brien    $infile = $ARGV[0];
108c80476e4SDavid E. O'Brien} else {
109c80476e4SDavid E. O'Brien    &usage("$whatami: Please specify one and only one file.\n");
110c80476e4SDavid E. O'Brien}
111c80476e4SDavid E. O'Brien
112c80476e4SDavid E. O'Brien$index = $index || $cgibin;		# $index is true if $cgibin is true
113c80476e4SDavid E. O'Brien
114c80476e4SDavid E. O'Brienif ($cgibin && ! $host) {
115c80476e4SDavid E. O'Brien    die "$whatami: Must specify host with -h if using -c.\n";
116c80476e4SDavid E. O'Brien}
117c80476e4SDavid E. O'Brien
118c80476e4SDavid E. O'Brien# Decide on HTML suffix and append it to filenames
119c80476e4SDavid E. O'Brien
120c80476e4SDavid E. O'Brien$html = $shortfiles ? 'htm' : 'html';	# Max 3-character extension
121c80476e4SDavid E. O'Brien$dir		.= ".$html";		# Directory in which to put the pieces
122c80476e4SDavid E. O'Brien$headerfile	.= ".$html";		# HTML file for initial comments
123c80476e4SDavid E. O'Brien$topfile	.= ".$html";		# Top-level HTML file (or moved notice)
124c80476e4SDavid E. O'Brien$indexfile	.= ".$html";		# Symlink to $topfile
125c80476e4SDavid E. O'Brien$listsfile	.= ".$html";		# Mailing list description HTML file
126c80476e4SDavid E. O'Brien
127c80476e4SDavid E. O'Brien# Check for input file
128c80476e4SDavid E. O'Brien
129c80476e4SDavid E. O'Brienunless ($infile eq 'STDIN') {
130c80476e4SDavid E. O'Brien    die "$whatami: $infile doesn't exist!\n"	unless -e $infile;
131c80476e4SDavid E. O'Brien    die "$whatami: $infile is unreadable!\n"	unless -r _;
132c80476e4SDavid E. O'Brien    die "$whatami: $infile is empty!\n"		unless -s _;
133c80476e4SDavid E. O'Brien}
134c80476e4SDavid E. O'Brien
135c80476e4SDavid E. O'Brien# Check for output directory and create if necessary
136c80476e4SDavid E. O'Brien
137c80476e4SDavid E. O'Brienif (-e $dir) {
138c80476e4SDavid E. O'Brien    -d _ || die "$whatami: $dir is not a directory!\n";
139c80476e4SDavid E. O'Brien    -r _ && -w _ && -x _ || die "$whatami: $dir is inaccessible!\n"
140c80476e4SDavid E. O'Brien} else {
141c80476e4SDavid E. O'Brien    mkdir($dir, 0755) || die "$whatami: Can't create $dir!\n";
142c80476e4SDavid E. O'Brien}
143c80476e4SDavid E. O'Brien
144c80476e4SDavid E. O'Brien# Slurp manpage
145c80476e4SDavid E. O'Brien
146c80476e4SDavid E. O'Brienif ($infile eq 'STDIN') {
147c80476e4SDavid E. O'Brien    @man = <STDIN>;
148c80476e4SDavid E. O'Brien} else {
149c80476e4SDavid E. O'Brien    open(MAN, $infile) || die "$whatami: Error opening $infile!\n";
150c80476e4SDavid E. O'Brien    @man = <MAN>;
151c80476e4SDavid E. O'Brien    close MAN;
152c80476e4SDavid E. O'Brien}
153c80476e4SDavid E. O'Brien
154c80476e4SDavid E. O'Brien# Print manpage to HTML directory (can't use cp if we're reading from STDIN)
155c80476e4SDavid E. O'Brien
156c80476e4SDavid E. O'Brienopen(MAN, ">$dir/$outfile") || die "$whatami: Can't open $dir/$outfile!\n";
157c80476e4SDavid E. O'Brienprint MAN @man;
158c80476e4SDavid E. O'Brienclose MAN;
159c80476e4SDavid E. O'Brien
160c80476e4SDavid E. O'Brien# Copy script to HTML directory
161c80476e4SDavid E. O'Brien
162c80476e4SDavid E. O'Brien(system("cp $0 $dir") >> 8) && die "$whatami: Can't copy $0 to $dir!\n";
163c80476e4SDavid E. O'Brien
164c80476e4SDavid E. O'Brien# Link top.html to index.html in case someone looks at tcsh.html/
165c80476e4SDavid E. O'Brien
166c80476e4SDavid E. O'Briensystem("rm -f $dir/$indexfile");    # Some systems can't ln -sf
167c80476e4SDavid E. O'Brien(system("ln -s $topfile $dir/$indexfile") >> 8)
168c80476e4SDavid E. O'Brien    && die "$whatami: Can't link $topfile to $dir/$indexfile!\n";
169c80476e4SDavid E. O'Brien
170c80476e4SDavid E. O'Brien### Get title and section headings
171c80476e4SDavid E. O'Brien
172c80476e4SDavid E. O'Brien$comment = 0;			    # 0 for text, 1 for ignored text
173c80476e4SDavid E. O'Brien@sectionlines = (0);		    # First line of section
174c80476e4SDavid E. O'Brien@sectiontypes = (0);		    # H or S
175c80476e4SDavid E. O'Brien@sectiontexts = ('Header');	    # Text of section heading
176c80476e4SDavid E. O'Brien@sectionfiles = ($headerfile);	    # Filename in which to store section
177c80476e4SDavid E. O'Brien%name = ();			    # Array of name anchors
178c80476e4SDavid E. O'Brien@name = () if $index;		    # Ordered array of name anchors
179c80476e4SDavid E. O'Brien$font = '';		    	    # '' to not make names, 'B' or 'I' to do so
180c80476e4SDavid E. O'Brien
181c80476e4SDavid E. O'Brien$line = 0;
182c80476e4SDavid E. O'Brienforeach (@man) {
183c80476e4SDavid E. O'Brien    if (/^\.ig/) {		    # Start ignoring
184c80476e4SDavid E. O'Brien	$comment = 1;
185c80476e4SDavid E. O'Brien    } elsif (/^\.\./) {		    # Stop ignoring
186c80476e4SDavid E. O'Brien	$comment = 0;
187c80476e4SDavid E. O'Brien    } elsif (! $comment) {	    # Not in .ig'ed section; do stuff
188c80476e4SDavid E. O'Brien
189c80476e4SDavid E. O'Brien	# nroff special characters
190c80476e4SDavid E. O'Brien
191c80476e4SDavid E. O'Brien	s/\\-/-/g;		    # \-
192c80476e4SDavid E. O'Brien	s/\\^//g;		    # \^
193c80476e4SDavid E. O'Brien	s/^\\'/'/;		    # leading ' escape
194c80476e4SDavid E. O'Brien	s/^\\(\s)/$1/;		    # leading space escape
195c80476e4SDavid E. O'Brien	s/\\(e|\\)/\\/g;	    # \e, \\; must do this after other escapes
196c80476e4SDavid E. O'Brien
197c80476e4SDavid E. O'Brien	# HTML special characters; deal with these before adding more
198c80476e4SDavid E. O'Brien
199c80476e4SDavid E. O'Brien	s/&/&amp\;/g;
200c80476e4SDavid E. O'Brien	s/>/&gt\;/g;
201c80476e4SDavid E. O'Brien	s/</&lt\;/g;
202c80476e4SDavid E. O'Brien
203c80476e4SDavid E. O'Brien	# Get title
204c80476e4SDavid E. O'Brien
205c80476e4SDavid E. O'Brien	if (/^\.TH\s+(\w+)\s+(\w+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"/) {
206c80476e4SDavid E. O'Brien	    $title = "$1($2) $4 ($3) $1($2)";
207c80476e4SDavid E. O'Brien	}
208c80476e4SDavid E. O'Brien
209c80476e4SDavid E. O'Brien	# Build per-section info arrays
210c80476e4SDavid E. O'Brien
211c80476e4SDavid E. O'Brien	if (($type, $text) = /^\.S([HS])\s+\"?([^\"]*)\"?/) {
212c80476e4SDavid E. O'Brien
213c80476e4SDavid E. O'Brien	    push(@sectionlines, $line);	    # Index of first line of section
214c80476e4SDavid E. O'Brien	    push(@sectiontypes, $type eq 'H' ? 0 : 1);	# Type of section
215c80476e4SDavid E. O'Brien	    $text =~ s/\s*$//;		    # Remove trailing whitespace
216c80476e4SDavid E. O'Brien	    push(@sectiontexts, $text);	    # Title of section (key for href)
217c80476e4SDavid E. O'Brien	    $text =~ s/\s*\(\+\)$//;	    # Remove (+)
218c80476e4SDavid E. O'Brien	    if ($shortfiles) {
219c80476e4SDavid E. O'Brien		$file = $#sectionlines;	    # Short filenames; use number
220c80476e4SDavid E. O'Brien	    } else {
221c80476e4SDavid E. O'Brien		$file = $text;		    # Long filenames; use title
222c80476e4SDavid E. O'Brien		$file =~ s/[\s\/]+/_/g;	    # Replace whitespace and / with _
223c80476e4SDavid E. O'Brien	    }
224c80476e4SDavid E. O'Brien	    $file .= ".$html" unless $single;
225c80476e4SDavid E. O'Brien	    push(@sectionfiles, $file);	    # File in which to store section
226c80476e4SDavid E. O'Brien	    $name{"$text B"} = ($single ? '#' : '') . $file;
227c80476e4SDavid E. O'Brien					    # Index entry for &make_hrefs
228c80476e4SDavid E. O'Brien	    push(@name, "$text\t" . $name{"$text B"}) if $index;
229c80476e4SDavid E. O'Brien					    # Index entry for CGI script
230c80476e4SDavid E. O'Brien	    # Look for anchors in the rest of this section if $link_me{$text}
231c80476e4SDavid E. O'Brien	    # is non-null, and mark them with the font which is its value
232c80476e4SDavid E. O'Brien
233c80476e4SDavid E. O'Brien	    $font = $link_me{$text};
234c80476e4SDavid E. O'Brien    	}
235c80476e4SDavid E. O'Brien	&make_name(*name, *font, *file, *index, *_) if $font;
236c80476e4SDavid E. O'Brien    }
237c80476e4SDavid E. O'Brien    $line++;
238c80476e4SDavid E. O'Brien}
239c80476e4SDavid E. O'Brien
240c80476e4SDavid E. O'Brien### Make top page
241c80476e4SDavid E. O'Brien
242c80476e4SDavid E. O'Brienopen(TOP, ">$dir/$topfile");
243c80476e4SDavid E. O'Brienselect TOP;
244c80476e4SDavid E. O'Brien
245c80476e4SDavid E. O'Brien# Top page header
246c80476e4SDavid E. O'Brien
247c80476e4SDavid E. O'Brienprint <<EOP;
248c80476e4SDavid E. O'Brien<HEAD>
249c80476e4SDavid E. O'Brien<TITLE>$title</TITLE>
250c80476e4SDavid E. O'Brien</HEAD>
251c80476e4SDavid E. O'Brien<BODY>
252c80476e4SDavid E. O'Brien<A NAME="top"></A>
253c80476e4SDavid E. O'Brien<H1>$title</H1>
254c80476e4SDavid E. O'Brien<HR>
255c80476e4SDavid E. O'BrienEOP
256c80476e4SDavid E. O'Brien
257c80476e4SDavid E. O'Brien# FORM block, if we're making an index
258c80476e4SDavid E. O'Brien
259c80476e4SDavid E. O'Brien$action = $cgibin ? "http://$host/$cgibindir/$cgifile" : $cgifile;
260c80476e4SDavid E. O'Brien
261c80476e4SDavid E. O'Brienprint <<EOP if $index;
262c80476e4SDavid E. O'Brien<FORM METHOD="GET" ACTION="$action">
263c80476e4SDavid E. O'BrienGo directly to a section, command or variable: <INPUT NAME="input">
264c80476e4SDavid E. O'Brien</FORM>
265c80476e4SDavid E. O'BrienEOP
266c80476e4SDavid E. O'Brien
267c80476e4SDavid E. O'Brien# Table of contents
268c80476e4SDavid E. O'Brien
269c80476e4SDavid E. O'Brienprint <<EOP;
270c80476e4SDavid E. O'Brien<H2>
271c80476e4SDavid E. O'BrienEOP
272c80476e4SDavid E. O'Brien
273c80476e4SDavid E. O'Brienforeach $section (1 .. $#sectionlines) {
274c80476e4SDavid E. O'Brien    if ($sectiontypes[$section - 1] < $sectiontypes[$section]) {
275c80476e4SDavid E. O'Brien	print "</H2> <menu>\n";	    # Indent, smaller font
276c80476e4SDavid E. O'Brien    } elsif ($sectiontypes[$section - 1] > $sectiontypes[$section]) {
277c80476e4SDavid E. O'Brien	print "</menu> <H2>\n";	    # Outdent, larger font
278c80476e4SDavid E. O'Brien    }
279c80476e4SDavid E. O'Brien    if ($inline_me{$sectiontexts[$section]}) {    # Section is in %inline_me
280c80476e4SDavid E. O'Brien
281c80476e4SDavid E. O'Brien	# Print section inline
282c80476e4SDavid E. O'Brien
283c80476e4SDavid E. O'Brien	print "$sectiontexts[$section]\n";
284c80476e4SDavid E. O'Brien	print "</H2> <menu>\n";	    # Indent, smaller font
285c80476e4SDavid E. O'Brien	&printsectionbody(*man, *sectionlines, *section, *name);
286c80476e4SDavid E. O'Brien	print "</menu> <H2>\n";	    # Outdent, larger font
287c80476e4SDavid E. O'Brien    } else {
288c80476e4SDavid E. O'Brien
289c80476e4SDavid E. O'Brien	# Print link to section
290c80476e4SDavid E. O'Brien
291c80476e4SDavid E. O'Brien	print "<A HREF=\"", $single ? '#' : '',
292c80476e4SDavid E. O'Brien	    "$sectionfiles[$section]\">$sectiontexts[$section]</A><BR>\n";
293c80476e4SDavid E. O'Brien    }
294c80476e4SDavid E. O'Brien}
295c80476e4SDavid E. O'Brien
296c80476e4SDavid E. O'Brienprint <<EOP;
297c80476e4SDavid E. O'Brien</H2>
298c80476e4SDavid E. O'BrienEOP
299c80476e4SDavid E. O'Brien
300c80476e4SDavid E. O'Brienprint "<HR>\n" if $single;
301c80476e4SDavid E. O'Brien
302c80476e4SDavid E. O'Brien### Make sections
303c80476e4SDavid E. O'Brien
304c80476e4SDavid E. O'Brienforeach $section (0 .. $#sectionlines) {
305c80476e4SDavid E. O'Brien
306c80476e4SDavid E. O'Brien    # Skip inlined sections
307c80476e4SDavid E. O'Brien
308c80476e4SDavid E. O'Brien    next if $inline_me{$sectiontexts[$section]};
309c80476e4SDavid E. O'Brien
310c80476e4SDavid E. O'Brien    if ($single) {
311c80476e4SDavid E. O'Brien
312c80476e4SDavid E. O'Brien	# Header
313c80476e4SDavid E. O'Brien
314c80476e4SDavid E. O'Brien	print <<EOP if $section;	# Skip header section
315c80476e4SDavid E. O'Brien<H2><A NAME="$sectionfiles[$section]">$sectiontexts[$section]</A></H2>
316c80476e4SDavid E. O'Brien<menu>
317c80476e4SDavid E. O'BrienEOP
318c80476e4SDavid E. O'Brien	&printsectionbody(*man, *sectionlines, *section, *name);
319c80476e4SDavid E. O'Brien	print <<EOP if $section;	# Skip header section
320c80476e4SDavid E. O'Brien<A HREF="#top">Table of Contents</A>
321c80476e4SDavid E. O'Brien</menu>
322c80476e4SDavid E. O'BrienEOP
323c80476e4SDavid E. O'Brien
324c80476e4SDavid E. O'Brien    } else {
325c80476e4SDavid E. O'Brien
326c80476e4SDavid E. O'Brien	# Make pointer line for header and trailer
327c80476e4SDavid E. O'Brien
328c80476e4SDavid E. O'Brien	$pointers  = "<A HREF=\"$topfile\">Up</A>";
329c80476e4SDavid E. O'Brien	$pointers .= "\n<A HREF=\"$sectionfiles[$section + 1]\">Next</A>"
330c80476e4SDavid E. O'Brien	    if ($section < $#sectionlines) &&
331c80476e4SDavid E. O'Brien	    ! $inline_me{$sectiontexts[$section + 1]};
332c80476e4SDavid E. O'Brien	$pointers .= "\n<A HREF=\"$sectionfiles[$section - 1]\">Previous</A>"
333c80476e4SDavid E. O'Brien	    if ($section > 1) &&		# section 0 is initial comments
334c80476e4SDavid E. O'Brien	    ! $inline_me{$sectiontexts[$section - 1]};
335c80476e4SDavid E. O'Brien
336c80476e4SDavid E. O'Brien	# Header
337c80476e4SDavid E. O'Brien
338c80476e4SDavid E. O'Brien	open(OUT, ">$dir/$sectionfiles[$section]");
339c80476e4SDavid E. O'Brien	select OUT;
340c80476e4SDavid E. O'Brien	print <<EOP;
341c80476e4SDavid E. O'Brien<HEAD>
342c80476e4SDavid E. O'Brien<TITLE>$sectiontexts[$section]</TITLE>
343c80476e4SDavid E. O'Brien</HEAD>
344c80476e4SDavid E. O'Brien<BODY>
345c80476e4SDavid E. O'Brien$pointers
346c80476e4SDavid E. O'Brien<H2>$sectiontexts[$section]</H2>
347c80476e4SDavid E. O'BrienEOP
348c80476e4SDavid E. O'Brien	&printsectionbody(*man, *sectionlines, *section, *name);
349c80476e4SDavid E. O'Brien
350c80476e4SDavid E. O'Brien	# Trailer
351c80476e4SDavid E. O'Brien
352c80476e4SDavid E. O'Brien	print <<EOP;
353c80476e4SDavid E. O'Brien$pointers
354c80476e4SDavid E. O'Brien</BODY>
355c80476e4SDavid E. O'BrienEOP
356c80476e4SDavid E. O'Brien
357c80476e4SDavid E. O'Brien    }
358c80476e4SDavid E. O'Brien}
359c80476e4SDavid E. O'Brien
360c80476e4SDavid E. O'Brienselect TOP unless $single;
361c80476e4SDavid E. O'Brien
362c80476e4SDavid E. O'Brien# Top page trailer
363c80476e4SDavid E. O'Brien
364c80476e4SDavid E. O'Brienprint <<EOP;
365c80476e4SDavid E. O'Brien</H2>
366c80476e4SDavid E. O'Brien<HR>
367c80476e4SDavid E. O'BrienHere are the <A HREF="$outfile">nroff manpage</A> (175K)
368c80476e4SDavid E. O'Brienfrom which this HTML version was generated,
369c80476e4SDavid E. O'Brienthe <A HREF="$script">Perl script</A> which did the conversion
370dc86a98eSDavid E. O'Brienand the <A HREF="ftp://ftp.astron.com/pub/tcsh/">
371c80476e4SDavid E. O'Briencomplete source code</A> for <I>tcsh</I>.
372c80476e4SDavid E. O'Brien<HR>
373c80476e4SDavid E. O'Brien<I>tcsh</I> is maintained by
374*cc698b49SBrooks DavisChristos Zoulas <A HREF="mailto:christos\@astron.com">&lt;christos\@astron.com&gt;</A>
375c80476e4SDavid E. O'Brienand the <A HREF="$listsfile"><I>tcsh</I> maintainers' mailing list</A>.
376c80476e4SDavid E. O'BrienDave Schweisguth <A HREF="mailto:dcs\@proton.chem.yale.edu">&lt;dcs\@proton.chem.yale.edu&gt;</A>
377c80476e4SDavid E. O'Brienwrote the manpage and the HTML conversion script.
378c80476e4SDavid E. O'Brien</BODY>
379c80476e4SDavid E. O'BrienEOP
380c80476e4SDavid E. O'Brien
381c80476e4SDavid E. O'Brienclose TOP;
382c80476e4SDavid E. O'Brien
383c80476e4SDavid E. O'Brien### Make lists page
384c80476e4SDavid E. O'Brien
385c80476e4SDavid E. O'Brienopen(LISTS, ">$dir/$listsfile");
386c80476e4SDavid E. O'Brienselect LISTS;
387c80476e4SDavid E. O'Brienwhile(($_ = <DATA>) ne "END\n") {   # Text stored after __END__
388c80476e4SDavid E. O'Brien    s/TOPFILEHERE/$topfile/;
389c80476e4SDavid E. O'Brien    print;
390c80476e4SDavid E. O'Brien}
391c80476e4SDavid E. O'Brienclose LISTS;
392c80476e4SDavid E. O'Brien
393c80476e4SDavid E. O'Brien### Make search script
394c80476e4SDavid E. O'Brien
395c80476e4SDavid E. O'Brienif ($index) {
396c80476e4SDavid E. O'Brien
397c80476e4SDavid E. O'Brien    # URL of $dir; see comments in search script
398c80476e4SDavid E. O'Brien
399c80476e4SDavid E. O'Brien    $root = $cgibin
400c80476e4SDavid E. O'Brien	? "'http://$host/" . ($updir ? "$updir/" : '') . "$dir/'"
401c80476e4SDavid E. O'Brien	: '"http://$ENV{\'SERVER_NAME\'}:$ENV{\'SERVER_PORT\'}" . (($_ = $ENV{\'SCRIPT_NAME\'}) =~ s|[^/]*$||, $_)';
402c80476e4SDavid E. O'Brien
403c80476e4SDavid E. O'Brien    # String for passing @name to search script
404c80476e4SDavid E. O'Brien
405c80476e4SDavid E. O'Brien    $name = join("',\n'", @name);
406c80476e4SDavid E. O'Brien
407c80476e4SDavid E. O'Brien    open(TOP, ">$dir/$cgifile");
408c80476e4SDavid E. O'Brien    select TOP;
409c80476e4SDavid E. O'Brien    while(($_ = <DATA>) ne "END\n") {   # Text stored after __END__
410c80476e4SDavid E. O'Brien	s/ROOTHERE/$root/;
411c80476e4SDavid E. O'Brien	s/NAMEHERE/$name/;
412c80476e4SDavid E. O'Brien	s/TOPFILEHERE/$topfile/;
413c80476e4SDavid E. O'Brien	print;
414c80476e4SDavid E. O'Brien    }
415c80476e4SDavid E. O'Brien    close TOP;
416c80476e4SDavid E. O'Brien    chmod(0755, "$dir/$cgifile") ||
417c80476e4SDavid E. O'Brien	die "$whatami: Can't chmod 0755 $dir/$cgifile!\n";
418c80476e4SDavid E. O'Brien    warn "$whatami: Don't forget to move $dir/$cgifile to /$cgibindir.\n"
419c80476e4SDavid E. O'Brien	if $cgibin;
420c80476e4SDavid E. O'Brien}
421c80476e4SDavid E. O'Brien
422c80476e4SDavid E. O'Brien### That's all, folks
423c80476e4SDavid E. O'Brien
424c80476e4SDavid E. O'Brienexit;
425c80476e4SDavid E. O'Brien
426c80476e4SDavid E. O'Brien### Subroutines
427c80476e4SDavid E. O'Brien
428c80476e4SDavid E. O'Brien# Process and print the body of a section
429c80476e4SDavid E. O'Brien
430c80476e4SDavid E. O'Briensub printsectionbody {
431c80476e4SDavid E. O'Brien
432c80476e4SDavid E. O'Brien    local(*man, *sectionlines, *sline, *name) = @_;	# Number of section
433c80476e4SDavid E. O'Brien    local($sfirst, $slast, @paralines, @paratypes, $comment, $dl, $pline,
434c80476e4SDavid E. O'Brien	  $comment, $pfirst, $plast, @para, @tag, $changeindent);
435c80476e4SDavid E. O'Brien
436c80476e4SDavid E. O'Brien    # Define section boundaries
437c80476e4SDavid E. O'Brien
438c80476e4SDavid E. O'Brien    $sfirst = $sectionlines[$sline] + 1;
439c80476e4SDavid E. O'Brien    if ($sline == $#sectionlines) {
440c80476e4SDavid E. O'Brien	$slast = $#man;
441c80476e4SDavid E. O'Brien    } else {
442c80476e4SDavid E. O'Brien	$slast = $sectionlines[$sline + 1] - 1;
443c80476e4SDavid E. O'Brien    }
444c80476e4SDavid E. O'Brien
445c80476e4SDavid E. O'Brien    # Find paragraph markers, ignoring those between '.ig' and '..'
446c80476e4SDavid E. O'Brien
447c80476e4SDavid E. O'Brien    if ($man[$sfirst] =~ /^\.[PIT]P/) {
448c80476e4SDavid E. O'Brien	@paralines = ();
449c80476e4SDavid E. O'Brien	@paratypes = ();
450c80476e4SDavid E. O'Brien    } else {
451c80476e4SDavid E. O'Brien	@paralines = ($sfirst - 1);		# .P follows .S[HS] by default
452c80476e4SDavid E. O'Brien	@paratypes = ('P');
453c80476e4SDavid E. O'Brien    }
454c80476e4SDavid E. O'Brien    $comment = 0;
455c80476e4SDavid E. O'Brien    foreach ($sfirst .. $slast) {
456c80476e4SDavid E. O'Brien	if ($man[$_] =~ /^\.ig/) {		# Start ignoring
457c80476e4SDavid E. O'Brien	    $comment = 1;
458c80476e4SDavid E. O'Brien	} elsif ($man[$_] =~ /^\.\./) {		# Stop ignoring
459c80476e4SDavid E. O'Brien	    $comment = 0;
460c80476e4SDavid E. O'Brien	} elsif (! $comment && $man[$_] =~ /^\.([PIT])P/) {
461c80476e4SDavid E. O'Brien	    push(@paralines, $_);
462c80476e4SDavid E. O'Brien	    push(@paratypes, $1);
463c80476e4SDavid E. O'Brien	}
464c80476e4SDavid E. O'Brien    }
465c80476e4SDavid E. O'Brien
466c80476e4SDavid E. O'Brien    # Process paragraphs
467c80476e4SDavid E. O'Brien
468c80476e4SDavid E. O'Brien    $changeindent = 0;
469c80476e4SDavid E. O'Brien    $dl = 0;
470c80476e4SDavid E. O'Brien    foreach $pline (0 .. $#paralines) {
471c80476e4SDavid E. O'Brien
472c80476e4SDavid E. O'Brien	@para = ();
473c80476e4SDavid E. O'Brien	$comment = 0;
474c80476e4SDavid E. O'Brien
475c80476e4SDavid E. O'Brien	# Define para boundaries
476c80476e4SDavid E. O'Brien
477c80476e4SDavid E. O'Brien	$pfirst = $paralines[$pline] + 1;
478c80476e4SDavid E. O'Brien	if ($pline == $#paralines) {
479c80476e4SDavid E. O'Brien	    $plast = $slast;
480c80476e4SDavid E. O'Brien	} else {
481c80476e4SDavid E. O'Brien	    $plast = $paralines[$pline + 1] - 1;
482c80476e4SDavid E. O'Brien	}
483c80476e4SDavid E. O'Brien
484c80476e4SDavid E. O'Brien	foreach (@man[$pfirst .. $plast]) {
485c80476e4SDavid E. O'Brien	    if (/^\.ig/) {		    # nroff begin ignore
486c80476e4SDavid E. O'Brien		if ($comment == 0) {
487c80476e4SDavid E. O'Brien		    $comment = 2;
488c80476e4SDavid E. O'Brien		    push(@para, "<!--\n");
489c80476e4SDavid E. O'Brien		} elsif ($comment == 1) {
490c80476e4SDavid E. O'Brien		    $comment = 2;
491c80476e4SDavid E. O'Brien		} elsif ($comment == 2) {
492c80476e4SDavid E. O'Brien		    s/--/-/g;		    # Remove double-dashes in comments
493c80476e4SDavid E. O'Brien		    push(@para, $_);
494c80476e4SDavid E. O'Brien		}
495c80476e4SDavid E. O'Brien	    } elsif (/^\.\./) {		    # nroff end ignore
496c80476e4SDavid E. O'Brien		if ($comment == 0) {
497c80476e4SDavid E. O'Brien		    ;
498c80476e4SDavid E. O'Brien		} elsif ($comment == 1) {
499c80476e4SDavid E. O'Brien		    ;
500c80476e4SDavid E. O'Brien		} elsif ($comment == 2) {
501c80476e4SDavid E. O'Brien		    $comment = 1;
502c80476e4SDavid E. O'Brien		}
503c80476e4SDavid E. O'Brien	    } elsif (/^\.\\\"/) {	    # nroff comment
504c80476e4SDavid E. O'Brien		if ($comment == 0) {
505c80476e4SDavid E. O'Brien		    $comment = 1;
506c80476e4SDavid E. O'Brien		    push(@para, "<!--\n");
507c80476e4SDavid E. O'Brien		    s/^\.\\\"//;
508c80476e4SDavid E. O'Brien		} elsif ($comment == 1) {
509c80476e4SDavid E. O'Brien		    s/^\.\\\"//;
510c80476e4SDavid E. O'Brien		} elsif ($comment == 2) {
511c80476e4SDavid E. O'Brien		    ;
512c80476e4SDavid E. O'Brien		}
513c80476e4SDavid E. O'Brien		s/--/-/g;		    # Remove double-dashes in comments
514c80476e4SDavid E. O'Brien		push(@para, $_);
515c80476e4SDavid E. O'Brien	    } else {			    # Nothing to do with comments
516c80476e4SDavid E. O'Brien		if ($comment == 0) {
517c80476e4SDavid E. O'Brien		    ;
518c80476e4SDavid E. O'Brien    		} elsif ($comment == 1) {
519c80476e4SDavid E. O'Brien		    $comment = 0;
520c80476e4SDavid E. O'Brien		    push(@para, "-->\n");
521c80476e4SDavid E. O'Brien		} elsif ($comment == 2) {
522c80476e4SDavid E. O'Brien		    s/--/-/g;		    # Remove double-dashes in comments
523c80476e4SDavid E. O'Brien		}
524c80476e4SDavid E. O'Brien
525c80476e4SDavid E. O'Brien		unless ($comment) {
526c80476e4SDavid E. O'Brien
527c80476e4SDavid E. O'Brien		    if (/^\.TH/) {	    # Title; got this already
528c80476e4SDavid E. O'Brien			next;
529c80476e4SDavid E. O'Brien		    } elsif (/^\.PD/) {	    # Para spacing; unimplemented
530c80476e4SDavid E. O'Brien			next;
531c80476e4SDavid E. O'Brien		    } elsif (/^\.RS/) {	    # Indent (one width only)
532c80476e4SDavid E. O'Brien			$changeindent++;
533c80476e4SDavid E. O'Brien			next;
534c80476e4SDavid E. O'Brien		    } elsif (/^\.RE/) {	    # Outdent
535c80476e4SDavid E. O'Brien			$changeindent--;
536c80476e4SDavid E. O'Brien			next;
537c80476e4SDavid E. O'Brien		    }
538c80476e4SDavid E. O'Brien
539c80476e4SDavid E. O'Brien		    # Line break
540c80476e4SDavid E. O'Brien		    s/^\.br.*/<BR>/;
541c80476e4SDavid E. O'Brien
542c80476e4SDavid E. O'Brien		    # More nroff special characters
543c80476e4SDavid E. O'Brien
544c80476e4SDavid E. O'Brien		    s/^\\&amp\;//;	    # leading dot escape; save until
545c80476e4SDavid E. O'Brien					    #   now so leading dots aren't
546c80476e4SDavid E. O'Brien					    #   confused with ends of .igs
547c80476e4SDavid E. O'Brien
548c80476e4SDavid E. O'Brien		    &make_hrefs(*name, *_);
549c80476e4SDavid E. O'Brien		}
550c80476e4SDavid E. O'Brien		push(@para, $_);
551c80476e4SDavid E. O'Brien	    }
552c80476e4SDavid E. O'Brien	}
553c80476e4SDavid E. O'Brien
554c80476e4SDavid E. O'Brien	push(@para, "-->\n") if $comment;   # Close open comment
555c80476e4SDavid E. O'Brien
556c80476e4SDavid E. O'Brien    	# Print paragraph
557c80476e4SDavid E. O'Brien
558c80476e4SDavid E. O'Brien	if ($paratypes[$pline] eq 'P') {
559c80476e4SDavid E. O'Brien	    &font(*para);
560c80476e4SDavid E. O'Brien	    print   @para;
561c80476e4SDavid E. O'Brien	} elsif ($paratypes[$pline] eq 'I') {
562c80476e4SDavid E. O'Brien	    &font(*para);
563c80476e4SDavid E. O'Brien	    print   "<menu>\n",
564c80476e4SDavid E. O'Brien		    @para,
565c80476e4SDavid E. O'Brien		    "</menu>\n";
566c80476e4SDavid E. O'Brien	} else {			# T
567c80476e4SDavid E. O'Brien	    @tag = shift(@para);
568c80476e4SDavid E. O'Brien	    &font(*tag);
569c80476e4SDavid E. O'Brien	    &font(*para);
570c80476e4SDavid E. O'Brien	    print   "<DL compact>\n" unless $dl;
571c80476e4SDavid E. O'Brien	    print   "<DT>\n",
572c80476e4SDavid E. O'Brien		    @tag,
573c80476e4SDavid E. O'Brien		    "<DD>\n",
574c80476e4SDavid E. O'Brien		    @para;
575c80476e4SDavid E. O'Brien	    if ($pline == $#paratypes || $paratypes[$pline + 1] ne 'T') {
576c80476e4SDavid E. O'Brien		# Perl 5 lossage alert
577c80476e4SDavid E. O'Brien		# Next para is not a definition list
578c80476e4SDavid E. O'Brien		$dl = 0;		    # Close open definition list
579c80476e4SDavid E. O'Brien		print "</DL>\n";
580c80476e4SDavid E. O'Brien	    } else {
581c80476e4SDavid E. O'Brien		$dl = 1;		    # Leave definition list open
582c80476e4SDavid E. O'Brien	    }
583c80476e4SDavid E. O'Brien	}
584c80476e4SDavid E. O'Brien	print "<P>\n";
585c80476e4SDavid E. O'Brien
586c80476e4SDavid E. O'Brien	# Indent/outdent the *next* para
587c80476e4SDavid E. O'Brien
588c80476e4SDavid E. O'Brien	while ($changeindent > 0) {
589c80476e4SDavid E. O'Brien	    print "<menu>\n";
590c80476e4SDavid E. O'Brien	    $changeindent--;
591c80476e4SDavid E. O'Brien	}
592c80476e4SDavid E. O'Brien	while ($changeindent < 0) {
593c80476e4SDavid E. O'Brien	    print "</menu>\n";
594c80476e4SDavid E. O'Brien	    $changeindent++;
595c80476e4SDavid E. O'Brien	}
596c80476e4SDavid E. O'Brien    }
597c80476e4SDavid E. O'Brien    1;
598c80476e4SDavid E. O'Brien}
599c80476e4SDavid E. O'Brien
600c80476e4SDavid E. O'Brien# Make one name anchor in a line; cue on fonts (.B or .I) but leave them alone
601c80476e4SDavid E. O'Brien
602c80476e4SDavid E. O'Briensub make_name {
603c80476e4SDavid E. O'Brien
604c80476e4SDavid E. O'Brien    local(*name, *font, *file, *index, *line) = @_;
605c80476e4SDavid E. O'Brien    local($text);
606c80476e4SDavid E. O'Brien
607c80476e4SDavid E. O'Brien    if (($text) = ($line =~ /^\.[BI]\s+([^\s\\]+)/)) {	# Found pattern
608c80476e4SDavid E. O'Brien
609c80476e4SDavid E. O'Brien	if (
610c80476e4SDavid E. O'Brien	    $text !~ /^-/		    # Avoid lists of options
611c80476e4SDavid E. O'Brien	    && (length($text) > 1	    # and history escapes
612c80476e4SDavid E. O'Brien		||  $text =~ /^[%:@]$/)	    # Special pleading for %, :, @
613c80476e4SDavid E. O'Brien	    && ! $name{"$text $font"}	    # Skip if there's one already
614c80476e4SDavid E. O'Brien	) {
615c80476e4SDavid E. O'Brien	    # Record link
616c80476e4SDavid E. O'Brien
617c80476e4SDavid E. O'Brien	    $name{"$text $font"} = ($single ? '' : $file) . "#$text";
618c80476e4SDavid E. O'Brien	    push(@name, "$text\t" . $name{"$text $font"}) if $index;
619c80476e4SDavid E. O'Brien
620c80476e4SDavid E. O'Brien	    # Put in the name anchor
621c80476e4SDavid E. O'Brien
622c80476e4SDavid E. O'Brien	    $line =~ s/^(\.[BI]\s+)([^\s\\]+)/$1<A NAME=\"$text\">$2<\/A>/;
623c80476e4SDavid E. O'Brien	}
624c80476e4SDavid E. O'Brien    }
625c80476e4SDavid E. O'Brien    $line;
626c80476e4SDavid E. O'Brien}
627c80476e4SDavid E. O'Brien
628c80476e4SDavid E. O'Brien# Make all the href anchors in a line; cue on fonts (\fB ... \fR or
629c80476e4SDavid E. O'Brien# \fI ... \fR) but leave them alone
630c80476e4SDavid E. O'Brien
631c80476e4SDavid E. O'Briensub make_hrefs {
632c80476e4SDavid E. O'Brien
633c80476e4SDavid E. O'Brien    local(*name, *line) = @_;
634c80476e4SDavid E. O'Brien    local(@pieces, $piece);
635c80476e4SDavid E. O'Brien
636c80476e4SDavid E. O'Brien    @pieces = split(/(\\f[BI][^\\]*\\fR)/, $line);
637c80476e4SDavid E. O'Brien
638c80476e4SDavid E. O'Brien    $piece = 0;
639c80476e4SDavid E. O'Brien    foreach (@pieces) {
640c80476e4SDavid E. O'Brien	if (/\\f([BI])([^\\]*)\\fR/	# Found a possibility
641c80476e4SDavid E. O'Brien
642c80476e4SDavid E. O'Brien	# It's not followed by (, i.e. it's not a manpage reference
643c80476e4SDavid E. O'Brien
644c80476e4SDavid E. O'Brien	&& substr($pieces[$piece + 1], 0, 1) ne '(') {
645c80476e4SDavid E. O'Brien	    $key = "$2 $1";
646c80476e4SDavid E. O'Brien	    if ($name{$key}) {			# If there's a matching name
647c80476e4SDavid E. O'Brien		s/(\\f[BI])([^\\]*)(\\fR)/$1<A HREF=\"$name{$key}\">$2<\/A>$3/;
648c80476e4SDavid E. O'Brien	    }
649c80476e4SDavid E. O'Brien	}
650c80476e4SDavid E. O'Brien	$piece++;
651c80476e4SDavid E. O'Brien    }
652c80476e4SDavid E. O'Brien    $line = join('', @pieces);
653c80476e4SDavid E. O'Brien}
654c80476e4SDavid E. O'Brien
655c80476e4SDavid E. O'Brien# Convert nroff font escapes to HTML
656c80476e4SDavid E. O'Brien# Expects comments and breaks to be in HTML form already
657c80476e4SDavid E. O'Brien
658c80476e4SDavid E. O'Briensub font {
659c80476e4SDavid E. O'Brien
660c80476e4SDavid E. O'Brien    local(*para) = @_;
661c80476e4SDavid E. O'Brien    local($i, $j, @begin, @end, $part, @pieces, $bold, $italic);
662c80476e4SDavid E. O'Brien
663c80476e4SDavid E. O'Brien    return 0 if $#para == -1;   # Ignore empty paragraphs
664c80476e4SDavid E. O'Brien				# Perl 5 lossage alert
665c80476e4SDavid E. O'Brien
666c80476e4SDavid E. O'Brien    # Find beginning and end of each part between HTML comments
667c80476e4SDavid E. O'Brien
668c80476e4SDavid E. O'Brien    $i = 0;
669c80476e4SDavid E. O'Brien    @begin = ();
670c80476e4SDavid E. O'Brien    @end = ();
671c80476e4SDavid E. O'Brien    foreach (@para) {
672c80476e4SDavid E. O'Brien	push(@begin, $i + 1) if /^-->/ || /^<BR>/;
673c80476e4SDavid E. O'Brien	push(@end, $i - 1) if /^<!--/ || /^<BR>/;
674c80476e4SDavid E. O'Brien	$i++;
675c80476e4SDavid E. O'Brien    }
676c80476e4SDavid E. O'Brien    if ($para[0] =~ /^<!--/ || $para[0] =~ /^<BR>/) {
677c80476e4SDavid E. O'Brien	shift(@end);
678c80476e4SDavid E. O'Brien    } else {
679c80476e4SDavid E. O'Brien	unshift(@begin, 0);	# Begin at the beginning
680c80476e4SDavid E. O'Brien    }
681c80476e4SDavid E. O'Brien    if ($para[$#para] =~ /^-->/ || $para[$#para] =~ /^<BR>/) {
682c80476e4SDavid E. O'Brien	pop(@begin);
683c80476e4SDavid E. O'Brien    } else {
684c80476e4SDavid E. O'Brien	push(@end, $#para);	# End at the end
685c80476e4SDavid E. O'Brien    }
686c80476e4SDavid E. O'Brien
687c80476e4SDavid E. O'Brien    # Fontify each part
688c80476e4SDavid E. O'Brien
689c80476e4SDavid E. O'Brien    $bold = $italic = 0;
690c80476e4SDavid E. O'Brien    foreach $i (0 .. $#begin) {
691c80476e4SDavid E. O'Brien	$part = join('', @para[$begin[$i] .. $end[$i]]);
6929ccc37e3SMark Peek	$part =~ s/^\.([BI])\s+(.*)$/\\f$1$2\\fR/gm;	    # .B, .I
6939ccc37e3SMark Peek	@pieces = split(/(\\f[BIR])/m, $part);
694c80476e4SDavid E. O'Brien	$part = '';
695c80476e4SDavid E. O'Brien	foreach $j (@pieces) {
696c80476e4SDavid E. O'Brien	    if ($j eq '\fB') {
697c80476e4SDavid E. O'Brien		if ($italic) {
698c80476e4SDavid E. O'Brien		    $italic = 0;
699c80476e4SDavid E. O'Brien		    $part .= '</I>';
700c80476e4SDavid E. O'Brien		}
701c80476e4SDavid E. O'Brien		unless ($bold) {
702c80476e4SDavid E. O'Brien		    $bold = 1;
703c80476e4SDavid E. O'Brien		    $part .= '<B>';
704c80476e4SDavid E. O'Brien		}
705c80476e4SDavid E. O'Brien	    } elsif ($j eq '\fI') {
706c80476e4SDavid E. O'Brien		if ($bold) {
707c80476e4SDavid E. O'Brien		    $bold = 0;
708c80476e4SDavid E. O'Brien		    $part .= '</B>';
709c80476e4SDavid E. O'Brien		}
710c80476e4SDavid E. O'Brien		unless ($italic) {
711c80476e4SDavid E. O'Brien		    $italic = 1;
712c80476e4SDavid E. O'Brien		    $part .= '<I>';
713c80476e4SDavid E. O'Brien		}
714c80476e4SDavid E. O'Brien	    } elsif ($j eq '\fR') {
715c80476e4SDavid E. O'Brien		if ($bold) {
716c80476e4SDavid E. O'Brien		    $bold = 0;
717c80476e4SDavid E. O'Brien		    $part .= '</B>';
718c80476e4SDavid E. O'Brien		} elsif ($italic) {
719c80476e4SDavid E. O'Brien		    $italic = 0;
720c80476e4SDavid E. O'Brien		    $part .= '</I>';
721c80476e4SDavid E. O'Brien		}
722c80476e4SDavid E. O'Brien	    } else {
723c80476e4SDavid E. O'Brien		$part .= $j;
724c80476e4SDavid E. O'Brien	    }
725c80476e4SDavid E. O'Brien	}
726c80476e4SDavid E. O'Brien
727c80476e4SDavid E. O'Brien	# Close bold/italic before break
728c80476e4SDavid E. O'Brien
729c80476e4SDavid E. O'Brien	if ($end[$i] == $#para || $para[$end[$i] + 1] =~ /^<BR>/) {
730c80476e4SDavid E. O'Brien	    # Perl 5 lossage alert
731c80476e4SDavid E. O'Brien	    if ($bold) {
732c80476e4SDavid E. O'Brien		$bold = 0;
733c80476e4SDavid E. O'Brien		$part =~ s/(\n)?$/<\/B>$1\n/;
734c80476e4SDavid E. O'Brien	    } elsif ($italic) {
735c80476e4SDavid E. O'Brien		$italic = 0;
736c80476e4SDavid E. O'Brien		$part =~ s/(\n)?$/<\/I>$1\n/;
737c80476e4SDavid E. O'Brien	    }
738c80476e4SDavid E. O'Brien	}
739c80476e4SDavid E. O'Brien
740c80476e4SDavid E. O'Brien	# Rebuild this section of @para
741c80476e4SDavid E. O'Brien
742c80476e4SDavid E. O'Brien	foreach $j ($begin[$i] .. $end[$i]) {
743c80476e4SDavid E. O'Brien	    $part =~ s/^([^\n]*(\n|$))//;
744c80476e4SDavid E. O'Brien	    $para[$j] = $1;
745c80476e4SDavid E. O'Brien	}
746c80476e4SDavid E. O'Brien    }
747c80476e4SDavid E. O'Brien
748c80476e4SDavid E. O'Brien    # Close bold/italic on last non-comment line
749c80476e4SDavid E. O'Brien    # Do this only here because fonts pass through comments
750c80476e4SDavid E. O'Brien
751c80476e4SDavid E. O'Brien    $para[$end[$#end]] =~ s/(\n)?$/<\/B>$1/ if $bold;
752c80476e4SDavid E. O'Brien    $para[$end[$#end]] =~ s/(\n)?$/<\/I>$1/ if $italic;
753c80476e4SDavid E. O'Brien}
754c80476e4SDavid E. O'Brien
755c80476e4SDavid E. O'Briensub usage {
756c80476e4SDavid E. O'Brien    local ($message) = $_[0];
757c80476e4SDavid E. O'Brien
758c80476e4SDavid E. O'Brien    warn $message if $message;
759c80476e4SDavid E. O'Brien    warn <<EOP;
760c80476e4SDavid E. O'BrienUsage: $whatami [-1icsu] [-C dir] [-d dir] [-h host] [file]
761c80476e4SDavid E. O'BrienWithout [file], reads from tcsh.man or stdin.
762c80476e4SDavid E. O'Brien-1	    Makes a single page instead of a table of contents and sections
763c80476e4SDavid E. O'Brien-i	    Makes a CGI searchable index script, tcsh.html/tcsh.cgi, intended
764c80476e4SDavid E. O'Brien	    for a server which respects the .cgi extension in any directory.
765c80476e4SDavid E. O'Brien-c	    Like -i,  but the CGI script is intended for a server which wants
766c80476e4SDavid E. O'Brien	    scripts in /cgi-bin (or some other privileged directory separate
767c80476e4SDavid E. O'Brien	    from the rest of the HTML) and must be moved there by hand.
768c80476e4SDavid E. O'Brien-C dir	    Uses /dir instead of /cgi-bin as the CGI bin dir.
769c80476e4SDavid E. O'Brien	    Meaningless without -c.
770c80476e4SDavid E. O'Brien-d dir	    Uses /dir/tcsh.html instead of /tcsh.html as the HTML dir.
771c80476e4SDavid E. O'Brien	    Meaningless without -c.
772c80476e4SDavid E. O'Brien-D dir	    Uses /dir.html instead of /tcsh.html as the HTML dir.
773c80476e4SDavid E. O'Brien	    Meaningless without -c.
774c80476e4SDavid E. O'Brien-G name	    Uses name instead of tcsh.cgi as the name of the CGI script.
775c80476e4SDavid E. O'Brien	    Meaningless without -c or -i.
776c80476e4SDavid E. O'Brien-h host	    Uses host as the host:port part of the URL to the entry point.
777c80476e4SDavid E. O'Brien	    Meaningless without -c.
778c80476e4SDavid E. O'Brien-s	    Filenames are shorter (max 8 + 3) but less descriptive.
779c80476e4SDavid E. O'Brien-u	    This message
780c80476e4SDavid E. O'BrienEOP
781c80476e4SDavid E. O'Brien    exit !! $message;
782c80476e4SDavid E. O'Brien}
783c80476e4SDavid E. O'Brien
784c80476e4SDavid E. O'Brien### Inlined documents. Watch for *HERE tokens.
785c80476e4SDavid E. O'Brien
786c80476e4SDavid E. O'Brien__END__
787c80476e4SDavid E. O'Brien<HEAD>
788c80476e4SDavid E. O'Brien<TITLE>The tcsh mailing lists</TITLE>
789c80476e4SDavid E. O'Brien</HEAD>
790c80476e4SDavid E. O'Brien<BODY>
791c80476e4SDavid E. O'Brien<A HREF="TOPFILEHERE">Up</A>
792c80476e4SDavid E. O'Brien<H2>The <I>tcsh</I> mailing lists</H2>
793c80476e4SDavid E. O'BrienThere are three <I>tcsh</I> mailing lists:
794c80476e4SDavid E. O'Brien<DL>
795c80476e4SDavid E. O'Brien<DT>
796*cc698b49SBrooks Davis<I>tcsh@mailman.astron.com</I>
797c80476e4SDavid E. O'Brien<DD>
798c80476e4SDavid E. O'BrienThe <I>tcsh</I> maintainers and testers' mailing list.
799c80476e4SDavid E. O'Brien<DT>
800*cc698b49SBrooks Davis<I>tcsh-bugs@astron.com</I>
801c80476e4SDavid E. O'Brien<DD>
80223338178SMark PeekOpen bug and user comment discussion.
803c80476e4SDavid E. O'Brien</DL>
80423338178SMark PeekYou can subscribe to either of these lists by visiting
805*cc698b49SBrooks Davis<I><A HREF="https://mailman.astron.com/">https://mailman.astron.com/</A></I>
80623338178SMark Peek<P>
80723338178SMark PeekTo file a bug report or a feature suggestion (preferably
80823338178SMark Peekwith code), please visit
809*cc698b49SBrooks Davis<I><A HREF="https://bugs.astron.com/">https://bugs.astron.com/</A></I>
810c80476e4SDavid E. O'Brien<P>
811c80476e4SDavid E. O'Brien<A HREF="TOPFILEHERE">Up</A>
812c80476e4SDavid E. O'Brien</BODY>
813c80476e4SDavid E. O'BrienEND
8146767bd61SMark Peek: # -*- perl -*-
815c80476e4SDavid E. O'Brien
816c80476e4SDavid E. O'Brien# Emulate #!/usr/local/bin/perl on systems without #!
817c80476e4SDavid E. O'Brien
818dc86a98eSDavid E. O'Brieneval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
819dc86a98eSDavid E. O'Brien& eval 'exec perl -S $0 $argv:q' if 0;
820c80476e4SDavid E. O'Brien
821c80476e4SDavid E. O'Brien# Setup
822c80476e4SDavid E. O'Brien
823c80476e4SDavid E. O'Brien# Location: doesn't work with relative URLs, so we need to know where to find
824c80476e4SDavid E. O'Brien#   the top and section files.
825c80476e4SDavid E. O'Brien# If the search engine is in /cgi-bin, we need a hard-coded URL.
826c80476e4SDavid E. O'Brien# If the search engine is in the same directory, we can figure it out from CGI
827c80476e4SDavid E. O'Brien#   environment variables.
828c80476e4SDavid E. O'Brien
829c80476e4SDavid E. O'Brien$root = ROOTHERE;
830c80476e4SDavid E. O'Brien$topfile = 'TOPFILEHERE';
831c80476e4SDavid E. O'Brien@name = (
832c80476e4SDavid E. O'Brien'NAMEHERE'
833c80476e4SDavid E. O'Brien);
834c80476e4SDavid E. O'Brien
835c80476e4SDavid E. O'Brien# Do the search
836c80476e4SDavid E. O'Brien
837c80476e4SDavid E. O'Brien$input = $ENV{'QUERY_STRING'};
838c80476e4SDavid E. O'Brien$input =~ s/^input=//;
839c80476e4SDavid E. O'Brien$input =~ s/\+/ /g;
840c80476e4SDavid E. O'Brienprint "Status: 302 Found\n";
841c80476e4SDavid E. O'Brienif ($input ne '' && ($key = (grep(/^$input/,  @name))[0] ||
842c80476e4SDavid E. O'Brien			    (grep(/^$input/i, @name))[0] ||
843c80476e4SDavid E. O'Brien			    (grep( /$input/i, @name))[0]   )) {
844c80476e4SDavid E. O'Brien    $key =~ /\t([^\t]*)$/;
845c80476e4SDavid E. O'Brien    print "Location: $root$1\n\n";
846c80476e4SDavid E. O'Brien} else {
847c80476e4SDavid E. O'Brien    print "Location: $root$topfile\n\n";
848c80476e4SDavid E. O'Brien}
849c80476e4SDavid E. O'BrienEND
850