Как я могу использовать существующую директиву в пользовательской директиве/расширении python-sphinx?

Я хотел бы создать пользовательскую Directive, которая использует существующую директиву (code-block в этом примере) в своей реализации.

Ручной эквивалент этого в reStructuredText будет:

.. mydirective:: py

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

Однако я бы хотел, чтобы code-block создавалось в рамках определения my-directive. Я нашел пример, который жестко кодирует соответствующий 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

Как я могу реализовать это независимым от парсера способом?


person David Foster    schedule 19.07.2020    source источник


Ответы (1)


В итоге мое решение было таким:

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]

Где OtherDirective была другой существующей директивой.

Я не смог создать подкласс обеих директив и использовать их функциональность через super, так как мне нужно было вызвать метод с именем run из обоих.

Обновлять

Вы можете увидеть окончательное решение в CodeTabDirective из sphinx-tabs.

person David Foster    schedule 27.07.2020