#!/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 if [ -z "$n" -o -n "$s" ]; then printf '%s\n' "$s" >> rc/README.md~ || return 5 fi 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 "$@"