在 Sphinx Makefile 代码块中保留选项卡

Preserve tabs in Sphinx Makefile code-block's

我使用带有 reStructuredText 输入和 HTML 输出的 Sphinx 来记录基础设施的不同部分。这个想法是阅读文档的用户可以复制示例并将它们粘贴到她的文件中。对于 Makefile 示例如何做到这一点? Makefiles 在某些地方需要制表符,但 Sphinx 将制表符转换为空格。

示例:command 行必须以最后一个 HTML 中的制表符开头。这里写了三个空格缩进和一个制表符:

.. code-block:: Makefile

   target: dependency
    command -i $< -o $@

code-block 没有控制选项卡扩展的选项。

使用 sphinx 代码块 makefile 选项卡进行网络搜索 可以找到包含代码中选项卡扩展的答案(我更喜欢内联)或如何编辑 Sphinx Makefile,但没有什么能解决我的问题。

制表符扩展发生在解析 RST 的早期阶段,因此您必须自定义解析器本身以禁用它。我希望这有效。

from typing import Union
from docutils.nodes import document
from docutils.statemachine import StringList
from sphinx.parsers import RSTParser


class NoTabExpansionRSTParser(RSTParser):
    def parse(self, inputstring: Union[str, StringList], document: document) -> None:
        if isinstance(inputstring, str):
            lines = inputstring.splitlines()
            inputstring = StringList(lines, document.current_source)
        super().parse(inputstring, document)


def setup(app):
    app.add_source_parser(NoTabExpansionRSTParser, override=True)

仅供参考,这里是制表符扩展发生的地方,上面的代码绕过了它。

sphinx.parsers.RSTParser#parse

lines = docutils.statemachine.string2lines(
    inputstring, tab_width=document.settings.tab_width,
    convert_whitespace=True)

docutils.statemachine.string2lines

return [s.expandtabs(tab_width).rstrip() for s in astring.splitlines()]