Control indentation with Org–Babel

3.4k views Asked by At

When writing literate Python with Org–Babel, I need to be able to control the indentation level (either explicitly with :indentation-level 3 or implicitly with some clever indication).

Here's an example file that demonstrates the problem.

#+BEGIN_SRC python :tangle "sample.py"
  class Test:
      def __init__(self):
          self.a = 'a test class'
#+END_SRC
#+BEGIN_SRC python :tangle "sample.py"
      def say_hi(self):
          print 'Hi from this Test object!'
          print 'ID: {}'.format(repr(self))
          print 'Data: {}'.format(str(self.__dict__))
#+END_SRC
3

There are 3 answers

2
Tobias On

Set org-src-preserve-indentation to t.

0
coltoneakins On

I didn't perfectly like Tobias' answer because when I org-edit-special (C-c ') a code block, my python-mode buffer would yell at me (I have several python minor modes with syntax checkers) because of the unexpected indent for blocks with stand-alone methods (because with org-src-preserve-indentation set, I would have indents in front of all my methods in their individual blocks). So instead, I like this solution using org-mode's :noweb header argument:

#+BEGIN_SRC python :tangle "sample.py" :noweb yes
  class Test:
      <<init_method>> # these are indented
      <<more_methods>> # these are indented
#+END_SRC

#+BEGIN_SRC python :noweb-ref init_method
  def __init__(self):
      self.a = 'a test class'
#+END_SRC

#+BEGIN_SRC python :noweb-ref more_methods
  def say_hi(self):
      print 'Hi from this Test object!'
      print 'ID: {}'.format(repr(self))
      print 'Data: {}'.format(str(self.__dict__))
#+END_SRC

As long as you just indent the Noweb syntax references (the double << >>) in your class definition, the other blocks ("init_method" and "more_methods") will be tangled with respect to your indentation. So, the final output "sample.py" file looks like this:

class Test:
    def __init__(self):
        self.a = 'a test class'
    def say_hi(self):
        print 'Hi from this Test object!'
        print 'ID: {}'.format(repr(self))
        print 'Data: {}'.format(str(self.__dict__))

Nice!

0
Markus On

I know it is not the desired solution but as a work around you can insert a comment (specific to your programming language) in the source block and make the desired indentation after that comment. This will also preserve the indentation when exiting the edit-buffer

#+BEGIN_SRC python :tangle "sample.py"
  class Test:
      def __init__(self):
          self.a = 'a test class'
#+END_SRC
#+BEGIN_SRC python :tangle "sample.py"
  # This is my dummy python comment to keep the correct indentation 
      def say_hi(self):
          print 'Hi from this Test object!'
          print 'ID: {}'.format(repr(self))
          print 'Data: {}'.format(str(self.__dict__))
#+END_SRC