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

如何创建调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:13:26