如何在reStructuredText代码块中强制保留空白

11 投票
3 回答
4320 浏览
提问于 2025-04-16 23:26

在RST中,我们在代码块前面加一些空格,来表示这是一个代码块。因为Python也用空格来缩进代码块,所以如果我在写Python代码时,希望我的RST代码块能保留这些空格,该怎么做呢?

假设我们有一个类:

class Test(object):

我们想写一个叫做 __init__ 的方法,这个方法是这个类的一部分。这个方法属于另一个代码块,但我们想给读者一些视觉上的提示,让他们知道这个第二个代码块是前一个的延续。目前,我用 # 来标记代码块的竖直引导线,像这样:

    def __init__(self):
        pass
#

如果没有 #,那么 def __init__(self) 就会和 class Test(object) 在同一个缩进层级上。肯定有更优雅的办法。

3 个回答

0

你还可以试试行块,它们的样子是这样的:

|     def foo(x):
|         pass

不过它们并不专门用于代码示例。

1

你需要自己定义一个指令(确实,标准的 .. code:: 指令会吞掉空格,但你可以创建一个自己的指令,它不会这样做):

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)

当然,你也可以用这个来覆盖标准的 .. code:: 指令。

0

啊……我之前也遇到过这个问题;)。我通常会用#这个小技巧,遗憾的是。如果你看一下规范,里面说它总是会去掉开头的缩进。[1]

你也可以使用另一种语法:

::

>     def foo(x):
>         pass

在开头加上">",这样就能保留开头的空格了。

[1] : http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#indented-literal-blocks

编辑

我刚刚翻了一下docutils的代码(这个问题也让我很困扰),可以确认它总是会去掉公共的缩进,毫无疑问。虽然可以很容易地修改代码来改变这个行为,但那样生成的重构文本就不符合标准了。

撰写回答