Sphinx reStructuredText 语法入门

本文是一篇符合 MegEngine 文档特色的 《Sphinx reStructuredText 》 入门教程,同时也请文档内容的编写人员遵循其中的各项规范。除了这篇供初学者入门的教程以外, 《reStructuredText User Documentation 》 也是一份比较权威的文档,本页面中的所有 参考 链接已经指向了权威文档中对应的部分。

注解

注解

警告

这些指令和自己的可选参数之间不能存在空行,但和被渲染的内容之间必须有空行。

缩进(Indentation)

警告

  • reST 语法要求使用 3 格缩进(有的是 2 格),错误的缩进将导致无法正确渲染样式。

  • 如果在 Sphinx reST 内使用代码块,其缩进要求不受影响(如 Python)。

对于不同的编辑器,都有着对应的调整缩进宽度的办法(以 Vim 为例子):

:set shiftwidth=3
:set autoindent
:set smartindent
:20, 37 >

上面的命令可以快速对 20 至 37 行的内容进行向右缩进。

章节(Sections)

通过使用标点符号对节标题加下划线(并可选地对它们进行加上划线)来创建节标题(参考 ),

MegEngine 采用如下的章节结构语法规范:

========
一级标题
========

二级标题
--------

三级标题
~~~~~~~~

警告

  • 标记符必须与文本长度一致,否则会导致 Warning (无法通过 CI)。

  • 你可以采用更深的嵌套级别,但在文档中应当避免出现四级甚至更深的标题。

正确示范

========
一级标题
========

错误示范

======================
一级标题
======================

段落(Paragraphs)

段落(参考 )即一个或多个空白行分隔的文本块,是 reST 文档中最基本的部分。 缩进在 reST 语法中很重要(与 Python 一样),因此同一段落的所有行都必须左对齐到相同的缩进级别。

没有空行的情况

第一部分,
第二部分。

第一部分,第二部分。

存在空行的情况

第一部分,

第二部分。

第一部分,

第二部分。

保留换行特性

行块(参考 )是保留换行符的一种方法:

| 第一部分,
| 第二部分。
第一部分,
第二部分。

内联标记(Inline markup)

包裹使用,标准的 reST 内联标记用法十分简单:

单个星号表示 <em>
*HTML 着重元素 (<em>) 标记出需要用户着重阅读的内容*

HTML 着重元素 (<em>) 标记出需要用户着重阅读的内容

两个星号表示 <strong>
**Strong 元素 (<strong>)表示文本十分重要,一般用粗体显示。**

Strong 元素 (<strong>)表示文本十分重要,一般用粗体显示。

单个反引号表示 <cite>
`HTML引用( Citation)标签 (<cite>) 表示一个作品的引用,且必须包含作品的标题。`

HTML引用( Citation)标签 (<cite>) 表示一个作品的引用,且必须包含作品的标题。

两个反引号表示 <pre>
``HTML <pre> 元素表示预定义格式文本``

HTML <pre> 元素表示预定义格式文本

列表(List)

警告

列表语法是最容易被用错的地方,在文档中也极为常见。

定义列表

定义列表(参考 )在 API 文档很常见,使用方法如下:

术语 (限定在一行文本)
   术语的定义,必须使用缩进。

   支持使用多个段落。

下一个术语
   下一个术语对应的定义。
术语 (限定在一行文本)

术语的定义,必须使用缩进。

支持使用多个段落。

下一个术语

下一个术语对应的定义。

无序列表

无序列表(参考 )的用法很自然。 只需要在段落开头放置星号,然后正确地缩进:

正确的示范(2 格缩进)

* 这是一个无序列表。
* 它有两个元素,
  第二个元素占据两行源码,视作同一个段落。
  • 这是一个无序列表。

  • 它有两个元素, 第二个元素占据两行源码,视作同一个段落。

错误的示范(4 格缩进)

* 这是一个无序列表。
* 它有两个元素,
    第二个元素被解析成定义列表。
  • 这是一个无序列表。

  • 它有两个元素,

    第二个元素被解析成定义列表。

有序列表

对于有序列表,可以自己编号,也可以使用 # 来自动编号:

1. 这是一个有序列表。
2. 它也有两个元素。
  1. 这是一个有序列表。

  2. 它也有两个元素。

#. 这又是一个有序列表。
#. 但是它能够自动编号~
  1. 这又是一个有序列表。

  2. 但是它能够自动编号~

嵌套列表

嵌套列表必须使用空白行和父列表项目隔开:

正确示范

* 这是一个列表。

  * 它嵌套了一个子列表,
  * 并且有自己的子元素。

