Skip to content

Executable Markdown (MD)

ExecMD is a tool (not a Dr.) which executes commands from Markdown code blocks. Inspired by Literate Programming, this is useful e.g. to create documentation which automatically updates itself to stay in line with current code of tools being documented - such as later on this page! 😃

Usage

A code block such as this one in demo.md:

    ```bash
    $ echo Hi
    WHATEVER IS WRITTEN HERE IS IGNORED
    ```

when ran through ./enola execmd docs/use/execmd/demo.md produces:

$ echo Hi
Hi

MD Format

  • Only ``` fenced code blocks are processed. (Any ~~~ or inline ` are ignored.)
  • Only bash language format code blocks are executed. (Other languages are ignored.)
  • The code block must start with $ which must be followed by the command to run
  • As long as lines end with \ they are appended to the command to run
  • All lines after are ignored (and replaced, with CLI option --inline)
  • The Markdown file may contain several such code blocks

Some flags can be specified in the preamble after ```bash:

  • ```bash $? = command is expected to have non-zero exit code
  • ```bash INIT = runs INIT before the command after the $ (but “hidden” from MD)

The tool does the following:

  • The line is not directly exec, but passed as-is to bash -c
  • The working directory is set to the processed Markdown file’s directory (use e.g. ```bash cd .. to change it)
  • Command must exit with 0, otherwise the tool aborts and returns that code (unless ```bash $?)
  • Command is killed (times out) after 7s if it “hangs” (useful on CI)
  • STDOUT & STDERR are both captured, and interspersed in MD
  • STDIN is closed (but you can use < ...)
  • TODO TERM … ? 🤔

Script Extraction

The commands in the MD are also extracted and written into a file named script next to the MD. This can be used e.g. to automagically record screencast videos, such as those on other pages of this documentation.

CLI Options

$ ./enola execmd --help
Missing required parameter: '<files>'
Usage: enola execmd [-iv] <files>...
Execute Commands in Markdown
      <files>...   URI/s (incl. Globs) of Markdown (MD) files to process
  -i, --in-place   Edit MD files in place
  -v, --verbose    Error verbosity; specify multiple -v options to increase it;
                     e.g. -v -v -v or -vvv.

Noteworthy

  • Using & inside the code block, e.g. to start a server in the background for a demo, is a PITA. Instead, put such a demo with the & into a script, and call that script in the code block.
  • Beware of the Fork Bomb 😈 which would happen if a Markdown file were to to include an execmd command on itself!

Inspiration