Journal de bord

Journal de bord 6 — Carnet de dev sur rst2gemtext, mise à jour des articles, et réflexions sur la langue de publication

Bienvenu dans ce nouveau journal de bord ! Décidément j'arrive pas à ralentir le rythme malgré la chaleur écrasante de la cinquième canicule qui nous tombe dessus. Et pourtant c'est pas faute d'essayer, mais j'ai encore des notes qui traînent et que je veux publier ! 😅️

Au programme aujourd'hui, un journal de développement sur rst2gemtext (un outil pour convertir des fichiers d'une syntaxe de balisage à une autre) dans lequel je vais vous expliquer comment je gère les tableaux et quels choix pragmatiques j'ai dû faire pour ne pas y passer un temps infini. Ensuite, je vais vous parler d'une petite amélioration que j'ai apporté au blog qui vous permettra de mieux voir quand un article a été mis à jour. Et on terminera par une réflexion sur un petit article que j'ai lu il y a quelques semaines et qui m'a poussé à me questionner sur la langue dans laquelle je publie sur ce blog.

Bonne lecture ! 😁️

Carnet de dev : Amélioration du support des tableaux dans rst2gemtext

Les articles de mon blog sont formatés à l'aide d'une syntaxe nommée reStructuredText. C'est la même syntaxe que celle utilisée par les docs Sphinx dont j'ai déjà parlé il y a quelques années sur le blog.

Lorsque je publie la version Web de mon blog, le reStructuredText est converti en HTML pour qu'il puisse s'afficher dans votre navigateur. En parallèle de la version Web, je publie également une version Gemini du blog [non, rien à voir avec l'IA de Google 😛️], et ce même reStrucuredText est alors transformé en Gemtext, le format de balisage utilisé pour les capsules Gemini.

Docutils, la bibliothèque Python qui permet de parser et de convertir le reStructuredText vers de nombreux autres formats dont HTML, ODT ou encore DOCX, ne supporte malheureusement pas le Gemtext en sortie. J'ai donc dû m'y coller moi-même. C'est comme ça que j'ai créé rst2gemtext, qui est à la fois un outil en ligne de commande et une bibliothèque Python permettant de convertir le reStructuredText en Gemtext.

Je ne vous en dis pas plus, car j'ai déjà écrit un article complet sur Gemini et les outils que j'ai développés autours :

Étant donné que j'ai avant tout créé cette bibliothèque pour mon propre usage, j'ai commencé par supporter principalement les éléments de la syntaxe de reStructuredText que j'utilisais moi-même.

Actuellement la plupart des « balises » courantes sont supportées, mais il m'arrive d'en rajouter quand j'en ai besoin (ou quand quelqu'un me le demande). J'ai par exemple récemment implémenté le nécessaire pour les notes de bas de pages, car je m'en suis servi pour la première fois dans un de mes derniers articles.

Et donc on en vient aux tableaux... C'est un sacré sujet les tableaux... 🙃

Déjà premier problème : Gemtext est une syntaxe volontairement très limitée, et ne supporte pas du tout les tableaux. Du coup la seule façon d'en représenter un quand on en a quand même besoin, c'est de le dessiner avec des caractères dans un bloc de texte préformaté.

Sauf que dessiner des tableaux, bah c'est compliqué. Surtout quand il peut y avoir des cellules fusionnées sur des lignes et des colonnes... Comme j'avais pas envie de trop me casser la tête avec les tableaux, et que par chance, en reStructuredText, pour faire un tableau, il faut le dessiner en ASCII-art, et bah j'ai triché.

Au lieu de prendre l'arbre de nœuds fournit par Docutils et d'essayer de redessiner le tableau par moi-même... et bah je vais juste le récupérer dans le document reStructuredText d'origine (puisqu'il y est déjà dessiné) et je le colle en l'état dans le document final.

Exemple de tableau en reStructuredText, avec des cellules fusionnées dans tous les sens :

+----------+-------+-----------------+-------------------+-------------------+
|          |       | Cores (threads) | Base clock rate   | Turbo Boost       |
| Branding | Model +--------+--------+---------+---------+---------+---------+
|          |       | P      | E      | P       | E       | P       | E       |
+==========+=======+========+========+=========+=========+=========+=========+
|          | 1280P | 6 (12) |        | 1.8 GHz | 3.6 GHz |         | 3.6 GHz |
|          +-------+--------+        +---------+---------+ 4.8 GHz +---------+
| Core i7  | 1270P |        |        | 2.2 GHz | 1.6 GHz |         | 3.5 GHz |
|          +-------+        |        +---------+---------+---------+---------+
|          | 1260P |        |        | 2.1 GHz | 1.5 GHz | 4.7 GHz | 3.4 GHz |
+----------+-------+ 4 (8)  | 8 (8)  +---------+---------+---------+---------+
|          | 1250P |        |        |         |         |         |         |
| Core i5  +-------+        |        | 1.7 GHz | 1.2GHz  |         |         |
|          | 1240P |        |        |         |         | 4.4 GHz | 3.3 GHz |
+----------+-------+--------+        +---------+---------+         |         |
| Core i3  | 1220P | 2 (4)  |        | 1.5 GHz | 1.1 GHz |         |         |
+----------+-------+--------+--------+---------+---------+---------+---------+

