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

如何遍历Sphinx所有文档并提取已有figure指令的元信息?

实现Sphinx全局图片列表扩展

要实现遍历现有.. figure::指令生成图片列表的自定义扩展,核心思路参考Sphinx官方Todo扩展的全局注册模式,分为元数据收集和列表渲染两个部分:

1. 核心实现逻辑

1.1 收集所有figure的元数据

通过监听Sphinx的doctree-read事件,在每个文档解析完成后,遍历其中的figure节点,提取图片的标题、文件路径、编号等元信息,存储到Sphinx环境(env)的全局变量中,供后续指令调用。

1.2 定义渲染列表的自定义指令

创建一个自定义指令(比如.. figure-list::),读取环境中收集到的所有figure数据,生成对应的列表节点,最终渲染到文档中。

2. 完整可运行代码

from docutils import nodes
from sphinx.util.docutils import SphinxDirective
from sphinx.application import Sphinx

def collect_figures(app: Sphinx, doctree):
    # 初始化全局存储容器,仅在第一次运行时创建
    if not hasattr(app.env, 'all_figures'):
        app.env.all_figures = []
    
    # 遍历当前文档中的所有figure节点
    for figure_node in doctree.findall(nodes.figure):
        # 提取图片标题(如果有caption)
        caption = ""
        caption_node = figure_node.find(nodes.caption)
        if caption_node:
            caption = caption_node.astext()
        
        # 提取图片文件路径(figure节点的第一个子节点通常是image节点)
        img_path = ""
        img_node = figure_node.find(nodes.image)
        if img_node and 'uri' in img_node.attributes:
            img_path = img_node['uri']
        
        # 提取图片编号(由Sphinx自动生成的编号)
        fig_number = figure_node.get('number', "")
        
        # 收集元数据,包含标题、路径、编号、所在文档
        app.env.all_figures.append({
            'caption': caption,
            'img_path': img_path,
            'number': fig_number,
            'docname': app.env.docname
        })

class FigureListDirective(SphinxDirective):
    def run(self):
        env = self.state.document.settings.env
        # 获取全局收集的所有figure数据
        all_figures = getattr(env, 'all_figures', [])
        
        # 创建无序列表节点
        list_node = nodes.bullet_list()
        
        for fig in all_figures:
            # 创建列表项节点
            list_item = nodes.list_item()
            
            # 构建列表项内容:编号 + 标题 + 路径
            content_text = f"{fig['number']} {fig['caption']} ({fig['img_path']})"
            para_node = nodes.paragraph(text=content_text)
            
            list_item.append(para_node)
            list_node.append(list_item)
        
        return [list_node]

def setup(app: Sphinx):
    # 注册事件监听,用于收集figure数据
    app.connect('doctree-read', collect_figures)
    # 注册自定义指令
    app.add_directive('figure-list', FigureListDirective)
    
    return {
        'version': '0.1',
        'parallel_read_safe': True,
        'parallel_write_safe': True,
    }

3. 使用说明

  1. 将上述代码保存为sphinx_figure_list.py,放在你的Sphinx项目的扩展目录(比如_extensions)中。
  2. 在conf.py中添加扩展:
    extensions = [
        # 其他扩展...
        '_extensions.sphinx_figure_list',
    ]
    
  3. 在任意.rst文档中添加指令.. figure-list::,即可生成所有图片的列表。

4. 关键细节说明

  • 元数据收集时机:doctree-read事件在每个文档被解析为doctree后触发,确保能捕获所有figure节点。
  • 全局存储:使用app.env.all_figures作为全局容器,Sphinx会在构建过程中维护这个环境变量,跨文档共享数据。
  • 节点遍历:通过doctree.findall(nodes.figure)精准定位所有figure节点,再从中提取caption、image路径等关键信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 04:48:25