开发一个 “Hello world” 扩展

本教程的目标是创建一个添加新指令的基本扩展.该指令将输出一个包含“hello world”的段落.

本教程仅提供基本信息.有关更多信息,请参阅 other tutorials,其中包含更多详细信息.

警告

对于此扩展,您需要对 docutils 和 Python 有一些基本的了解.

概述

我们希望扩展程序将以下内容添加到Sphinx中:

  • 一个 helloworld 指令,它将简单地输出文本 “hello world”.

预备条件

我们不会通过 PyPI 分发这个插件,而是将其作为现有项目的一部分包含在内.这意味着您将需要使用现有项目或使用 sphinx-quickstart 创建一个新项目.

我们假设您使用单独的源(source)和build(build)文件夹.您的扩展文件可以位于项目的任何文件夹中.在我们的例子中,让我们做以下事情:

  1. source 中创建一个 _ext 文件夹

  2. _ext 文件夹中创建一个名为 helloworld.py 的新Python文件

以下是您可能获得的文件夹结构的示例:

└── source
    ├── _ext
    │   └── helloworld.py
    ├── _static
    ├── conf.py
    ├── somefolder
    ├── index.rst
    ├── somefile.rst
    └── someotherfile.rst

编写扩展

打开 helloworld.py 并将以下代码粘贴到其中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from docutils import nodes
from docutils.parsers.rst import Directive


class HelloWorld(Directive):

    def run(self):
        paragraph_node = nodes.paragraph(text='Hello World!')
        return [paragraph_node]


def setup(app):
    app.add_directive("helloworld", HelloWorld)

    return {
        'version': '0.1',
        'parallel_read_safe': True,
        'parallel_write_safe': True,
    }

在这个例子中发生了一些重要的事情,你将看到它们适用于所有指令.

指令类

我们的新指令在 HelloWorld 类中声明.

1
2
3
4
5
class HelloWorld(Directive):

    def run(self):
        paragraph_node = nodes.paragraph(text='Hello World!')
        return [paragraph_node]

这个类扩展了 docutilsDirective 类.创建指令的所有扩展都应扩展此类.

该类包含一个 run 方法.此方法是一项要求,它是每个指令的一部分.它包含指令的主要逻辑,并返回Sphinx要处理的docutils节点列表.这些节点是docutils表示文档内容的方式.有许多类型的节点可用: 文本,段落,参考,表格等.

参见

节点 上的docutils文档

nodes.paragraph 类创建一个新的段落节点.段落节点通常包含一些我们可以在实例化期间使用 text 参数设置的文本.

The setup function

此功能是必需的.我们用它将我们的新指令插入Sphinx.

1
2
3
4
5
6
7
8
def setup(app):
    app.add_directive("helloworld", HelloWorld)

    return {
        'version': '0.1',
        'parallel_read_safe': True,
        'parallel_write_safe': True,
    }

你能做到的最简单的事就是调用 add_directive() 方法,这就是我们在这里所做的.对于此特定调用,第一个参数是reST文件中使用的指令本身的名称.在这种情况下,我们将使用 helloworld.例如:

Some intro text here...

.. helloworld::

Some more text here...

我们还返回 扩展元数据,它表示扩展的版本,以及使用扩展进行并行读写的安全性这一事实.

使用扩展

扩展必须在你的 conf.py 文件中声明,以使Sphinx意识到它.这里有两个步骤:

  1. 使用 sys.path.append_ext 目录添加到 Python path 中.这应该放在文件的顶部.

  2. 更新或创建 extensions 列表并将扩展名文件名添加到列表中

例如:

import os
import sys

sys.path.append(os.path.abspath("./_ext"))

extensions = ['helloworld']

小技巧

我们不是将这个扩展名分发为 Python package,我们需要修改 Python path,以便Sphinx可以找到我们的扩展.这就是我们需要调用 sys.path.append 的原因.

您现在可以在文件中使用扩展名.例如:

Some intro text here...

.. helloworld::

Some more text here...

上面的示例将生成:

Some intro text here...

Hello World!

Some more text here...

延伸阅读

这是创建新指令的扩展的基本原则.

有关更高级的示例,请参阅 开发 “TODO” 扩展.