[GB10ans] 3. Chaîne éditoriale scriptée

Publié le 27 février 2025 par Gee dans Sur le blog

Le 30 janvier 2015 ouvrait le blog Grise Bouille. Pour fêter ces 10 ans de blog, un livre best of a été publié, accompagné d'un site-anniversaire et d'une série d'articles spéciaux pour vous raconter les coulisses du blog.

Cet article explique comment est généré le site (ainsi que les livres) à partir de sources Markdown et de scripts Python…

Bon, évidemment, cet article va beaucoup parler de technique, mais je vais essayer de rester accessible et clair pour tout le monde (pas forcément entrer dans les détails des scripts, mais plutôt expliquer le principe général).

Je précise aussi tout de suite que la plupart de ces scripts ne sont pas publiés : non pas que je souhaite garder le secret dessus (sinon je ne ferais pas cet article) ou que je ne souhaite pas qu'ils soient libres… Mais plutôt parce que ces scripts sont relativement « dégueux » (plein de trucs pas propres, de variables hard-codées très spécifiques, de hacks foireux, etc.), peu utilisables en dehors de mon propre espace de travail, et qu'ils reposent systématiquement sur des fichiers lourds et donc pas partagés sur le dépôt (typiquement : les exports PNG des articles).

Au départ : Wordpress et LaTeX

