Pandoc

December 2014 · 5 minute(s) de lecture

Pandoc est un outil de conversion de fichier multi formats. C’est un véritable couteau suisse, il suffit de voir le petit graphique sur la page pour voir les possibilités. Bon en réalité c’est surtout le format markdown qui est prisé.

Je vais vous détailler pourquoi je m’y intéresse et quels ont été les points forts par rapport à d’autre solutions.

Pourquoi j’ai décidé de m’y intéresser

En développant irccd, j’ai évidemment été confronté à la question de la documentation. De plus de ce côté là je suis assez strict et j’aime les choses propres.

À l’origine, au tout début d’irccd, j’avais écrit la documentation d’irccd avec deux outils :

Le premier est plutôt bon, il nécessite un certain temps d’adaptation pour connaître toute la syntaxe mais en quelques minutes on obtient déjà quelque chose de fait. Cependant, je trouve qu’il est assez difficile de mettre des “template” personnalisés ainsi que de modifier certaines partie du code généré.

Le deuxième, LDoc est une vraie plaie. Il fonctionne un peu comme Doxygen, vous écrivez la documentation sur du code Lua et il en extrait tout directement. C’est pratique car vous avez pas à gérer la documentation extérieurement. Mais pour irccd, il y a un gros point faible : il n’y a pas de code Lua ! En effet, l’intégralité de l’API Lua d’irccd est écrite directement en C++. Cela nécessitait donc d’écrire de faux fichiers Lua pour documenter chaque fonction.

De plus, j’avais pris une template LDoc et modifié légèrement pour avoir mon propre rendu. Seulement, à chaque mise à jour de LDoc ma template ne fonctionnait plus et c’était vraiment pénible à maintenir.

J’ai par la suite, choisi de passer par le wiki du redmine pour documenter l’intégralité d’irccd, guides comme la Lua API. C’est bien car vous avez quelque chose de propre, bien intégré aux autres composants de redmine (demandes, forum, fichiers, etc). Vous avez aussi la possibilité de gérer immédiatement les fautes ou autres erreurs.

Malheureusement, il y a d’autre problèmes à utiliser une documentation centralisée sur un wiki :

1. Gestion des versions

Comme vous êtes un bon développeur, vous utilisez [SemVer][semver], ainsi vous documentez correctement l’API de votre produit pour la version 1.0.

Un an plus tard, vous décidez de sortir la version 2.0, l’API change et beaucoup de composants sont différents. Comment mettre en place ces changements sur un wiki tout en gardant celle de la 1.0 ?

Et bien vous ne le faites pas, ou alors vous faites une copie du wiki (ce que redmine ne sait pas faire).

2. Thèmes, site vitrine

Quand on réalise un projet, il est aussi important d’avoir quelque chose de beau et homogène. À l’heure actuelle (irccd 1.1.4), vous pouvez constater un certain thème sur la page officielle d’irccd.

Mais dès que vous entrez dans la documentation, vous arrivez sur le redmine, des couleurs différentes, des mises en forme différentes. C’est assez déroutant et je n’aime pas ça.

En externalisant la documentation, je peux générer les pages avec le même thème, les mêmes composants des pages web d’irccd ce qui fera un ensemble cohérent.

En prime, je permet aux utilisateurs d’autres versions de pouvoir continuer à lire la documentation des versions précédentes.

3. Formats multiple

Comme dit plus haut, pandoc est un convertisseur multi-formats, je compte bien l’utiliser avec le même contenu écrit en markdown pour générer :

Et tout ça, avec les même sources markdown :-).

Comment pandoc est mis en place dans irccd

Alors bien que ce soit encore en travaux, la documentation apparait petit à petit. Je couple pandoc avec CMake afin de générer la documentation de manière efficace.

Évidemment cela nécessite beaucoup de code CMake pour arriver à quelque chose de puissant, mais le résultat en vaut la peine.

En effet, c’est grâce à CMake que je regénère certaines parties uniquement si tel ou tel fichier a changé. Par exemple chaque fonction de l’API Lua est documentée dans un fichier markdown et seulement celui ci est regénéré si son contenu a changé.

Voici avec les commandes add_custom_command et add_custom_target, comment on peut générer efficacement de la documentation avec CMake :

Génération d’un fichier

On utilise la commande add_custom_command pour créer une règle qui va nous permettre de générer le fichier, utilisé en tant que tel, il ne vous servira à rien si le fichier généré n’est pas attaché à une cible.

add_custom_command(
    OUTPUT ${CMAKE_BINARY_DIR}/monfichier.html
    COMMAND pandoc${CMAKE_SOURCE_DIR}/monfichier.txt
        -f markdown -t html5
        -o ${CMAKE_BINARY_DIR}/monfichier.html
    DEPENDS ${CMAKE_SOURCE_DIR}/monfichier.txt
)

Notez l’importance de mettre monfichier.txt, c’est ce qui permettra de regénérer le fichier si monfichier.txt a été modifié.

Création d’un target

Maintenant, pour que le fichier soit généré, il doit être attaché à une dépendance d’une cible. On peut utiliser les commandes comme add_executable, add_library mais dans notre cas, nous utiliserons add_custom_target.

add_custom_target(
    monfichier
    DEPENDS ${CMAKE_BINARY_DIR}/monfichier.html
    SOURCES ${CMAKE_SOURCE_DIR}/monfichier.txt
)

Nous spécifions :

Maintenant, il vous suffit juste de taper make monfichier ou de le générer depuis votre IDE.