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
Set org-src-preserve-indentation
to t
.
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!
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With