Reputation: 1793
In RST, we use some whitespaces in front of a block to say this is a code block. Because Python also uses whitespace to indent a code block, I would like my RST code block to preserve those whitespaces if I were writing Python code. How can I do that?
Let's say we have a class:
class Test(object):
And we want to write a method called __init__
that is a member of this class. This method belongs to another code block but we want to have some visual clue so that readers know that this second block is a continuation of the previous one. At the moment, I use #
to mark the vertical guide line of a code block like this:
def __init__(self):
pass
#
Without the #
, def __init__(self)
would be printed at the same indentation level as class Test(object)
. There's gotta be more elegant way.
Upvotes: 11
Views: 4581
Reputation: 12937
You need to define your own directive (it's true that the standard .. code::
directive gobbles spaces but you can make your own directive that doesn't):
import re
from docutils.parsers.rst import directives
INDENTATION_RE = re.compile("^ *")
def measure_indentation(line):
return INDENTATION_RE.match(line).end()
class MyCodeBlock(directives.body.CodeBlock):
EXPECTED_INDENTATION = 3
def run(self):
block_lines = self.block_text.splitlines()
block_header_len = self.content_offset - self.lineno + 1
block_indentation = measure_indentation(self.block_text)
code_indentation = block_indentation + MyCodeBlock.EXPECTED_INDENTATION
self.content = [ln[code_indentation:] for ln in block_lines[block_header_len:]]
return super(MyCodeBlock, self).run()
directives.register_directive("my-code", MyCodeBlock)
You could of course overwrite the standard .. code::
directive with this, too.
Upvotes: 1
Reputation: 4295
You can also try Line Blocks which look like this:
| def foo(x):
| pass
though they aren't specific to code examples.
Upvotes: 0
Reputation: 39366
Ah... I've run into this before ;). The # trick is usually what I use, alas. If you read the spec it sounds like it will always take away the leading indent. [1]
You could also use an alternate syntax:
::
> def foo(x):
> pass
With the leading ">" that will preserve leading space.
[1] : http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#indented-literal-blocks
EDIT
Just dug through the docutils code (this has been bugging me a lot too) and can confirm that it will always strip out the common indent, no questions asked. It would be easy to modify to change this behavior but that would make the resulting restructured text non-standard.
Upvotes: 0