So, why am I going through all this? It's pretty apparent what the script does, right?

The point of this is to demonstrate an actual literate programming example. So let's break down how I'd do this in a literate style.

This assumes you're not squeamish about reading about Emacs, and explaining how to get set up with Emacs, org-mode, and org-babel is outside the scope of this article.

In org-mode, there is a neat feature that allows you to embed pieces of code that can be edited, run, exported, tangled individually. So for our script, we write the first part (where the index is deleted and created) inside of #+BEGIN_SRC and #+END_SRC blocks. I also write a little description of what I'm actually doing:

* Testing whether nested documents are included in _all The first thing I need to do is delete the old index and create the new one: #+BEGIN_SRC sh curl -XDELETE 'localhost:9200/ntest' echo curl -XPOST 'localhost:9200/ntest' -d '{ "mappings": { "doc": { "properties": { "body": { "type": "nested", "properties": { "text": {"type": "string"} } } } } } }' echo #+END_SRC

Now, org-mode has a few neat features here, I can hit `C-c C-'` and edit the code block in the appropriate major mode (shell-mode in this case) with all the configuration and niceties of that mode, or I can hit C-c C-c while the cursor is placed inside the code block to execute just this particular code. When I hit C-c C-c , the results are added to the buffer in a new section:

* Testing whether nested documents are included in _all The first thing I need to do is delete the old index and create the new one: #+BEGIN_SRC sh curl -XDELETE 'localhost:9200/ntest' echo curl -XPOST 'localhost:9200/ntest' -d '{ "mappings": { "doc": { "properties": { "body": { "type": "nested", "properties": { "text": {"type": "string"} } } } } } }' echo #+END_SRC #+RESULTS: #+BEGIN_SRC sh { "error" : "IndexMissingException[[ntest] missing]" , "status" :404} { "ok" :true, "acknowledged" :true} #+END_SRC

Fantastic! I now have a "section" of a script that I can re-run as many times as I want. This allows me to access one of the great benefits of writing like this - being able to selectively re-run any individual part of a script without having to copy and paste a part into a separate program or shell!

So this is fantastic, I can write documentation into the org-mode file around my code, leaving myself notes when I (inevitably) forget what a script does. However, this doesn't really help when I need to publish the script to a Github issue (for reproducing a bug), or sending to a customer for something they can run for themselves. Fortunately org-babel has an ability called "tangling" which can take chunks of code in a human-readable file like the example and export them into any number of other files. So let's make our script tangle-able:

* Testing whether nested documents are included in _all The first thing I need to do is delete the old index and create the new one: #+BEGIN_SRC sh :tangle issue-182.sh curl -XDELETE 'localhost:9200/ntest' echo curl -XPOST 'localhost:9200/ntest' -d '{ "mappings": { "doc": { "properties": { "body": { "type": "nested", "properties": { "text": {"type": "string"} } } } } } }' echo #+END_SRC

All I did was add the :tangle issue-182.sh line to the source block, this tells org-babel the name of the file this block should be tangled to, running org-babel-tangle on the file now generates the issue-182.sh file, which looks like this:

∴ cat issue-182.sh #!/usr/bin/env zsh curl -XDELETE 'localhost:9200/ntest' echo curl -XPOST 'localhost:9200/ntest' -d'{ "mappings": { "doc": { "properties": { "body": { "type": "nested", "properties": { "text": {"type": "string"} } } } } } }' echo

Fantastic! Now I can write documentation that is exportable to something I can give any of my colleagues to run!

The last thing I'll show off is reusable pieces of code with the noweb feature. The noweb feature allows you to reuse pieces of code in other code blocks by naming a piece, for example, something that is done frequently in ES scripts is to refresh, so we can have a block named "refresh" that looks like this:

#+NAME: refresh #+BEGIN_SRC sh curl -XPOST 'localhost:9200/_refresh' echo #+END_SRC

Which can be used in other blocks, like this:

#+BEGIN_SRC sh :noweb yes curl -XPOST 'localhost:9200/thing/doc/1' -d '{"body": "foo"}' curl -XPOST 'localhost:9200/thing/doc/2' -d '{"body": "bar"}' <<refresh>> #+END_SRC

Pretty neat! Reusable code! This is just scratching the surface of the depth with org-babel, it also supports things like variable substitution, language sessions, and parsing output as multiple formats.