From 691b8251dff369aec25c3d13d98e1d2c862d113b Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Fri, 30 Jul 2021 16:35:00 -0700 Subject: [PATCH] add documentation tool (no docstrings yet) --- README.md | 8 +-- sh/document | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 sh/document diff --git a/README.md b/README.md index 2be02cf..bbecb77 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,6 @@ quick install for random boxes: cd && curl -L https://github.com/notwa/rc/archive/master.tar.gz | tar zx && mv rc-master rc && rc/install ``` -## stuff defined in RC files +**NOTE:** everything below this line is overwritten and regenerated by `sh/document`. -hold on, this needs to be rewritten. - -## shell scripts - -hold on, this needs to be rewritten. + diff --git a/sh/document b/sh/document new file mode 100644 index 0000000..fe0030e --- /dev/null +++ b/sh/document @@ -0,0 +1,139 @@ +#!/usr/bin/env dash +# NO_ZSH +# NO_BASH +# YES_DASH +# okay, so this probably does run with zsh and bash, but why bother? + +# NOTE: a lot of boilerplate code is pulled from the pure sh bible: +# https://github.com/dylanaraps/pure-sh-bible + +document2() { + local f="$1" + local c=0 + local e="${f#sh/}" + [ "$f" != "$e" ] || e="" + [ "$e" != document ] || return 0 + while IFS= read -r line; do + : $((c+=1)) + case "$line" in *'###'*) :;; *) continue;; esac + + local code="${line%%###*}" docs="${line#*###}" + code="${code#${code%%[![:space:]]*}}" # ltrim + docs="${docs#${docs%%[![:space:]]*}}" # ltrim + + local s=' ' n='' + + case "$docs" in + @-*) + s="$code" + n="${s%%[!a-zA-Z0-9_-]*}" + while [ -z "$n" -o "$n" = function -o "$n" = alias ]; do + [ -n "$s" ] || break + s="${s#${s%%[!a-zA-Z0-9_-]*}}" + s="${s#*[!a-zA-Z0-9_-]}" + n="${s%%[!a-zA-Z0-9_-]*}" + done + s="${docs#@-}" + s="${s#${s%%[![:space:]]*}}" # ltrim + ;; + + @*-*) + n="${docs%%-*}" + s="${docs#*-}" + + n="${n#@}" + n="${n#${n%%[![:space:]]*}}" # ltrim + n="${n%${n##*[![:space:]]}}" # rtrim + + s="${s#${s%%[![:space:]]*}}" # ltrim + ;; + + @*) + n="${docs#@}" + n="${n#${n%%[![:space:]]*}}" # ltrim + ;; + + *) + s="${docs#${docs%%[![:space:]]*}}" # ltrim + ;; + esac + + if [ -n "$n" ]; then + local url + [ "$url" != "${url#sh/}" ] && url="/sh/$f#L$c" || url="/home/${f#.}#L$c" + if [ "$n" = "$e" ]; then + printf '\n### [%s](%s)\n\n' "$n" "$url" >> rc/README.md~ || return 5 + else + printf '\n### [%s](%s)\n\n' "$n.${f#.}" "$url" >> rc/README.md~ || return 5 + #printf '\n### %s\n\n* defined in [%s](%s)\n\n' "$n" "$f" "$url" >> rc/README.md~ || return 5 + fi + fi + + if [ "$s" != ' ' ]; then + printf '%s\n' "$s" >> rc/README.md~ || return 5 + fi + done < "$f" || return 4 +} + +document1() { + # NOTE: in the future, it'd be nice to support arbitary files through arguments. + [ $# -le 0 ] || return 1 + + cd || return 2 + [ -d rc ] && [ -d sh ] && [ -f .zshrc ] && [ -f .-shrc ] && [ -f .bashrc ] || return 3 + + : > rc/README.md~ || return 4 + + local line + + if [ -f rc/README.md ]; then + while IFS= read -r line; do + printf '%s\n' "$line" >> rc/README.md~ || return 5 + case "$line" in *DOCUMENT*) break;; esac + done < rc/README.md || return 4 + fi + + printf '\n## %s\n' 'shell functions' >> rc/README.md~ || return 5 + for f in sh/*; do + [ -e "$f" ] || continue + document2 "$f" || return $? + done + + printf '\n## %s\n' 'miscellaneous' >> rc/README.md~ || return 5 + document2 .zshrc || return $? + document2 .bashrc || return $? + document2 .-shrc || return $? +} + +document() { ### @ document + ### generate a markdown file out of docstrings in shell scripts. + ### **TODO:** describe. i have a rough outline written in my scrap file. + + document1 "$@" + local ret=$? + + case $ret in + 0) + return 0;; + 1) + printf '%s\n' "$0: too many arguments" >&2 + return 1;; + 2) + printf '%s\n' "$0: failed to change directory" >&2 + return 1;; + 3) + printf '%s\n' "$0: essential files are missing" >&2 + return 1;; + 4) + printf '%s\n' "$0: failed to open file" >&2 + return 1;; + 5) + printf '%s\n' "$0: failed to read line" >&2 + return 1;; + *) + printf '%s\n' "$0: unknown error occurred" >&2 + return 1;; + esac +} + +[ "${SOURCING:-0}" -gt 0 ] || document "$@"