将外部文档包含到 Sphinx 项目中

发布于 2024-11-08 18:32:37 字数 201 浏览 3 评论 0原文

我们在 SVN 中使用 Sphinx 维护了相当大的文档。

作为生成输出的一部分,我们希望包含相关 Python 模块的发行说明作为主要内容(而不是超链接!)。外部模块的发行说明也在 SVN 中维护。是否有一些类似 Sphinx 的方法可以从其他(SVN)来源获取部分文档?好吧,使用 SVN 外部是解决问题的一种方法,但也许不是最明智的方法......还有更好的选择吗?

We maintain a fairly large documentation using Sphinx in SVN.

As part of the generated output we would like to include the release notes of related Python modules as primary content (not as hyperlink!). The release notes of the external modules are also maintained in SVN. Is there some Sphinx-ish way to pull in the parts of the documentation from other (SVN) sources? Ok, using SVN externals is a way to solve the problem but perhaps not the smartest way...any better options?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

給妳壹絲溫柔 2024-11-15 18:32:37

我能想到的两个选项是:

  1. 将 svn:externals 链接添加到远程项目(您已经了解)。
  2. 使用自定义指令扩展 Sphinx 以包含来自远程 subversion 存储库的文件。

我不是 Sphinx 内部的专家,但能够拼凑出一个快速扩展,该扩展嵌入来自远程颠覆存储库的文件。

该扩展添加了一个 svninclude 指令,该指令采用 1 个参数,即您的文档所在存储库的 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/项目/one.rst

您当然希望打包 svninclude.py 并将其安装在您的 Python 路径中。以下是我对其进行的测试:

  1. 'svninclude' 添加到 source/conf.py 中的 extensions 列表。
  2. 将 svninclude.py 放置在项目根目录中。

然后跑:

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

The two options I can think of are:

  1. Add an svn:externals link to the remote project (which you already know about).
  2. Extend Sphinx with a custom directive to include files from remote subversion repositories.

I'm no expert on Sphinx internals but was able to cobble together a quick extension which embeds files from a remote subversion repository.

The extension adds an svninclude directive which takes 1 argument, the url of the repository where your docs are located. It checks this repository out into a temp directory _svncache located in the project root, and then proceeds to read the contents of each file and insert them into the parser's state machine.

Here is the code for the svninclude.py extension. It is oversimplified and has no error checking at the moment. If you plan to implement this let me know and I can provide some additional tips if you get stuck:

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))

Here is an example of the markup you'd include in your index.rst (or other file):

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

    one.rst
    doc/two.rst

Where the paths one.rst and doc/two.rst are relative to the subversion url, for example http://svn.domain.com/svn/project/one.rst.

You'd of course want to package up the svninclude.py and get it installed in your Python path. Here's what I did to test it:

  1. Added 'svninclude' to the extensions list in source/conf.py.
  2. Placed svninclude.py in the project root.

Then ran:

% PYTHONPATH=. sphinx-build -b html ./source ./build
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文