将 Jinja2 与 Sphinx 自动摘要结合使用
Using Jinja2 with Sphinx autosummary
我正在尝试使用 sphinx.ext.autosummary 来记录 Python 包。由于 'autosummary' 要求我们列出所有要包含的项目,我想使用 Jinja2 指定这些项目。
我的conf.py如下(相关部分显示):
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.doctest',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinx_automodapi.automodapi'
]
autodoc_default_options = {
'imported-members':True
}
add_module_names = False
autosummary_generate = True
numpydoc_show_class_members = False
def rstjinja(app, docname, source):
"""
Render our pages as a jinja template for fancy templating goodness.
"""
# Make sure we're outputting HTML
if app.builder.format != 'html':
return
src = source[0]
rendered = app.builder.templates.render_string(
src, app.config.html_context
)
source[0] = rendered
def setup(app):
app.connect("source-read", rstjinja)
# in actual usage, `entities` is determined at docs generation time via some code
html_context = {
'entities' : ["classA", "classB", "classD"]
}
方法rstjinja()
和setup()
借鉴自here。它明确指出:
The Jinja templates will be rendered before the RST is processed.
我的.rst文件如下:
#####
Title
#####
.. currentmodule:: Package.SubModule
.. autosummary::
:nosignatures:
:toctree:
{% for item in entities %}
{{ item }}
{% endfor %}
输出正确地向我显示了包含 3 个条目的摘要 table(我指定的三个 classes 中的每一个:"classA"、"classB"、 "classD")。第一列显示 class 的名称,第二列显示单行描述(来自其文档字符串)。第二列中的数据清楚地表明 Sphinx 能够识别相关的 classes 并提取其文档字符串。
我的问题是 'autosummary' 不会为这些 class 生成 存根 ,因此 table 中的这些条目不会可点击。在终端上,我看到每个 class 缺少存根的警告:
WARNING: autosummary: stub file not found
'Package.SubModule.classA'. Check your
autosummary_generate setting.
如我的 conf.py 文件所示,此设置已经 True
。
如果我(为了探索)将 .rst 文件更改为以下内容:
#####
Title
#####
.. currentmodule:: Package.SubModule
.. autosummary::
:nosignatures:
:toctree:
{% for item in entities %}
{{ item }}
{% endfor %}
classA
然后我得到一个类似于前一个案例的 table,但在末尾有一个额外的行对应于 "classA"。有趣的是,"classA" 的两个条目(第一个通过 Jinja 生成,第二个通过明确指定)现在超链接到为 "classA".
创建的存根
为什么会这样?为什么仅通过 Jinja 指定相同的信息时不创建存根(即使 sphinx 确实在 table 中显示了这些的文档字符串)?
我该如何解决这个问题?能够通过 Jinja 提供要记录的实体列表对我来说很重要(因为我通过 conf.py
中的一些 Python 代码确定了这些)。
附加信息:
在上面的示例中,可以通过
导入 classes
from Package.SubModule import classA, classB, classD
我找到了使用 sphinx_automodapi.automodapi 扩展的解决方法。
我的相关位 conf.py
:
import sphinx_automodapi
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinx_automodapi.automodapi'
]
add_module_names = False
autosummary_generate = True
numpydoc_show_class_members = False
def rstjinja(app, docname, source):
"""
Render our pages as a jinja template for fancy templating goodness.
"""
# Make sure we're outputting HTML
if app.builder.format != 'html':
return
src = source[0]
rendered = app.builder.templates.render_string(
src, app.config.html_context
)
source[0] = rendered
def setup(app):
app.connect("source-read", rstjinja)
html_context = {
'entities' : ["classC", "classE"] # NOTE: specify classes NOT to be included/documented; items specified here will be skipped in doc generation
}
注意:通过 html_context
传递的 类 列表是要从文档中 排除 的 类。如果扩展允许直接指定所需的 类 就好了。我已经为相同的(目前未解决)开了一张票(这里:https://github.com/astropy/sphinx-automodapi/issues/92)。
在实际使用中,类的列表是可以动态确定的。例如:
import inspect, importlib, sciunit
package_import_name = "package_name"
submodule = "{}.submodule_name".format(package_import_name)
module = importlib.import_module(submodule)
exlcude_classes = [x[0] for x in inspect.getmembers(module,
lambda member: inspect.isclass(member)
and not(<<specify condition>>))]
html_context = {
'entities' : exlcude_classes
}
我的 .rst 文件示例:
##########
Submodules
##########
.. automodapi:: package_name.submodule_name
:nosignatures:
:no-main-docstr:
:skip: {{ entities|join(', ') }}
我正在尝试使用 sphinx.ext.autosummary 来记录 Python 包。由于 'autosummary' 要求我们列出所有要包含的项目,我想使用 Jinja2 指定这些项目。
我的conf.py如下(相关部分显示):
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.doctest',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinx_automodapi.automodapi'
]
autodoc_default_options = {
'imported-members':True
}
add_module_names = False
autosummary_generate = True
numpydoc_show_class_members = False
def rstjinja(app, docname, source):
"""
Render our pages as a jinja template for fancy templating goodness.
"""
# Make sure we're outputting HTML
if app.builder.format != 'html':
return
src = source[0]
rendered = app.builder.templates.render_string(
src, app.config.html_context
)
source[0] = rendered
def setup(app):
app.connect("source-read", rstjinja)
# in actual usage, `entities` is determined at docs generation time via some code
html_context = {
'entities' : ["classA", "classB", "classD"]
}
方法rstjinja()
和setup()
借鉴自here。它明确指出:
The Jinja templates will be rendered before the RST is processed.
我的.rst文件如下:
#####
Title
#####
.. currentmodule:: Package.SubModule
.. autosummary::
:nosignatures:
:toctree:
{% for item in entities %}
{{ item }}
{% endfor %}
输出正确地向我显示了包含 3 个条目的摘要 table(我指定的三个 classes 中的每一个:"classA"、"classB"、 "classD")。第一列显示 class 的名称,第二列显示单行描述(来自其文档字符串)。第二列中的数据清楚地表明 Sphinx 能够识别相关的 classes 并提取其文档字符串。
我的问题是 'autosummary' 不会为这些 class 生成 存根 ,因此 table 中的这些条目不会可点击。在终端上,我看到每个 class 缺少存根的警告:
WARNING: autosummary: stub file not found 'Package.SubModule.classA'. Check your autosummary_generate setting.
如我的 conf.py 文件所示,此设置已经 True
。
如果我(为了探索)将 .rst 文件更改为以下内容:
#####
Title
#####
.. currentmodule:: Package.SubModule
.. autosummary::
:nosignatures:
:toctree:
{% for item in entities %}
{{ item }}
{% endfor %}
classA
然后我得到一个类似于前一个案例的 table,但在末尾有一个额外的行对应于 "classA"。有趣的是,"classA" 的两个条目(第一个通过 Jinja 生成,第二个通过明确指定)现在超链接到为 "classA".
创建的存根为什么会这样?为什么仅通过 Jinja 指定相同的信息时不创建存根(即使 sphinx 确实在 table 中显示了这些的文档字符串)?
我该如何解决这个问题?能够通过 Jinja 提供要记录的实体列表对我来说很重要(因为我通过 conf.py
中的一些 Python 代码确定了这些)。
附加信息: 在上面的示例中,可以通过
导入 classesfrom Package.SubModule import classA, classB, classD
我找到了使用 sphinx_automodapi.automodapi 扩展的解决方法。
我的相关位 conf.py
:
import sphinx_automodapi
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinx_automodapi.automodapi'
]
add_module_names = False
autosummary_generate = True
numpydoc_show_class_members = False
def rstjinja(app, docname, source):
"""
Render our pages as a jinja template for fancy templating goodness.
"""
# Make sure we're outputting HTML
if app.builder.format != 'html':
return
src = source[0]
rendered = app.builder.templates.render_string(
src, app.config.html_context
)
source[0] = rendered
def setup(app):
app.connect("source-read", rstjinja)
html_context = {
'entities' : ["classC", "classE"] # NOTE: specify classes NOT to be included/documented; items specified here will be skipped in doc generation
}
注意:通过 html_context
传递的 类 列表是要从文档中 排除 的 类。如果扩展允许直接指定所需的 类 就好了。我已经为相同的(目前未解决)开了一张票(这里:https://github.com/astropy/sphinx-automodapi/issues/92)。
在实际使用中,类的列表是可以动态确定的。例如:
import inspect, importlib, sciunit
package_import_name = "package_name"
submodule = "{}.submodule_name".format(package_import_name)
module = importlib.import_module(submodule)
exlcude_classes = [x[0] for x in inspect.getmembers(module,
lambda member: inspect.isclass(member)
and not(<<specify condition>>))]
html_context = {
'entities' : exlcude_classes
}
我的 .rst 文件示例:
##########
Submodules
##########
.. automodapi:: package_name.submodule_name
:nosignatures:
:no-main-docstr:
:skip: {{ entities|join(', ') }}