Interpolate variables into org source blocks on babel tangle
See also Literate programming with org-mode
I made a org document to generate boiler plate docker files for quickly spinning up a Ruby on Rails app without having to install any local dependencies (other than docker). To make it easier to re-use for different projects, docker images, etc., I found a way to have a single place to define the images so I didn’t have to edit each source block in multiple places. See docker-compose Rails PG Redis Sidekiq Travis-CI for the details.
Anyway, here’s a simplified example of how it works.
# Define the variables
- Create a named source block in emacs-lisp. You could use another language if you want, however.
- I used a Association List (ie, key-value pairs) so the block can support multiple variables.
- Have the source block accept a
keyvariable used to fetch the desired value.
#+name: variables
#+begin_src emacs-lisp :var key=""
(setq variables
'(("var1" . "value1")
("var2" . "value2")
("var3" . "value3")))
(cdr (assoc key variables))
#+end_src
# Call the variables code in subsequent source blocks
For this, I used the header argument :noweb. This let me reference the
variables named source block in other source blocks like calling a function,
passing the key corresponding to the value I wanted to interpolate. This will
work for export, evaluating and tangling. See Noweb Reference Syntax for more
on this.
#+begin_src ruby :noweb yes
<<-TXT
var1 = <<variables("var1")>>
var2 = <<variables("var2")>>
var3 = <<variables("var3")>>
TXT
#+end_src
#+RESULTS:
: var1 = value1
: var2 = value2
: var3 = value3