commit 888886a7bf0f0a20e6a3f4370067ab9f850c78c3 from: noodle date: Wed Dec 31 19:07:16 2025 UTC initial commit commit - /dev/null commit + 888886a7bf0f0a20e6a3f4370067ab9f850c78c3 blob - /dev/null blob + e4030f6b9cd85e95ac2b48a57e7b98cd473f6607 (mode 644) --- /dev/null +++ Makefile @@ -0,0 +1,9 @@ +PREFIX = ${HOME} + +install: + install -d ${DISTDIR}${PREFIX}/bin + install readman ${DISTDIR}${PREFIX}/bin/readman + +uninstall: + rm -f ${DESTDIR}${PREFIX}/bin/readman + blob - /dev/null blob + 7b3b57c95c53ea39a3b23ceeda4e019337c9ecf1 (mode 755) --- /dev/null +++ readman @@ -0,0 +1,148 @@ +#!/bin/sh +aflag=false +dflag=false +progname=${0##*/} +men=$HOME/.manread + +cleanup() { + [ -w "$mymen" ] && rm -f "$mymen" + [ -w "$allmen" ] && rm -f "$sysmen" +} + +usage() { + echo "usage: ${progname} [-d]" 1>&2 + echo " ${progname} [-d] section" 1>&2 + echo " ${progname} [-a|-d] section mantitle" 1>&2 + return 1 +} + +err() { + echo "$1" 1>&2 + return 1 +} + +prompt() { + res='' + until [ "$res" = no ] || [ "$res" = yes ]; do + printf '%s (yes,no)[no]: ' "$1" + read -r res + [ -z "$res" ] && res=no + done + [ "$res" = yes ] + return $? +} + +issec() { + [ "$1" -ge 1 ] && [ "$1" -le 9 ]; + return $? +} + +diffhash() { + nread=$(awk "/^${1}/"'{ print $3 }' "$men" | + sort | tee "$mymen" | wc -l | tr -d ' ') + nall=$(man -ws "$1" -k . | xargs cksum | awk '{ print $1 }' | + sort | tee "$allmen" | wc -l | tr -d ' ') + changed=$(comm -23 "$mymen" "$allmen") +} + +secstats() { + nchanged=0 + diffhash "$1" + printf '* man %s: %s/%s' "$1" $nread $nall + if [ -n "$changed" ]; then + nchanged="$(echo "$changed" | tr ' ' '\n' | wc -l)" + printf '\t(%s changed)' $nchanged + fi + echo +} + +diffmen() { + diffhash "$1" + man -ws "$1" -k . | xargs cksum | \ + awk -F/ "/^$(echo "$changed" | tr ' ' '|')$/"'{ split($NF, a, /\.[1-9]/); print a[1] }' +} + +trap cleanup EXIT +trap exit HUP INT TERM + +while getopts ad arg; do + case ${arg} in + a) aflag=true;; + d) dflag=true;; + ?) usage;; + esac +done +shift $((OPTIND - 1)) +$aflag && $dflag && usage + +[ -f $men ] || touch $men +[ -r $men ] || err "unable to read ${men}!" +mymen=$(echo 'mkstemp(/tmp/readman.XXXXXXXXXX)' | m4) +allmen=$(echo 'mkstemp(/tmp/readman.XXXXXXXXXX)' | m4) +case $# in +0) + if $aflag; then + usage + elif $dflag; then + prompt 'Do you really want to delete all your stats?' && :>"$men" + else + for sec in $(seq 1 9); do + secstats "$sec" + done + fi + ;; +1) + sec=$1 + + if $aflag || ! issec "$sec" + then + usage + elif $dflag && prompt "Do you really want to delete all stats for section ${sec}?" + then + printf 'g/%s/d\nwq\n' "$sec" | ed - "$men" + else + secstats "$sec" + [ "$nchanged" -gt 0 ] && echo "* to reread:" $(diffmen "$sec") + awk "/^${1}/"'{print $2 }' "$men" >"$mymen" + man -ws "$1" -k . | awk -F/ '{ split($NF, a, /\.[1-9]/); print a[1] }' >"$allmen" + if [ "$nread" -gt 0 ]; then + echo "* have read:" $(comm -12 "$mymen" "$allmen") + fi + echo "* to read:" $(comm -13 "$mymen" "$allmen") + fi + ;; +2) + sec=$1 + page=$2 + mantitle="$page($sec)" + + if ! issec "$sec"; then + usage + elif ! manpath=$(man -w "$sec" "$page" 2>/dev/null); then + err "man page ${mantitle} doesn't exist!" + elif $aflag; then + if grep "^${sec} ${page}" "$men" >/dev/null; then + echo "you've already read ${mantitle}" + exit 0 + else + cksum "$manpath" | awk '{ print $1 }' | + xargs printf '%s\t%s\t%s' "$sec" "$page" >>"$men" + sort -o "$men" "$men" + fi + elif $dflag; then + if ! grep "^${sec} ${page}" "$men" >/dev/null; then + echo "you haven't read ${mantitle}" + exit 0 + elif prompt "Do you really want to unread ${mantitle}?"; then + printf 'g/%s\t%s/d\nw\nq\n' "$sec" "$page" | ed - "$men" + fi + else + if grep "^${sec} ${page}" "$men" >/dev/null; then + echo "you've read ${mantitle}" + else + echo "you've not read ${mantitle}" + fi + fi + ;; +?) usage ;; +esac