You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Sphinx自定义指令内容解析为docutil节点

LicenceDirective 自定义指令实现方案

你可以基于docutils和Sphinx的原生API实现该需求,完整实现逻辑如下:

核心实现代码

from docutils import nodes
from docutils.parsers.rst import Directive
from sphinx.util.nodes import nested_parse_with_titles
import os

class LicenceDirective(Directive):
    # 指令基础配置
    required_arguments = 1  # 接收第一个参数作为软件名称
    option_spec = {
        "url": str,
        "path": str,
    }
    has_content = True  # 开启指令内容块支持,对应你说的CONTENT部分

    def run(self):
        env = self.state.document.settings.env
        return_nodes = []

        # 1. 生成一级标题节点
        soft_name = self.arguments[0]
        title_id = nodes.make_id(soft_name)
        h1_node = nodes.title(soft_name, soft_name, ids=[title_id])
        return_nodes.append(h1_node)

        # 2. 生成下载链接节点
        if "url" in self.options:
            link = nodes.reference(
                "Download page", 
                "Download page", 
                refuri=self.options["url"]
            )
            link_para = nodes.paragraph()
            link_para.append(link)
            return_nodes.append(link_para)

        # 3. 解析内容块的RST语法,支持所有原生RST格式(标题、列表、代码块等)
        content_container = nodes.container()
        # 使用nested_parse_with_titles支持内容块内的标题层级解析
        nested_parse_with_titles(self.state, self.content, content_container)
        return_nodes.extend(content_container.children)

        # 4. 读取许可证文件生成pre节点
        if "path" in self.options:
            lic_path = os.path.join(env.srcdir, self.options["path"].lstrip("/"))
            if os.path.exists(lic_path):
                with open(lic_path, "r", encoding="utf-8") as f:
                    lic_content = f.read()
                pre_node = nodes.literal_block(lic_content, lic_content)
                return_nodes.append(pre_node)

        return return_nodes

# 在Sphinx扩展中注册指令
def setup(app):
    app.add_directive("licence", LicenceDirective)
    return {"version": "0.1"}

注意说明

  • 如果需要调整许可证文件的查找逻辑,可以修改路径拼接规则,比如改为相对于当前RST文件的路径,可通过env.docname获取当前文档路径拼接
  • 如果不需要支持内容块内的标题,可以把nested_parse_with_titles替换为原生的self.state.nested_parse方法,功能完全兼容

内容的提问来源于stack exchange,提问作者Oragon Efreet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 19:06:03