如何创建仅在生成XML时执行的自定义Sphinx扩展?
解决Sphinx自定义XML指令的包裹问题
要让自定义指令只在XML输出时生成<mycustom>标签且不被<raw>包裹,不能直接依赖nodes.raw(),得通过自定义节点类型+XML构建器专属访问器来实现,具体步骤如下:
1. 定义专属自定义节点类
创建一个独立的节点类型,绕过Sphinx对raw节点的默认包装逻辑:
from docutils import nodes class MyCustomNode(nodes.Element): pass
2. 实现指令处理逻辑
在指令函数里生成自定义节点,而非raw节点:
from docutils.parsers.rst import Directive class MyCustomDirective(Directive): # 允许指令携带内容(可根据需求删除此配置) has_content = True def run(self): node = MyCustomNode() # 解析指令内的嵌套内容(不需要内容可删除此行) self.state.nested_parse(self.content, self.content_offset, node) return [node]
3. 注册XML构建器的节点处理方法
仅针对XML输出构建器,直接输出目标标签,跳过默认节点处理流程:
def visit_mycustom_node(self, node): # 写入自定义标签的开始标记 self.body.append('<mycustom>') def depart_mycustom_node(self, node): # 写入自定义标签的结束标记 self.body.append('</mycustom>') def setup(app): app.add_node(MyCustomNode, # 只给XML构建器绑定访问/离开方法 xml=(visit_mycustom_node, depart_mycustom_node)) app.add_directive('mycustom', MyCustomDirective) return { 'version': '0.1', 'parallel_read_safe': True, }
核心说明
- 用自定义节点替代
nodes.raw(),从根源避免Sphinx自动添加<raw>包裹层 - 仅给XML构建器注册节点处理逻辑,确保HTML等其他输出格式不会触发该节点的处理(如需支持其他格式,可添加对应构建器的访问方法)
- 若指令不需要内容,可删除
has_content = True和嵌套解析的代码,直接生成空的<mycustom></mycustom>标签
内容的提问来源于stack exchange,提问作者PeppeA82
相关产品推荐
相关产品推荐

