10

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

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

.. toctree::
   :maxdepth: 2

   intro
   strings
   datatypes
   numeric
   .. only:: university
      complex

有没有办法做到这一点?

4

4 回答 4

6

如果您有目录层次结构,我之前的答案将失败,因此我编写了一个简单的toctree-filt指令,该指令能够根据条目的前缀过滤条目。例如,给定一个toctree-filt指令,如

.. toctree-filt::
   :maxdepth: 1

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

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

.. 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为即可。请注意,Sphinx 会发布错误,因为它会查找文档中未包含的文件。不知道如何解决。

于 2017-10-06T07:01:11.460 回答
4

一个非常简单的解决方案是维护两个不同名称的独立索引文件。您可以指定默认使用哪个索引文件,并在命令行上conf.py使用特殊构建覆盖它。-D master_doc=alternate-indexsphinx-build

于 2017-03-09T07:29:27.800 回答
3

据我所知,没有办法做你想做的事。我一直在努力解决同样的问题,请参阅https://github.com/sphinx-doc/sphinx/issues/1717

原因是 Sphinx 将目录树节点中包含的所有行都作为纯文本处理。

我看到两种选择:

  1. 您可以编写自己的 toctree 指令;
  2. 您可以扩展目录树,包括一个包含要评估的表达式的选项

    .. toctree:
       :condition: expression
    
       file1
    

然后你自定义 doctree resolve 事件。

  1. 您可以在定义您自己的标签的原始文本上使用文本替换。您可以为源读取事件实现事件处理程序。例如$$condition$$可以包含要评估的条件,而$$$块的结尾,即

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

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

数字 3 很简单,而对我来说,数字 2 是最优雅的。

于 2015-03-10T21:01:57.787 回答
3

我的解决方案是将条件内容放在单独的目录“实习生”中并使用标签“内部”。

在 conf.py 我添加了这些行

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

现在,当我在命令行上传递“内部”标志时,我得到了所有信息,否则除了实习生目录中的内容之外的所有内容。

标签 internal 只能与 with 结合使用。

ToC 包含对实习生/somedoc 的引用,并且根据需要包含或跳过它们。我确实收到了许多有关丢失页面的警告,但可以将其静音。

于 2017-01-11T12:32:55.777 回答