目录
编写文档
文档过去需要学习 reStructuredText(有时称为 reST / rST),但今天我们有了很棒的 Markdown 文档选择,与 GitHub、维基百科等使用的格式相同。本指南涵盖了 Sphinx,并使用现代 MyST 插件来获得 Markdown 支持。
其他框架
还有其他框架;这些框架通常更简单,但使用频率不高,并且示例和插件相对较少。它们是
- JupyterBook:一个强大的系统,用于使用内部 Sphinx 渲染笔记本集合。也可以用于文档,尽管如此,请参阅 echopype。
- MkDocs:一个基于 Markdown 和 HTML 的全新文档系统。与 Sphinx 相比,对手册页和 PDF 的支持较少,因为它不使用 docutils。拥有超过 200 个插件 - 它们比 Sphinx 更容易编写。示例站点包括 hatch、PDM、cibuildwheel、Textual 和 pipx。
包含内容
理想情况下,软件文档应包括
- 教程简介,帮助新用户(或潜在用户)了解软件的功能并迈出第一步。
- 面向任务的指南,解决特定用途的示例。
- 参考,指定代码库中每个公共对象的详细输入和输出。
- 解释传达对软件为何以及如何以这种方式运行的更深入理解。
Diátaxis 框架
这个整体框架有一个名称,Diátaxis,如果您有兴趣,可以阅读更多相关信息。
手写文档
在您的项目中创建 docs/
目录(即在 src/
旁边)。有一个 sphinx-quickstart 工具,但它会创建不必要的文件(make/bat,我们建议使用跨平台的 noxfile),并使用 rST 而不是 Markdown。相反,这是我们推荐的 conf.py
起点
conf.py
from __future__ import annotations
import importlib.metadata
from typing import Any
project = "package"
copyright = "2024, My Name"
author = "My Name"
version = release = importlib.metadata.version("package")
extensions = [
"myst_parser",
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.mathjax",
"sphinx.ext.napoleon",
"sphinx_autodoc_typehints",
"sphinx_copybutton",
]
source_suffix = [".rst", ".md"]
exclude_patterns = [
"_build",
"**.ipynb_checkpoints",
"Thumbs.db",
".DS_Store",
".env",
".venv",
]
html_theme = "furo"
html_theme_options: dict[str, Any] = {
"footer_icons": [
{
"name": "GitHub",
"url": "https://github.com/org/package",
"html": """
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path>
</svg>
""",
"class": "",
},
],
"source_repository": "https://github.com/org/package",
"source_branch": "main",
"source_directory": "docs/",
}
myst_enable_extensions = [
"colon_fence",
]
intersphinx_mapping = {
"python": ("https://docs.pythonlang.cn/3", None),
}
nitpick_ignore = [
("py:class", "_io.StringIO"),
("py:class", "_io.BytesIO"),
]
always_document_param_types = True
我们首先设置一些配置值,但最值得注意的是,我们从已安装的包版本中获取包版本。我们列出了几个好的扩展
myst_parser
是 Sphinx 的 Markdown 解析引擎。sphinx.ext.autodoc
将帮助我们通过 reStructuredText 和动态分析构建 API 文档。另请参阅包 sphinx-autodoc2,它支持 Markdown 并使用静态分析;不过,它目前可能没有经过充分的测试。sphinx.ext.intersphinx
将交叉链接到其他文档。sphinx.ext.mathjax
允许您包含数学公式。sphinx.ext.napoleon
添加了对多种常见文档样式(如 numpydoc)的支持。sphinx_autodoc_typehints
处理类型提示sphinx_copybutton
在代码片段中添加了一个小的复制按钮。
我们包含了两种可能的文件扩展名。我们也避免了一些常见的文件模式,以防万一。
对于主题,许多科学软件包选择 pydata-sphinx-theme。 Furo 主题 是另一种流行的选择。站点 sphinx-themes.org 可用于比较选项。
我们启用了有用的 MyST 扩展:colon_fence
允许您对指令使用三个冒号,如果指令包含文本而不是三个反引号,则可能更好地突出显示。在 MyST 的文档 中查看更多内置扩展。
Sphinx 的一个关键特性是 intersphinx,它允许文档相互交叉引用。您可以列出您正在使用的其他项目,但一个好的最低限度是至少链接到 CPython 文档。您需要提供 objects.inv
文件的路径,通常位于主要文档 URL。
我们将启用 nitpick 模式,当我们这样做时,如果某些类没有与 intersphinx 链接,它们可能会抱怨。这里列出了几个常见的示例(StringIO/BytesIO 没有指向正确的内容) - 请随意添加/删除。
最后,当我们有静态类型时,我们希望它们始终列在文档字符串中,即使参数尚未记录。您可以查看 sphinx-autodoc-typehints 以获取更多选项。
index.md
您的 index.md
文件可以像这样开始
# package
```{toctree}
:maxdepth: 2
:hidden:
```
```{include} ../README.md
:start-after: <!-- SPHINX-START -->
```
## Indices and tables
- {ref}`genindex`
- {ref}`modindex`
- {ref}`search`
您可以将您的项目名称作为标题。 toctree
指令包含您的目录;您将在该指令内列出您添加的每个新页面。
如果您想插入自述文件,您可以使用上面显示的 include
指令。您不想将自述文件的标题(以及可能您的徽章)添加到您的文档中,因此您可以在自述文件中添加一个表达式(<!-- SPHINX-START -->
上方)以标记您希望文档部分从哪里开始。
您可以在最后添加标准索引和表格。
pyproject.toml 添加
设置 docs
额外内容如下所示
[project.optional-dependencies]
docs = [
"furo",
"myst_parser >=0.13",
"sphinx >=4.0",
"sphinx-copybutton",
"sphinx-autodoc-typehints",
]
虽然还有其他方法可以指定文档,并且您不必将文档需求设为额外内容,但这是一个好主意,因为它强制文档构建始终安装项目,而不是试图仅安装 Sphinx 和插件并尝试对未安装的项目版本进行构建。
.readthedocs.yaml
为了使用 https://readthedocs.org 构建、托管和预览您的文档,您必须有一个 .readthedocs.yaml
文件 RTD100,如下所示
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
version: 2
build:
os: ubuntu-22.04
tools:
python: "3.12"
commands:
- asdf plugin add uv
- asdf install uv latest
- asdf global uv latest
- uv venv
- uv pip install .[docs]
- .venv/bin/python -m sphinx -T -b html -d docs/_build/doctrees -D
language=en docs $READTHEDOCS_OUTPUT/html
这设置了 Read the Docs 配置版本(需要 2) RTD101。
build
表格是指定运行程序的现代方法。您需要一个 os
(现代 Ubuntu 应该没问题) RTD102,一个 tools
表格(我们将使用 Python RTD103,这里支持多种语言)。
添加 sphinx
表格告诉 Read the Docs 启用 Sphinx 集成。MkDocs 也受支持。
最后,我们有一个 python
表格,其中包含一个 install
键来描述如何安装我们的项目。这将启用我们的“docs”额外内容。
noxfile.py 添加
向您的 noxfile.py
添加一个会话以生成文档
@nox.session(reuse_venv=True)
def docs(session: nox.Session) -> None:
"""
Build the docs. Pass --non-interactive to avoid serving. First positional argument is the target directory.
"""
parser = argparse.ArgumentParser()
parser.add_argument(
"-b", dest="builder", default="html", help="Build target (default: html)"
)
parser.add_argument("output", nargs="?", help="Output directory")
args, posargs = parser.parse_known_args(session.posargs)
serve = args.builder == "html" and session.interactive
session.install("-e.[docs]", "sphinx-autobuild")
shared_args = (
"-n", # nitpicky mode
"-T", # full tracebacks
f"-b={args.builder}",
"docs",
args.output or f"docs/_build/{args.builder}",
*posargs,
)
if serve:
session.run("sphinx-autobuild", "--open-browser", *shared_args)
else:
session.run("sphinx-build", "--keep-going", *shared_args)
这只是一个更复杂的 Nox 作业,因为它采用了一些选项(构建和服务的能力,而不仅仅是构建)。第一部分只是设置参数解析,以便我们可以在构建 html
时进行服务。然后它根据参数进行一些条件安装(仅在服务时需要 sphinx-autobuild)。它对您的包进行了可编辑的安装,因此您可以跳过安装步骤并使用 -R
仍然获得更新的文档。
然后有一个专门用于“linkcheck”构建器的处理程序,它只检查链接,并且实际上不生成输出。最后,我们收集一些有用的参数,并运行 autobuild(用于 --serve
)或常规构建。我们本可以添加 python -m http.server
指向已构建的文档,但如果您在服务时更改了文件,autobuild 将重新构建。
API 文档
要构建 API 文档,您需要添加以下 Nox 作业。它将重新运行 sphinx-apidoc
以为您每个公共模块生成 sphinx autodoc 页面。
noxfile.py 添加
@nox.session
def build_api_docs(session: nox.Session) -> None:
"""
Build (regenerate) API docs.
"""
session.install("sphinx")
session.run(
"sphinx-apidoc",
"-o",
"docs/api/",
"--module-first",
"--no-toc",
"--force",
"src/<package-name-here>",
)
您需要将其添加到您的 docs/index.md
中
```{toctree}
:maxdepth: 2
:hidden:
:caption: API
api/<package-name-here>
```
请注意,您的文档字符串仍被解析为 reStructuredText。
文档中的笔记本
您可以将笔记本组合到您的文档中。为此使用的工具是 nbsphinx
。如果您想使用它,请将 nbsphinx
添加到您的文档需求中,将 "nbsphinx"
添加到您的 conf.py
的 extensions =
列表中,并在 conf.py
中添加一些 nbsphinx 选项
nbsphinx_execute = "auto"
nbsphinx_execute_arguments = [
"--InlineBackend.figure_formats={'png2x'}",
"--InlineBackend.rc=figure.dpi=96",
]
nbsphinx_kernel_name = "python3"
您可以将 nbsphinx_execute
设置为 always
、never
或 auto
- auto
仅会执行空笔记本。上面显示的执行参数将从 Matplotlib 生成“视网膜”图像。您可以设置内核名称(确保您可以执行所有(未执行的)笔记本)。
如果您想使用 Markdown 而不是笔记本,您可以使用 jupytext(请参阅 此处)。