From cf7da1843c45a4c2df7a749f7886a2d2ba0ee92a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 19:25:40 +0200 Subject: Adding upstream version 7.2.6. Signed-off-by: Daniel Baumann --- doc/development/tutorials/helloworld.rst | 189 +++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 doc/development/tutorials/helloworld.rst (limited to 'doc/development/tutorials/helloworld.rst') diff --git a/doc/development/tutorials/helloworld.rst b/doc/development/tutorials/helloworld.rst new file mode 100644 index 0000000..8940e3d --- /dev/null +++ b/doc/development/tutorials/helloworld.rst @@ -0,0 +1,189 @@ +Developing a "Hello world" extension +==================================== + +The objective of this tutorial is to create a very basic extension that adds a +new directive. This directive will output a paragraph containing "hello world". + +Only basic information is provided in this tutorial. For more information, refer +to the :doc:`other tutorials ` that go into more details. + +.. warning:: + + For this extension, you will need some basic understanding of docutils_ + and Python. + + +Overview +-------- + +We want the extension to add the following to Sphinx: + +* A ``helloworld`` directive, that will simply output the text "hello world". + + +Prerequisites +------------- + +We will not be distributing this plugin via `PyPI`_ and will instead include it +as part of an existing project. This means you will need to use an existing +project or create a new one using :program:`sphinx-quickstart`. + +We assume you are using separate source (:file:`source`) and build +(:file:`build`) folders. 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 +    ├── conf.py +    ├── somefolder +    ├── index.rst +    ├── somefile.rst +    └── someotherfile.rst + + +Writing the extension +--------------------- + +Open :file:`helloworld.py` and paste the following code in it: + +.. literalinclude:: examples/helloworld.py + :language: python + :linenos: + +Some essential things are happening in this example, and you will see them for +all directives. + +.. rubric:: The directive class + +Our new directive is declared in the ``HelloWorld`` class. + +.. literalinclude:: examples/helloworld.py + :language: python + :linenos: + :lines: 5-9 + +This class extends the docutils_' ``Directive`` class. All extensions that +create directives should extend this class. + +.. seealso:: + + `The docutils documentation on creating directives `_ + +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. + +.. seealso:: + + `The docutils documentation on nodes `_ + +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. + +.. rubric:: The ``setup`` function + +.. currentmodule:: sphinx.application + +This function is a requirement. We use it to plug our new directive into +Sphinx. + +.. literalinclude:: examples/helloworld.py + :language: python + :linenos: + :lines: 12- + +The simplest thing you can do is to call the :meth:`~Sphinx.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: + +.. code-block:: rst + + Some intro text here... + + .. helloworld:: + + Some more text here... + +We also return the :ref:`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 :file:`conf.py` file to make Sphinx +aware of it. There are two steps necessary here: + +#. Add the :file:`_ext` directory to the `Python path`_ using + ``sys.path.append``. This should be placed at the top of the file. + +#. Update or create the :confval:`extensions` list and add the extension file + name to the list + +For example: + +.. code-block:: python + + import os + import sys + + sys.path.append(os.path.abspath("./_ext")) + + extensions = ['helloworld'] + +.. tip:: + + 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: + +.. 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... + + +Further reading +--------------- + +This is the very basic principle of an extension that creates a new directive. + +For a more advanced example, refer to :doc:`todo`. + + +.. _docutils: https://docutils.sourceforge.io/ +.. _docutils directives: https://docutils.sourceforge.io/docs/howto/rst-directives.html +.. _docutils nodes: https://docutils.sourceforge.io/docs/ref/doctree.html +.. _PyPI: https://pypi.org/ +.. _Python package: https://packaging.python.org/ +.. _Python path: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH -- cgit v1.2.3