如何创建调用image指令的自定义Sphinx指令?
自定义Sphinx指令解析JSON生成图片列表
问题背景
我需要展示存储在JSON文件中的赞助商图片列表,JSON格式如下:
{ "toto": "path/to/image", "tutu": "path/to/image", ... }
同事不熟悉reStructuredText,让他们逐个编写image指令太麻烦。我希望创建一个自定义指令,只需要写.. logo:: path/to/json就能自动解析JSON并生成图片列表。之前尝试的自定义指令仅在HTML输出中生效,还需要编写额外的visit_method,现在想改成直接生成原生的image节点,让所有输出格式都能支持。
解决方案
无需自定义新节点,直接在指令的run方法中生成docutils原生的image节点即可,Sphinx会自动处理不同输出格式的渲染,无需额外编写访问方法。修改后的代码如下:
"""Logo扩展:从JSON文件生成图片列表""" import json from pathlib import Path from typing import List from docutils import nodes from sphinx.util.docutils import SphinxDirective class Logos(SphinxDirective): """从JSON文件生成图片列表的自定义指令 使用示例: .. logo:: funder """ required_arguments = 1 optional_arguments = 0 final_argument_whitespace = False option_spec = {} def run(self) -> List[nodes.Node]: # 构建JSON文件路径 data_dir = Path(__file__).parents[1] / "_data" / "logo" logo_file = data_dir / f"{self.arguments[0]}.json" # 读取并解析JSON with open(logo_file, 'r', encoding='utf-8') as f: logos = json.load(f) # 生成图片节点列表 image_nodes = [] for name, img_path in logos.items(): # 创建image节点,设置图片路径和替代文本 image_node = nodes.image(uri=img_path, alt=name) # 可选:添加自定义样式类 # image_node['classes'].append('sponsor-logo') image_nodes.append(image_node) # 可选:添加换行(仅HTML生效) image_nodes.append(nodes.raw('', '<br />', format='html')) return image_nodes def setup(app): app.add_directive("logo", Logos) return { "parallel_read_safe": True, "parallel_write_safe": True, }
关键修改说明
- 移除自定义节点:删掉原有的
logo_node类及对应的visit_*/depart_*方法,不再需要为不同输出格式编写自定义渲染逻辑。 - 生成原生image节点:遍历JSON中的图片路径,直接创建docutils标准的
nodes.image节点,Sphinx会自动适配HTML、LaTeX等所有输出格式。 - 简化注册逻辑:
setup函数仅需注册自定义指令,无需处理新节点的渲染配置。
扩展优化(可选)
- 添加图片链接:如果需要给图片绑定跳转链接,用
nodes.reference包裹image_node即可:ref_node = nodes.reference(uri="https://example.com", refuri="https://example.com") ref_node.append(image_node) image_nodes.append(ref_node) - 适配复杂JSON结构:如果你的JSON包含尺寸、深色/浅色版本等字段(如原代码中的
size、light/dark),可调整遍历逻辑,将这些属性映射到节点的对应参数中。
内容的提问来源于stack exchange,提问作者Pierrick Rambaud
相关产品推荐
相关产品推荐