* 这里是父列表的后续元素。
  • 这是一个列表。

    • 它嵌套了一个子列表,

    • 并且有自己的子元素。

  • 这里是父列表的后续元素。

错误示范

* 这并不是嵌套列表,
  * 前面三行被看作是同一个元素,
  * 其中星号被解析成普通的文本。
* 这是列表的第二个元素。
  • 这并不是嵌套列表, * 前面三行被看作是同一个元素, * 其中星号被解析成普通的文本。

  • 这是列表的第二个元素。

表格(Tables)

网格表

对于网格表(参考 ),必须手动“画”出单元格:

+------------------------+------------+----------+----------+
| Header row, column 1   | Header 2   | Header 3 | Header 4 |
| (header rows optional) |            |          |          |
+========================+============+==========+==========+
| body row 1, column 1   | column 2   | column 3 | column 4 |
+------------------------+------------+----------+----------+
| body row 2             | ...        | ...      |          |
+------------------------+------------+----------+----------+

Header row, column 1 (header rows optional)

Header 2

Header 3

Header 4

body row 1, column 1

column 2

column 3

column 4

body row 2

简单表

简单表(参考 )写起来很简单,但有局限性: 它们必须包含多个行,并且第一列单元格不能包含多行。

=====  =====  =======
A      B      A and B
=====  =====  =======
False  False  False
True   False  False
False  True   False
True   True   True
=====  =====  =======

A

B

A and B

False

False

False

True

False

False

False

True

False

True

True

True

CSV 表

CSV 表格可以根据 CSV(逗号分隔值)数据创建表。

.. csv-table:: Frozen Delights!
   :header: "Treat", "Quantity", "Description"
   :widths: 15, 10, 30

   "Albatross", 2.99, "On a stick!"
   "Crunchy Frog", 1.49, "If we took the bones out,
   it wouldn't becrunchy, now would it?"
   "Gannet Ripple", 1.99, "On a stick!"
Frozen Delights!

Treat

Quantity

Description

Albatross

2.99

On a stick!

Crunchy Frog

1.49

If we took the bones out, it wouldn’t becrunchy, now would it?

Gannet Ripple

1.99

On a stick!

List 表

List 表可以根据两级无序列表来生成表格:

.. list-table:: Frozen Delights!
   :widths: 15 10 30
   :header-rows: 1

   * - Treat
     - Quantity
     - Description
   * - Albatross
     - 2.99
     - On a stick!
   * - Crunchy Frog
     - 1.49
     - If we took the bones out, it wouldn't be
       crunchy, now would it?
   * - Gannet Ripple
     - 1.99
     - On a stick!
Frozen Delights!

Treat

Quantity

Description

Albatross

2.99

On a stick!

Crunchy Frog

1.49

If we took the bones out, it wouldn’t be crunchy, now would it?

Gannet Ripple

1.99

On a stick!

图片(Images)

reST 支持图像指令,用法如下:

.. image:: gnu.png
   :height: 100px (length)
   :width: 200px (length or percentage of the current line width)
   :scale: integer percentage (the "%" symbol is optional)
   :alt: alternate text
   :align: "top", "middle", "bottom", "left", "center", or "right"
   :target: text (URI or reference name)

当在 Sphinx 中使用时,给定的文件名(在此处为 ``gnu.png`` )必须相对于源文件。

警告

  • MegEngine 文档中所使用的图片请统一放置在 source/_static/images 目录内。 绝对不允许 直接将图片放在和文本文件相同的文件夹内,这样虽然方便了写作时进行引用, 但却给整个文档的维护引入了技术债务,将形成潜在的风险。

  • 一般情况下请优先使用 SVG 格式的矢量图,使用位图请权衡好图片体积和清晰度。

  • 尽可能使用 GraphvizMermaid 语法绘制示意图。

  • 图片文件名需要有相应的语义信息,不可使用完全随机生成的字符。

注解

如果你想要给图片添加描述性文字,请使用 figure 代替 image, 接着使用 :caption: text 作为传入的参数,其它参数用法一致。

交叉引用(Cross-reference)

使用 :role:`target` 语法,就会创造一个 role 类型的指向 target 的链接。

  • 最常见的使用情景是文档内部页面的相互引用(尤其是引用 API 参考内容时)。

  • 显示的链接文本会和 target 一致, 你也可以使用 :role:`title <target>` 来将链接文本指定为 title

通过 ref 进行引用

为了支持对任意位置的交叉引用,使用了标准的 reST 标签(标签名称在整个文档中必须唯一)。

