在狮身人面像条件toctree(Conditional toctree in Sphinx)

2019-07-20 07:21发布

我想做一个文件的多个版本,其在所包含的部分不同。 为了实现这一点,我通常会请使用唯一指令或使用ifconfig扩展。 但是,我不能结合使用任何这些toctree指令。

我想基本上是这样的:

.. toctree::
   :maxdepth: 2

   intro
   strings
   datatypes
   numeric
   .. only:: university
      complex

有没有办法做到这一点?

Answer 1:

据我所知是没有办法做你想要什么。 我一直在用同样的问题挣扎,看到https://github.com/sphinx-doc/sphinx/issues/1717 。

其原因是,包含在作为纯文本toctree节点斯芬克斯过程的所有行。

我看到了两个备选方案:

  1. 您可以编写自己的toctree指令;
  2. 可以延长toctree包括包含要计算的表达式的一个选项

     .. toctree: :condition: expression file1 

然后你定制doctree解决事件。

  1. 您可以在原始文本定义自己的标签使用的文本替换。 你可以这样做实现了源读取事件的事件处理程序。 例如$$condition$$可能包含的条件进行评估,而$$$块的端部,即

     .. toctree: file1 $$mycondition$$ file2 $$$ 

根据mycondition ,您可以删除以下块行。

3号是相当简单的,而对我来说,2是最优雅的。



Answer 2:

我的解决办法是在一个单独的目录“实习生”,并用标签“内部”有条件的内容中投放。

在conf.py我增加了线条

if tags.has('internal'):
    exclude_patters = ['_build']
else:
    exclude_patterns = ['_build', 'intern*']

现在,当我通过在命令行中我得到的所有的“内部”标志,否则一切都只是在实习生目录中的内容。

标签内部可组合使用只。

TOC的包含实习生/ somedoc的标记,包括或需要跳过。 我得到一个关于失踪页数警告,但这些可以沉默。



Answer 3:

如果你有目录的层次,所以我写了一个简单的我以前的答案失败toctree-filt指令,能够根据前缀条目可以过滤条目。 例如,给定一个toctree-filt指令一样

.. toctree-filt::
   :maxdepth: 1

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

和排除列表设置为['draft','erik']将导致看起来像一个有效toctree

.. toctree-filt::
   :maxdepth: 1

   user-manual
   supervisor-api
   api

添加以下行到你的conf.py

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

将下面的代码/sphinx_ext旁边的/source目录:

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

现在,只需要改变现有的toctree指令来toctree-filt ,你是好滚。 需要注意的是狮身人面像将发布错误,因为它会发现,不包含在文档中的文件。 不知道如何解决这个问题。



Answer 4:

一个非常简单的解决方案是维护不同的名字两个单独的索引文件。 可以指定默认情况下使用哪个索引文件conf.py和覆盖它使用一种特殊的构建-D master_doc=alternate-index的上sphinx-build命令行。



文章来源: Conditional toctree in Sphinx