我想做一个文档的多个版本,它们在包含的部分中有所不同。为了实现这一点,我通常会使用only指令或ifconfig扩展。但是,我不能将其中任何一个与toctree指令结合使用。
我基本上想要的是这样的:
.. toctree::
:maxdepth: 2
intro
strings
datatypes
numeric
.. only:: university
complex
有没有办法做到这一点?
如果您有目录层次结构,我之前的答案将失败,因此我编写了一个简单的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 会发布错误,因为它会查找文档中未包含的文件。不知道如何解决。
一个非常简单的解决方案是维护两个不同名称的独立索引文件。您可以指定默认使用哪个索引文件,并在命令行上conf.py
使用特殊构建覆盖它。-D master_doc=alternate-index
sphinx-build
据我所知,没有办法做你想做的事。我一直在努力解决同样的问题,请参阅https://github.com/sphinx-doc/sphinx/issues/1717。
原因是 Sphinx 将目录树节点中包含的所有行都作为纯文本处理。
我看到两种选择:
您可以扩展目录树,包括一个包含要评估的表达式的选项
.. toctree:
:condition: expression
file1
然后你自定义 doctree resolve 事件。
您可以在定义您自己的标签的原始文本上使用文本替换。您可以为源读取事件实现事件处理程序。例如$$condition$$
可以包含要评估的条件,而$$$
块的结尾,即
.. toctree:
file1
$$mycondition$$
file2
$$$
根据mycondition
,您可以删除以下块行。
数字 3 很简单,而对我来说,数字 2 是最优雅的。
我的解决方案是将条件内容放在单独的目录“实习生”中并使用标签“内部”。
在 conf.py 我添加了这些行
if tags.has('internal'):
exclude_patters = ['_build']
else:
exclude_patterns = ['_build', 'intern*']
现在,当我在命令行上传递“内部”标志时,我得到了所有信息,否则除了实习生目录中的内容之外的所有内容。
标签 internal 只能与 with 结合使用。
ToC 包含对实习生/somedoc 的引用,并且根据需要包含或跳过它们。我确实收到了许多有关丢失页面的警告,但可以将其静音。