Sphinx 中的条件目录树 [英] Conditional toctree in Sphinx

查看:20
本文介绍了Sphinx 中的条件目录树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做一个文档的多个版本,这些版本在包含的部分中有所不同.为了实现这一点,我通常会使用 only 指令或 ifconfig 扩展.但是,我不能将其中任何一个与 toctree 指令结合使用.p>

我基本上想要的是这样的:

.. toctree:::最大深度:2介绍字符串数据类型数字.. 只有:: 大学复杂的

有没有办法做到这一点?

解决方案

如果你有目录层次结构,我之前的答案会失败,所以我写了一个简单的 toctree-filt 指令,它能够过滤基于条目前缀的条目.例如,给定一个 toctree-filt 指令,如

.. toctree-filt:::最大深度:1用户手册:internal:supervisor-api:draft:new-feature:erik:erik-mathsapi

并将排除列表设置为 ['draft','erik'] 将导致看起来像这样的有效目录树

.. toctree-filt:::最大深度:1用户手册主管APIapi

将以下行添加到您的 conf.py:

sys.path.append(os.path.abspath('../sphinx-ext/'))扩展 = ['toctree_filter']toc_filter_exclude = ['草稿','erik']

将以下代码放入 /source 目录旁边的 /sphinx_ext 中:

import re从 sphinx.directives.other 导入 TocTree默认设置(应用程序):app.add_config_value('toc_filter_exclude', [], 'html')app.add_directive('toctree-filt', TocTreeFilt)返回{'版本':'1.0.0'}TocTreeFilt 类(TocTree):"""通知 Sphinx 有关文档层次结构的指令,并在当前文档中包含一个目录,如树.这version 根据前缀列表过滤条目.我们只是过滤指令的内容并调用超级版本的运行.这排除列表存储在 **toc_filter_exclusion** 列表中.任何以这些字符串之一为前缀的目录条目将被排除.如果 `toc_filter_exclusion=['secret','draft']` 那么所有 toc 条目形式 `:secret:ultra-api` 或 `:draft:new-features` 将被排除在外最后的目录.始终包含不带前缀的条目."""hasPat = re.compile('^s*:(.+):(.+)$')# 删除内容中我们不想要的任何条目并剥离# 去掉我们想要但显然不想要的任何过滤器前缀# 前缀混淆文件名.def filter_entries(自我,条目):excl = self.state.document.settings.env.config.toc_filter_exclude过滤= []对于条目中的 e:m = self.hasPat.match(e)如果 m != 无:如果不是 m.groups()[0],则不包括:过滤的.append(m.groups()[1])别的:过滤的.append(e)返回过滤定义运行(自我):# 删除所有不应显示的 TOC 条目self.content = self.filter_entries(self.content)返回 super().run()

现在只需将现有的 toctree 指令更改为 toctree-filt 即可.请注意,Sphinx 会发布错误,因为它会查找文档中未包含的文件.不知道如何解决.

I want to do multiple versions of a documentation, which differ in the sections that are included. To achieve this I would usually use either the only directive or the ifconfig extension. However, I cannot use any of those in combination with the toctree directive.

What I basically want is something like this:

.. toctree::
   :maxdepth: 2

   intro
   strings
   datatypes
   numeric
   .. only:: university
      complex

Is there a way to do that?

解决方案

My previous answer fails if you have hierarchies of table of contents so I wrote a simple toctree-filt directive that is able to filter entries based on a prefix to the entry. For example, given a toctree-filt directive like

.. toctree-filt::
   :maxdepth: 1

   user-manual
   :internal:supervisor-api
   :draft:new-feature
   :erik:erik-maths
   api

and setting the exclusion list to ['draft','erik'] will result in an effective toctree that looks like

.. toctree-filt::
   :maxdepth: 1

   user-manual
   supervisor-api
   api

Add the following lines to your conf.py:

sys.path.append(os.path.abspath('../sphinx-ext/'))
extensions = ['toctree_filter']
toc_filter_exclude = ['draft','erik']

Put the following code in /sphinx_ext next to your /source directory:

import re
from sphinx.directives.other import TocTree


def setup(app):
    app.add_config_value('toc_filter_exclude', [], 'html')
    app.add_directive('toctree-filt', TocTreeFilt)
    return {'version': '1.0.0'}

class TocTreeFilt(TocTree):
    """
    Directive to notify Sphinx about the hierarchical structure of the docs,
    and to include a table-of-contents like tree in the current document. This
    version filters the entries based on a list of prefixes. We simply filter
    the content of the directive and call the super's version of run. The
    list of exclusions is stored in the **toc_filter_exclusion** list. Any
    table of content entry prefixed by one of these strings will be excluded.
    If `toc_filter_exclusion=['secret','draft']` then all toc entries of the
    form `:secret:ultra-api` or `:draft:new-features` will be excuded from
    the final table of contents. Entries without a prefix are always included.
    """
    hasPat = re.compile('^s*:(.+):(.+)$')

    # Remove any entries in the content that we dont want and strip
    # out any filter prefixes that we want but obviously don't want the
    # prefix to mess up the file name.
    def filter_entries(self, entries):
        excl = self.state.document.settings.env.config.toc_filter_exclude
        filtered = []
        for e in entries:
            m = self.hasPat.match(e)
            if m != None:
                if not m.groups()[0] in excl:
                    filtered.append(m.groups()[1])
            else:
                filtered.append(e)
        return filtered

    def run(self):
        # Remove all TOC entries that should not be on display
        self.content = self.filter_entries(self.content)
        return super().run()

Now just change your existing toctree directives to toctree-filt and you are good to roll. Note that Sphinx will post errors because it will find files that are not included in the document. Not sure how to fix that.

这篇关于Sphinx 中的条件目录树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