catium

Un générateur de site statique - retour accueil

git clone git://bebou.netlib.re/catium
Log | Files | Refs | README |

commit dfe467550ba31f6e58289d2a221dba8aaedce11c
parent f0eda2826af88ffd39f9889d6bd3c18cb83ef8ff
Auterice: Arthur Pons <arthur.pons@unistra.fr>
Date:   Mon, 26 Aug 2024 16:33:44 +0200

Comment construire Francium du README à CONSTRUIRE

Diffstat:
MREADME | 1086+------------------------------------------------------------------------------
1 file changed, 13 insertions(+), 1073 deletions(-)

diff --git a/README b/README @@ -1,6 +1,16 @@ -Dépôt contenant les élèments du générateur de site statique Francium et les -sources du site du collectif Katzele -=========================================================================== +# Francium + +``` +shshsh shshsh shshsh sh sh shshsh shshsh sh sh sh sh +sh sh sh sh sh shsh sh sh sh sh sh shshsh +shsh shshsh shshsh sh shsh sh sh sh sh sh sh +sh shsh sh sh sh shs sh sh sh sh sh sh +sh sh sh sh sh sh sh shshsh shshsh shshsh sh sh + + Wait it's all shell scripts ? + / + 🚶🔫🚶 - Always has been +``` ## Une histoire de Francium @@ -502,1073 +512,3 @@ règle pour les fichiers html : Cette fois-ci la recette ne contient que la commande install puisqu'il n'y a pas de transformation à faire. Hop c'est fait ! - -#### page et le format des fichiers markdown - -Quelque chose vous aura peut-être fait ticker dans cette explication du -makefile. Comment la commande suivante peut elle fonctionner et quel est son -rapport au script `page` prérequis a son bon fonctionnement sans pour autant -qu'il apparaisse. - - src/index.md | install -D /dev/stdin root/index.html - -La réponse courte à cette question est : - -> Deux astronautes sont dans l'espace faisant face à un Francium géant constitué de pleins de petits 'sh'\ -> Les astronautes sont l'un derrière l'autre, le premier contemple Francium, le -> second tient le premier à bout portant avec un pistolet\ -> Le premier dit "Wait, it's all shell scripts ?", le second répond "Always has been" - -``` -shshsh shshsh shshsh sh sh shshsh shshsh sh sh sh sh -sh sh sh sh sh shsh sh sh sh sh sh shshsh -shsh shshsh shshsh sh shsh sh sh sh sh sh sh -sh shsh sh sh sh shs sh sh sh sh sh sh -sh sh sh sh sh sh sh shshsh shshsh shshsh sh sh - - 웃 🔫웃-Always has been - \ - Wait it's all shell scripts ? -``` - -Plus sérieusement nous allons procéder comme pour le makefile, en partant du -premier besoin, le plus essentiel, et en brodant petit à petit autour jusqu'à -arriver au degré d'abstraction existant dans le projet du site Kaztele -aujourd'hui. En cours de route nous répondrons à la question. - -Vous savez peut-être déjà convertir du markdown en html. Le problème n'est pas -trivial parce qu'html c'est compliqué et le markdown défini de façon assez -ambigüe. Cette ambiguité est la raison pour laquelle un même fichier markdown -sera rendu de façon différente selon si c'est le README d'un projet github, de -la documentation docbook etc. Le projet commonmark tente de faire émerger un -standard. Plusieurs implémentations existent. Pandoc peut traduire du mardown -en html selon les specifications commonmark. Le projet lowdown en est une -implémentation assez légère en C. A l'heure où j'écris ces lignes le site de -Kaztele utilise lowdown.\ -Son utilisation est simple, markdown en entrée, html en sortie : - - <<% lowdown - # Titre 1 - - Une liste cool - - * elem 1 - * elem 2 - - [lien 1](katzele.net) - - ## titre 2 - - du texte - % - - <h1>Titre 1</h1> - <p>Une liste cool</p> - <ul> - <li>elem 1</li> - <li>elem 2</li> - </ul> - <p><a href="katzele.net">lien 1</a></p> - <h2>titre 2</h2> - <p>du texte</p> - -Si la syntaxe <<%...% ne vous est pas familière pas de souci, on en parlera -plus tard. - -Pandoc, lowdown etc ne génèrent que le strict minimum d'html nécessaire. Le -résultat ne comporte pas le "boilerplate" nécessaire pour faire une page html -complète, même la plus simple possible. De plus il faudrait pouvoir en plus du -contenu de la page permettre de spécifier par exemple le titre de l'article à -mettre dans la balise `<title> du header. Pour le premier besoin pandoc a un -système de template, pour le second il a une autre solution que j'ai utilisé -une fois y'a longtemps et que j'ai oublié.\ -Puisque nous utilisons lowdown qui essaye de rester très limité dans son -périmètre nous allons devoir faire preuve d'ingéniosité. - -Pour rester sur quelque chose de simple on voudrait créer un fichier avec cette -tête : - - <html> - <header> - <title>TITRE</title> - </header> - <body> - <main id="main" class="main"> - <h1>Titre 1</h1> - <p>Une liste cool</p> - <ul> - <li>elem 1</li> - <li>elem 2</li> - </ul> - <p><a href="katzele.net">lien 1</a></p> - <h2>titre 2</h2> - <p>du texte</p> - </div> - </body> - </html> - -La structure du template peut être spécifiée dans un heredoc. Un here-document (ou heredoc, here-doc) est une redirection particulière en shell. Sa syntaxe est : - - cmd <<delim - du texte - blabla - machin - delim - -ou encore - - <<delim cmd - du texte - blabla - machin - delim - -Le texte entre le premier délimiteur et le second sera donné à la commande -`cmd` dans son entrée standard `stdin`. Le heredoc utilisé plus haut disait -donc que tout le texte écrit entre la première ligne et le prochain `%` devait -être lu par la commande `lowdown`. Un template (ou layout) html sous la forme -d'un heredoc pourrait être : - - layout() { - <<@@ cat - <html><header><title>TITRE</title></header><body><main id="main" class="main">CONTENU</div></body></html> - @@ - } - -En l'état cette fonction shell ne fait que prendre le texte du template pour le -mettre dans la sortie standard `stdout` à l'aide de `cat`. Pour que `TITRE` et -`CONTENU` soit remplacés par les données que l'on veut on peut utiliser des -variables shell : - - TITRE="Page d'accueil" - CONTENU="# Page d'accueil du site - blabla - blabla" - -Il faudrait modifier le heredoc pour que `TITRE` et `CONTENU` deviennent des variables : - - layout() { - <<@@ cat - <html><header><title>$TITRE</title></header><body><main id="main" class="main">$CONTENU</div></body></html> - @@ - } - -Si l'on fait ça le markdown dans `$CONTENU` ne sera pas transformé en html. -Il faudrait donner son contenu à `lowdown` en faisant par exemple : - - layout() { - <<@@ cat - <html><header><title>$TITRE</title></header><body><main id="main" class="main">$(echo $CONTENU | lowdown)</div></body></html> - @@ - } - -La syntaxe `$(cmd) est une substitution de commande (ou command substitution ou -capture). Le shell va exécuter la commande entre parenthèses et remplacer la -substitution par sa sortie standard. Ici on utilise `echo` pour que le contenu -de `$CONTENU` se trouve en entrée de la commande `lowdown` qui renverra de -l'html. On aura donc entre les deux chevrons l'html du corps de la page. La commande donne : - - echo $CONTENU | lowdown - <h1>Page d'accueil du site</h1> - <p>blabla - blabla</p> - - -Donc à l'exécution de layout le shell déroulera les variables `$TITRE` et `$CONTENU` - - layout() { - <<@@ cat - <html><header><title>Page d'accueil</title></header><body><main id="main" class="main">$(echo "# Page d'accueil du site\nblabla\nblabla" | lowdown)</div></body></html> - @@ - } - -Puis déroulera la substitution de commande : - - layout() { - <<@@ cat - <html><header><title>Page d'accueil</title></header><body><main id="main" class="main"><h1>Page d'accueil du site</h1><p>blabla\nblabla</p></div></body></html> - @@ - } - -Et le heredoc s'exécutera : - - <html><header><title>Page d'accueil</title></header><body><main id="main" class="main"><h1>Page d'accueil du site</h1><p>blabla\nblabla</p></div></body></html> - -Au final notre document "markdown" ressemblera à ceci : - - layout() { - <<@@ cat - <html><header><title>$TITRE</title></header><body><main id="main" class="main">$(echo $CONTENU | lowdown)</div></body></html> - @@ - } - - TITRE="Page d'accueil" - CONTENU="# Page d'accueil du site - blabla - blabla" - layout - -A l'exécution ce script génèrera l'html que l'on souhaite. C'est sur ce -principe, l'idée que les fichiers markdown sont en réalité des scripts -exécutables, que repose la commande construite pour le makefile. `src/index.md` -a lui seul produit l'html qui est ensuite pipé à `install` pour en faire -`root/index.html`. - -Maintenant que l'on sait comment construire et remplir un template html il est -temps de se simplifier quelque peu la tâche. Vous aurez peut-être remarqué -quelques faiblesses à ce système. - -La première est qu'il faudra réécrire la fonction layout et son appel dans -chaque fichier markdown. Si le site est destiné à accueillir de très nombreux -articles imaginez la galère que ce serait de vouloir le modifier partout en -même temps. Pour y remédier on peut chercher à faire un peu de factorisation en -déclarant la fonction layout dans un script séparé qui sera appelé en amont -lors de l'exécution des fichiers markdown. Appelons le layouthtml : - - layout() { - <<@@ cat - <html><header><title>$TITRE</title></header><body><main id="main" class="main">$(echo $CONTENU | lowdown)</div></body></html> - @@ - } - - layout - -En l'état les variables `TITRE` et `CONTENU` ne contiennent rien. Si l'on -exécute layout tel quel on récupèrera le layout html sans titre et sans corps. -Il faut exécuter le script markdown entre temps. Pour cela on pourrait penser -qu'il suffit de l'exécuter avant l'appel à `layout` : - - layout() { - <<@@ cat - <html><header><title>$TITRE</title></header><body><main id="main" class="main">$(echo $CONTENU | lowdown)</div></body></html> - @@ - } - - ./index.md - - layout - -Sauf que le résultat est le même. En effet un nouveau shell (un subshell) sera -ouvert pour interpréter les commandes se trouvant dans `index.md`. Ce subshell -ne partagera pas ses variables avec son processus père. Dans `layouthtml` -`$CONTENU` et `$TITRE` seront toujours vides. On peut contrôler ce qu'il se -passe visuellement dans `htop` : - - /bin/zsh - |_sh ./layouthtml - |_ /bin/sh ./index.md - -Il faudrait un moyen de faire comme si l'on copiait-collait les commandes -d'`index.md` dans `layouthtml`. Le shell a une commande spécifiquement prévue -pour cela, la commande `.` : - - . ./index.md - -Dans `htop` : - - /bin/zsh - |_sh ./layouthtml - -On voit qu'un seul processus est appelé, les commandes d'`index.md` sont -exécutées directement "dans" `layout.html`. Résultat, on a bien accès au -contenu des variables déclarées dans `index.md` et l'html est généré -correctement. - -Nous avons au final deux fichiers, l'un contenant l'échafaudage, l'autre le -contenu : - -layouthtml que génère l'html à l'exécution - - layout() { - <<@@ cat - <html><header><title>$TITRE</title></header><body><main id="main" class="main">$(echo $CONTENU | lowdown)</div></body></html> - @@ - } - - . ./index.md - - layout - -et index.md dans lequel on écrit le contenu - - TITRE="Page d'accueil" - CONTENU="# Page d'accueil du site - blabla - blabla" - -Vous pourriez vous dire "On ne va pas tout de même modifier le chemin du -fichier md source à la main à chaque fois ?". Effectivement, on ne va pas. -D'autant plus qu'il sera préférable que le contenu de layouthtml ne change pas, -qu'il soit générique peut importe le fichier source. Pour cela on peut passer -le chemin du fichier source en argument à `layouthtml`. En le modifiant de la -sorte : - - . $1 - -On peut faire - - layouthtml ./chemin/vers/index.md - -`$1` est la variable contenant le premier argument passé à la commande. Ici -cette variable deviendra donc le chemin du fichier md. Cette technique nous -donne la possibilité d'appeler layouthtml sur tous les fichiers sources md. -Encore mieux, quitte à ce que les fichiers md soient en réalité des scripts, on -peut utiliser les shebang. Cette syntaxe que vous avez probablement déjà -rencontré permet d'indiquer par quel programme un fichier doit être interprété. -Elle prend la forme d'un dièse suivant d'un point d'exclamation suivi du chemin -vers un programme. Le plus classique est de voir - - #! /bin/sh - -au début de scripts shell. Si l'on met cela dans le fichier "exemple1" le -système passera le chemin du fichier en argument à ce qui suit le point -d'exclmation. Ici `/bin/sh exemple1`. Plutôt que de répétitivement exécuter -`page fichier.md` on peut donc ajouter `#! page` en première ligne de nos -fichiers markdown. Ainsi on pourra faire : - - ./index.md - -qui construira : - - page ./index.md - -qui exécutera bien la liste suivante de commandes : - - layout() { - <<@@ cat - <html><header><title>$TITRE</title></header><body><main id="main" class="main">$(echo $CONTENU | lowdown)</div></body></html> - @@ - } - - . ./index.md - - layout - -Point d'étape, nous avons toujours deux fichiers avec le contenu suivant : - -page - - #! /bin/sh - - layout() { - <<@@ cat - <html><header><title>$TITRE</title></header><body><main id="main" class="main">$(echo $CONTENU | lowdown)</div></body></html> - @@ - } - - . $1 - - layout - -index.md ou tout autre fichier md, en considérant que le script `page` se -trouve dans le dossier dans lequel on exécute le script. On peut toujours -changer le chemin. - - #! page - - TITRE="Page d'accueil" - CONTENU="# Page d'accueil du site - blabla - blabla" - -La deuxième faiblesse de ce système, toute relative, est la syntaxe des -fichiers markdown. Il est assez évident que ce ne sont pas des fichiers -markdown, il serait préférable de quelque peu le masquer. De plus, il faudrait -échapper tous les `"` pour éviter de mettre fin prématurément au contenu des -variables. Bref, pas très pratique.\ -Impossible d'échapper à la syntaxe de création de variables shell mais possible -de le masquer dans le script `page` à l'aide de variables. Admettons que l'on souhaite déclarer le titre d'un document avec un syntaxe type : - - %T Ceci est le titre de l'article - -On peut insérer un alias dans `page` : - - alias %T="title" - title() TITRE="$*" - -Un alias permet de donner un autre nom à une commande. Par exemple si je donne -la valeur `ls -la` à l'alias nommé `l` alors la commande : - - l truc - -sera remplacée par - - ls -la truc - -Dans notre cas `%T` sera remplacé par `title` qui se trouve être une fonction -que l'on défini juste en dessous qui donne une valeur à la variable `TITRE`. -`$*` est une variable sépciale qui, lorsqu'elle est entre double quote `"` est -remplacée par tous les arguments passés à la commande séparés par un espace et -rassemblés en une seule chaîne de caractère. La commande - - title Ceci est un titre blablabla - -sera donc équivalente à faire - - TITRE="Ceci est un titre blablabla" - -L'ajout de cet alias dans `page` permet donc d'écrire `index.md` comme ceci : - - %T Page d\'accueil - CONTENU="# Page d'accueil du site - blabla - blabla" - -En veillant à échapper le `'`. Echapper un caractère permet à l'interpréteur de -commande de ne pas considérer un caractère pour sa signification spéciale mais -pour sa valeur intrinsèque.\ -C'est un peu plus joli. Appliquer le même principe pour le contenu sera un peu -plus difficile. Le contenu se trouvant sur plusieurs lignes il faudra avoir -recours à un heredoc. L'alias sera : - - alias %S="<<% layout" - -Et le contenu d'`index.md` : - - %T Page d\'accueil - %S - - # Page d'accueil du site - blabla - blabla - - % - -La fonction layout doit également changer puisqu'il n'y a plus de variable -`CONTENU`. On peut la remplacer par un appel direct à la commande `lowdown` qui -prendra l'entrée de layout, c'est à dire le markdown dans le heredoc. On retire -également l'appel à layout à la fin du fichier puisque c'est `index.md` qui le -fait avec `%S`. - - layout() { - <<@@ cat - <html><header><title>$TITRE</title></header><body><main id="main" class="main">$(lowdown)</div></body></html> - @@ - } - -Nous avons enfin un fichier "markdown" très proche de ce à quoi ressemblerait -le fichier s'il ne contenait vraiment que du markdown. Maintenant imaginons que -l'on veut écrire un article avec des commandes dedans. On pourrait retrouver -dans le heredoc `%S` des choses comme : - - dc -e "2k $(wc -l < README) 50 / p" - -Cette commande calcul environ combien de pages A4 `README` remplirait. Si -l'on exécute `index.md` on obtient : - - <html><header><title>Page d'accueil</title></header><body><main id="main" class="main"><h2>Page d'accueil du site</h2> - <p>blabla - blabla</p> - <p>dc -e &quot;2k 13 50 / p&quot;</p></div></body></html> - -Vous remarquerez que la commande `wc -l < README` a été substituée. Par -défaut les heredocs déroulent (en anglais expand) les variables, les -substitutions de commandes etc. C'est évidemment très dangereux. Si le contenu -du l'article contient `$(rm -rf)` vous pourriez perdre des fichiers. La -solution est d'échapper le délimiteur. Ainsi le heredoc prendra tout au sens -littéral sans chercher à dérouler quoi que ce soit. L'alias sécurisé devrait -donc être : - - alias %S="<<\% layout" - -A ce stade si vous avez bien compris le fonctionnement vous pouvez apporter des -modifications simples et rapides au layout et aux données à y faire rentrer. -Par exemple nous pourrions vouloir ajouter le nom de l'auteur de l'article. -L'alias dans page : - - alias %A="author" - author() AUTHOR="$*" - -Dans le layout : - - layout() { - <<@@ cat - <html><header><meta name="author" content="$AUTHOR"<title>$TITRE</title></header><body><main id="main" class="main">$(lowdown)</div></body></html> - @@ - } - -et dans l'article - - %T Page d\'accueil - %A Jean Dupont - %S - - # Page d'accueil du site - blabla - blabla - - % - -Aussi simple que cela. - -On sait que si l'on oublie un champ la variable dans le layout sera simplement -remplacée par rien du tout. Comment lui donner une valeur par défaut ou lever -une alerte s'il manque ? Le shell à la rescousse. Prenons la variable `TITRE`. -Jusqu'à maintenant nous avons utilisé les variables sous des formes `${TITRE}` -ou `$TITRE`. Avec cette syntaxe le tout sera substitué par la valeur de la -variable si elle existe mais il en existe d'autre : - - * `${TITRE:-Titre par défaut}` - si `TITRE` n'existe pas ou est vide alors le - tout sera substitué par "Titre par défaut". - * `${TITRE:?Attention il manque un titre à l'article}` - si `TITRE` - n'existe pas ou est vide alors le script affiche le message d'erreur - et se termine - -Pour en connaître d'autres voir le chapitre "Parameter Expansion" du -manuel de sh. - -Nous pourrions donc modifier le layout comme ceci : - - layout() { - <<@@ cat - <html><header><meta name="author" content="${AUTHOR:-Jean Dupont}"><title>${TITRE:?Titre obligatoire (%T)}</title></header><body><main id="main" class="main">$(lowdown)</div></body></html> - @@ - } - -Pour que Jean Dupont soit l'auteur des articles par défaut à moins qu'il -soit précisé autrement, et qu'un article ne puisse être publié sans -titre. - -Point d'étape, nous avons - -page avec un peu de mise en forme pour le layout - - #! /bin/sh - - layout() { - <<@@ cat - <html> - <head> - <meta name="author" content="${AUTHOR:-Jean Dupont}"> - <title>${TITRE:?Titre obligatoire (%T)}</title> - </head> - <body> - <main id="main" class="main"> - $(lowdown) - </div> - </body> - </html> - @@ - } - - alias %T="title" - title() title="$*" - - alias %A="author" - author() author="$*" - - alias %S="<<\% layout" - - . $1 - -index.md ou tout autre fichier md, en considérant que le script `page` se -trouve dans le dossier dans lequel on exécute le script. On peut toujours -changer le chemin. - - #! page - - %T Page d\'accueil - %A Jean Dupont - %S - - # Page d'accueil du site - blabla - blabla - - % - -Il serait bon de vouloir sortir le layout dans un autre fichier. Pour cela nous pouvons -mettre la fonction ailleurs, disons un fichier `html` et l'appeler dans `page` à la -manière dont nous appelons `index.md`. - -html - - layout() { - <<@@ cat - <html> - <head> - <meta name="author" content="${AUTHOR:-Jean Dupont}"> - <title>${TITRE:?Titre obligatoire (%T)}</title> - </head> - <body> - <main id="main" class="main"> - $(lowdown) - </div> - </body> - </html> - @@ - } - -page - - #! /bin/sh - - alias %T="title" - title() title="$*" - - alias %A="author" - author() author="$*" - - alias %S="<<\% layout" - - . html - . $1 - -L'une des limitations de notre système qui vaut probablement la peine d'être -levée est celle de ne pouvoir insérer de l'html généré qu'à un seul endroit -prédéfini dans notre template. Cela peut tout à fait convenir à des sites très -simples mais être handicapant si l'on souhaite créer des structures plus -complexes et changeantes. - -TODO trouver un meilleur exemple ? - -Par exemple, admettons que notre site comporte une section "aside" dans -laquelle se trouve une courte description un peu meta de la page consultée. -Il faut donc un moyen pour la personne écrivant le contenu de dire que cela -va dans telle section du template et ceci dans telle autre section. Côté -utilisateurice une syntaxe sympa pourrait être de donner la section cible -après l'alias %S. Par exemple - - %S main - # Titre 1 - blabla - % - -irait dans la section main, le corps de l'article. - - %S aside - Cet article parle de ceci cela - % - -irait dans le section aside. Pour accomplir cela nous pouvons générer les -différentes parties html, les stocker dans des fichiers temporaires et -rappeler leurs contenus au bon endroit dans la fonction layout. Pour -créer un dossier temporaire nous pouvons utiliser la commande `mktemp` -avec l'option `-d` - - tempfolder=$(mktemp -d) - -Cette commande renvoie le chemin absolu du dossier temporaire créé, que -l'on stocke dans la variable tempfolder. Dans ce dossier temporaire nous -allons créer des fichiers ayant pour contenu l'HTML généré par lowdown pour -les différentes sections. Pour l'instant le markdown est directement donné -à la fonction layout qui interprète tout dans la section main de son -template. Pour éviter ce comportement il faut que l'alias %S appelle -une autre fonction qui elle créera les différents fichiers. Appelons cette -fonction `save_md` et modifions %S - - save_md() lowdown >> "$tempfolder/$1" - alias %S="<<\% save_md" - -L'alias %S appelle dorénavant la fonction `save_md` en lui passant en argument -le nom d'une section donnée (dans les exemples précédemment "main" et "aside") -qui se retrouveront dans la variable $1. Elle prendra dans stdin le markdown -écrit dans le heredoc, ce comportement n'a pas changé. Ainsi écrire - - %S main - # Titre 1 - blabla - % - -reviendra à exécuter - - <<% save_md main - # Titre 1 - blabla - % - -ou encore - - echo "# Titre 1\nblabla" | save_md main - -ce qui revient à - - echo "# Titre 1\nblabla" | lowdown >> "$tempfolder/main" - -ainsi il existera dans un fichier dont le chemin serait quelque chose -ressemblant à "tmp/tmp.xTpN5urieE/main" le contenu de l'HTML destiné à -la section main. Dans notre fichier `index.md` si l'on n'oublie pas de -bien fermer le heredoc pour la section main on peut enchainer les deux -sections - - %S main - # Titre 1 - blabla - % - - %S aside - Cet article parle de ceci cela - % - -Il ne reste plus qu'à adapter la fonction layout pour insérer l'html aux bon -endroits. Pour cela créons dans page une courte fonction qui permet de se -déplacer dans le dossier correspondant et d'afficher l'HTML d'une section -donnée - - display () { - cd $the; cat "$@" - } - -TODO demander à Marc pourquoi faire un cd ici et pas cat directement le chemin total - -L'utilisation du point virgule permet ici d'écrire deux instructions sur une -même ligne. Cela a pour seul but de raccourcir le fichier, notamment quand les -instruction en question sont courtes et très intelligibles. Cela est -strictement équivalent à - - display () { - cd $the - cat "$@" - } - -Utilisons là dans le layout - - layout() { - <<@@ cat - <html> - <head> - <meta name="author" content="${AUTHOR:-Jean Dupont}" - <title>${TITRE:?Titre obligatoire (%T)}</title> - </head> - <body> - <aside id="aside" class="aside"> - $(display aside) - </aside> - <main id="main" class="main"> - $(display main) - </main> - </body> - </html> - @@ - } - -Il faut s'assurer que la fonction layout soit bien appelée, maintenant qu'elle -ne l'est plus par l'alias %S. Il faut également s'assurer que le dossier -temporaire soit bien supprimé quand nous n'en avons plus besoin. `page` -ressemble dorénavant à - - #! /bin/sh - - tempfolder=$(mktemp -d) ; trap "rm -rf $tempfolder" EXIT - - alias %T="title" - title() title="$*" - - alias %A="author" - author() author="$*" - - save_md() lowdown >> "$tempfolder/$1" - alias %S="<<\% save_md" - - display () { - cd $the; cat "$@" - } - - . html - . $1 - layout - -La commande trap permet de demande l'exécution de `rm -rf $tempfolder` quand -le processus actif recevra le signal EXIT, autrement dit quand il se terminera. - -Voilà en l'état, avec ce triptyque nous avons les bases nécessaires pour écrire -des pages HTML depuis du markdown, agrémentées de métadonnées, suivant un -template modulaire. - -Petit bonus, le fait que les fichiers markdown soient des scripts shell permet -non seulement d'implémenter notre système de métadonnée et de templating mais -également d'avoir recours aux outils unix pour générer le contenu lui même. - -Exemple. Prenons un site avec une arborescence type - - . - ├── articles - │   ├── musique - │   │   └── index.md - │   └── youtube - │   └── index.md - ├── index.md - └── notes - ├── chatgpt - │   └── index.md - └── laconvivialite - └── index.md - -Dont les pages ont les métadonnées que l'on a vu précédemment, déclarées avec -%T et %A. Nous voudrions avoir la liste exhaustive de tous les articles du site. -Nous commençons à rédiger notre page, très sommaire (je mets un petit commentaire -pour l'exemple) : - - #! page - - %T Plan du site - %A Jean Dupont - - %S main - # Archives du site de Jean Dupont - - ## Articles - - Ci dessous tous les articles du site. Il n'y a pas encore grand chose mais ça arrive ! - % - -en fermant le heredoc je peux recommencer à y mettre du shell. Nous allons -chercher les fichiers markdown et les lister : - - find . -type f -name "*.md" - ./articles/youtube/index.md - ./articles/musique/index.md - -dont on va chercher les métadonnées - - - find . -type f -name "*.md" | xargs grep -EHm2 "%T|%A" - ./articles/youtube/index.md:%T Guide de survie en territoire youtubesque - ./articles/youtube/index.md:%A Jean Dupont - ./articles/musique/index.md:%T Gestion simpliste de playlist et migration depuis Spotify - ./articles/musique/index.md:%A Jean Dupont - -pour en faire une ligne par article - - find ./articles -type f -name "*.md" | xargs grep -EHm2 "%T|%A" | paste - - - ./articles/youtube/index.md:%T Guide de survie en territoire youtubesque /tmp/tmp.xTpN5urieE/articles/youtube/index.md:%A Jean Dupont - ./articles/musique/index.md:%T Gestion simpliste de playlist et migration depuis Spotify /tmp/tmp.xTpN5urieE/articles/musique/index.md:%A Jean Dupont - -et remanier les infos de façon à en faire du markdown - - find . -type f -name "*.md" | xargs grep -EHm2 "%T|%A" | paste - - | sed -Ee 's,(.*).md:%T (.*) .*%A (.*).*,* [\2](\1.html) - \3,' - * [Guide de survie en territoire youtubesque](./articles/youtube/index.html) - Jean Dupont - * [Gestion simpliste de playlist et migration depuis Spotify](./articles/musique/index.html) - Jean Dupont - -On ne peut pas le laisser vivre tout seul comme ça sinon à l'exécution le résultat ne -se retrouvera dans aucune section et n'apparaîtra pas. Il faut donc terminer parce un appel -à `save_md` - - find ./articles -type f -name "*.md" | xargs grep -EHm2 "%T|%A" | paste - - | sed -Ee 's,(.*).md:%T (.*) .*%A (.*).*,* [\2](\1.html) - \3,' | save_md main - -On peut ensuite appeler à nouveau l'alias %S pour reprendre la rédaction de l'article : - - %S main - - ## Notes - - Et les notes : - % - - find ./notes -type f -name "*.md" | xargs grep -EHm2 "%T|%A" | paste - - | sed -Ee 's,(.*).md:%T (.*) .*%A (.*).*,* [\2](\1.html) - \3,' | save_md main - -Cela fonctionne puisque l'on utilise l'opérateur de concaténation dans la fonction `save_md`. -On *ajoutera* toujours au fichier d'une section, sans le réécrire. - -Au final notre article source ressemble à - - #! page - - %T Plan du site - %A Jean Dupont - - %S main - # Archives du site de Jean Dupont - - ## Articles - - Ci dessous tous les articles du site. Il n'y a pas encore grand chose mais ça arrive ! - % - - find ./articles -type f -name "*.md" | xargs grep -EHm2 "%T|%A" | paste - - | sed -Ee 's,(.*).md:%T (.*) .*%A (.*).*,* [\2](\1.html) - \3,' | save_md main - %S main - - ## Notes - - Et les notes : - % - - find ./notes -type f -name "*.md" | xargs grep -EHm2 "%T|%A" | paste - - | sed -Ee 's,(.*).md:%T (.*) .*%A (.*).*,* [\2](\1.html) - \3,' | save_md main - -Ce qui reviendrait à écrire à la main - - #! page - - %T Plan du site - %A Jean Dupont - - %S main - # Archives du site de Jean Dupont - - ## Articles - - Ci dessous tous les articles du site. Il n'y a pas encore grand chose mais ça arrive ! - - * [Guide de survie en territoire youtubesque](./articles/youtube/index.html) - Jean Dupont - * [Gestion simpliste de playlist et migration depuis Spotify](./articles/musique/index.html) - Jean Dupont - - ## Notes - - Et les notes : - - * [Dialogue avec ChatGPT](./notes/chatgpt/index.html) - ChatGPT, Jean Dupont - * [Notes sur "La Convivialité" d'Ivan Illich](./notes/laconvivialite/index.html) - Jean Dupont - % - -En combinant markdown et instructions exécutables nous pouvons donc adapter le -contenu de nos pages en fonction de conditions extérieures, comme ici la -présence ou non d'un certain nombre d'articles. A noter, nous pouvons utiliser -ce que nous voulons comme langage. Il est naturel d'écrire du shell puisque -c'est comme cela que le fichier est interprété mais si vous êtes plus à l'aise -avec un autre langage il est tout à fait possible de l'utiliser. Par exemple -nous pourrions générer du markdown similaire en écrivant : - - python3 -c " - insérer du python ici - blabla - " | save_md main - -Pour avoir un aperçu complet de ce qu'il se passe déroulons tout le code à -partir de l'exécution du script index.md :\ -(j'ai un gros doute sur la façon de présenter ce truc, je sais pas ce que -je fais, qu'est-ce qu'il faut que je déroule ou pas etc) - -Pour l'index.md suivant - - #! page - %T Titre de la page - %A Jean Dupont - %S main - # Titre 1 - blabla - - * el1 - * el2 - % - - uptime | save_md main - - %S aside - ici le contenu de l'aside - % - -`./index.md` tombera sur `#! page` qui appelera `./page index.md` et -le code suivant sera exécuté : -TODO : rendre cela lisible en texte pur *et* en HTML ? - -Tel quel Avec les appels `. fichier` et la fonction layout dépliés Avec les variables, alias dépliés et appels à display dépliés - -tempfolder=$(mktemp -d) tempfolder=$(mktemp -d) tempfolder=$(mktemp -d) -trap "rm -rf $tempfolder" EXIT trap "rm -rf $tempfolder" EXIT trap "rm -rf /tmp/tmp.azerty" EXIT - -alias %T="title" alias %T="title" alias %T="title" -title() title="$*" title() title="$*" title() title="$*" - -alias %A="author" alias %A="author" alias %A="author" -author() author="$*" author() author="$*" author() author="$*" - -save_md() lowdown >> "$tempfolder/$1" save_md() lowdown >> "$tempfolder/$1" save_md() lowdown >> "/tmp/tmp.azerty/$1" -alias %S="<<\% save_md" alias %S="<<\% save_md" alias %S="<<\% save_md" - -display () { display () { display () { - cd $tempfolder cd $tempfolder cd $tempfolder - cat "$@" cat "$@" cat "$@" -} } } - -. html layout() {...} layout() {...} - -. $1 %T Titre de la page title="Titre de la page" - %A Jean Dupont author="Jean Dupont" - - %S main <<\% lowdown >> "/tmp/tmp.azerty/main" - # Titre 1 # Titre 1 - blabla blabla - - * el1 * el1 - * el2 * el2 - % % - - uptime | save_md main uptime | lowdown >> "/tmp/tmp.azerty/main" - - %S aside <</% lowdown >> "/tmp/tmp.azerty/aside" - ici le contenu de l'aside ici le contenu de l'aside - % % - -layout <<@@ cat <<@@ cat - <html> <html> - <head> <head> - <meta name="author" content="${author:-Jean Dupont}"> <meta name="author" content="Jean Dupont"> - <title>${title?Titre obligatoire (%T)}</title> <title>Titre de la page</title> - </head> </head> - <body> <body> - <aside id="aside" class="aside"> <aside id="aside" class="aside"> - $(display aside) cd /tmp/tmp.azerty - cat aside - </aside> </aside> - <main id="main" class="main"> <main id="main" class="main"> - $(display main) cd /tmp/tmp.azerty - cat main - </main> </main> - </body> </body> - </html> </html> - @@ @@ - -rm -rf $tempfolder rm -rf /tmp/tmp.azerty rm -rf /tmp/tmp.azerty - -J'ai généré le tableau précédent avec le format de donnée suivant et la commande -`column -ets';'`. - - Tel quel;Avec les appels `. fichier` et la fonction layout dépliés;Avec les variables, alias dépliés et appels à display dépliés - tempfolder=$(mktemp -d);tempfolder=$(mktemp -d);tempfolder=$(mktemp -d) - trap "rm -rf $tempfolder" EXIT;trap "rm -rf $tempfolder" EXIT;trap "rm -rf /tmp/tmp.azerty" EXIT - - alias %T="title";alias %T="title";alias %T="title" - title() title="$*";title() title="$*";title() title="$*" - - alias %A="author";alias %A="author";alias %A="author" - author() author="$*";author() author="$*";author() author="$*" - - save_md() lowdown >> "$tempfolder/$1";save_md() lowdown >> "$tempfolder/$1";save_md() lowdown >> "/tmp/tmp.azerty/$1" - alias %S="<<\% save_md";alias %S="<<\% save_md";alias %S="<<\% save_md" - - display () {;display () {;display () { - cd $tempfolder; cd $tempfolder; cd $tempfolder - cat "$@"; cat "$@"; cat "$@" - };};} - - . html;layout() {...};layout() {...} - - . $1;%T Titre de la page;title="Titre de la page" - ;%A Jean Dupont;author="Jean Dupont" - ; - ;%S main;<<\% lowdown >> "/tmp/tmp.azerty/main" - ;# Titre 1;# Titre 1 - ;blabla;blabla - ; - ;* el1;* el1 - ;* el2;* el2 - ;%;% - ; - ;uptime | save_md main;uptime | lowdown >> "/tmp/tmp.azerty/main" - ; - ;%S aside;<</% lowdown >> "/tmp/tmp.azerty/aside" - ;ici le contenu de l'aside;ici le contenu de l'aside - ;%;% - - layout;<<@@ cat;<<@@ cat - - ;<html>;<html> - ; <head>; <head> - ; <meta name="author" content="${author:-Jean Dupont}">; <meta name="author" content="Jean Dupont"> - ; <title>${title?Titre obligatoire (%T)}</title>; <title>Titre de la page</title> - ; </head>; </head> - ; <body>; <body> - ; <aside id="aside" class="aside">; <aside id="aside" class="aside"> - ; $(display aside); cd /tmp/tmp.azerty - ;; cat aside - ; </aside>; </aside> - ; <main id="main" class="main">; <main id="main" class="main"> - ; $(display main); cd /tmp/tmp.azerty - ;; cat main - ; </main>; </main> - ; </body>; </body> - ;</html>;</html> - ;@@;@@ - rm -rf $tempfolder;rm -rf /tmp/tmp.azerty;rm -rf /tmp/tmp.azerty - -TODO Atomic ?