Introduction à Sphinx, un outil de documentation puissant

Sphinx est un outil très complet permettant de générer des documentations riches et bien structurées. Il a originellement été créé pour la documentation du langage Python, et a très vite été utilisé pour documenter de nombreux autres projets.

Il peut être utilisé pour simplement écrire un ouvrage technique (sans rapport direct avec une base de code) ou pour documenter du code. Pour ce qui est de la documentation de code, il est évidemment bien adapté au Python, mais peut aussi être utilisé avec d'autres langages, comme le JavaScript ou encore le PHP (il est d'ailleurs utilisé pour la documentation du framework Symfony).

Parmi toutes les fonctionnalités qu'il propose, on peut mentionner :

  • le support de plusieurs formats de sortie (HTML, PDF, EPUB, pages de manuel,...),
  • la génération automatique de la documentation liée à du code (avec le support de nombreux langages),
  • la possibilité de faire facilement des références entre les pages,
  • ou encore sa gestion d'extensions permettant de l'adapter à toutes les situations et langages.

Dans ce premier article sur Sphinx, on va voir comment l'installer et comment l'utiliser pour générer une documentation. On abordera aussi rapidement la syntaxe reStructuredText sur laquelle il s'appuie. Dans de futurs articles, on verra plus spécifiquement comment l'utiliser pour documenter du Python ou du JavaScript.

Note

Cet article fait partie d'une série consacrée à l'outil de documentation Sphinx :

  1. Introduction à Sphinx, un outil de documentation puissant
  2. Documenter un projet Python avec Sphinx

Cet autre article peut également être intéressant en complément :

Installer Sphinx

La première étape, c'est évidemment d'installer Sphinx.

L'outil est développé en Python, vous aurez donc besoin de ce dernier pour le faire fonctionner. Sous Debian et Ubuntu, vous pouvez utiliser la commande suivante pour vous assurer d'avoir tout ce qu'il vous faut :

sudo apt install build-essential python3 python3-pip python3-venv

Si vous êtes sous Windows, il vous faudra télécharger et installer la dernière version de Python 3.x disponible sur le site officiel :

Ensuite, pour installer Sphinx en lui-même, il suffit d'exécuter la commande suivante :

$ pip install sphinx

Et c'est tout !

Note

NOTE : faire les choses proprement avec un virtualenv

Pour éviter de mettre le bazar sur mon système, j'exécuterais toutes les commandes Python de cet article dans un virtualenv utilisant Python 3.

Si vous avez une version de Python supérieure à 3.3 (ça devrait être le cas normalement), vous pouvez créer l'environnement avec la commande suivante :

$ python3 -m venv __env__

Cette commande va créer un dossier __env__/ dans le dossier courant, qui contient Python ainsi que tout ce qu'on va installer par la suite.

Une fois l'environnement créé, il faut l'activer :

$ source __env__/bin/activate

Si tout c'est bien passé, le prompt du terminal devrait être préfixé du nom de l'environnement (__env__).

Vous pouvez à présent exécuter n'importe laquelle des commandes cet article, comme le pip install ci-dessus, ou la commande de génération de la doc que l'on va voir par la suite.

Une fois que vous avez terminé de travailler avec votre environnement, vous pouvez le désactiver à l'aide de la commande suivante :

$ deactivate

La prochaine fois, vous n'aurez pas besoin de recréer l'environnement, seulement de le réactiver.

Les commandes que je vous ai présentées ci-dessus sont valables pour Linux avec un shell POSIX (Bash, Dash, ZSH,...). Si vous utilisez un shell exotique (coucou Fish) ou un autre OS (ou si vous êtes simplement curieux), vous trouverez plus d'informations sur la documentation officielle de venv.

Créer la documentation

Maintenant que Sphinx est installé, on va pouvoir créer la documentation. Pour cela il faut créer un certain nombre de dossiers et de fichiers... mais heureusement, Sphinx dispose d'une commande pour faire tout ça automatiquement !

On va donc initialiser la documentation à l'aide de la commande suivante :

$ sphinx-quickstart

Là, Sphinx va nous poser un certain nombre de questions auxquelles vous pouvez répondre comme vous le souhaitez. Mais pour suivre la suite de cet article dans de bonnes conditions, je vous recommande de répondre "y" à la première question (Séparer les répertoires build et source) :

Bienvenue dans le kit de démarrage rapide de Sphinx 3.1.2.

Please enter values for the following settings (just press Enter to
accept a default value, if one is given in brackets).

Selected root path: .

You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.
> Séparer les répertoires build et source (y/n) [n]: y

The project name will occur in several places in the built documentation.
> Nom du projet: Example Sphinx Project
> Nom(s) de l'auteur: me
> version du projet []:

If the documents are to be written in a language other than English,
you can select a language here by its language code. Sphinx will then
translate text that it generates into that language.

For a list of supported codes, see
https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language.
> Langue du projet [en]:

[...]

Une fois les quelques questions répondues, vous vous retrouvez avec un dossier source/ qui contiendra votre documentation, et deux fichiers :

  • Makefile pour générer la doc depuis Linux, MacOS,...
  • et make.bat pour générer la doc depuis Windows.

Renommer le dossier source

Personnellement, je n'aime pas que le dossier contenant la documentation s'appelle source/, je le renomme donc en doc/ :

$ mv source doc

Si vous faites cela, il vous faudra également modifier les fichiers Makefile et make.bat, dans lesquels il faudra adapter le contenu de la variable SOURCEDIR.

Makefile :

SOURCEDIR     = doc

make.bat :

set SOURCEDIR=doc

À présent, votre dossier de travail devrait ressembler à ceci :

Aperçu des dossiers et fichiers créés

Générer la doc

Pour générer la doc, c'est très simple, il suffit d'ouvrir un terminal dans le dossier du projet et de taper la commande suivante :

$ make html

Note

NOTE : la commande make

Si vous êtes sous Linux et que vous n'avez pas la commande make, il vous faudra l'installer. Ça peut se faire avec la commande suivante si vous utilisez Debian, Ubuntu ou l'un de leurs dérivés :

$ sudo apt install build-essential

Note

NOTE : Windows + Git Bash

Si vous êtes sous Windows et que vous utilisez Git Bash, il vous faudra utiliser la commande suivante puis générer votre documentation :

$ ./make.bat html

Une fois la doc générée, vous retrouverez le résultat dans le dossier build/html/. Vous pouvez à présent ouvrir index.html dans votre navigateur et admirer le résultat.

Capture d'écran de la documentation avec le thème Alabaster

Bon ok... c'est pas super méga magnifique... 😅️

Le thème par défaut, Alabaster, est très minimaliste. Et même si certains arrivent à faire des trucs sympas avec, la plupart des gens préfèrent changer le thème.

Changer le thème

Il existe un certain nombre de thèmes intégrés à Sphinx, et de nombreux autres disponibles, mais la plupart des gens installent le thème « Read The Doc » qui est assez complet, et pratique pour naviguer dans la documentation.

On va donc voir comment installer ce thème (mais libre à vous d'en choisir un autre, le principe reste le même).

Pour utiliser le thème « Read The Doc », il faut commencer par l'installer, ce qui peut être fait à l'aide de la commande suivante :

$ pip install sphinx-rtd-theme

Ensuite, il faut indiquer à Sphinx d'utiliser ce thème. Pour cela, il faut éditer le fichier conf.py qui devrait se trouver dans le dossier doc/ (ou dans le dossier source/ si vous n'avez pas modifié le nom par défaut).

Il faudra remplacer le contenu de la variable "html_theme" par "sphinx_rtd_theme" :

html_theme = 'sphinx_rtd_theme'

Note

NOTE : Notez bien que pour installer le paquet il fallait taper sphinx-rtd-theme avec des tirets, et que pour déclarer l'utilisation du thème, il faut utiliser des underscores : sphinx_rtd_theme.

Vous pouvez à présent régénérer votre documentation, qui devrait maintenant ressembler à ceci :

Capture d'écran de la documentation avec le thème Alabaster

C'est déjà beaucoup mieux ! 😁️

Pour information, sachez que les thèmes Sphinx sont généralement configurables. Pour ce qui est du thème « Read The Doc », vous retrouverez tous les paramètres qu'il accepte dans sa documentation officielle.

Note

NOTE : Si vous souhaitez rédiger une documentation dans une autre langue que l'anglais, il vous faudra également activer l'extension Sphinx du thème afin de permettre la traduction des éléments de l'interface. Pour ce faire, éditez le fichier conf.py, et ajoutez 'sphinx_rtd_theme' à la liste des extensions :

extensions = [
    'sphinx_rtd_theme',
]

Vous trouverez plus d'informations dans la doc du thème.

Ajouter des pages

Pour ajouter une page à la documentation, c'est assez simple :

  • il suffit d'ajouter un fichier .rst dans le dossier contenant la documentation,
  • et de référencer cette page dans un index.

Créons par exemple la page « Hello World » que l'on va placer dans le fichier hello.rst :

Hello World
===========

Hello, this is a demo page.

Cette page doit au minimum disposer d'un titre pour que Sphinx accepte de l'utiliser.

Il ne nous reste plus qu'à la référencer dans une table des matières. Reprenons donc notre fichier index.rst qui avait été généré. Dedans, il suffit de rajouter notre document dans la directive toctree :

.. toctree::
   :maxdepth: 2
   :caption: Contents:

   ./hello.rst

Ici la directive est composée de 2 paramètres et de la liste des pages qui composent la doc. Quelques explications s'imposent :

  • maxdepth indique le nombre de niveaux de titre à afficher. Si on le définit à 1, seuls les titres des pages seront affichés, si on le définit à 2 comme dans le cas présent, le titre des pages et les titres des principales sections des pages seront affichés.
  • caption permet quant à lui de définir le titre à afficher au-dessus de la table des matières.
  • Il y a ensuite une ligne vide : elle est très importante car elle sert à séparer les paramètres de la directive et le contenu (ici le contenu c'est notre liste de pages, une par ligne).

Note

NOTE : Vous pouvez définir plusieurs toctree dans des fichiers différents (pour découper votre documentation en sous-parties). Le seul point important c'est que toutes les pages soient accessibles en naviguant de tables des matières en table des matières depuis le fichier index.rst.

reStructuredText

La syntaxe utilisée pour rédiger une documentation avec Sphinx s'appelle reStructuredText. Si vous êtes habitués au Markdown, vous verrez que cette syntaxe est beaucoup plus complète, mieux normalisée, mais aussi plus stricte.

Je pourrais vous écrire un article complet sur le reStructuredText tellement la syntaxe est complète. Mais comme ce n'est pas le sujet principal de cet article, je vous montre rapidement les principaux formatages, sans vous expliquer toutes les subtilités.

Voici quelques formatages inline :

Voici du texte en *italique*, en **gras**, et voici du ``code inline``.

Pour faire des liens, c'est aussi assez simple (notez bien l'espace avant le "<", il est très important) :

Pour faire un lien inline c'est simple :
lien vers le `blog de FLOZz <https://blog.flozz.fr/>`_

Voici comment on fait des paragraphes en reStructuredText :

Ceci est un paragraphe. Je peux retourner à la ligne, je
serais toujours dans le même paragraphe.

Pour écrire un second paragraphe, il suffit de le séparer
du premier par une ligne vide.

Pour organiser son contenu, il peut être utile d'utiliser des titres. En reStructuredText, il suffit de souligner une ligne pour faire un titre :

Titre principal
===============

Titre de niveau 2
-----------------

Titre de niveau 3
~~~~~~~~~~~~~~~~~

Un autre titre de niveau 2
--------------------------