Je dois bien avouer que c'est pas très propre. Des fois il reste des bouts de syntaxe reST dans les cellules, mais globalement ça fait le taf... Enfin ça, c'est ce que je croyais...

Le problème, c'est que Docutils fournit des directives permettant également de construire des tableaux depuis des CSV ou des listes... Je ne le savais pas, et c'est grâce à l'ami Dryusdan que je l'ai appris... Il utilise en effet cette fonctionnalité sur son blog, et il se trouve que ça faisait crasher rst2gemtext... Oops ! 😅

Voici un exemple de tableau en CSV, issu du dernier article de Dryusdan :

.. csv-table::
   :header: "Logiciel", "Moyenne", "Mediane", "Min", "Max"
   :widths: 6, 5, 5, 3, 3

   "Bind", "0.546", "0.1", "0.1", "11.8"
   "Blocky", "0.267", "0.2", "0.2", "3.9"
   "Knot", "0.192", "0.2", "0.1", "0.7"
   "Pihole", "0.182", "0.1", "0.1", "0.9"
   "Unbound", "0.371", "0.1", "0.1", "7.8"

J'ai donc commencé à réfléchir à la question... Et j'en suis venu à la conclusion qu'un tableau construit depuis un CSV, c'était un cas simple. Il n'y a pas de géométries bizarres comme des cellules fusionnées. J'ai donc entrepris de récupérer les données CSV brutes, et de dessiner moi-même le tableau en ASCII-Art.

Pour ça, j'ai surchargé la directive csv-table pour récupérer les données brutes, les transformer en une liste à deux dimensions que j'attache ensuite au node du tableau.

Lors du rendu du document Gemtext, j'ai juste à dessiner le tableau. Bon j'ai quand même pris quelques raccourcis. Pour le moment je ne gère absolument pas le découpage d'un texte sur plusieurs lignes, donc si une cellule contient un texte très long, bah le tableau sera très large. De plus, en dehors de l'option "headers" dans laquelle je récupère les entêtes du tableau, je ne tiens compte d'aucune autre option ("width" est totalement ignorée dans l'exemple ci-dessus). Pour le moment c'est suffisant, mais c'est des points qui pourraient être améliorés à l'avenir, si le besoin s'en fait sentir.

Donc voilà ce que ça donne :

À gauche le document reStructuredText avec le tableau CSV, à droite le document Gemini qui en résulte

À gauche le document reStructuredText avec le tableau CSV, à droite le document Gemini qui en résulte

Comme je l'ai mentionné, il est également possible de générer un tableau à partir de listes. Cela se fait avec la directive list-table, et elle est à présent gérée également :

À gauche le document reStructuredText avec le tableau à base de listes, à droite le document Gemini qui en résulte

À gauche le document reStructuredText avec le tableau à base de listes, à droite le document Gemini qui en résulte

À noter qu'il y a une petite subtilité avec les listes : il faut traiter tout le contenu de la directive comme un document reStructuredText à part entière et donc le parser. Il peut en effet y avoir des éléments de syntaxe dedans. D'ailleurs ici aussi j'ai pris des raccourcis... Si jamais il y a une référence quelque part (comprendre un lien), je pense qu'il sera perdu. Je ne fais qu'extraire le texte des éléments de la liste...

Voilà, c'est tout pour cette plongée au cœur des problématiques d'un petit convertisseur de syntaxe ; j'espère ne pas avoir été trop long ! 😅

Note

NOTE : rst2gemtext 0.7 est sorti avec les améliorations dont je viens de parler. Vous retrouverez la release sur GitHub :

Mises à jour d'articles plus visibles sur le blog

Jusqu'à présent, le fait qu'un article du blog ait été modifié après sa publication originale était assez peu visible. Je n'avais tout simplement rien prévu pour cela.

Par souci de transparence, j'ajoutais en général au niveau de la modification ou en fin d'article une mention expliquant le changement apporté. Avec le temps ça s'est structuré sous la forme d'une liste à puce en pied d'article avec le texte suivant : « EDIT YYYY-MM-DD: description du changement ».

C'est bien, mais ce n'est pas visible au premier coup d'œil pour le lecteur.

À présent, en plus de la liste des modifications en pied d'article, j'utilise la métadonnée :modified: de Pelican (mon générateur de site statique) pour définir la date de dernière modification, et j'ai adapté mes templates en conséquence pour faire apparaître cette information sur les articles concernés, de manière bien visible.

Mention de mise à jour sur la page d'un article

Mention de mise à jour sur la page d'un article

Mention de mise à jour sur la page « tous les articles »

Mention de mise à jour sur la page « tous les articles »

