URL: https://linuxfr.org/users/anaseto/journaux/frundis-philosophie-motivations-et-nouveautes Title: frundis : philosophie, motivations et nouveautés Authors: anaseto Date: 2015年02月07日T11:15:33+01:00 License: CC By-SA Tags: markup Score: 16 Cher journal, Il n'y a pas très longtemps, je [présentais](https://linuxfr.org/users/anaseto/journaux/frundis-langage-de-markup-pour-exporter-vers-latex-xhtml-et-epub) un nouveau projet de langage de balisage appelé [frundis](http://bardinflor.perso.aquilenet.fr/frundis/intro-fr), 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 `` 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) : ``` groff .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 `Texte Important`. 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 `
` 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 : ``` groff .\" 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
.Ef .\" ou, en une seule ligne : .Ft -f xhtml
``` 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](http://mdocml.bsd.lv/). *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.

AltStyle によって変換されたページ (->オリジナル) /