docutils/sphinx自定义指令创建同级节而不是子级

2024-05-17 12:46:47 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑具有以下骨架的RestructedText文档:

Main Title
==========

text text text text text

Subsection
----------

text text text text text

.. my-import-from:: file1
.. my-import-from:: file2

my-import-from指令是由特定于文档的Sphinx扩展提供的,它应该读取作为参数提供的文件,解析嵌入其中的reST,并将结果作为一个节插入当前输入文件中。(与autodoc类似,但文件格式不同。)我现在的代码如下:

^{pr2}$

这是有效的,除了新节作为当前节的而不是兄弟注入。换言之,上面的示例文档生成如下目录树:

  • Main Title
    • Subsection
      • File1
      • File2

而不是你想要的

  • Main Title
    • Subsection
    • File1
    • File2

我怎么解决这个问题?Docutils文档是。。。不充分,尤其是在断面深度控制方面。我尝试过的一个明显的方法是返回doc_section.children,而不是{};这将从TOC树中完全删除File1和{}(但确实会使文档正文中的节头显示为正确的嵌套级别)。在


Tags: 文件textfrom文档importtitlemainmy
2条回答

我认为不可能通过返回指令中的部分来实现这一点(不按照Florian的建议做一些事情),因为它将被附加到“当前”部分。但是,您可以通过self.state.section添加节,就像我在下面所做的那样(为了简洁起见,处理删除的选项)

class FauxHeading(object):
    """
    A heading level that is not defined by a string. We need this to work with
    the mechanics of
    :py:meth:`docutils.parsers.rst.states.RSTState.check_subsection`.

    The important thing is that the length can vary, but it must be equal to
    any other instance of FauxHeading.
    """

    def __init__(self, length):
        self.length = length

    def __len__(self):
        return self.length

    def __eq__(self, other):
        return isinstance(other, FauxHeading)


class ParmDirective(Directive):

    required_arguments = 1
    optional_arguments = 0
    has_content = True
    option_spec = {
        'type':          directives.unchanged,
        'precision':     directives.nonnegative_int,
        'scale':         directives.nonnegative_int,
        'length':        directives.nonnegative_int}

    def run(self):
        variableName = self.arguments[0]
        lineno = self.state_machine.abs_line_number()
        secBody = None
        block_length = 0

        # added for some space
        lineBlock = nodes.line('', '', nodes.line_block())

        # parse the body of the directive
        if self.has_content and len(self.content):
            secBody = nodes.container()
            block_length += nested_parse_with_titles(
                self.state, self.content, secBody)

        # keeping track of the level seems to be required if we want to allow
        # nested content. Not sure why, but fits with the pattern in
        # :py:meth:`docutils.parsers.rst.states.RSTState.new_subsection`
        myLevel = self.state.memo.section_level
        self.state.section(
            variableName,
            '',
            FauxHeading(2 + len(self.options) + block_length),
            lineno,
            [lineBlock] if secBody is None else [lineBlock, secBody])
        self.state.memo.section_level = myLevel

        return []

我不知道如何直接在你的自定义指令中执行。但是,可以使用自定义转换在解析后提升树中的File1和{}节点。例如,请参见^{}模块中的转换。在

在Sphinx扩展中,使用^{}方法注册自定义转换。在

更新:您还可以通过在节点列表中返回docutils.nodes.pending类的一个或多个实例,直接在指令中注册转换。在这种情况下,一定要调用文档的note_pending方法(在您的指令中,您可以通过self.state_machine.document获取文档)。在

相关问题 更多 >