scripts/dddoc/dddoc.sh

170 lines
4.6 KiB
Bash
Executable File

#!/bin/sh
#
## _This documentation file was extracted from `dddoc.sh` using the following
## command:_
##
## ./dddoc.sh -d . dddoc.sh && mv dddoc.sh.md README.md
##
## dddoc -- Double-Dièse Documentation extractor
## =============================================
##
## This script is designed to extract inline documentation from shell scripts
## or libraries, or any other language using the sharp (#) as a comment mark.
## It follows the tradition of POD (Plain Old Documentation), but permits an
## easier-to-read syntax, allowing you to use the markup language that suits
## you (such as MarkDown, txt2tags, etc.).
##
## The only pre-requisite is that the comment lines to be extracted start with
## two sharps (##), hence the name of this script ("dièse" stands for "sharp"
## in French). The two sharps must be followed by at least one space or an end
## of line for the line to be extracted; for instance, lines starting with
## three sharps won't be extracted. Both sharps starting the line, and exactly
## one space (if any) will be stripped.
##
## Each output file bares the name of the corresponding input file, with a
## user-defined suffix (`-s` switch), that defaults to "md".
##
## The input file hierarchy is respected, and this script is best used along
## with `find` and `xargs`, for instance:
##
## cd /project/path
## find * -type f -print0 | xargs -0 dddoc /path/to/destdir
##
## The destination directory could be a clone of a GitLab wiki (or Gitea, or
## GitHub...), which will allow you to easily publish a nice-looking set of
## docs.
##
## License
## =======
##
## Copyright 2018 Matteo Cypriani <mcy@lm7.fr>
##
## This program is free software. It comes without any warranty, to the extent
## permitted by applicable law. You can redistribute it and/or modify it under
## the terms of the Do What The Fuck You Want To Public License, Version 2, as
## published by Sam Hocevar. See http://sam.zoy.org/wtfpl/COPYING for more
## details.
set -e
#set -x
##
## Globals
## =======
##
## This section and the followings document `dddoc.sh`; they are not
## particularly interesting, but are meant as a demonstration and documenting
## guide.
##
## - `PROGNAME`: this script's name
PROGNAME="$(basename "$0")"
## - `DESTDIR`: output directory
DESTDIR=
## - `VERBOSE`: verbose level
VERBOSE=1
## - `SUFFIX`: suffix (extension) of output files
SUFFIX=".md"
## - `REGEX`: the regular expression that determines which lines will be
## extracted from input files
REGEX='^##( |$)'
##
## Functions
## =========
##
## print_usage()
## -------------
## Prints the usage message.
##
print_usage()
{
cat <<EOF
Usage:
$PROGNAME [-h]
$PROGNAME -d <output_dir> [-s <suffix>] [-v] <file1> [file2 ...]
Options:
-h: display this help and exit
-d: output files' destination directory
-s: output files' suffix (default: "$SUFFIX")
-q: set verbose level to 0
-v: increment verbose level; this option can be provided several times
Verbose levels (default is $VERBOSE):
0 = silent
1 = display global options
2 = print a message for each generated files
3 = print a message for skipped files as well
EOF
}
## bad_usage()
## -----------
## Prints the usage message to the standard error and exits with an error code.
##
bad_usage()
{
print_usage >&2
exit 127
}
###
### Main program
### ============
### (Note that these triple-dashed comments won't be extracted by this script.)
###
# Parse CLI options
while getopts d:hqs:v option ; do
case $option in
h) print_usage
exit 0
;;
d) DESTDIR="$OPTARG" ;;
q) VERBOSE=0 ;;
s) SUFFIX=".$OPTARG" ;;
v) VERBOSE=$((VERBOSE + 1)) ;;
*) bad_usage
esac
done
shift $((OPTIND - 1))
# Check CLI options
if [ -z "$DESTDIR" ] || [ $# -lt 1 ] ; then
bad_usage
fi
if [ $VERBOSE -ge 1 ] ; then
printf 'Verbose level: %d\n' "$VERBOSE"
printf 'Will use "%s" as the destination directory.\n' "$DESTDIR"
printf 'Will use "%s" as a suffix for output files.\n' "$SUFFIX"
fi
while [ -n "$1" ] ; do
src="$1"
shift
srcdir="$(dirname "$src")"
destdir="$DESTDIR/$srcdir"
dest="$destdir/$(basename "$src")$SUFFIX"
if ! grep -Eq "$REGEX" "$src" ; then
[ $VERBOSE -ge 3 ] && printf \
"\"%s\" doesn't seem to contain any double-sharp comments. Skipping.\\n" \
"$src"
continue
fi
[ $VERBOSE -ge 2 ] && \
printf 'Extracting doc from "%s" to "%s"...\n' "$src" "$dest"
mkdir -p "$destdir"
sed -rn "s/$REGEX//p" "$src" >"$dest"
done
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4