Docutils 标记 API

本节介绍用于添加 reStructuredText 标记元素(角色和指令)的 API。

角色

角色遵循以下描述的接口。它们必须由扩展使用 Sphinx.add_role()Sphinx.add_role_to_domain() 进行注册。

def role_function(
    role_name: str, raw_source: str, text: str,
    lineno: int, inliner: Inliner,
    options: dict = {}, content: list = [],
) -> tuple[list[Node], list[system_message]]:
    elements = []
    messages = []
    return elements, messages

optionscontent 参数仅用于通过 role 指令创建的自定义角色。返回值是一个包含两个列表的元组,第一个列表包含来自角色的文本节点和元素,第二个列表包含生成的任何系统消息。有关更多信息,请参阅 Docutils 的 自定义角色概述

创建自定义角色

Sphinx 提供了两个用于创建自定义角色的基类,SphinxRoleReferenceRole

这些类为创建角色提供了一个基于类的接口,其中主要逻辑必须在你的 run() 方法中实现。这些类提供了许多有用的方法和属性,例如 self.textself.configself.envReferenceRole 类实现了 Sphinx 的 title <target> 逻辑,公开了 self.targetself.title 属性。这对于创建交叉引用角色非常有用。

指令

指令由派生自 docutils.parsers.rst.Directive 的类处理。它们必须由扩展使用 Sphinx.add_directive()Sphinx.add_directive_to_domain() 进行注册。

class docutils.parsers.rst.Directive[source]

新指令的标记语法由以下五个类属性确定

required_arguments = 0

必需指令参数的数量。

optional_arguments = 0

必需参数之后的可选参数的数量。

final_argument_whitespace = False

最终参数可以包含空格吗?

option_spec = None

选项名称到验证器函数的映射。

选项验证器函数接受单个参数,即选项参数(如果未给定,则为 None),并且应该验证它或将其转换为正确的形式。它们会引发 ValueErrorTypeError 以指示失败。

docutils.parsers.rst.directives 模块中,有几个预定义且可能很有用的验证器。

has_content = False

指令可以包含内容吗?

新指令必须实现 run() 方法

run()[source]

此方法必须处理指令的参数、选项和内容,并返回一个 Docutils/Sphinx 节点列表,这些节点将插入到文档树中指令被遇到的位置。

指令上始终设置的实例属性是

name

指令名称(在以多个名称注册相同的指令类时很有用)。

arguments

提供给指令的参数,以列表形式。

options

提供给指令的选项,以字典形式,将选项名称映射到已验证/转换的值。

content

指令内容(如果给定),以 ViewList 形式。

lineno

指令出现的绝对行号。这不总是一个有用的值;请改用 srcline

content_offset

指令内容的内部偏移量。在调用 nested_parse 时使用(见下文)。

block_text

包含整个指令的字符串。

state
state_machine

控制解析的状态和状态机。用于 nested_parse

另请参阅

创建指令 Docutils 文档的 HOWTO

将指令内容解析为 reStructuredText

许多指令将包含更多必须解析的标记。为此,请使用 run() 方法中的以下 API 之一

第一个方法将指令的所有内容解析为标记,而第二个方法仅解析给定的 text 字符串。两种方法都在列表中返回解析后的 Docutils 节点。

这些方法的使用方式如下

def run(self) -> list[Node]:
    # either
    parsed = self.parse_content_to_nodes()
    # or
    parsed = self.parse_text_to_nodes('spam spam spam')
    return parsed

注意

上述实用工具方法是在 Sphinx 7.4 中添加的。在 Sphinx 7.4 之前,应使用以下方法来解析内容

  • self.state.nested_parse

  • sphinx.util.nodes.nested_parse_with_titles() – 这允许在解析的内容中使用标题。

def run(self) -> list[Node]:
    container = docutils.nodes.Element()
    # either
    nested_parse_with_titles(self.state, self.result, container)
    # or
    self.state.nested_parse(self.result, 0, container)
    parsed = container.children
    return parsed

要解析内联标记,请使用 parse_inline()。这仅适用于单行或段落的文本,并且不包含任何结构元素(标题、过渡、指令等)。

注意

sphinx.util.docutils.switch_source_input() 允许在指令中解析内容期间更改源(输入)文件。它对于解析混合内容很有用,例如在 sphinx.ext.autodoc 中,它用于解析文档字符串。

from sphinx.util.docutils import switch_source_input
from sphinx.util.parsing import nested_parse_to_nodes

# Switch source_input between parsing content.
# Inside this context, all parsing errors and warnings are reported as
# happened in new source_input (in this case, ``self.result``).
with switch_source_input(self.state, self.result):
    parsed = nested_parse_to_nodes(self.state, self.result)

自版本 1.7 起已弃用:在 Sphinx 1.6 之前,sphinx.ext.autodoc.AutodocReporter 用于此目的。它已被 switch_source_input() 替换。

ViewLists 和 StringLists (视图列表和字符串列表)

Docutils 在 StringList 类中表示文档源行,该类继承自 ViewList,两者都在 docutils.statemachine 模块中。这是一个具有扩展功能的列表,包括切片创建原始列表的视图以及列表包含有关源行号的信息。

Directive.content 属性是一个 StringList。如果生成要解析为 reStructuredText 的内容,则必须为 Docutils API 创建一个 StringList。Sphinx 提供的实用工具函数会自动处理此问题。内容生成的重要点如下

  • ViewList 构造函数接受字符串(行)列表和源(文档)名称。

  • ViewList.append() 方法也接受一行和一个源名称。