In literate programming, I often like to write my code in small snippets and then export them all at once via org-babel-tangle. This works great for non-indentation sensitive code (especially with post-processing), but doesn't work quite well with languages like Haskell or Python as org-babel-tangle removes the initial whitespace:

This is a completely self-contained example of the problem.
Copy it into an org-mode buffer and try both 
=M-x org-export-dispatch= and =M-x org-babel-tangle=.

* A simple Python function
:header-args:python: :tangle example.py :padline no

Here's a small example function in Python:

#+begin_src python  :shebang "#!/usr/bin/env python"
def foo():

According to org-mode's documentation[fn:1], we can use `-i' 
to keep the indentation, so let's do that on the continuation 
of the aforementioned example:

#+begin_src python -i
    """Says hello!"""
    print("Hello, world!")

If we (org-export-dispatch) the file, then everything seems 
nice. However, if we (org-babel-tangle) the file, then the 
indentation is gone and thus our Python file invalid.

* Footnotes

[fn:1] See [[info:org#Literal Examples][info:org#Literal Examples]].

The -i switch doesn't seem to work for org-babel-tangle at all. While I could use <<noweb>> to glue the code together in a hidden, non-exported source block, I would rather like to have org-babel-tangle behave correctly.

Is there some hidden option I'm missing? How can I keep the indentation when I tangle files via org-babel-tangle similarly to the -i switch for exporting?


You can use the variable org-src-preserve-indentation. If you set it to t before tangling like this:

#+begin_src emacs-lisp
(setq org-src-preserve-indentation t)

then the tangle will work as you expect.

The variable is defined with a defcustom so it is meant to be customized as you wish. You can either set it in your init file as above or customize it by hitting the customize link in its docstring, which you get with C-h v org-src-preserve-indentation.

  • Hm. It's unfortunate that a global variable is necessary. I usually like to keep #+OPTIONS or PROPERTIES local. I'll guess I'll use add-file-local-variable and add (org-src-preserver-indentation . t) to the safe values/variables.
    – Zeta
    Jan 6 at 11:04
  • You might want to suggest that as an RFE on the Org mode mailing list. The thinking goes, I'm guessing, that users prefer it one way or the other and that does not depend on the block or file. Making everything local to a file does have an overhead I imagine. I'm a bit surprised that the default value is nil though.
    – NickD
    Jan 6 at 14:46
  • Great answer. I had the same problem. It seems that the author of the document should determine how the code is tangled... but I'm sure there is wisdom in the current setup.
    – Schmudde
    Feb 9 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.