Разработка расширения «Hello world»¶
Тема данного руководства - создание простого расширения, которое добавляет новую директиву. Данная директива будет выводить параграф, содержащий «hello world».
В этом руководстве предоставлена только базовая информация. Для более подробной информации обращайтесь к разделу прочие руководства.
Предупреждение
Для данного расширения, необходимы базовые понятия в docutils и Python.
Введение¶
Мы хотим чтобы наше расширения добавляло следующий функционал к Sphinx:
Директиву
helloworld
, которая просто будет выводить текст «hello world».
Предварительные требования¶
Мы не будем распространять наш плагин через PyPI, а вместо этого просто включим его как часть существующего проекта. Это означает, что нужно будет использовать существующий проект или создать новый с помощью sphinx-quickstart.
Предполагается что вы будете использовать отдельные директории source (source
) и build (build
). Файл расширения может располагаться в любой директории вашего проекта. в данном случае сделайте следующее:
Создайте директорию
_ext
в директорииsource
Создайте новый файл Python
helloworld.py
в директории_ext
Приведём пример как должна выглядеть структура ваших директорий:
└── source
├── _ext
│ └── helloworld.py
├── _static
├── conf.py
├── somefolder
├── index.rst
├── somefile.rst
└── someotherfile.rst
Пишем расширение¶
Open helloworld.py
and paste the following code in it:
1from docutils import nodes
2from docutils.parsers.rst import Directive
3
4from sphinx.application import Sphinx
5from sphinx.util.typing import ExtensionMetadata
6
7
8class HelloWorld(Directive):
9 def run(self):
10 paragraph_node = nodes.paragraph(text='Hello World!')
11 return [paragraph_node]
12
13
14def setup(app: Sphinx) -> ExtensionMetadata:
15 app.add_directive('helloworld', HelloWorld)
16
17 return {
18 'version': '0.1',
19 'parallel_read_safe': True,
20 'parallel_write_safe': True,
21 }
Some essential things are happening in this example, and you will see them for all directives.
The directive class
Our new directive is declared in the HelloWorld
class.
1from sphinx.util.typing import ExtensionMetadata
2
3
4class HelloWorld(Directive):
5 def run(self):
This class extends the docutils“ Directive
class. All extensions that
create directives should extend this class.
This class contains a run
method. This method is a requirement and it is
part of every directive. It contains the main logic of the directive and it
returns a list of docutils nodes to be processed by Sphinx. These nodes are
docutils“ way of representing the content of a document. There are many types of
nodes available: text, paragraph, reference, table, etc.
См.также
The nodes.paragraph
class creates a new paragraph node. A paragraph
node typically contains some text that we can set during instantiation using
the text
parameter.
The setup
function
This function is a requirement. We use it to plug our new directive into Sphinx.
1
2
3def setup(app: Sphinx) -> ExtensionMetadata:
4 app.add_directive('helloworld', HelloWorld)
5
6 return {
7 'version': '0.1',
8 'parallel_read_safe': True,
9 'parallel_write_safe': True,
10 }
The simplest thing you can do is to call the add_directive()
method,
which is what we’ve done here. For this particular call, the first argument is
the name of the directive itself as used in a reST file. In this case, we would
use helloworld
. For example:
Some intro text here...
.. helloworld::
Some more text here...
We also return the extension metadata that indicates the version of our extension, along with the fact that it is safe to use the extension for both parallel reading and writing.
Using the extension¶
The extension has to be declared in your conf.py
file to make Sphinx
aware of it. There are two steps necessary here:
Add the
_ext
directory to the Python path usingsys.path.append
. This should be placed at the top of the file.Update or create the
extensions
list and add the extension file name to the list
Например:
import os
import sys
sys.path.append(os.path.abspath("./_ext"))
extensions = ['helloworld']
Совет
We’re not distributing this extension as a Python package, we need to
modify the Python path so Sphinx can find our extension. This is why we
need the call to sys.path.append
.
You can now use the extension in a file. For example:
Some intro text here...
.. helloworld::
Some more text here...
The sample above would generate:
Some intro text here...
Hello World!
Some more text here...
Further reading¶
This is the very basic principle of an extension that creates a new directive.
For a more advanced example, refer to Developing a «TODO» extension.