À noter que seules les modifications importantes seront rapportées, comme la modification, la suppression ou l'ajout d'une information. La simple correction d'une faute d'orthographe ou de grammaire ne sera pas indiquée : ça ne change pas le fond de l'article et puis tous les articles apparaîtraient comme modifiés dès le jour de leur sortie ! 😅

Donc voilà, la modification est en place, et je suis repassé sur les anciens articles pour ajouter la date de dernière modification à ceux qui avaient eu des mises à jour... À noter que j'ai juste fait un "grep -nr EDIT content/" sur mon blog pour repérer les articles qui contenaient le mot EDIT. Il est possible que quelques-uns soient passés à travers. Mais je les annoterai le jour où je tomberai dessus ! 😉

Réflexions sur un article : This blog is written in en-GB

Petit post en anglais britannique de Terence Eden dans lequel il répond à un commentaire qu'il a reçu récemment sur son blog. Le commentateur lui reprochait de ne pas être assez « inclusif », car il use d'un langage et de références culturelles qu'il ne juge pas assez « globales ». Terrence est anglais et utilise donc un vocabulaire, des expressions et des références culturelles britanniques. L'auteur du commentaire est quant à lui probablement américain.

Dans son article, le blogueur répond fermement « non ». C'est sa culture, sa manière de parler, son « accent ». Il ne compte pas changer sa manière de s'exprimer pour essayer de plaire à tout le monde. Et je pense qu'il a bien raison.

Le monde est plein de cultures différentes, chacune avec ses références étranges, ses expressions bizarres, ses phrasés exotiques, et c'est justement ce qui fait le charme des blogs personnels : on y découvre autre chose. C'est pas des sites corporates avec des contenus lisses, rédigés par des chargés de com' (ou pire, des LLM...).

À force d'être confronté à toutes ces autres cultures, on finit par les comprendre un peu, ça ouvre nos horizons. Ça serait un sacré gâchis d'essayer de tout normaliser autours d'une moyenne américano-centrée. On y perdrait beaucoup.

Dans le milieu de la tech, on communique principalement en anglais, et on m'a parfois demandé pourquoi je m'obstinais à écrire mes articles techniques en français. Mon blog pourrait toucher un public bien plus large s'il était en anglais.

D'un point de vue strictement numérique, il est vrai qu'écrire en français limite le nombre de lecteurs potentiel. Mais c'est la langue avec laquelle je suis le plus à l'aise. C'est la langue dans laquelle j'arrive vraiment à exprimer toutes les nuances que je souhaite, celle dans laquelle j'arrive à faire des jeux de mots plus ou moins subtiles [ou complètement pourris, selon votre sensibilité 😛].

Si j'écrivais en anglais, les textes que je produirais seraient moins personnels, et seraient en plus en concurrence avec une grande quantité d'autres blogs, écrits par des gens qui maîtrisent bien mieux les subtilités de la langue anglaise que moi. Pas sûr que j'arriverai à toucher tant de lecteurs que ça au final.

Et puis j'aurai aussi un autre problème avec l'écriture en anglais : la motivation. Je fais l'effort d'utiliser l'anglais pour les sites de mes projets (par exemple sur celui de Rivalcfg ou de YOGA) et dans ma newsletter sur Buy Me a Coffee. Mais je vois bien que ça me demande beaucoup plus de travail et de motivation, et que le résultat n'est pas au niveau que je souhaiterais. Il est probable que je publierai beaucoup moins — voire presque plus du tout — si je m'imposais l'anglais sur mon blog perso.

En y réfléchissant davantage, je me rends compte qu'en fait, la question n'est même pas là. Il faut garder en tête qu'il s'agit de mon blog perso et que je ne gagne pas d'argent avec. Le nombre de visiteurs importe finalement assez peu. Bien sûr, je regarde de temps en temps les stats de visite et je suis content quand il y a du monde qui vient lire un article, mais je n'essaye pas pour autant d'optimiser des KPI comme le nombre de visiteurs ou de pages vues, je publie juste ce qui me plaît, quand j'en ai envie et c'est très bien comme ça.

Avec le format journal de bord (dont vous êtes en train de lire l'une des entrées), j'ai essayé de réduire les frictions. J'ai cherché à me simplifier l'écriture et la publication d'article. Je ne vais donc pas me mettre des bâtons dans les roues en me forçant à publier dans une langue que je maîtrise moins.

Bref, ce blog restera en français de France, pour le meilleur et pour le pire ! 😁

C'est tout pour aujourd'hui

Et voilà, on a fait le tour des sujets du jour. Je sens que les JDB se structurent petit à petit, et je commence à distinguer des rubriques plus définies au milieu de sujets plus « libres ». Je constate que certaines de ces rubriques sont plus récurrentes que d'autres, comme les recommandations d'articles (même s'il n'y en a pas eu cette fois-ci) ou les carnets de dev (d'autres sont en approche). N'hésitez pas à me dire en commentaire lesquelles vous intéressent le plus !

À bientôt pour un prochain JDB ! 😉️