Aller au contenu

Asciidoctor, LaTeX et Markdown sont dans un bateau

·1114 mots·6 mins
Sommaire

Il y a quelques années que j’ai découvert le langage de balisage Markdown, proposé par John Gruber. Ce langage a évolué sous plusieurs formes, avec plusieurs extensions, pour devenir CommonMark, supporté par la majorité des plateformes connues (dont ce blog - cet article étant rédigé sous ce format également).

Markdown (CommonMark) = ❤️, d’abord pour sa simplicité, mais également pour sa syntaxe facile à retenir et pour sa rapidité de production de contenu. Par simplicité, j’entends de ne pas avoir à réapprendre chaque jour une syntaxe qui ne me convient pas : déclarer du texte comme étant \it{...}, c’est trop de caractères et trop de combinaisons de touches pour mes pauvres petits doigts boudinés, là où Markdown permet de simplement encapsuler le texte entre astérisques.

(Dans la suite de cet article, j’intervertirai aussi bien Markdown que CommonMark, mais la syntaxe que je vise est la même : quelque chose de simple à apprendre et à mémoriser, et qui se rapproche autant des standards que possibles 😉).

Avec mes idées (pourries) de rédaction de textes plus complets, Markdown devient trop étriqué :

  • Il lui manque la possibilité de gérer une table des matières [^1],
  • Des anotations au niveau des blocs de code,
  • Une bibliographie,
  • Un index reprenant les blocs de codes ou différents termes,
  • Une liste de où de placer correctement les images.

Le top en termes de résultat de rédaction consiste à passer par une distribution LaTeX, mais qui dispose de son propre écosystème, de plusieurs implémentations, de plusieurs outils et est finalement assez goinfre sur l’espace disque utilisé. Il existe quelques plateformes, notamment Overleaf, qui proposent une sorte de “Github Pages” évolué, mais tout ceci reste assez lourd comme déploiement.

Pour résumé, on a

  1. D’un côté Markdown qui dispose d’une syntaxe facile à mémoriser et retranscire, tout en étant relativement limité,
  2. De l’autre, LaTeX qui est un vrai langage et environnement de développement à lui tout seul, mais qui nécessite un apprentissage plus poussé et une maîtrise pointue de son écosystème.

Introducing Asciidoc
#

Entre les deux, on trouve Asciidoc, qui

  • Présente toujours du texte structuré mais lisible (comme Markdown),
  • Propose des options de personnalisation nettement plus poussées,
  • … tout en étant moins configurable qu’un document LaTex.

L’implémentation d’Asciidoc proposée par Asciidoctor définit les standards de ce qui est supporté, et gère quelques extensions au travers de l’outil gem du langage Ruby.

Comme l’indiquait Linus Torvald lui-même :

Use AsciiDoc for document markup. Really. It’s actually readable by humans, easier to parse and way more flexible than XML.

Métadonnées
#

Asciidoc déclare les métadonnées de son document directement à la racine, un peu comme Markdown, mais de manière beaucoup plus structurée - toute la documentation est très complète. Qquelques lignes types permettent ainsi de :

:doctype: book
:docinfo:
:toc:
:toclevels: 2
:pagenums:
:partnums:
:sectnums:
:bibtex-file: references.bib
:source-highlighter: rouge
:rouge-style: github
:imagesdir: images
  1. Déclarer le type de document que nous rédigeons ({book|article|…}),
  2. Ajouter automatiquement des métadonnées du document (qui pourraient être utiles si on utilise une conversion via DocBook),
  3. Ajouter une table des matières sur deux niveaux,
  4. Ajouter une numérotation des pages, des parties, des chapitres et des sections,
  5. Ajouter une référence à une bibliographie,
  6. Ajouter la coloration syntaxique en utilisant le style de Github,
  7. Et indiquer où se trouve le répertoire contenant l’ensemble des images. Ce dernier point sera utile pour référencer du PNG, par exemple via image::deploy-without-hassle.drawio.png[align="center"].

Là où :

  • Markdown sera nettement plus libre, puisque ses métadonnées dépendront du convertisseur,
  • LaTeX consistera à copier/coller des blocs de code depuis Stackoverflow sans en comprendre réellement l’intérêt.

Pour information, le dernier livre sur lequel j’ai travaillé commençait avec la structure (encore légère) suivante :

