Journal frundis : philosophie, motivations et nouveautés

Posté par (page perso) . Licence CC by-sa
Tags :
15
7
fév.
2015

Sommaire

Cher journal,

Il n'y a pas très longtemps, je présentais un nouveau projet de langage de balisage appelé frundis, permettant d'exporter des documents vers html, EPUB ou LaTeX. Depuis, le langage a connu un grand nombre d'évolutions. Un résumé des changements est donné à la fin dans la section « Changements ». Le reste du journal discute les motivations et la philosophie derrière ce langage, tout en fournissant quelques illustrations.

Philosophie et motivations

Beaucoup de langages, souvent orientés documentation (comme texinfo, docbook, mdoc, etc.), fournissent une multitude de commandes pour différents types d'éléments : on trouve des macros ou éléments prédéfinis pour des éléments spécifiques comme des noms de fichiers, de variables, etc. Avec frundis c'est, pour ainsi dire, tout le contraire. En fait, on trouvera même, initialement, moins d'éléments sémantiques que dans un langage comme markdown : pas de macro pour le code, ni double emphase **, mais juste un seul type de marquage, Sm (Semantic markup), qui par défaut correspond à une simple mise en emphase avec des * en markdown, i.e <em> en html, ou \emph en LaTeX. En fait, ceci rend aussi frundis assez différent de la plupart des langages de type roff, dont le nombre de noms de macros à retenir a tendance à exploser rapidement.

Le résultat positif est qu'un tableau récapitulatif des macros de base tient sur un seul écran. Bien sûr, si frundis ne pouvait pas dépasser la simple emphase, le fait qu'il y ait peu de macros à apprendre n'aurait pas d'importance, car le langage serait peu utile de toutes façons. Comme expliqué rapidement la dernière fois, frundis a été conçu pour permettre d'ajouter des tags arbitraires à la macro Sm, pouvant ainsi marquer du texte de mille façons différentes avec une seule macro (bon, il y a aussi une version multi-ligne Bm (Begin markup) de Sm, mais c'est la même chose). Pourquoi des tags arbitraires ? Parce qu'initialement frundis a été conçu pour un roman de fantasy, dont la sémantique peut être assez inventive et variable. Une conséquence est que frundis est relativement indépendant de la sémantique du document à produire.

Par exemple, les invocations suivantes (où X (eXport) est la macro permettant de définir des paramètres) :

