sphinx/doc/development/tutorials/helloworld.rst

162 lines
4.1 KiB
ReStructuredText
Raw Normal View History

2018-11-28 10:27:22 -06:00
Developing a "Hello world" directive
====================================
The objective of this tutorial is to create a very basic extension that adds a new
directive that outputs a paragraph containing `hello world`.
Only basic information is provided in this tutorial. For more information,
2018-12-19 09:45:15 -06:00
refer to the :doc:`other tutorials <index>` that go into more
2018-11-28 10:27:22 -06:00
details.
.. warning:: For this extension, you will need some basic understanding of docutils_
and Python.
Creating a new extension file
-----------------------------
Your extension file could be in any folder of your project. In our case,
let's do the following:
#. Create an :file:`_ext` folder in :file:`source`.
#. Create a new Python file in the :file:`_ext` folder called
:file:`helloworld.py`.
Here is an example of the folder structure you might obtain:
.. code-block:: text
└── source
   ├── _ext
  └── helloworld.py
   ├── _static
   ├── _themes
   ├── conf.py
   ├── somefolder
   ├── somefile.rst
   └── someotherfile.rst
Writing the extension
---------------------
Open :file:`helloworld.py` and paste the following code in it:
.. code-block:: python
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)
Some essential things are happening in this example, and you will see them
in all directives:
.. rubric:: Directive declaration
2018-12-19 10:33:22 -06:00
Our new directive is declared in the ``HelloWorld`` class, it extends
2018-11-28 10:27:22 -06:00
docutils_' code:`Directive` class. All extensions that create directives
should extend this class.
2018-12-19 09:45:15 -06:00
.. rubric:: ``run`` method
2018-11-28 10:27:22 -06:00
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.
2018-12-19 09:45:15 -06:00
.. seealso::
2018-12-19 10:33:22 -06:00
:doc:`todo`
2018-11-28 10:27:22 -06:00
.. rubric:: docutils nodes
2018-12-19 09:45:15 -06:00
The ``run`` method returns a list of nodes. Nodes are docutils' way of
2018-11-28 10:27:22 -06:00
representing the content of a document. There are many types of nodes
available: text, paragraph, reference, table, etc.
2018-12-19 10:33:22 -06:00
.. seealso::
2018-11-28 10:27:22 -06:00
2018-12-19 10:33:22 -06:00
`docutils nodes`_
2018-11-28 10:27:22 -06:00
2018-12-19 10:33:22 -06:00
The ``nodes.paragraph`` class creates a new paragraph node. A paragraph
2018-11-28 10:27:22 -06:00
node typically contains some text that we can set during instantiation using
the ``text`` parameter.
2018-12-19 10:33:22 -06:00
.. rubric:: ``setup`` function
This function is a requirement. We use it to plug our new directive into
Sphinx.
The simplest thing you can do it call the ``app.add_directive`` method.
2018-11-28 10:27:22 -06:00
2018-12-19 10:33:22 -06:00
.. note::
2018-11-28 10:27:22 -06:00
2018-12-19 10:33:22 -06:00
The first argument is the name of the directive itself as used in an rST file.
In our case, we would use ``helloworld``:
.. code-block:: rst
2018-11-28 10:27:22 -06:00
2018-12-19 10:33:22 -06:00
Some intro text here...
2018-11-28 10:27:22 -06:00
2018-12-19 10:33:22 -06:00
.. helloworld::
2018-11-28 10:27:22 -06:00
2018-12-19 10:33:22 -06:00
Some more text here...
2018-11-28 10:27:22 -06:00
Updating the conf.py file
-------------------------
The extension file has to be declared in your :file:`conf.py` file to make
Sphinx aware of it:
#. Open :file:`conf.py`. It is in the :file:`source` folder by default.
2018-12-19 10:33:22 -06:00
#. Add ``sys.path.append(os.path.abspath("./_ext"))`` before
2018-11-28 10:27:22 -06:00
the ``extensions`` variable declaration (if it exists).
2018-12-19 10:33:22 -06:00
#. Update or create the ``extensions`` list and add the
2018-11-28 10:27:22 -06:00
extension file name to the list:
.. code-block:: python
extensions.append('helloworld')
You can now use the extension.
.. admonition:: Example
.. code-block:: rst
Some intro text here...
.. helloworld::
Some more text here...
The sample above would generate:
.. code-block:: text
Some intro text here...
Hello World!
Some more text here...
This is the very basic principle of an extension that creates a new directive.
For a more advanced example, refer to :ref:`exttuto-todo`
2018-12-19 10:33:22 -06:00
Further reading
---------------
You can create your own nodes if needed, refer to the
:ref:`exttuto-todo` for more information.
2018-11-28 10:27:22 -06:00
.. _docutils: http://docutils.sourceforge.net/
.. _`docutils nodes`: http://docutils.sourceforge.net/docs/ref/doctree.html