aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/w3mman
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/w3mman')
-rw-r--r--scripts/w3mman/Makefile46
-rw-r--r--scripts/w3mman/README47
-rw-r--r--scripts/w3mman/hlink.cgi97
-rw-r--r--scripts/w3mman/w3mman41
-rw-r--r--scripts/w3mman/w3mman.in41
-rw-r--r--scripts/w3mman/w3mman2html.cgi252
-rw-r--r--scripts/w3mman/w3mman2html.cgi.in252
7 files changed, 776 insertions, 0 deletions
diff --git a/scripts/w3mman/Makefile b/scripts/w3mman/Makefile
new file mode 100644
index 0000000..1e596e0
--- /dev/null
+++ b/scripts/w3mman/Makefile
@@ -0,0 +1,46 @@
+
+prefix = /usr/local
+bindir = $(prefix)/bin
+libdir = $(prefix)/lib
+distdir = ./distfiles
+
+W3M_LIBDIR = $(libdir)/w3m
+
+INSTALL = install -c
+INSTALL_SCRIPT = $(INSTALL) -m 755
+
+PERL = /usr/local/bin/perl
+W3M = w3m
+# W3M = w3m -X -o confirm_qq=0
+MAN = man
+
+all: w3mman w3mman2html.cgi
+
+w3mman: w3mman.in Makefile
+ sed -e 's%@PERL@%$(PERL)%g' \
+ -e 's%@W3M@%$(W3M)%g' \
+ -e 's%@MAN@%$(MAN)%g' \
+ w3mman.in > w3mman
+ chmod +x w3mman
+
+w3mman2html.cgi: w3mman2html.cgi.in Makefile
+ sed -e 's%@PERL@%$(PERL)%g' \
+ -e 's%@MAN@%$(MAN)%g' \
+ w3mman2html.cgi.in > w3mman2html.cgi
+ chmod +x w3mman2html.cgi
+
+install: w3mman w3mman2html.cgi
+ $(INSTALL_SCRIPT) w3mman $(bindir)
+ $(INSTALL_SCRIPT) w3mman2html.cgi $(W3M_LIBDIR)
+
+dist: all
+ @-rm -fr $(distdir)/w3mman
+ mkdir -p $(distdir)/w3mman
+ cp Makefile README w3mman w3mman.in \
+ w3mman2html.cgi w3mman2html.cgi.in hlink.cgi \
+ $(distdir)/w3mman
+ ( cd $(distdir); \
+ tar -cf - w3mman | GZIP='' gzip ) \
+ > $(distdir)/w3mman.tar.gz
+ -rm -fr $(distdir)/w3mman
+
diff --git a/scripts/w3mman/README b/scripts/w3mman/README
new file mode 100644
index 0000000..699e068
--- /dev/null
+++ b/scripts/w3mman/README
@@ -0,0 +1,47 @@
+
+w3mman
+
+ 他のマニュアルやヘッダファイルにリンクをはることができる
+ man コマンドの代替コマンドです。
+
+使用法
+
+ w3mman
+ w3mman <command>[(<section>)]
+ w3mman [<section>] <command>
+ w3mman -k <keyword>
+
+インストール
+
+ make install
+ 必要なら PERL, MAN, W3M_LIBDIR を設定してください。
+ w3mman2html.cgi もインストールされます。
+
+================
+
+w3mman2html.cgi
+
+使用法
+
+ w3m file:///$LIB/w3mman2html.cgi
+ w3m file:///$LIB/w3mman2html.cgi?<command>[(<section>)]
+ w3m file:///$LIB/w3mman2html.cgi?man=<command>[&section=<section>]
+ w3m file:///$LIB/w3mman2html.cgi?keyword=<keyword>
+
+インストール
+
+ make install
+ 必要なら PERL, MAN, W3M_LIBDIR を設定してください。
+ w3mman もインストールされます。
+
+================
+
+hlink.cgi
+
+ ヘッダファイルなどにリンクを張る
+
+インストール
+
+ /$LIB/ にコピー
+ w3mman2html.cgi で使用するならば $CGI2 に設定してください。
+
diff --git a/scripts/w3mman/hlink.cgi b/scripts/w3mman/hlink.cgi
new file mode 100644
index 0000000..a92ac1d
--- /dev/null
+++ b/scripts/w3mman/hlink.cgi
@@ -0,0 +1,97 @@
+#!/usr/local/bin/perl
+
+$SCRIPT_NAME = $ENV{'SCRIPT_NAME'} || $0;
+$CGI = "file://$SCRIPT_NAME?";
+
+if ($ENV{'QUERY_STRING'}) {
+ $file = $ENV{'QUERY_STRING'};
+} else {
+ $file = $ARGV[0];
+}
+$file = &cleanup($file);
+
+if (-d $file) {
+ print <<EOF;
+Location: file:$file
+EOF
+ exit;
+}
+if (! open(FILE, "< $file")) {
+ $file = &html_quote($file);
+ $_ = "$file: " . &html_quote($!);
+ print <<EOF;
+Content-Type: text/html
+
+<head><title>$file</title></head>
+<b>$_</b>
+EOF
+ exit 1;
+}
+
+$file = &html_quote($file);
+($dir = $file) =~ s@[^/]*$@@;
+
+print <<EOF;
+Content-Type: text/html
+
+<head><title>$file</title></head>
+<pre>
+EOF
+while (<FILE>) {
+ $_ = &html_quote($_);
+
+ s/^(\#\s*include\s+)(\&quot;.*\&quot;|\&lt\;.*\&gt\;)/$1 . &header_ref($2)/ge;
+
+ print;
+}
+close(FILE);
+print "</pre>\n";
+
+sub header_ref {
+ local($_) = @_;
+ local($d);
+
+ if (s/^\&quot;//) {
+ s/\&quot;$//;
+ return "&quot;<a href=\"$CGI$dir$_\">$_</a>&quot;";
+ }
+ s/^\&lt\;//;
+ s/\&gt\;$//;
+
+ for $d (
+ "/usr/include",
+ "/usr/local/include",
+ "/usr/X11R6/include",
+ "/usr/X11/include",
+ "/usr/X/include",
+ "/usr/include/X11"
+ ) {
+ -f "$d/$_" && return "&lt;<a href=\"$CGI$d/$_\">$_</a>&gt;";
+ }
+ return $_;
+}
+
+
+sub html_quote {
+ local($_) = @_;
+ local(%QUOTE) = (
+ '<', '&lt;',
+ '>', '&gt;',
+ '&', '&amp;',
+ '"', '&quot;',
+ );
+ s/[<>&"]/$QUOTE{$&}/g;
+ return $_;
+}
+
+sub cleanup {
+ local($_) = @_;
+
+ s@//+@/@g;
+ s@/\./@/@g;
+ while(m@/\.\./@) {
+ s@^/(\.\./)+@/@;
+ s@/[^/]+/\.\./@/@;
+ }
+ return $_;
+}
diff --git a/scripts/w3mman/w3mman b/scripts/w3mman/w3mman
new file mode 100644
index 0000000..44aba2f
--- /dev/null
+++ b/scripts/w3mman/w3mman
@@ -0,0 +1,41 @@
+#!/usr/local/bin/perl
+
+@W3M = split(' ', 'w3m');
+$ENV{'MAN'} = 'man';
+$SCRIPT = 'file:///$LIB/w3mman2html.cgi';
+
+sub usage {
+ ($_ = $0) =~ s@.*/@@;
+ print STDERR "$_ [-M <path>] [[<section>] <command>]\n";
+ print STDERR "$_ [-M <path>] [-k <keyword>]\n";
+ exit 1;
+}
+
+$query = "";
+while (@ARGV) {
+ $_ = shift @ARGV;
+ if (/^-M$/) {
+ @ARGV || &usage();
+ $ENV{'MANPATH'} = shift @ARGV;
+ } elsif (/^-k$/) {
+ @ARGV || &usage();
+ $query = "?keyword=" . &form_encode(shift @ARGV);
+ } elsif (/^-/) {
+ &usage();
+ } elsif (/^\d/ || $_ eq 'n') {
+ @ARGV || &usage();
+ $query = "?quit=ok&man=" . &form_encode(shift @ARGV);
+ $query .= "&section=" . &form_encode($_);
+ } else {
+ $query = "?quit=ok&man=" . &form_encode($_);
+ }
+}
+
+exec @W3M, "$SCRIPT$query";
+
+sub form_encode {
+ local($_) = @_;
+ s/[\000-\040\+:#?&%<>"\177-\377]/sprintf('%%%02X', unpack('C', $&))/eg;
+ return $_;
+}
+
diff --git a/scripts/w3mman/w3mman.in b/scripts/w3mman/w3mman.in
new file mode 100644
index 0000000..0c57135
--- /dev/null
+++ b/scripts/w3mman/w3mman.in
@@ -0,0 +1,41 @@
+#!@PERL@
+
+@W3M = split(' ', '@W3M@');
+$ENV{'MAN'} = '@MAN@';
+$SCRIPT = 'file:///$LIB/w3mman2html.cgi';
+
+sub usage {
+ ($_ = $0) =~ s@.*/@@;
+ print STDERR "$_ [-M <path>] [[<section>] <command>]\n";
+ print STDERR "$_ [-M <path>] [-k <keyword>]\n";
+ exit 1;
+}
+
+$query = "";
+while (@ARGV) {
+ $_ = shift @ARGV;
+ if (/^-M$/) {
+ @ARGV || &usage();
+ $ENV{'MANPATH'} = shift @ARGV;
+ } elsif (/^-k$/) {
+ @ARGV || &usage();
+ $query = "?keyword=" . &form_encode(shift @ARGV);
+ } elsif (/^-/) {
+ &usage();
+ } elsif (/^\d/ || $_ eq 'n') {
+ @ARGV || &usage();
+ $query = "?quit=ok&man=" . &form_encode(shift @ARGV);
+ $query .= "&section=" . &form_encode($_);
+ } else {
+ $query = "?quit=ok&man=" . &form_encode($_);
+ }
+}
+
+exec @W3M, "$SCRIPT$query";
+
+sub form_encode {
+ local($_) = @_;
+ s/[\000-\040\+:#?&%<>"\177-\377]/sprintf('%%%02X', unpack('C', $&))/eg;
+ return $_;
+}
+
diff --git a/scripts/w3mman/w3mman2html.cgi b/scripts/w3mman/w3mman2html.cgi
new file mode 100644
index 0000000..0f75502
--- /dev/null
+++ b/scripts/w3mman/w3mman2html.cgi
@@ -0,0 +1,252 @@
+#!/usr/local/bin/perl
+
+$MAN = $ENV{'MAN'} || 'man';
+$QUERY = $ENV{'QUERY_STRING'} || $ARGV[0];
+$SCRIPT_NAME = $ENV{'SCRIPT_NAME'} || $0;
+$CGI = "file://$SCRIPT_NAME";
+$CGI2 = "file:";
+# $CGI2 = "file:///\$LIB/hlink.cgi?";
+$SQUEEZE = 1;
+
+if ($QUERY =~ /\=/) {
+ for (split('&', $QUERY)) {
+ ($v, $q) = split('=', $_, 2);
+ $query{$v} = &form_decode($q);
+ }
+} else {
+ $QUERY =~ s/^man=//;
+ $query{"man"} = &form_decode($QUERY);
+}
+
+if (! $query{"man"}) {
+ if ($query{"keyword"}) {
+ $keyword = $query{"keyword"};
+ $k = &html_quote($keyword);
+ print <<EOF;
+Content-Type: text/html
+
+<html>
+<head><title>man -k $k</title></head>
+<body>
+<h2>man -k <b>$k</b></h2>
+<ul>
+EOF
+ $keyword =~ s:([^\w./]):\\$1:g;
+ open(F, "$MAN -k $keyword 2> /dev/null |");
+ @line = ();
+ while(<F>) {
+ chop;
+ $_ = &html_quote($_);
+ s/(\s+-.*)$//;
+ $title = $1;
+ s@(\w[\w.\-]*(\s*\,\s*\w[\w.\-]*)*)\s*(\([\dn]\w*\))@&keyword_ref($1, $3)@ge;
+ print "<li>$_$title\n";
+ }
+ close(F);
+ print <<EOF;
+</ul>
+</body>
+</html>
+EOF
+ exit;
+ }
+ print <<EOF;
+Content-Type: text/html
+
+<html>
+<head><title>man</title></head>
+<body>
+<form action="$CGI">
+<table>
+<tr><td>Manual:<td><input name=man>
+<tr><td>Section:<td><input name=section>
+<tr><td>Keyword:<td><input name=keyword>
+<tr><td><td><input type=submit> <input type=reset>
+</table>
+</form>
+</body>
+</html>
+EOF
+ exit;
+}
+
+$man = $query{"man"};
+if ($man =~ s/\((\w+)\)$//) {
+ $section = $1;
+ $man_section = "$man($1)";
+} elsif ($query{"section"}) {
+ $section = $query{"section"};
+ $man_section = "$man($section)";
+} else {
+ $section = "";
+ $man_section = "$man";
+}
+
+$section =~ s:([^\w./]):\\$1:g;
+$man =~ s:([^\w./]):\\$1:g;
+open(F, "$MAN $section $man 2> /dev/null |");
+$ok = 0;
+undef $header;
+$blank = -1;
+while(<F>) {
+ if (! defined($header)) {
+ /^\s*$/ && next;
+ $header = $_;
+ $space = $header;
+ chop $space;
+ $space =~ s/\S.*//;
+ } elsif ($_ eq $header) { # delete header
+ $blank = -1;
+ next;
+ } elsif (!/\010/ && /^$space[\w\200-\377].*\s\S/o) { # delete footer
+ $blank = -1;
+ next;
+ }
+ if ($SQUEEZE) {
+ if (/^\s*$/) {
+ $blank || $blank++;
+ next;
+ } elsif ($blank) {
+ $blank > 0 && print "\n";
+ $blank = 0;
+ }
+ }
+
+ s/\&/\&amp;/g;
+ s/\</\&lt;/g;
+ s/\>/\&gt;/g;
+
+ s@([\200-\377].)(\010{1,2}\1)+@<b>$1</b>@g;
+ s@(\&\w+;|.)(\010\1)+@<b>$1</b>@g;
+ s@__\010{1,2}((\<b\>)?[\200-\377].(\</b\>)?)@<u>$1</u>@g;
+ s@_\010((\<b\>)?(\&\w+\;|.)(\</b\>)?)@<u>$1</u>@g;
+ s@((\<b\>)?[\200-\377].(\</b\>)?)\010{1,2}__@<u>$1</u>@g;
+ s@((\<b\>)?(\&\w+\;|.)(\</b\>)?)\010_@<u>$1</u>@g;
+ s@.\010(.)@$1@g;
+
+ s@\</b\>\</u\>\<b\>_\</b\>\<u\>\<b\>@_@g;
+ s@\</u\>\<b\>_\</b\>\<u\>@_@g;
+ s@\</u\>\<u\>@@g;
+ s@\</b\>\<b\>@@g;
+
+ if (! $ok) {
+ /^No/ && last;
+ print <<EOF;
+Content-Type: text/html
+
+<html>
+<head><title>man $man_section</title></head>
+<body>
+<pre>
+EOF
+ print;
+ $ok = 1;
+ next;
+ }
+
+ s@(http|ftp)://[\w.\-/~]+[\w/]@<a href="$&">$&</a>@g;
+ s@(\W)(mailto:)?(\w[\w.\-]*\@\w[\w.\-]*\.[\w.\-]*\w)@$1<a href="mailto:$3">$2$3</a>@g;
+ s@(\W)(\~?/[\w.][/\w.\-]*)@$1 . &file_ref($2)@ge;
+ s@(include(<\/?[bu]\>|\s)*\&lt;)([/\w.\-]+)@$1 . &include_ref($3)@ge;
+ s@(\w[\w.\-]*)((\</[bu]\>)*)(\([\dm]\w*\))@<a href="$CGI?$1$4">$1</a>$2$4@g;
+ print;
+}
+close(F);
+if (! $ok) {
+ if ($query{'quit'}) {
+ print STDERR "No manual entry for $man_section.\n";
+ print <<EOF;
+w3m-control: EXIT
+EOF
+ exit 1;
+ }
+ print <<EOF;
+Content-Type: text/html
+
+<html>
+<head><title>man $man_section</title></head>
+<body>
+<pre>
+EOF
+ print "No manual entry for <B>$man_section</B>.\n";
+}
+print <<EOF;
+</pre>
+</body>
+</html>
+EOF
+
+sub is_command {
+ local($_) = @_;
+ local($p);
+
+ (! -d && -x) || return 0;
+ if (! defined(%PATH)) {
+ for $p (split(":", $ENV{'PATH'})) {
+ $p =~ s@/+$@@;
+ $PATH{$p} = 1;
+ }
+ }
+ s@/[^/]*$@@;
+ return defined($PATH{$_});
+}
+
+sub file_ref {
+ local($_) = @_;
+
+ if (&is_command($_)) {
+ ($man = $_) =~ s@.*/@@;
+ return "<a href=\"$CGI?$man\">$_</a>";
+ }
+ if (/^\~/ || -f || -d) {
+ return "<a href=\"$CGI2$_\">$_</a>";
+ }
+ return $_;
+}
+
+sub include_ref {
+ local($_) = @_;
+ local($d);
+
+ for $d (
+ "/usr/include",
+ "/usr/local/include",
+ "/usr/X11R6/include",
+ "/usr/X11/include",
+ "/usr/X/include",
+ "/usr/include/X11"
+ ) {
+ -f "$d/$_" && return "<a href=\"$CGI2$d/$_\">$_</a>";
+ }
+ return $_;
+}
+
+sub keyword_ref {
+ local($_, $s) = @_;
+ local(@a) = ();
+
+ for (split(/\s*,\s*/)) {
+ push(@a, "<a href=\"$CGI?$_$s\">$_</a>");
+ }
+ return join(", ", @a) . $s;
+}
+
+sub html_quote {
+ local($_) = @_;
+ local(%QUOTE) = (
+ '<', '&lt;',
+ '>', '&gt;',
+ '&', '&amp;',
+ '"', '&quot;',
+ );
+ s/[<>&"]/$QUOTE{$&}/g;
+ return $_;
+}
+
+sub form_decode {
+ local($_) = @_;
+ s/\+/ /g;
+ s/%([\da-f][\da-f])/pack('c', hex($1))/egi;
+ return $_;
+}
+
diff --git a/scripts/w3mman/w3mman2html.cgi.in b/scripts/w3mman/w3mman2html.cgi.in
new file mode 100644
index 0000000..68f318a
--- /dev/null
+++ b/scripts/w3mman/w3mman2html.cgi.in
@@ -0,0 +1,252 @@
+#!@PERL@
+
+$MAN = $ENV{'MAN'} || '@MAN@';
+$QUERY = $ENV{'QUERY_STRING'} || $ARGV[0];
+$SCRIPT_NAME = $ENV{'SCRIPT_NAME'} || $0;
+$CGI = "file://$SCRIPT_NAME";
+$CGI2 = "file:";
+# $CGI2 = "file:///\$LIB/hlink.cgi?";
+$SQUEEZE = 1;
+
+if ($QUERY =~ /\=/) {
+ for (split('&', $QUERY)) {
+ ($v, $q) = split('=', $_, 2);
+ $query{$v} = &form_decode($q);
+ }
+} else {
+ $QUERY =~ s/^man=//;
+ $query{"man"} = &form_decode($QUERY);
+}
+
+if (! $query{"man"}) {
+ if ($query{"keyword"}) {
+ $keyword = $query{"keyword"};
+ $k = &html_quote($keyword);
+ print <<EOF;
+Content-Type: text/html
+
+<html>
+<head><title>man -k $k</title></head>
+<body>
+<h2>man -k <b>$k</b></h2>
+<ul>
+EOF
+ $keyword =~ s:([^\w./]):\\$1:g;
+ open(F, "$MAN -k $keyword 2> /dev/null |");
+ @line = ();
+ while(<F>) {
+ chop;
+ $_ = &html_quote($_);
+ s/(\s+-.*)$//;
+ $title = $1;
+ s@(\w[\w.\-]*(\s*\,\s*\w[\w.\-]*)*)\s*(\([\dn]\w*\))@&keyword_ref($1, $3)@ge;
+ print "<li>$_$title\n";
+ }
+ close(F);
+ print <<EOF;
+</ul>
+</body>
+</html>
+EOF
+ exit;
+ }
+ print <<EOF;
+Content-Type: text/html
+
+<html>
+<head><title>man</title></head>
+<body>
+<form action="$CGI">
+<table>
+<tr><td>Manual:<td><input name=man>
+<tr><td>Section:<td><input name=section>
+<tr><td>Keyword:<td><input name=keyword>
+<tr><td><td><input type=submit> <input type=reset>
+</table>
+</form>
+</body>
+</html>
+EOF
+ exit;
+}
+
+$man = $query{"man"};
+if ($man =~ s/\((\w+)\)$//) {
+ $section = $1;
+ $man_section = "$man($1)";
+} elsif ($query{"section"}) {
+ $section = $query{"section"};
+ $man_section = "$man($section)";
+} else {
+ $section = "";
+ $man_section = "$man";
+}
+
+$section =~ s:([^\w./]):\\$1:g;
+$man =~ s:([^\w./]):\\$1:g;
+open(F, "$MAN $section $man 2> /dev/null |");
+$ok = 0;
+undef $header;
+$blank = -1;
+while(<F>) {
+ if (! defined($header)) {
+ /^\s*$/ && next;
+ $header = $_;
+ $space = $header;
+ chop $space;
+ $space =~ s/\S.*//;
+ } elsif ($_ eq $header) { # delete header
+ $blank = -1;
+ next;
+ } elsif (!/\010/ && /^$space[\w\200-\377].*\s\S/o) { # delete footer
+ $blank = -1;
+ next;
+ }
+ if ($SQUEEZE) {
+ if (/^\s*$/) {
+ $blank || $blank++;
+ next;
+ } elsif ($blank) {
+ $blank > 0 && print "\n";
+ $blank = 0;
+ }
+ }
+
+ s/\&/\&amp;/g;
+ s/\</\&lt;/g;
+ s/\>/\&gt;/g;
+
+ s@([\200-\377].)(\010{1,2}\1)+@<b>$1</b>@g;
+ s@(\&\w+;|.)(\010\1)+@<b>$1</b>@g;
+ s@__\010{1,2}((\<b\>)?[\200-\377].(\</b\>)?)@<u>$1</u>@g;
+ s@_\010((\<b\>)?(\&\w+\;|.)(\</b\>)?)@<u>$1</u>@g;
+ s@((\<b\>)?[\200-\377].(\</b\>)?)\010{1,2}__@<u>$1</u>@g;
+ s@((\<b\>)?(\&\w+\;|.)(\</b\>)?)\010_@<u>$1</u>@g;
+ s@.\010(.)@$1@g;
+
+ s@\</b\>\</u\>\<b\>_\</b\>\<u\>\<b\>@_@g;
+ s@\</u\>\<b\>_\</b\>\<u\>@_@g;
+ s@\</u\>\<u\>@@g;
+ s@\</b\>\<b\>@@g;
+
+ if (! $ok) {
+ /^No/ && last;
+ print <<EOF;
+Content-Type: text/html
+
+<html>
+<head><title>man $man_section</title></head>
+<body>
+<pre>
+EOF
+ print;
+ $ok = 1;
+ next;
+ }
+
+ s@(http|ftp)://[\w.\-/~]+[\w/]@<a href="$&">$&</a>@g;
+ s@(\W)(mailto:)?(\w[\w.\-]*\@\w[\w.\-]*\.[\w.\-]*\w)@$1<a href="mailto:$3">$2$3</a>@g;
+ s@(\W)(\~?/[\w.][/\w.\-]*)@$1 . &file_ref($2)@ge;
+ s@(include(<\/?[bu]\>|\s)*\&lt;)([/\w.\-]+)@$1 . &include_ref($3)@ge;
+ s@(\w[\w.\-]*)((\</[bu]\>)*)(\([\dm]\w*\))@<a href="$CGI?$1$4">$1</a>$2$4@g;
+ print;
+}
+close(F);
+if (! $ok) {
+ if ($query{'quit'}) {
+ print STDERR "No manual entry for $man_section.\n";
+ print <<EOF;
+w3m-control: EXIT
+EOF
+ exit 1;
+ }
+ print <<EOF;
+Content-Type: text/html
+
+<html>
+<head><title>man $man_section</title></head>
+<body>
+<pre>
+EOF
+ print "No manual entry for <B>$man_section</B>.\n";
+}
+print <<EOF;
+</pre>
+</body>
+</html>
+EOF
+
+sub is_command {
+ local($_) = @_;
+ local($p);
+
+ (! -d && -x) || return 0;
+ if (! defined(%PATH)) {
+ for $p (split(":", $ENV{'PATH'})) {
+ $p =~ s@/+$@@;
+ $PATH{$p} = 1;
+ }
+ }
+ s@/[^/]*$@@;
+ return defined($PATH{$_});
+}
+
+sub file_ref {
+ local($_) = @_;
+
+ if (&is_command($_)) {
+ ($man = $_) =~ s@.*/@@;
+ return "<a href=\"$CGI?$man\">$_</a>";
+ }
+ if (/^\~/ || -f || -d) {
+ return "<a href=\"$CGI2$_\">$_</a>";
+ }
+ return $_;
+}
+
+sub include_ref {
+ local($_) = @_;
+ local($d);
+
+ for $d (
+ "/usr/include",
+ "/usr/local/include",
+ "/usr/X11R6/include",
+ "/usr/X11/include",
+ "/usr/X/include",
+ "/usr/include/X11"
+ ) {
+ -f "$d/$_" && return "<a href=\"$CGI2$d/$_\">$_</a>";
+ }
+ return $_;
+}
+
+sub keyword_ref {
+ local($_, $s) = @_;
+ local(@a) = ();
+
+ for (split(/\s*,\s*/)) {
+ push(@a, "<a href=\"$CGI?$_$s\">$_</a>");
+ }
+ return join(", ", @a) . $s;
+}
+
+sub html_quote {
+ local($_) = @_;
+ local(%QUOTE) = (
+ '<', '&lt;',
+ '>', '&gt;',
+ '&', '&amp;',
+ '"', '&quot;',
+ );
+ s/[<>&"]/$QUOTE{$&}/g;
+ return $_;
+}
+
+sub form_decode {
+ local($_) = @_;
+ s/\+/ /g;
+ s/%([\da-f][\da-f])/pack('c', hex($1))/egi;
+ return $_;
+}
+