1
0
src/bin/man
2022-05-14 20:52:57 -04:00

88 lines
2.2 KiB
Bash
Executable File

#!/bin/sh
argv0="$0"
die() { printf "$*" >/dev/stderr && exit 1; }
# A lot of these break convention when recording errors because this tries to
# imitate other implementations.
[ -n "$1" ] || die "What manual page do you want?\nFor example, try 'man man'.\n"
[ -n "$LANG" ] || LANG="C"
[ -n "$MANPATH" ] || MANPATH="/usr/share/man"
[ -d "$MANPATH" ] || die "$0: \$MANPATH: $MANPATH: Does not exist\n"
[ -n "$MANSECTIONS" ] \
&& default_mansections="$MANSECTIONS" \
|| default_mansections="1nl830254967"
[ -d "$MANPATH"/"$LANG" ] \
&& MANDIR="$MANPATH/$LANG" \
|| MANDIR="$MANPATH"
if [ -z "$PAGER" ]; then
for prog in $(printf "
less
more
cat
dd
"); do
if which "$prog" >/dev/null 2>&1; then
PAGER="$prog"
break
fi
done
fi
man() {
eq $# 2 || die "$argv0: man() called with $# arguments. Expected 2. This is a programmer error\n"
MANSECTIONS="$1"
NAME="$2"
# the way manpages are laid out SUCKS
# so, yeah, each man section is one character. which means it's totally
# bueno to just iterate over the string like this. but $MANDIR/man1 can
# have both man.1.gz AND man.1p.gz. ARGH!!!!
for SECTION in $(printf "$MANSECTIONS" | sed 's/\(.\)/\1\n/g'); do
PAGE="$(find "$MANDIR/man$SECTION" -type f 2>/dev/null | grep "\/$NAME\.\|\/$NAME$" | sed q)"
[ -z "$PAGE" ] || break
done
! [ -n "$PAGE" ] \
&& printf "No manual entry for $NAME\n" \
&& return 1
case "$(file -bir --no-buffer "$PAGE")" in
("text/"*)
COMMAND="cat" ;;
("application/gzip"*)
COMMAND="zcat" ;;
(*)
die "$argv0: $PAGE: Unknown file type.\n" ;;
esac
$COMMAND "$PAGE" | nroff -man | $PAGER
}
# this seems to be what the popular man does
# so like `man foo -k bar` will show the manpages for foo, -k, and bar
# expected behavior imo would be manpage for foo, then gist for bar
# but let's not break things
if streq "$1" "-k"; then # -k
printf "Not yet implemented\n" && exit 1
else # not -k
while gt $# 0; do
if eq $(fdivide $# 2) 0 && gt 1 $# || ! stris int "$1"; then
MANSECTIONS="$default_mansections"
NAME="$1"
SHIFTING=1
elif gt 1 $(fdivide $# 2); then
MANSECTIONS="$1"
NAME="$2"
SHIFTING=2
else exit 0 # no more args
fi
man "$MANSECTIONS" "$NAME"
shift $SHIFTING
done
fi