bashdoc - extract and format documentation embedded in bash scripts
bashdoc [-h|-v] format SCRIPT
bashdoc extracts documentation from a bash script and formats it nicely. The documentation in SCRIPT must be written in markdown. It will be formatted for output using pandoc.
For bashdoc to be able to format a script's documentation, a simple but rigid convention must be followed. Namely, documentation must be contained in a 'here document' that begins with either:
and ends with:
In all cases, the text must be exactly as shown and it must start in column 1. If multiple such here documents are encountered in a script, they are concatenated into a single documentation string before processing.
Contents of the documentation string must be created with pandoc's flavor of markdown with the extension for definition lists enabled.
The first argument to bashdoc is the output format, which must be one of the following:
Extract the raw documentation from SCRIPT and convert it to a man page, per gettroff, and view the resulting with man(1). Note that most user environments are typically setup so that man(1) displays the documentation with a pager, such as less.
Extract the raw documentation from SCRIPT and process it with pandoc and man(1) to create a postscript version of the man page generated by man. When used in this manner, man(1) adds headers, footers, and page numbers; the result is well suited for printing.
Extract the raw documentation from SCRIPT and process it with pandoc, converting it to troff code with man macros. The troff code is then written to stdout. The output is suitable for use with the man(1) command.
Extract the raw documentation from SCRIPT and process it with pandoc to create a pdf document formatted for printing. The pdf document is written to stdout. This differs from the output of manps in that it is formatted with a common LaTeX document style.
Extract the raw documentation from SCRIPT and process it with pandoc, converting it to troff code with man macros. The troff code is then run through groff. This nicely formatted output is written to stdout. The output should resemble that of the previously described man format, the difference being that a pager is not used. This output is suitable for a, possibly verbose, usage text for a script. The '-h' option to bashdoc uses this for its output.
Extract the raw markdown documentation from SCRIPT and write it in its raw unprocessed form to stdout.
Extract the raw documentation from SCRIPT, process it with pandoc, then write a version of the documentation in a 'safe' flavor of markdown to stdout. Why would this be useful? Many online code repositories, e.g. Bitbucket, can automatically format and display files containing markdown. However, the markdown they support is rudimentary at best, meaning that a document containing pandoc markdown may not be rendered properly. This option attempts to transform the docstring into a 'safe' flavor of markdown that it can be successfully rendered. Some useful formatting may be lost in the process, but this is better than viewing impenetrable blocks of gibberish on such sites.
The second argument, SCRIPT is a path to the bash script from which the documentation will be extracted.
Write help information to stdout. This actually invokes bashdoc on itself, requesting tty format output.
Write the version string to stdout. Semantic versioning is used.
The first three lines of the documentation string may contain meta information to be used by pandoc when creating output. Those lines are in the format:
% BASHDOC(1) % Kenneth East <http://east.fm> % December 13, 2015
Their purpose is self-evident. It is guaranteed not to render properly with anything other than pandoc. See the pandoc documentation on meta-information for details.
Bash parameter expansion
In here documents that begin with
any shell variables within the here document are left as-is, i.e., they are not expanded.
To enable parameter substitution for shell variables, begin the docstring with
Note the absence of single quotes around
DOC. In this case, bash
parameter substitution is performed on the body of the here doc.
In the latter case, note that if the docstring contains
`foo`, it will be expanded by the shell, which will replace it
with the output of the
foo command. See the bash(1) man page for more
To see an example of what a documentation string looks like, simply run the command:
$ bashdoc md `type -p bashdoc`
The above command will extract the documentation string from the file which implements the bashdoc command (i.e., the file containing the documentation string which generated this document) and write it to stdout.
To convert the same documentation string to a man page and then view it with man(8):
$ bashdoc man `type -p bashdoc`
To create a printable pdf version of the documentation for the bash
~/bin/foo and then view it in OS-X preview:
$ bashdoc pdf ~/bin/foo $ open foo.pdf
As a Documentation Provider Within Other Scripts
bashdoc can also be used as a documentation provider within other scripts. For example, if the script 'foo' is documented in the manner just described, bashdoc can be called within 'foo' to produce 'foo's documentation. E.g.:
# Code snippet from within the 'foo' script. # OPT is a command line option to 'foo' case "$OPT" in -h|--help) # formatted documentation for 'foo' on stdout bashdoc tty "$0" ;; --man) # display formatted documentation for 'foo' with man(1) bashdoc man "$0" ;; --md) # raw documentation string for 'foo' on stdout bashdoc md "$0" ;; esac
If you have a script with documentation formatted for use with bashdoc but you do not wish to use bashdoc, you can get the raw documentation on stdout with a one-liner:
$ S=.../path/to/script/to/get/doc/from/foo.sh $ sed '/^:/,/^DOC/!d;s/^:/cat/' "$S" | sh -s
This one line is actually the key to the entire bashdoc scheme.
mikeserv for the excellent idea.
bashdoc exits with a status of 0 when successful and non-zero otherwise.
Put the file bashdoc somewhere in your path and make it executable.
pandoc must be present on your system. groff is required for man, gettroff, and tty. LaTeX is required for pdf.
No line in the docstring can begin with
DOC in the first column, as
this will terminate the here document prematurely. If you wish to embed
DOC in your docstring, one workaround is to precede the embedded
DOC with a space in column 1. For an example of this workaround,
inspect the docstring used to create this document.
It can be difficult to create markdown that renders satisfactorily in both pdf and in man formats.
More specifically, markdown code intended to render verbatim text / code
`x = 33`) is rendered correctly by pandoc in pdf,
as unadorned plain text in pandoc man pages, and surrounded by a shaded
box on Bitbucket. This is most unsatisfying. Trying to get satisfactory
rendering in pandoc's pdf, pandoc's man page, and Bitbucket's/Github's
markdown from a single document can be extremely frustrating, if not
impossible. If something isn't clear in a man rendering, it will
likely be clarified with a pdf rendering, which should be more
Single quotes within the documentation string can confuse syntax highlighing in editors and code formatters.
Argument error handling is de-minimis.
N.B. This documentation was created with bashdoc.
The idea for this approach to embedding documentation in a shell script
was taken from
mikeserv's answer in:
This has only been tested on OS-X 10.11.2.
It is a simple matter to add additional pandoc markdown features by extending the value of the '-f' option in this script's implementation. It would be nice to allow additional extensions to be enabled from within the script being documented.
Should test for the presence of pandoc, groff, and LaTeX and act accordingly.
Would be nice to allow for two classes of documentation strings: summary
and detailed. This would allow a brief
usage type output for
along with a full version which would produce complete documentation.
docopt uses semantic versioning.
This documentation is amusingly lengthy given the brevity of the associated code.
pandoc, bash(1), groff(1), man(1)
'socco.sh' is a more advanced documentation tool that prints comments and code side-by-side, literate programming style. See http://rtomayko.github.io/shocco/.
Source code for bashdoc is available at https://bitbucket.org/MaDeuce/bashdoc.
 This is bashdoc v2.0.0.