.X mtag -f xhtml -t ` -c code
.X mtag -f xhtml -t ** -c strong

nous ramènent au même niveau d'expressivité que markdown : on peut maintenant écrire .Sm -t ** Texte Important qui donnera <strong class="**">Texte Important</strong>. Ceci dit, en pratique, c'est une meilleure idée d'utiliser des tags qui décrivent la nature du contenu (donc ni **, ni gras, etc.).

Bref, ça ressemble à ajouter des classes en html à des éléments, puis à utiliser du css. En fait, c'est en gros ce qui se passe, sauf que l'on exporte en même temps aussi vers LaTeX : il suffit de donner une invocation de X spécifique à LaTeX pour les mêmes tags. Une autre différence est que frundis va se plaindre si un tag est utilisé alors qu'il n'est pas défini.

frundis étend le concept aux éléments de type <div> pour marquer un ensemble de paragraphes (ça donne des environnements en LaTeX), ce qui fait qu'il n'y a aussi qu'une seule macro Bd (Begin display block) pour faire des regroupements.

Pour résumer, l'idée est que frundis fournisse de base le moins possible de choses qui ne seront pas utilisées par tous et ne feront que rallonger le manuel, sans pour autant empêcher d'enrichir la sémantique.

Dans le même objectif d'économie, frundis essaie de tirer le plus parti possible de chaque macro. Par exemple, la même macro Tc (Table of contents) sert à faire des tables des matières de plusieurs sortes (complète, résumé .Tc -summary, résumé des sections en début de chapitre .Tc -mini, liste des tables, figures). Au lieu de retenir les noms de plusieurs macros, il suffit d'en retenir un, puis d'aller lire le manuel à la bonne place pour les options.

Une motivation, à l'heure de créer une nouvelle macro de base du langage, peut provenir de différences importantes entre html et LaTeX pour une certaine tâche, qui rendent difficile de faire soi-même une macro simple qui marche pour les deux formats. Par exemple, écrire une table des matières automatique en LaTeX est très facile (une commande existe de base), mais ce n'est pas le cas en html, d'où le fait que la macro Tc soit plutôt complète. De même, frundis propose des moyens de faire des références croisées quelconques qui marchent pour les différents formats.

Ceci dit, frundis n'a pas l'intention d'essayer (sans y parvenir) de permettre d'écrire, en pur frundis, des choses compliquées peu courantes et très différentes en LaTeX et HTML, et dont une sémantique commune est difficile à établir : celles-ci peuvent être incluses telles quelles dans des blocs spécifiques à un format, ou mises dans un fichier à part à inclure ; le langage fournit assez d'outils pour ça :

.\" inclure tel quel un fichier LaTeX tel quel lors de l'export en LaTeX
.If -f latex -as-is fichier-à-inclure.tex
.\" inclure tel quel un fichier html tel quel lors de l'export en XHTML
.If -f xhtml -as-is fichier-à-inclure.html
.\" écrire un bloc html directement dans le fichier frundis
.Bf -f xhtml
<hr>
.Ef
.\" ou, en une seule ligne :
.Ft -f xhtml <hr>

On remarquera que, pour chaque fonction, une seule macro est utilisée pour les différents formats (pas de « iftex », « ifhtml », etc.).

Enfin, frundis veut aussi donner un minimum de bagage pour structurer ses documents et faire un peu de programmation. Il permet donc d'inclure des fichiers, de filtrer des parties à travers des commandes externes, et de ne pas se répéter à l'aide de variables et de macros textuelles un peu dans le style de roff (ou texinfo), mais avec des limitations : pas de macros récursives ou ce genre de choses, frundis ne va pas réinventer un nouveau (mauvais) langage de programmation. Il doit rester simple pour produire des messages d'erreur compréhensibles. Par contre, frundis est maintenant extensible en Perl à l'aide d'une API objet assez simple, ce qui ouvre la voie à beaucoup de possibilités pour ceux qui veulent (tout le CPAN peut être utilisé !).

Limitations de frundis

LaTeX et html sont deux langages assez différents, complexes, chacun avec ses particularités, et frundis ne vise pas à les comprendre ni à les analyser. En particulier, le choix d'un nom de commande d'export LaTeX pour une macro Sm doit être raisonnable et correspondre à quelque chose qui marque du texte : si le nom est documentclass ou autre commande qui n'a rien à voir avec marquer du texte, frundis ne va rien dire, et des choses bizarres peuvent arriver (pour html il y a un warning si on met n'importe quel élément, ceci dit). L'avantage, c'est qu'on peut mettre des noms de commandes LaTeX que l'on a créés soi-même. En pratique, ce n'est pas vraiment un problème, et au pire on a une erreur en compilant le LaTeX après, par exemple, et frundis a ceci d'intéressant que le layout du code LaTeX produit ressemble assez au code source frundis original, donc c'est assez facile de s'y repérer.

Le fait de devoir inventer soi-même la sémantique à utiliser n'est pas forcément optimal pour tous les usages. Initialement, le système a été prévu pour des romans, pour lesquels prévoir à l'avance un ensemble fixé d'éléments pour décrire la sémantique n'est pas possible. Après, quelques invocations de X servent pour de nombreux usages, mais pour des documents spécifiques frundis n'est pas le meilleur outil : en particulier, les pages de manuel de frundis ne sont pas écrites en frundis, mais à l'aide du langage mdoc. frundis ne sert pas non plus à écrire un article scientifique, ni une lettre, ni une présentation, etc., bien qu'il soit probablement souvent facile d'écrire quelques macros qui produisent ce que l'on veut, mais ça n'a pas forcément d'intérêt si l'on vise un seul format d'export, comme c'est souvent le cas pour ce type de documents. Néanmoins, si c'est html qui est le seul format visé, et pas LaTeX, frundis reste une bonne solution pour le générer grâce aux facilités qu'il fournit qui n'existent pas en html.

Il est vrai aussi que la définition des tags demande de connaître un peu de LaTeX et de html. Ceci dit, frundis ne demande de connaître que les quelques commandes de LaTeX ou éléments html pour marquer du texte que l'on veut utiliser. De plus, la plupart des choses, comme les tables de matières, les références, etc., sont gérées par frundis indépendamment du format.

Une autre limitation est que frundis n'a à aucun moment en mémoire une représentation abstraite de tout le code source, donc, niveau implémentation, des manipulations complexes à la xml ne sont pas possibles. frundis parcourt le code source deux fois : une première fois pour chercher des informations (pour les références, etc.), une deuxième fois pour produire la sortie au fur et à mesure. Un avantage de ce mode d'opération est que, malgré le fait que frundis soit écrit dans un langage dynamique comme Perl, il est suffisamment rapide : un roman de quatre cent pages prend chez moi un tiers de seconde, c'est-à-dire plusieurs fois moins que pandoc. Un autre avantage est que, pour étendre frundis, il suffit d'appliquer quelques méthodes à un objet, puis de faire un print de ce qu'on veut afficher pendant la phase d'affichage. C'est plus accessible que de faire des manipulations d'arbre syntaxique, tout en utilisant le même langage qui sert à écrire frundis : on évite d'avoir à transformer le langage frundis lui-même en un langage de programmation, qui resterait inévitablement rudimentaire.

frundis n'est pas prévu non plus pour exporter vers une multitude de formats différents, contrairement à beaucoup de langages de balisage légers. Un avantage est que la page de manuel décrivant les options en ligne de commande est bien plus courte (au point que la section d'exemples est exhaustive).

Enfin, et surtout, frundis utilise, malheureusement, une syntaxe à la roff, et il faut un peu de temps pour commencer à apprécier ses avantages qui sont, principalement, qu'il y a moins à écrire par rapport à du html ou xml, que le texte se sépare bien visuellement des commandes, et que c'est facile à utiliser avec des outils comme grep, diff ou n'importe quel éditeur de texte orienté ligne à ligne. On peut noter aussi le fait qu'il n'y a que deux caractères spéciaux à échapper en frundis, \ (partout) et " (dans les arguments de macros seulement).

Quoi de plus ?

Voilà, j'espère avoir expliqué les objectifs du langage suffisamment clairement. En particulier, frundis n'essaie pas de réinventer la roue avec encore un nouveau langage de balisage. En fait, frundis fait tout sauf réinventer la roue : il exporte vers des formats standard, utilise une syntaxe connue et un langage d'extension qui est dans sa troisième décennie. Le programme (hors tests, manuels et quelques outils annexes) fait quatre mille lignes de code, c'est-à-dire moins que la plupart des langages de balisage légers utilisés aujourd'hui. Enfin, je ne connais aucun langage de balisage avec les mêmes caractéristiques. Autrement, je n'aurais pas écrit frundis, à part peut-être pour m'amuser, mais, dans ce cas, je me serais arrêté il y a un bon moment probablement ;)

Changements

Voici une liste des principaux changements depuis la dernière fois.

Langage :

  • Tables des matières variées (index complet, résumé), des mini tables de matières en début de chapitre (voire même en début de partie pour l'export html).
  • Listes des figures et des tables.
  • Possibilité d'ajouter manuellement de nouveaux identifiants (id en html ou un label en LaTeX) et d'y faire référence ensuite avec la macro Sx.
  • Possibilité de filtrer des portions de texte à travers une commande externe.
  • Support complet de la ponctuation (au sens n'importe quel caractère Unicode de ponctuation), ainsi que des ajouts automatiques d'espaces insécables en français.
  • Les paragraphes (macro P) peuvent recevoir un titre (ce qui donne un \paragraph{titre} en LaTeX en particulier).
  • Une nouvelle macro #fl pour contrôler certains paramètres d'état (par exemple pour supprimer l'ajout d'espaces entre les appels de macro, ce qui permet de marquer des portions d'un mot, par exemple).
  • Une nouvelle macro #if pour exécuter conditionnellement un partie du document (imbrication possible).
  • Une nouvelle macro #dv qui permet de définir des variables qui peuvent ensuite être interpolées dans le texte ou les arguments de macros (par exemple dans le test d'un #if).
  • Possibilité d'écrire un nouveau type de macros plus complexes avec #de -perl : une API objet assez simple permet d'utiliser tout le langage Perl pour définir de nouvelles macros.
  • Une variable d'environnement FRUNDISLIB contenant une liste de répertoires dans lesquels chercher des fichiers à inclure.
  • de est préfixée par un # maintenant, comme toutes les macros (hormis X) qui ne produisent pas directement un résultat.
  • Les macros Dt et Dd ont disparu : il faut utiliser les paramètres document-title et document-date maintenant.
  • frundis essaie de faire son possible quand il rencontre des erreurs de syntaxe, tout en lançant des alertes informatives, plutôt que de s'arrêter à la première erreur dans le fichier source.

Quelques spécificités liées au format produit :

  • nouveau export vers EPUB3
  • nouveau export vers du HTML5
  • les EPUB générés sont totalement valides maintenant (normalement).
  • la page d'index de la sortie html peut être personnalisée.

Et bien sûr, aussi, beaucoup de bugs corrigés, une documentation plus complète et des tests plus exhaustifs.

  • # Typos

    Posté par (page perso) . Évalué à 2.

    Il y a un « ajouter des tag arbitraires" » avec un " au lieu d'un *, ce qui fait qu'une phrase part en italique… si un modérateur veut bien corriger, je lui en serai reconnaissant !

  • # Cycle de Shaedra

    Posté par (page perso) . Évalué à 1.

    Quand j'ai lu le nom du projet j'ai tout de suite pensé au fameux bâton saïjit (Forcement, je suis en cour de lecture du dernier tome).
    Et bien oui, il y a bien un lien :)

    • [^] # Re: Cycle de Shaedra

      Posté par (page perso) . Évalué à 3.

      Oui, au tout début je pensais juste faire un langage pour le Cycle de Shaedra, puis il a grossit un peu avec le temps. Après, le choix de frundis comme nom, spécifiquement, plutôt qu'un autre personnage ou nom de la saga n'est pas plus profond que ça, juste que ça sonnait bien, musicalement ;)

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.