I recently came across a little-known (to me, anyway) feature of org mode,
thanks to this mailing list reply: conditional tangling. In the :tangle
argument, as
well as the standard values (yes
, no
or a filename string), you can also set it
dynamically, by specifying an elisp expression which evaluates to the
tangle setting.
This is quite useful together with tags. Here’s a function which sets the argument based on which tags are currently set in the file:
(defun if-tags (tags &optional filename)
"Return tangle setting based on tags.
This function is intended to be used as a :tangle argument.
TAGS is a colon-separated list of tags. If all the tags are set, the tangle setting
is \"yes\" (or FILENAME, if defined). Otherwise it is \"no\"."
(let ((tags (split-string tags ":")))
(if (equal (seq-intersection (org-get-tags) tags) tags)
(or filename "yes") "no")))
With this function defined, things like this become possible:
#+begin_src toml :tangle (if-tags "foo") foo = "I am only tangled if 'foo' is set" #+end_src #+begin_src toml :tangle (if-tags "bar") bar = "I am only tangled if 'bar' is set" #+end_src #+begin_src toml :tangle (if-tags "foo:bar") foobar = "I am only tangled if both 'foo' and 'bar' are set" #+end_src
I’m using this to define feature tags set by #+filetags:
in a literate
project config file, and it’s working pretty well.