Ici je vous ai mis ma façon de faire (qui est relativement répendue) mais vous pouvez utiliser pas mal de caractères différents pour souligner vos titres (=-~_#^+<>:'"*...), le parseur se débrouillera pour déterminer le niveau du titre en fonction de l'ordre d'apparition des symboles ; le tout c'est de rester cohérent.

Besoin d'une liste à puce ou ordonnée ?

Liste à puce :

* Ceci est une liste
* un autre élément

  * Une sous-liste
  * notez bien le saut de ligne avec la liste principale,
    ça ne marchera pas si vous l'oubliez !

* un dernier élément

Liste ordonnée :

1. Un
2. Deux
3. Trois

Une autre liste ordonnée :

#. Un
#. Deux
#. Trois

Dans une documentation on a souvent besoin d'écrire du code :

Voici comment faire un bloc que code simple ::

   Ceci est un bloc de code. Il est créé grâce aux doubles deux-points.

On peut également placer les doubles deux-points seuls si on ne veut pas
terminer sa phrase par ce symbole.

::

   Voici un autre bloc de code...

Et c'est pas fini ! On peut aussi définir un bloc de code avec une syntaxe
plus explicite, grâce à laquelle on peut indiquer à Sphinx dans quel
langage il est rédigé, ce qui lui permettra d'activer la coloration
syntaxique :

.. code-block:: python

   #!/usr/bin/env python

   print("Ceci est un bloc de code Python\n")

On peut également faire des citations, pour cela il suffit d'indenter, comme pour un bloc de code, mais sans mettre les doubles deux points :

FLOZz a dit :

     Ceci est une citation

Si vous voulez mettre en évidence des notes, des avertissements ou des choses importantes, c'est également possible :

.. NOTE::

   Ceci est une note.

.. WARNING::

   Ceci est un avertissement !

.. IMPORTANT::

   Ceci est important !

Il est également possible d'ajouter des images :

Voici une image :

.. figure:: ./images/image.png

Voici un autre image avec quelques paramètres en plus :

.. figure:: ./images/image.png
   :alt: Texte alternatif
   :target: http://blog.flozz.fr/
   :width: 400px
   :align: center

   Texte affiché sous l'image

Et pour les plus fifou d'entre vous, il est également possible de faire des tableaux, avec des cellules fusionnées et tout ! Et pour faire ça, il suffit simplement de dessiner le tableau tel qu'on veut le voir s'afficher :

+-----------+-----------+-----------+
| Heading 1 | Heading 2 | Heading 3 |
+===========+===========+===========+
| Hello     | World     |           |
+-----------+-----------+-----------+
| foo       |                       |
+-----------+          bar          |
| baz       |                       |
+-----------+-----------------------+

Sachez qu'en plus des éléments de syntaxe standards de reStructuredText, Sphinx rajoute de nombreux éléments supplémentaires pour les besoins de la documentation.

On a pu voir par exemple toctree un peu plus tôt, mais il y a également des syntaxes pour effectuer des références entre des éléments de la doc, des syntaxes pour documenter des classes, des fonctions,...

Je vous en dis pas plus pour cette fois-ci, et je vous donne le lien vers la documentation de Sphinx pour en apprendre davantage :

C'est tout ?

Eh oui c'est tout pour cette fois-ci, il ne s'agit que d'un article d'introduction !

Vous disposez déjà toutes les informations pour bien débuter avec cet outil, et je vous encourage à jeter un œil à des doc Sphinx existantes pour avoir des exemples plus complets, et plus concrets. Je vous en liste quelques-unes que j'ai moi-même rédigées, ça sera un bon point de départ :

J'ai laissé les liens "View page source" sur l'ensemble des documentations ci-dessus, n'hésitez donc pas à cliquer dessus pour voir comment c'est fait.

Et pendant que vous êtes occupés à regarder les exemples, je m'en vais vous écrire un second article sur Sphinx, qui sera orienté cette fois-ci sur la documentation de code Python. À bientôt ! ☺️


EDIT 2021-01-24 : Ajout d'une note sur la nécessité d'activer l'extension du thème RTD pour la traduction des éléments d'UI suite au commentaire de @niconil.