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
key
variable 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