Lorsque je lance Grise Bouille en janvier 2015, je me base sur ce que je connais : Wordpress, le célèbre moteur de blog (qui héberge aujourd'hui une immense partie des sites web du monde). La « chaîne éditoriale » est alors des plus classiques :

  • j'écris mes scénarios dans mon éditeur de texte (Emacs) ;

  • je dessine les BD dans Inkscape ;

  • j'écris l'intro dans l'éditeur graphique de Wordpress et j'importe l'image de la BD.

Côté livres, je les écris en LaTeX : si vous ne connaissez pas, il s'agit d'un langage de description qui permet d'écrire des documents en séparant le contenu et la mise en forme (en gros, on écrit un peu de « code » et on fait tourner une moulinette qui produit un joli PDF). C'est notamment très utilisé dans la recherche, et c'est d'ailleurs une des raisons qui font que je connais l'outil, puisque j'ai moi-même passé un doctorat d'informatique en 2015.

Ça marche plutôt bien, mais c'est relativement fastidieux : tout d'abord parce qu'une fois mes BD segmentées en une image par page, je dois intégrer chacune de ces images dans la source LaTeX… et évidemment, comme toute tâche répétitive à base de copiés-collés, il y a un moment où je me gourre : dans les premières versions du tome I de Grise Bouille, il manque une image à un moment donné.

En plus de cela, je dois maintenir deux versions de chaque livre : en effet, le LaTeX permet de générer des PDF pour l'impression et la lecture sur écran, mais pour les liseuses, on a besoin de générer du format EPUB. Et dans ce cas, là source est en HTML… Ce qui fait que je dois aussi avoir une version HTML de mes livres.

Évidemment, on a des utilitaires pour passer d'un format à l'autre (coucou Pandoc), mais ça veut aussi dire qu'à chaque correction de faute sur un format, il faut ensuite penser à corriger l'autre.

Novembre 2017 : génération de livres scriptée

Plusieurs changements arrivent petit à petit :

  • je gagne en compétences en écriture de script ;

  • je me mets de plus en plus au format Markdown, que je trouve particulièrement pratique quand on veut écrire du texte avec un peu de mise en forme sans que ça ne soit invasif (comme le LaTeX) ;

  • je découvre l'utilisation de Inkscape en mode console.

Tout cela fait que j'imagine un mécanisme qui me permettrait de générer mes livres d'une manière à la fois plus propre et plus automatisée, donc en m'économisant du travail tout en évitant pas mal d'erreurs. Le principe général est celui-ci :

  • chaque livre a un fichier source unique, écrit en Markdown ;

  • les BD sont simplement référencées par leur « tag » (par exemple, la dixième BD de la catégorie Comic Trip a pour tag ct_010) ;

  • un script va générer, au choix, du PDF pour impression, pour lecture sur écran, ou de l'EPUB pour lecture sur liseuse ;

  • ce script va aussi gérer l'export d'un SVG par BD en plusieurs images pour chaque page via Inkscape en ligne de commande.

En pratique, on va évidemment quand même passer par du LaTeX pour les PDF et du HTML pour l'EPUB… mais la grosse différence, c'est que ces formats ne sont utilisés que pour les fichiers template (modèle), faits une fois pour toutes au moment où je mets en place ces scripts. Une fois faits, je peux les oublier, et écrire tous les bouquins directement en Markdown.

Prenons la BD Balai magique. La source LaTeX (qui utilise une macro personnalisée, '\illustration`) ressemble à ça :


\mychapter{Balai magique}

\label{ct_001}

\illustration{ct_001_00}

\illustration{ct_001_01}

\illustration{ct_001_02}

\illustration{ct_001_03}

\illustration{ct_001_04}

\illustration{ct_001_05}

et la version HTML :


<head>
  <title>Balai magique</title>
  <link href="stylesheet.css" type="text/css" rel="stylesheet" />
</head>
<body epub:type="bodymatter chapter">

  <img src="png/ct_001_00.png" />
  <img src="png/ct_001_01.png" />
  <img src="png/ct_001_02.png" />
  <img src="png/ct_001_03.png" />
  <img src="png/ct_001_04.png" />
  <img src="png/ct_001_05.png" />
  <img src="png/ct_001_06.png" />
  <img src="png/ct_001_07.png" />
  <img src="png/ct_001_08.png" />
  <img src="png/ct_001_09.png" />
  <img src="png/ct_001_10.png" />
  <img src="png/ct_001_11.png" />
  <img src="png/ct_001_12.png" />

</body>

Ni l'un ni l'autre ne sont très agréables à taper à la main. Et comme je le disais, copier-coller les lignes qui appellent les images peut vite amener à des erreurs, ce qui est déjà arrivé.

À présent, avec mon script, il me suffit d'une ligne pour générer à la fois le LaTeX et le HTML :


## Balai magique [ct_001]

Le tag s'affiche mal car il ne s'agit par de Markdown standard : peu importe puisque ce sera traité par mes scripts !

Et voilà ! Mon script va chercher tout seul la source svg/bd_a5/ct_001.svg pour la version LaTeX, calcule le nombre de pages selon la taille du document, appelle Inkscape avec l'option --export-area qui permet de sélectionner un rectangle, et ajoute ces images au document. Même chose pour la version HTML avec svg/bd_paysage/ct_001.svg (le format des images et le nombre de page ne sont pas les mêmes pour le format EPUB). Pour les traitements des textes à proprement parler, j'oscille entre des appels à pandoc et des outils comme le package markdown de Python.

C'est un mécanisme dont j'ai un peu parlé, en plus des questions administratives, dans cette conférence aux JDLL (avec un son un peu pourri, désolé) :

Janvier 2022 : site statique généré par script

Lorsque je me décide à passer mon site en statique, comme j'en parlais dans le making-of précédent, je me rends compte que je vais aussi pouvoir intégrer tout ça dans le même dépôt et avec des mécanismes similaires à ceux utilisés pour générer les bouquins.

Terminé le site sous Wordpress, l'intégralité du contenu est une bête liste de fichiers Markdown qui ressemble à ça :


2024-04-10_ct_la-raquette-a-travers-les-ages.md
2024-04-23_tsq_comment-ecrit-on-internet.md
2024-04-29_slb_grise-bouille-tome-6.md
2024-05-28_ct_chez-les-grecs-i.md
2024-06-03_jb_lhdg18-ia-partout-justice-nulle-part.md
2024-06-10_lf_le-bon-moment-pour-dissoudre.md
2024-06-13_slb_quoi-de-neuf-31.md
2024-06-17_tsq_oranges-bleues-et-roses-rouges.md

Les métadonnées sont directement incluses dans les noms des fichiers :

  • la date, au format ISO 8601 (qui permet d'avoir un tri chronologique via le tri alphabétique) ;

  • la catégorie, sous forme d'un tag en forme courte (ct pour Comic Trip, tsq pour Tu sais quoi ?, etc.) ;

  • le code du titre, qui se retrouve notamment dans l'url (https://grisebouille.net/quoi-de-neuf-31 par exemple).

Encore une fois, je n'ai eu besoin de toucher concrètement à des fichiers HTML (et CSS et Javascript) qu'au moment de créer le site : le reste du temps, je n'ai qu'à écrire du Markdown et à recompiler le site avec mon script, et basta !

(Bon évidemment, il m'arrive de mettre à jour le design ou les fonctionnalités de mon site, auxquels cas je vais évidemment modifier du HTML et cie, mais c'est relativement rare.)

Quant au contenu, il est pour le coup écrit dans un Markdown classique, sans fioriture. Enfin… à l'exception des BD depuis qu'elles sont accessibles 😀

J'ai pas mal montré comment tout cela se passait dans un stream dont vous pouvez retrouver le replay :

Mai 2023 : accessibilisation

C'était le sujet du making-of précédent : les BD sont écrites de manière accessible, en séparant les images et les textes, et en décrivant les images.

Mais pour retrouver l'esthétique des BD « non-accessibles » d'avant, il a bien fallu bricoler un CSS et donc générer un code HTML qui l'utilise !

Pour ça, j'ai de nouveau utilisé un Markdown « perso » avec des petits tags en plus. Pour que ce soit le plus rapide possible à taper, j'ai opté pour des tags de la forme <T> (oui, ça ressemble à un tag XML, mais en pratique ça n'a pas grand-chose à voir).

Prenons un extrait de la BD Mickey dans le domaine public. Le code de mon Markdown ressemble à ça :


<M> Je sais, là, vous allez me dire…

<L> Mais POURQUOI cette extension ?

<:> La justification est très simple :

![Un connard cravaté explique, souriant mais transpirant, devant la
Geekette et le Geek, pas convaincus. Il dit : « Ben comment vous dire…
comme il est mort pour la France, il est mort jeune… et du coup il a
pas pu écrire tous les bouquins qu'il aurait dû écrire… À cause de la
France… Donc c'est logique que ses livres publiés soient protégés plus
longtemps, comme ça il peut… enfin, ses descendants… lointains…  en
2030 quoi… ses descendants pourront continuer à gagner de la thune
dessus, et c'est…  j'sais pas, c'est juste ? C'est
équitable ? »](dm_034_09.png)

<!> Bon, vous en pensez c'que vous voulez, mais moi je trouve qu'on
nous prend un peu pour des moutons dans une boîte, avec cette
histoire.

![Gee : « Notez que le livre est dans le domaine public ailleurs : en
Belgique, par exemple*. Le lien est en note de bas de page, mais
évidemment, si vous résidez en France, NE CLIQUEZ PAS DESSUS, parce
que ce serait quand même pas très gentil. » Marcel Morbak est là et
commente : « Faudrait être sévèrement burné pour cliquer là-dessus. »
Le smiley le regarde d'un air mauvais en disant : « Tu veux pas foutre
le camp, toi ? »](dm_034_10.png)

<F> Vous pouvez télécharger le livre dans le domaine public belge
depuis
[saintexupery-domainepublic.be](https://www.saintexupery-domainepublic.be/).
Sauf si vous êtes en France, bien sûr, je le répète, mais déconnez pas,
hein.

Au niveau des images, on met tout simplement la description à l'intérieur du [], comme prévu par Markdown. Les autres tags permettent de choisir une classe CSS : <M> pour medium, <L> pour large, <!> pour important, <F> pour footnote (note de bas de page)… il y en a encore plein d'autres que je ne détaille.

Mon script lit ce Markdown et recrache le code HTML suivant :


<p class="medium">Je sais, là, vous allez me dire…</p>

<p class="large">Mais POURQUOI cette extension ?</p>

<p class="box okay"><span class="nostyle">▶️ </span>La justification
est très simple :</p>

<p><img alt="Un connard cravaté explique, souriant mais transpirant,
devant la Geekette et le Geek, pas convaincus. Il dit :
« Ben comment vous dire… comme il est mort pour la France, il est
mort jeune… et du coup il a pas pu écrire tous les bouquins qu'il
aurait dû écrire… À cause de la France… Donc c'est logique que ses
livres publiés soient protégés plus longtemps, comme ça il peut…
enfin, ses descendants… lointains…  en 2030 quoi… ses descendants
pourront continuer à gagner de la thune dessus, et c'est…  j'sais pas,
c'est juste ? C'est équitable ? »"
src="https://grisebouille.net/mickey-dans-le-domaine-public/dm_034_09.png"></p>

<p class="box warning"><span class="nostyle">⚠️ </span>Bon, vous en
pensez c'que vous voulez, mais moi je trouve qu'on nous prend un peu
pour des moutons dans une boîte, avec cette histoire.</p>

<p><img alt="Gee : « Notez que le livre est dans le domaine
public ailleurs : en Belgique, par exemple*. Le lien est en note
de bas de page, mais évidemment, si vous résidez en France, NE CLIQUEZ
PAS DESSUS, parce que ce serait quand même pas très gentil. »
Marcel Morbak est là et commente : « Faudrait être
sévèrement burné pour cliquer là-dessus. » Le smiley le regarde
d'un air mauvais en disant : « Tu veux pas foutre le camp,
toi ? »"
src="https://grisebouille.net/mickey-dans-le-domaine-public/dm_034_10.png"></p>

<p class="footnote"><span class="nostyle">✷ </span>Vous pouvez
télécharger le livre dans le domaine public belge depuis <a
href="https://www.saintexupery-domainepublic.be/">saintexupery-domainepublic.be</a>. Sauf
si vous êtes en France, bien sûr, je le répète, mais déconnez pas,
hein.</p>

Notez la présence d'émoji dans une balise nostyle : c'est un truc que j'ai ajouté par la suite, et qui permet notamment aux gens qui lisent le blog via un lecteur RSS (qui n'utilise pas le CSS) ou autre de voir une alternative aux petites icônes en haut de mes blocs colorés. Ils ne sont pas affichés par défaut.

Pour le reste, ce sont de bêtes classes qui vont permettre de donner le thème voulu aux BD, ce que je faisais avant « à la main » via Inkscape (avec tout ce que ça impliquait de « chiant », comme de tout bêtement devoir redimensionner les blocs…).

Et voilà !

Image qui reprend les deux extraits de code ci-dessous avec l'image générée à côté

Résumé : on a du Markdown transformé en HTML qui nous donne une jolie BD à l'affichage (bon, bien sûr, faut le bon CSS et les bonnes images !)

Plein de petits trucs en plus…

Le fait d'avoir scripté ce site fait que j'ai pu ajouter plein de fonctionnalités hyper facilement :

  • dans chaque article, j'indique dans quel livre il a été publié (si c'est le cas), en allant tout simplement chercher si le tag de l'article est présent dans un des fichiers sources Markdown des livres ;

  • lorsque le blog comportait encore des articles non-accessibles, je taguais automatiquement les articles accessibles en vérifiant la présence de texte alternatif dans les images ;

  • la génération de boutons de partage sans intégration de code tiers ;

  • des menus de navigation en dessous des articles, par catégorie ou pour l'ensemble des articles ;

  • l'intégration dynamique de mes niveaux de finance avec les appels au don encore en dessous ;

  • la possibilité d'activer des annonces temporaires en haut des articles ;

  • etc.

Si vous utilisez GNU/Linux, vous savez sans doute à quel point il est pratique d'avoir le contrôle de son système via des fichiers qui sont principalement des fichiers textes : c'est le même principe ici. Dès que je veux ajouter une fonctionnalité à mon site, c'est rarement très compliqué grâce au fait que tout repose sur des simples fichiers textes, des formats ouverts et des logiciels libres. En général, ça revient à lire des fichiers, à les interpréter, à les traiter de la façon qui me plaît, et de recracher d'autres fichiers.

Mine de rien, quand je pense à la complexité que ça aurait été sur Wordpress : trouver un plugin qui fait ce que je veux (pas toujours simple), l'installer, ne pas oublier de le mettre à jour pour les questions de sécurité, éventuellement le remplacer quand il n'est plus maintenu… et tout ça via des interfaces graphiques dans le navigateur, sans pouvoir automatiser grand-chose.

Des scripts… pour tout !

Personnellement, plus le temps passe, plus je scripte absolument tout : de la création des releases de mes jeux vidéos au suivi de mes finances, de la création des devis et facture de mon autoentreprise, des statistiques en tous genres…

Avec toujours la même subdivision :

  • les données dans un format simple (Markdown pour du texte, Yaml pour des données complexes) ;

  • des modèles fixes dépendant de ce que je veux générer (HTML, LaTeX, autre…)

  • des scripts qui moulinent le tout et recrachent ce que je veux.

Alors évidemment, je connais la BD de XKCD qui ironise sur le fait qu'on se perd parfois dans l'automatisation au point de finir par perdre du temps :

BD extraite de XKCD

(Randall Munroe, CC By Nc Sa) « Je passe beaucoup de temps sur cette tâche, je devrais écrire un programme pour l'automatiser ! En théorie, on passe d'abord du temps à écrire le code, puis l'automatisation fait gagner du temps. En pratique, une fois le code écrit, on passe encore plus de temps à le débuguer, le repenser, puis le développement du script prend tellement de temps qu'on finit par ne plus avoir de temps pour la tâche d'origine.

En pratique, justement, mon expérience se situe plutôt sur la première image : j'avais d'ailleurs beaucoup tendance à surestimer le temps que me prendrait l'écriture de tel ou tel script. Le fait est que j'ai rarement regretté de m'être lancé dans l'automatisation de quelque chose…

Et donc, ma conclusion : les scripts, en informatique, c'est la vie. Si vous ne connaissez aucun langage de script et qu'automatiser des trucs vous intéresse, je ne saurais que vous conseiller de vous y mettre… et cela, même si vous ne connaissez rien à la programmation ! Car justement, en général les langages de script sont plus faciles d'accès que les langages compilés (pour avoir fait du C++ haut niveau pendant des années, je sais de quoi je parle). C'est une bonne façon de commencer ! Au hasard, prenez Python.

En vous souhaitant une bonne automatisation. De mon côté, il ne me reste qu'à relancer mon script de compilation et de mettre à jour mon Grise Bouille. À bientôt 😊

Publié le 27 février 2025 par Gee dans Sur le blog

Soutenir

Ce blog est publié sous licence libre, il est librement copiable, partageable, modifiable et réutilisable. Il est gratuit car financé principalement par vos dons. Sans inscription, vous pouvez très simplement me soutenir :

Pour la saison 2024-2025, 6 961 € ont pour l'instant été collectés sur un objectif annuel de 21 200 € (SMIC brut), soit 33 % de l'objectif :

Sources de revenu

La saison étant entamée à 59 %, il y a actuellement un retard de 5 429 € sur l'objectif.

Avancement de la saison

Vous pouvez également, si vous le souhaitez, passer par une plateforme de financement participatif :