如何将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
相关产品推荐
相关产品推荐

