From cameron@cse.unsw.edu.au Tue Feb 15 13:48:08 1994 Article: 7916 of comp.infosystems.www From: cameron@cse.unsw.edu.au Subject: Re: man to html? Organization: Computing Facility, CS&E, Uni Of NSW, Oz Date: Fri, 11 Feb 94 07:17:47 MET I use the following to provide a web manual browser for our students. It may not be what you want, but the "man2html" subroutine should readily adapt to your needs. Please put my name and email address on it if you use it. You can try it out at http://www.cse.unsw.edu.au/scripts/man. You'll get our SGI machine; the students get their local architecture by redirecting through http://localhost. - Cameron Simpson cameron@cse.unsw.edu.au, DoD#743 -- Ignorance is preferable to error; and he is less remote from the truth who believes nothing, than he who believes what is wrong. - Thomas Jefferson #!/bin/sh # sed 's/^X//' > man.pl <<'EOF-/home/cs/orchestra/crwth/1/cameron/etc/web/../scripts/man' X#!/usr/local/bin/perl X# X# Script to produce manual entries. X# - Cameron Simpson, 05jan94 X# X Xif ($#ARGV >= $[ && $ARGV[$[] eq '-q') X { shift; X $ENV{QUERY_STRING}=shift; X } Xelse X{ open(STDERR,'>/dev/null'); X} X Xprint "Content-Type: text/html\n\n"; X X@manpath=('/usr/local/man', X '/usr/local/gnu/man', X '/usr/local/lib/elm/man', X '/usr/local/lib/tcl', X '/usr/local/share/man', X '/usr/man', X '/usr/catman/local', X '/usr/catman/a_man', X '/usr/catman/g_man', X '/usr/catman/p_man', X '/usr/catman/u_man', X '/usr/local/X11/man', X '/usr/X11/man'); X@mansubdirs=('ftn','pas','standard','X','Xt','libmalloc','audio','X11'); X Xif (length($ENV{PATH_INFO})) X { $ENV{PATH_INFO}=&clean_path($ENV{PATH_INFO}); X } X Xif (length($ENV{QUERY_STRING})) X { $title="UNSW CSE Manual Lookup for $ENV{QUERY_STRING}"; X } Xelsif (length($ENV{PATH_INFO})) X { $title="UNSW CSE Manual Entry for $ENV{PATH_INFO}"; X } Xelse { $title="UNSW CSE Manual Lookup"; X } X Xprint "
\n"; X if ($#manuals < $[) X # no matches X { print "Sorry, no match for \"$ENV{QUERY_STRING}\".\n"; X } X elsif ($#manuals == $[) X # exactly one match X { &showman(shift @manuals); X } X else X { print "\"^$ENV{QUERY_STRING}\" matches ", X $#manuals-$[+1, X " manual entries:\n
X
\n"; X print "
\n"; X X local($hadblank)=1; X X while () X { $_=join('',&man2html($_)); X s/\s+$//; X if (length) X { print $_, "\n"; X $hadblank=0; X } X else X { if (!$hadblank) X { print $_, "\n"; X } X X $hadblank=1; X } X } X X close(MAN); X X print "
\n";
X
X if ($queries > 1)
X { local($query);
X
X print "[ ", $queries, " queries (",
X $newqueries, " distinct) in ",
X $querytime, " seconds. ]
\n";
X
X for (sort keys %querytime)
X { print "[ query: $_, time=$querytime{$_} ]
\n";
X }
X }
X
X 1;
X }
X
Xsub man2html
X { local(@lines)=@_;
X local($_);
X
X for (@lines)
X { # convert special characters
X s:()+([<>&]):$2:g; # clear underlines from specials
X s:(([<>&])+\2:$2:g;# clear bold from specials
X s:&:&:g; # replace with SGML escapes
X s:<:<:g;
X s:>:>:g;
X
X # recognise bold (accomodating underlined bold!)
X s:(()*(.)\3)+)+:$&:g;
X s:(.)\1)+:$1:g;
X
X # recognise italics
X s:(()+.)+:$&:g;
X s:()+(.):$2:g;
X
X # recognise references
X # all upper MLALIAS(8L)
X s:(<[bi]>)?\b([A-Z_\d]+)([bi]>)?\((\d)\w*\):&manhref($&,"\L$2\E.$4"):eg;
X # mixed
X s:(<[bi]>)?\b(\w*[a-z]\w*)([bi]>)?\((\d)\w*\):&manhref($&,"$2.$4"):eg;
X }
X
X @lines;
X }
X
Xsub manhref # (label,query) -> href
X { local($label,$query)=@_;
X
X # doing the search now is a waste of time as it turns out
X return "$label";
X
X local(@matches)=&searchfor($query);
X local($ref);
X
X if (@matches < 1)
X { $label;
X }
X else
X { if (@matches == 1)
X { $ref="http:$ENV{SCRIPT_NAME}$matches[$[]";
X }
X else
X { $ref="http:$ENV{SCRIPT_NAME}?$query";
X }
X
X "$label";
X }
X }
X
X# strip . and .. from path
Xsub clean_path
X { local($path)=@_;
X local(@path,$_);
X
X @path=();
X for (grep(length,split(m:/+:,$path)))
X { if ($_ eq '.') {}
X elsif ($_ eq '..') { pop @path; }
X else { push(@path,$_); }
X }
X '/'.join('/',@path);
X }
X
Xsub dirents # dir -> @entries
X { local($dir)=@_;
X local(@dirents);
X
X if (!defined($dirents{$dir}))
X { local($dstart,$dend);
X
X if (-d "$dir/." && opendir(DIRENTS,$dir))
X { $opendirs++;
X print STDERR "opendir($dir)\n";
X @dirents=readdir(DIRENTS);
X closedir(DIRENTS);
X }
X
X $dirents{$dir}=join("\0",@dirents);
X }
X else
X { @dirents=split(/\0/,$dirents{$dir});
X }
X
X @dirents;
X }
X
Xsub searchfor
X { local($QUERY)=@_;
X local(@matched,$sectnum);
X local($qstart,$qend);
X
X $queries++;
X if (defined($searchfor{$QUERY}))
X { @matched=split(/\0/,$searchfor{$QUERY});
X }
X else
X { local($mandir,%notneeded,@cats,$cat,$sub,$glob,$globbed,$path);
X
X if ($QUERY =~ /\.(\d)/) { $sectnum=$1; }
X
X $newqueries++;
X $qstart=time;
X MANDIR:
X for $mandir (@manpath)
X { undef %notneeded; # used to mark catX as seen so manX can be ignored
X # sort so that we consider cat before man
X @cats=sort grep(/^(man|cat)/,&dirents($mandir));
X @cats=grep(!/^(man|cat)(\d)/ || $2 eq $sectnum,@cats) if length($sectnum);
X next MANDIR unless @cats;
X for $cat (@cats)
X { SUBDIR:
X for $sub ('',@mansubdirs)
X { $glob="$mandir/$cat/";
X $glob.="$sub/" if length($sub);
X @globbed=sort &dirents($glob);
X last SUBDIR if !@globbed && !length($sub);
X next SUBDIR if !@globbed;
X @globbed=grep(/^$QUERY/,@globbed);
X PATH:
X for $globbed (@globbed)
X { $path=$glob.$globbed;
X next PATH if $notneeded{$path};
X push(@matched,$path) if -r $path;
X if ($path =~ m:/cat(\d+[^/.]*)/:)
X { $notneeded{"$`/man$1/$'"}=1;
X }
X }
X }
X }
X }
X
X $searchfor{$QUERY}=join("\0",@matched);
X
X $qend=time;
X $querytime+=$qend-$qstart;
X $querytime{$QUERY}=$qend-$qstart;
X }
X
X @matched;
X }
EOF-/home/cs/orchestra/crwth/1/cameron/etc/web/../scripts/man
exit 0