在Sphinx项目中包含外部文档

7 投票
1 回答
1323 浏览
提问于 2025-04-16 18:01

我们在SVN上维护着一份相当大的文档,使用的是Sphinx工具。

在生成的内容中,我们希望把相关Python模块的发布说明作为主要内容包含进去(而不是作为超链接!)。这些外部模块的发布说明也保存在SVN里。有没有什么Sphinx的方法可以从其他(SVN)来源提取文档的部分内容?使用SVN的外部链接是一种解决方案,但可能不是最聪明的办法……有没有更好的选择?

1 个回答

8

我想到的两个选项是:

  1. 在远程项目中添加一个 svn:externals 链接(你应该已经知道这个了)。
  2. 通过自定义指令扩展 Sphinx,以便从远程的 Subversion 仓库中包含文件。

我对 Sphinx 的内部工作不是很精通,但我能拼凑出一个简单的扩展,它可以从远程的 Subversion 仓库中嵌入文件。

这个扩展添加了一个 svninclude 指令,它需要一个参数,就是你文档所在的仓库的 URL。它会把这个仓库的内容下载到一个临时目录 _svncache,这个目录位于项目的根目录下,然后读取每个文件的内容,并把它们插入到解析器的状态机中。

下面是 svninclude.py 扩展的代码。这个代码比较简单,目前没有错误检查。如果你打算实现这个功能,告诉我,我可以提供一些额外的建议,帮助你解决问题:

import os, re, subprocess, sys
from docutils import nodes, statemachine
from docutils.parsers.rst import directives
from sphinx.util.compat import Directive, directive_dwim

class SvnInclude(Directive):

    has_content = True
    required_arguments = 1
    optional_arguments = 0
    final_argument_whitespace = False

    def _setup_repo(self, repo):
        env = self.state.document.settings.env
        path = os.path.normpath(env.doc2path(env.docname, base=None))
        cache = os.path.join(os.path.dirname(path), '_svncache')
        root = os.path.join(cache, re.sub('[\W\-]+', '_', repo))
        if not os.path.exists(root):
            os.makedirs(root)
        subprocess.call(['svn', 'co', repo, root])
        return root

    def run(self):
        root = self._setup_repo(self.arguments[0])
        for path in self.content:
            data = open(os.path.join(root, path), 'rb').read()
            lines = statemachine.string2lines(data)
            self.state_machine.insert_input(lines, path)
        return []

def setup(app):
    app.add_directive('svninclude', directive_dwim(SvnInclude))

下面是你在 index.rst(或其他文件)中需要包含的标记示例:

.. svninclude:: http://svn.domain.com/svn/project

    one.rst
    doc/two.rst

其中路径 one.rstdoc/two.rst 是相对于 Subversion URL 的,比如 http://svn.domain.com/svn/project/one.rst

当然,你需要把 svninclude.py 打包,并确保它安装在你的 Python 路径中。以下是我测试时所做的步骤:

  1. source/conf.pyextensions 列表中添加 'svninclude'
  2. svninclude.py 放在项目根目录。

然后运行:

% PYTHONPATH=. sphinx-build -b html ./source ./build

撰写回答