\documentclass[twoside=no,parskip=half,numbers=enddot,bibliography=totoc,index=totoc,listof=totoc]{scrbook}
\usepackage{amsmath}
\usepackage{makeidx}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage{csquotes}
\usepackage[acronym]{glossaries}
\usepackage{hyperref}
\usepackage{setspace}
\usepackage{listing}
\usepackage{minted}[tabsize=4]
\usepackage{graphics}
\usepackage{float}
\usepackage[export]{adjustbox}

… que je serais totalement incapable d’expliquer de mémoire, sans un accès à différentes ressources.

Convertisseurs et backends
#

Je le disais plus haut, l’obtention d’un résultat avec LaTeX va dépendre de plusieurs paramètres et pourra être relativement complexe à appréhender pour quelqu’un qui débuterait - tous les outils n’étant pas forcément cross-platforms.

Avec Markdown, cela dépendra également de plusieurs paramètres, dont l’interpréteur : du texte rendu avec Hugo ne sera pas obligatoirement identique à un rendu réalisé avec Jekyll ou Docusaurus, là où Asciidoc va être beaucoup plus structuré - l’implémentation par défaut étant réalisée avec Asciidoctor - ce qui évite la dispersion des ressources.

Admonitions
#

Un exemple assez intéressant concerne les admonitions. LaTeX ne propose (à ma connaissance) rien sans implémenter quelque chose comme ceci :

\RequirePackage{tcolorbox}

\definecolor{flyingblue}{RGB}{49, 123, 181}

\newenvironment{advicebox}
    {
        \begin{tcolorbox}[colback=flyingblue!5!white, colframe=flyingblue!100!black,title={Conseils}]
    }
    {
        \end{tcolorbox}
    }

Pour Markdown, cela dépendra du moteur de rendu :

  • Docusaurus sépare le début et la fin par :::{note|tip|info|warning|danger},
  • Jekyll ne semble rien avoir en natif,
  • Hugo par contre demanderait à passer par des shortcodes - autant dire que cela dépend du thème utilisé et d’un certain nombre de câblages : lorsqu’un article en Markdown contient ce type de morceaux de code {{ ... }}...{{ ... }}, c’est finalement assez dégueulasse et casse l’idée de devoir écrire quelque chose qui sera totalement indépendant de la solution de conversion.

Pour Asciidoc(tor), la documentation est assez claire :

WARNING: Wolpertingers are known to nest in server racks.
Enter at your own risk.

Compilation
#

Comme je l’ai déjà indiqué, la compilation de Markdown dépend énormément du moteur de rendu choisi.

Avec LaTeX, il est possible de repartir d’un container Docker, type :

set -e
docker run -ti -v miktex:/miktex/.miktex -v `pwd`:/miktex/work miktex-pygments pdflatex main.tex -shell-escape
docker run -ti -v miktex:/miktex/.miktex -v `pwd`:/miktex/work miktex-pygments makeindex main.idx
docker run -ti -v miktex:/miktex/.miktex -v `pwd`:/miktex/work miktex-pygments bibtex main
docker run -ti -v miktex:/miktex/.miktex -v `pwd`:/miktex/work miktex-pygments pdflatex main.tex -shell-escape
set +e

… ce qui ressemble furieusement à un joyeux bordel, avec plusieurs démarrages de commandes successives au travers de containers identiques. Il y a moyen de faire mieux.

Côté Asciidoctor, on est sur quelque chose de beaucoup plus soft, bien qu’il faille installer quelques dépendances malgré tout :

podman run -v `pwd`:/documents docker.io/asciidoctor/docker-asciidoctor asciidoctor-pdf\
		-r asciidoctor-bibtex\
		-a pdf-themesdir=resources/themes\
		-a pdf-fontsdir=resources/fonts\
		-a pdf-theme=gwift\
		gwift-reborn.asc

Conclusions
#

Pour des textes simples, je garde CommonMark pour sa reconnaissance sur les différentes plateformes. Lorsque la structure est plus complexe, je penche pour Asciidoc. Et lorsque j’y suis obligé, LaTeX reste une option, mais avec la nécessité de bloquer du temps pour replonger dans la construction d’un environnement poussif.

Je suis passé volontairement au-dessus de reStructuredText (d’abord parce que je dois systématiquement réfléchir à comment l’écrire et que j’ai développé une forme de dyslexie localisée pour ce langage), notamment à cause de son intégration qui me semble localisée au langage Python.

[^1] Même si l’option existe au travers d’une extension [TOC], sa configuration reste limitée.