迫使狮身人面像解释Python Docstrings中的Markdown,而不是重组文本



我正在使用sphinx记录一个python项目。我想在我的Docstrings中使用Markdown进行格式化。即使我使用recommonmark扩展名,它也仅涵盖手动编写的.md文件,而不是DocStrings。

我在我的扩展中使用autodocnapoleonrecommonmark

我如何在我的docstrings中制作sphinx parse markdown

sphinx的autodoc扩展名在每次处理DOC串时都会发出名为autodoc-process-docstring的事件。我们可以钩住该机制以将语法从Markdown转换为重组文本。

不幸的是,推荐标志不会暴露降压到件转换器。它直接将解析的标记映射到Docutils对象,即Sphinx本身从重组文本内部创建的相同表示形式。

相反,我使用Commonmark进行项目的转换。因为它很快 - 例如,比潘多克(Pandoc(快得多。速度很重要,因为转换在飞行上发生并单独处理每个文档。除此之外,任何降价转换器都将做到。M2R2将是第三个示例。其中任何一个的缺点是它们不支持推荐标志的语法扩展,例如对文档其他部分的交叉引用。只是基本的降价。

要插入Commargark Doc-string Converter,请确保安装该软件包(pip install commonmark(并将以下内容添加到Sphinx的配置文件conf.py

import commonmark
def docstring(app, what, name, obj, options, lines):
    md  = 'n'.join(lines)
    ast = commonmark.Parser().parse(md)
    rst = commonmark.ReStructuredTextRenderer().render(ast)
    lines.clear()
    lines += rst.splitlines()
def setup(app):
    app.connect('autodoc-process-docstring', docstring)

同时,推荐标志于2021年5月被弃用。Sphinx扩展Myst是一个更丰富的Markdown Parser,是Sphinx推荐的替代品和读取式的替代品。有了Myst,人们可以使用相同的" hack"。如上所述,获得有限的降级支持。尽管在2023年2月,扩展名sphinx-autodoc2出版了,该扩展名承诺在包括交叉引用在内的DOC串中获得完整的(Myst-Fravory(Markdown支持。

此处概述的方法的一种可能的替代方法是使用MKDocStrings插件使用MKDOC,该插件将完全从该过程中消除sphinx和重组文本。

在 @john-hennig答案上构建,以下将保持重组的文本字段,例如: :py:attr::py:class:等。这使您可以参考其他类,等等

import re
import commonmark
py_attr_re = re.compile(r":py:w+:(``[^:`]+``)")
def docstring(app, what, name, obj, options, lines):
    md  = 'n'.join(lines)
    ast = commonmark.Parser().parse(md)
    rst = commonmark.ReStructuredTextRenderer().render(ast)
    lines.clear()
    lines += rst.splitlines()
    for i, line in enumerate(lines):
        while True:
            match = py_attr_re.search(line)
            if match is None:
                break 
            start, end = match.span(1)
            line_start = line[:start]
            line_end = line[end:]
            line_modify = line[start:end]
            line = line_start + line_modify[1:-1] + line_end
        lines[i] = line
def setup(app):
    app.connect('autodoc-process-docstring', docstring)

我必须扩展约翰·亨(John-Hen(接受的答案,以允许将Args:条目的多行描述视为一个参数:

def docstring(app, what, name, obj, options, lines):
  wrapped = []
  literal = False
  for line in lines:
    if line.strip().startswith(r'```'):
      literal = not literal
    if not literal:
      line = ' '.join(x.rstrip() for x in line.split('n'))
    indent = len(line) - len(line.lstrip())
    if indent and not literal:
      wrapped.append(' ' + line.lstrip())
    else:
      wrapped.append('n' + line.strip())
  ast = commonmark.Parser().parse(''.join(wrapped))
  rst = commonmark.ReStructuredTextRenderer().render(ast)
  lines.clear()
  lines += rst.splitlines()
def setup(app):
  app.connect('autodoc-process-docstring', docstring)

当前的 @john-hennig很棒,但似乎以python风格的多行Args:失败了。这是我的修复:


def docstring(app, what, name, obj, options, lines):
    md = "n".join(lines)
    ast = commonmark.Parser().parse(md)
    rst = commonmark.ReStructuredTextRenderer().render(ast)
    lines.clear()
    lines += _normalize_docstring_lines(rst.splitlines())

def _normalize_docstring_lines(lines: list[str]) -> list[str]:
    """Fix an issue with multi-line args which are incorrectly parsed.
    ```
    Args:
        x: My multi-line description which fit on multiple lines
          and continue in this line.
    ```
    Is parsed as (missing indentation):
    ```
    :param x: My multi-line description which fit on multiple lines
    and continue in this line.
    ```
    Instead of:
    ```
    :param x: My multi-line description which fit on multiple lines
        and continue in this line.
    ```
    """
    is_param_field = False
    new_lines = []
    for l in lines:
        if l.lstrip().startswith(":param"):
            is_param_field = True
        elif is_param_field:
            if not l.strip():  # Blank line reset param
                is_param_field = False
            else:  # Restore indentation
                l = "    " + l.lstrip()
        new_lines.append(l)
    return new_lines

def setup(app):
    app.connect("autodoc-process-docstring", docstring)

最新更新