可以通过两种方式引用标签:

  • 在章节标题之前放置一个标签,引用时则可以使用 :ref:`label-name` , 比如:

    .. _my-reference-label:
    
    Section to cross-reference
    --------------------------
    
    This is the text of the section.
    
    It refers to the section itself, see :ref:`my-reference-label`.
    

    这种方法将自动获取章节标题作为链接文本,且对图片和表格也一样有效。

  • 如果标签没有放在标题之前,则需要使用 :ref:`Link title <label-name>` 来指定名称。

交叉引用 Python 对象

MegEngine 文档按照 Sphinx Python Domain 组织好了 Python API 页面,通常这些信息由 Sphinx 的 autodoc 插件从 MegEngine Python 接口源码的 docstring 处获得并自动生成。不同的 Python API 的 docstring 之间可以交叉引用,其它类型的文档也可以借此快速跳转到 API 页面。

注解

你可以在 MegEngine 的用户指南文档源码中找到非常多的使用参考。

如果找到匹配的标识符,则会自动生成对应的超链接:

  • :py:mod: 引用一个模块(Module);可以使用点名。也适用于包(Package)。

  • :py:func: 引用一个 Python 函数;可以使用点名。可不添加括号以增强可读性。

  • :py:data: 引用模块级变量。

  • :py:const: 引用一个 “已定义的” 常量。

  • :py:class: 引用一个类(Class);可以使用点名。

  • :py:meth: 引用一个对象的方法(Method);可以使用点名。

  • :py:attr: 引用一个对象的特性(Attribute),也适用于属性(Property)。

  • :py:exc: 引用一个异常(Exception);可以使用点名。

  • :py:obj: 引用未指定类型的对象。

默认情况下,将在 当前的模块 中进行搜索。

.. currentmodule:: megengine.functional

比如 :py:func:`add` 可以指向当前 funtional 模块内名为 add 的一个函数或者 Python Built-in 的函数。 如果使用 :py:func:`functional.add` 则可以明确指向到 functional 模块中的 add 函数。

如果使用前缀 ~ , 链接文本将会只显示 target 的最后一部分。 例如 :py:func:`~megengine.functional.add` 将会指向 megengine.functional.add 但显示为 add .

如果使用 . 点名,在没有找到完全匹配的内容时,会将点名作为后缀, 并开始搜索和匹配带有该后缀的所有对象的名称(即使匹配到的结果不在当前模块)。 例如在已知当前模块为 data 时,使用 :py:func:`.functional.add` 会找到 functional.add . 我们也可以结合使用 ~. , 如 :py:func:`~.functional.add` 将只显示 add .

警告

MegEngine 文档列举出的 Python API 通常是最短调用路径。 比如 add 的实际路径是 megengine.functional.elemwise.add , 但在文档中能够搜索到的路径只有 megengine.functional.add . 因此在引用时应当使用 :py:func:`~.functional.add` 而不是 :py:func:`~.functional.elemwise.add` (后者会因为匹配失败而无法生成超链接)。

警告

对于 Conv2d 这种存在多个前缀的 API, 请补全部分前缀以防止冲突,比如 :py:class:`.module.Conv2d`.

交叉引用 C++ 对象

与 Python API 的交叉引用方法类似,语法形如:

指向 :cpp:class:`lite::Tensor` 的 API 文档。

指向 lite::Tensor 的 API 文档。

脚注(Footnotes)

