Sometimes, a document might require some custom build logic. For example, a report might contain a table of data extracted from a Crux database. Naturally we use GNU Make and bash to knit together these customised builds, but whenever you try to do something complex, you can end up thrashing around in the long grass.

For example, we have a document named ETH001.adoc which includes an image stored as ETH001/boy-and-computer.jpg . The PDF version of the document can be generated using a Make rule:

target/pdf/%.pdf: %.adoc brand/juxt-theme.yml asciidoctor-pdf -r asciidoctor-diagram -o $@ $<

This means that a change to the original Asciidoc source file, or a change to the theme we use to build the PDFs, will result in the asciidoctor-pdf executable being run and the resulting PDF rebuilt.

However, since the PDF also contains images, if those images change (sometimes we’re in the process of enhancing images in Gimp), we want the PDF to be rebuilt. But how is it possible to let Make know about these dependencies?

Well, we could go through the source file and look for any image:: tags. Here’s one:

image::ETH001/boy-and-computer.jpg[width=300pt]

Then we can add an additional dependency rule inside the Makefile:

target/pdf/ETH001.pdf: ETH001/boy-and-computer.jpg

Maintaining these rules might be a pain, and we’ll quickly forget to do it. My sed and awk skills might be up to the tasks of grep’ing out the include:: lines of each file, but …​ I’d much rather be using Clojure. I’m always struck by the startling contrast between the consistency and elegance of the Unix line-by-line data processing model and the inconsistency and ugliness of the syntax of the individual tools. This is what makes Lisps such as Clojure all the more extraordinary - an easy-to-learn, consistent syntax which can scale up to the tackle the most ambitious of problems.