如何自动更新Sphinx的index.rst文件以纳入所有生成的.rst文件?
自动更新 Sphinx index.rst 的 toctree 内容
需求
我的 index.rst 当前内容是:
.. toctree:: :maxdepth: 2
想自动把它更新成这样:
.. toctree:: :maxdepth: 2 doc1 doc2
其中 doc1、doc2 是自动生成的 .rst 文件,有没有办法实现?
实现方案
1. 写个 Python 脚本搞定
直接写个简单的脚本,遍历目录里的 .rst 文件(排除 index.rst 自己),然后自动更新 toctree 部分:
import os # 配置参数,根据自己的路径修改 INDEX_FILE = "index.rst" RST_DIR = "./" # 生成的.rst文件所在目录 EXCLUDE_FILES = ["index.rst"] # 读取现有index.rst内容 with open(INDEX_FILE, "r", encoding="utf-8") as f: lines = f.readlines() # 定位toctree块的位置 toctree_start = None toctree_end = None for i, line in enumerate(lines): if ".. toctree::" in line: toctree_start = i # 找到toctree配置后的第一个空行作为结束位置 elif toctree_start is not None and line.strip() == "" and i > toctree_start + 1: toctree_end = i break # 如果没找到空行,就在maxdepth行后插入空行 if toctree_end is None: for i in range(toctree_start, len(lines)): if ":maxdepth:" in lines[i]: toctree_end = i + 1 break lines.insert(toctree_end, "\n") # 收集所有要添加的.rst文件名(去掉后缀) rst_files = [] for file in os.listdir(RST_DIR): if file.endswith(".rst") and file not in EXCLUDE_FILES: rst_files.append(os.path.splitext(file)[0]) # 排序避免顺序混乱 rst_files.sort() # 生成要插入的行 new_lines = [f" {fname}\n" for fname in rst_files] # 先删除原有toctree下的文件行(如果存在) if toctree_end < len(lines): i = toctree_end while i < len(lines) and lines[i].startswith(" "): del lines[i] # 插入新的文件行 lines[toctree_end:toctree_end] = new_lines # 写回更新后的内容 with open(INDEX_FILE, "w", encoding="utf-8") as f: f.writelines(lines)
把脚本放在项目根目录,运行一次就能自动更新 index.rst。如果需要每次生成文档都自动更新,可以用下面的方法。
2. 集成到 Sphinx 构建流程
如果用 Sphinx 生成文档,把更新逻辑加到 conf.py 里,每次构建前自动执行:
在 conf.py 末尾添加这段代码:
import os def update_toctree(app): INDEX_FILE = os.path.join(app.srcdir, "index.rst") RST_DIR = app.srcdir EXCLUDE_FILES = ["index.rst"] with open(INDEX_FILE, "r", encoding="utf-8") as f: lines = f.readlines() toctree_start = None toctree_end = None for i, line in enumerate(lines): if ".. toctree::" in line: toctree_start = i elif toctree_start is not None and line.strip() == "" and i > toctree_start + 1: toctree_end = i break if toctree_end is None: for i in range(toctree_start, len(lines)): if ":maxdepth:" in lines[i]: toctree_end = i + 1 break lines.insert(toctree_end, "\n") rst_files = [] for file in os.listdir(RST_DIR): if file.endswith(".rst") and file not in EXCLUDE_FILES: rst_files.append(os.path.splitext(file)[0]) rst_files.sort() new_lines = [f" {fname}\n" for fname in rst_files] if toctree_end < len(lines): i = toctree_end while i < len(lines) and lines[i].startswith(" "): del lines[i] lines[toctree_end:toctree_end] = new_lines with open(INDEX_FILE, "w", encoding="utf-8") as f: f.writelines(lines) def setup(app): app.connect("builder-inited", update_toctree)
这样每次执行 sphinx-build 命令时,都会先自动更新 index.rst 的 toctree,再构建文档。
3. 用 Makefile 简化操作
如果项目用 Makefile 管理,把更新步骤整合到构建命令里:
在 Makefile 中添加:
update-toctree: python update_toctree.py html: update-toctree sphinx-build -b html . _build/html
以后执行 make html,就会先跑脚本更新 toctree,再生成 HTML 文档。
内容的提问来源于stack exchange,提问作者Sib
相关产品推荐
相关产品推荐