脚注(参考 )使用 [#name]_ 来标记脚注的位置,并在 Footnotes 专栏(rubic)后显示,例如:

Lorem ipsum [1]_ dolor sit amet ... [2]_

.. rubric:: Footnotes

.. [1] Text of the first footnote.
.. [2] Text of the second footnote.

Lorem ipsum 1 dolor sit amet … 2

Footnotes

1

Text of the first footnote.

2

Text of the second footnote.

你可以显式使用 [1]_ 来编号,否则使用 [#]_ 进行自动编号。

引用(Citation)

引用和脚注类似,但不需要进行编号,且全局可用:

Lorem ipsum [Ref]_ dolor sit amet.

.. [Ref] Book or article reference, URL or whatever.

Lorem ipsum [Ref] dolor sit amet.

Ref

Book or article reference, URL or whatever.

数学公式(Math)

只需要使用类似的语法:

Since Pythagoras, we know that :math:`a^2 + b^2 = c^2`.

Sphinx 拓展指令

警告

以下语法非原生 ReStructuredText 语法,需要通过 Sphinx 进行支持。

.. toctree::

Table of contents tree. 用于组织文档结构。

.. note::

用于添加提示性信息,用户忽视这些信息可能出错。

.. warning::

用于添加警告性信息,用户忽视这些信息一定出错。

.. versionadded:: version

描述 API 添加版本,如果用于单个模块, 则必须放在显式文本内容顶部。

.. versionchanged:: version

描述 API 变更版本,指出以何种方式(新参数)进行了更改以及可能的副作用。

.. deprecated:: version

描述 API 弃用版本,简要地告知替代使用方式。

.. seealso::

包括对模块文档或外部文档的引用列表,内容应该是一个 reST 定义列表,比如:

.. seealso::

Module :py:mod:`zipfile`
   Documentation of the :py:mod:`zipfile` standard module.

`GNU tar manual, Basic Tar Format <http://link>`_
   Documentation for tar archive files, including GNU tar extensions.

也可以使用简略写法,如下所示:

.. seealso:: modules :py:mod:`zipfile`, :py:mod:`tarfile`
.. rubric:: title

用于创建一个不会产生导航锚点的标题。

.. centered::

创建居中文本

.. math::

LaTeX 标记的数学公式,相较于 :math: 语法提供了更干净的阅读空间。

.. math::

 (a + b)^2 = a^2 + 2ab + b^2

 (a - b)^2 = a^2 - 2ab + b^2
\[ \begin{align}\begin{aligned}(a + b)^2 = a^2 + 2ab + b^2\\(a - b)^2 = a^2 - 2ab + b^2\end{aligned}\end{align} \]

警告

用于 Python 文档字符串中时,必须将所有反斜杠加倍,或者使用 Python 原始字符串 r"raw".

.. highlight:: language

使用指定语言(Pygments 支持)的语法高亮,直到再次被定义。

.. code-block:: [language]

展示代码块,如果未设置 language, highlight_language 将被使用。

注解

想要了解完整的指令和配置项,请访问 Directives 页面。

Sphinx 插件语法

注解

下面的语法通过 Sphinx Extensions 支持,同样可以用于 Python 文档字符串。

Bibtex 语法支持

文档已经通过 sphinxcontrib-bibtex 插件支持 Bibtex 语法。

Graphviz 语法支持

文档已经通过 sphinx.ext.graphviz 插件支持 Graphviz 语法,样例如下:

.. graphviz::

   digraph foo {
      "bar" -> "baz";
   }
digraph foo {
   "bar" -> "baz";
}

Mermaid 语法支持

文档已经通过 sphinxcontrib-mermaid 插件支持 Mermaid 语法,样例如下:

.. mermaid::

   sequenceDiagram
      participant Alice
      participant Bob
      Alice->John: Hello John, how are you?
      loop Healthcheck
          John->John: Fight against hypochondria
      end
      Note right of John: Rational thoughts <br/>prevail...
      John-->Alice: Great!
      John->Bob: How about you?
      Bob-->John: Jolly good!
sequenceDiagram participant Alice participant Bob Alice->John: Hello John, how are you? loop Healthcheck John->John: Fight against hypochondria end Note right of John: Rational thoughts <br/>prevail... John-->Alice: Great! John->Bob: How about you? Bob-->John: Jolly good!

Toggle 语法支持

文档已经通过 sphinx-togglebutton 插件支持常见 Toggle 功能,样例如下:

.. admonition:: Here's my title
   :class: dropdown, warning

   My note

以上展示的为基础用法,更多用法请参考文档。

Pannels 语法支持

文档已经通过 sphinx-panels 插件支持常见 Pannels 功能,样例如下:

.. panels::
   :container: container-lg pb-3
   :column: col-lg-4 col-md-4 col-sm-6 col-xs-12 p-2

   panel1
   ---
   panel2
   ---
   panel3
   ---
   :column: col-lg-12 p-2
   panel4

panel1

panel2

panel3

panel4

以上展示的为 Grid Layout 用法,Card Layout, Image Caps 等用法请参考文档。

注解

该插件也实现了 Toggle, Tabs 语法功能。

Tabs 语法支持

文档已经通过 sphinx-tabs 插件支持常见 Tabs 功能,样例如下:

.. tabs::

   .. tab:: Apples

      Apples are green, or sometimes red.

   .. tab:: Pears

      Pears are green.

   .. tab:: Oranges

      Oranges are orange.

Apples are green, or sometimes red.

以上展示的为 Basic 用法,Nested / Group / Code Tabs 用法请参考文档。

GitHub URL 缩写

为了方面写文档时引用 GitHub 上的源代码,支持如下语法:

* :src:`imperative/python/megengine/`
* :docs:`source/conf.py`
* :issue:`142`
* :pr:`148`

该功能通过 sphinx.ext.extlinks 插件支持。