I don't know how to do this without changing the code (it might be possible with org-babel-pre-tangle-hook
but it did not seem at all simple, so I didn't try that). But as soon as you accept code changes, it does not seem too bad.
The simplest possible way I could think of was to emulate in org-babel-tangle
what org-export-as
is doing WRT included files. A simple test (similar to what you describe above) succeeded easily (but see caveats at the end), so if you want to try replicating the change, I include the patch below.
The patch itself would look big, but that's only because I'm taking all of the code of org-babel-tangle
and enclosing it in another layer, which changes the indentation and that's most of the change. Ignoring whitespace changes, the "real" change is much smaller: I got the patch below with git diff -b
in order to ignore whitespace. You can then see that it is very small: we just enclose almost the whole body of org-babel-tangle
in (org-export-with-buffer-copy ...)
, so that we can do transformations to the text in a temp buffer and not disturb the original and then add one more transformation to process the #+INCLUDE:
directives, before the resulting buffer is then tangled:
diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el
index b74b3fa0c..5e6eebf63 100644
--- a/lisp/ob-tangle.el
+++ b/lisp/ob-tangle.el
@@ -206,6 +206,9 @@ export file for all source blocks. Optional argument LANG-RE can
be used to limit the exported source code blocks by languages
matching a regular expression."
(interactive "P")
+ (org-export-with-buffer-copy
+ (org-export-expand-include-keyword)
+
(run-hooks 'org-babel-pre-tangle-hook)
;; Possibly Restrict the buffer to the current code block
(save-restriction
@@ -306,7 +309,7 @@ matching a regular expression."
(mapc (lambda (pair)
(when (cdr pair) (set-file-modes (car pair) (cdr pair))))
path-collector)
- (mapcar #'car path-collector)))))
+ (mapcar #'car path-collector))))))
(defun org-babel-tangle-clean ()
"Remove comments inserted by `org-babel-tangle'.
That produces the expected results WRT the tangled files I think, but you should check to make sure that it does the right thing in your case: my tests are toy tests so they might miss tricky situations that might arise in your "real world" tests.
There is one problem which I don't understand yet: the config.org
buffer itself is changed in my tests, despite the org-export-with-copy-buffer
, so at the end of the tangle I have to undo the change with C-x u
and save it. That's probably because I don't understand what org-export-with-copy-buffer
is really doing, but I have not checked that code yet.
OTOH, if that is resolved and the tests all pass, we can propose this as an enhancement to the Org mode mailing list and put that problem (from 2010!) behind us.
EDIT: I don't see any problem with org-babel-tangle-file
- it calls org-babel-tangle
underneath, so in theory it should do the (almost) right thing and testing it with a simple example works fine for me. Maybe you can post a (small) example that gives you problems by editing your question?
I'm also testing with the following workaround to get around the issue of config.org
getting changed:
#+begin_src emacs-lisp
(copy-file "./config.org.orig" "./config.org")
(org-babel-tangle-file "./config.org")
(delete-file "./config.org")
#+end_src
Ugly, but it seems to work (except that I have to answer the "changed on disk" question).