简体   繁体   English

如何在自定义 python-sphinx 指令/扩展中使用现有指令?

[英]How can I use an existing Directive within a custom python-sphinx Directive/extension?

I'd like to create a custom Directive that uses the an existing Directive ( code-block in this example) in it's implementation.我想创建一个自定义Directive ,该指令在其实现中使用现有指令(本示例中的code-block )。

The manual equivalent of this in reStructuredText would be: reStructuredText 中的手动等效项是:

.. mydirective:: py

   .. code-block: py
        
      print("Hello world")     

However, I would like the code-block to be created within my-directive 's definition.但是,我希望在my-directive的定义中创建code-block I found an example that hard-codes the appropriate reStructuredText for the existing Directive (below), but this depends on the parser using rST .我找到了一个为现有指令(如下)硬编码适当reStructuredText的示例,但这取决于使用rST的解析器。

class MyDirective(Directive):
    has_content = True

    def run(self):
        # Do custom stuff...

        # Use code-block Directive
        new_content = [
            '.. tab:: {}'.format(json.dumps(tab_args)),
            '   {}'.format(tab_name),
            '',
            '   .. code-block:: {}'.format(lang),
        ]

        if 'linenos' in self.options:
            new_content.append('      :linenos:')

        new_content.append('')

        for idx, line in enumerate(new_content):
            self.content.data.insert(idx, line)
            self.content.items.insert(idx, (None, idx))

        node = nodes.container()
        self.state.nested_parse(self.content, self.content_offset, node)
        return node.children

How could I implement this in a parser-independent fashion?我如何以独立于解析器的方式实现它?

In the end, my solution was:最后,我的解决方案是:

from sphinx.directives.code import CodeBlock


class CodeTabDirective(CodeBlock):
    """ Tab directive with a codeblock as its content"""

    def run(self):
        self.assert_has_content()
        
        code_block = super().run()[0]

        # Set anything required by OtherDirective

        node = OtherDirective.run(self)[0]  # Generates container
        node.append(code_block)  # Put code block inside container

        return [node]

Where OtherDirective was another existing directive. OtherDirective是另一个现有指令。

I wasn't able to subclass both directives and use their functionality via super , as I needed to call a method named run from both.我无法继承这两个指令并通过super使用它们的功能,因为我需要从两者调用一个名为run的方法。

Update更新

You can see the final solution in place in the CodeTabDirective of sphinx-tabs .您可以在sphinx-tabsCodeTabDirective中看到最终解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM