Un site pour la promotion de catium - retour accueil
git clone git://bebou.netlib.re/site-catium
Log | Files | Refs | README |
commit e5096326d53b74f1856ab6e61884269ecdcfe3c7 parent 9f6c08c7b221a813a59154974d0cc0a5360af9ec Auterice: Arthur Pons <arthur.pons@unistra.fr> Date: Wed, 25 Sep 2024 16:48:23 +0200 Ajout de la philo, le "get started" et la doc Diffstat:
A | contents/documentation/construire.sh | | | 702 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | contents/documentation/histoire.sh | | | 183 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | contents/documentation/usage.sh | | | 415 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | contents/index.sh | | | 91 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | contents/style.css | | | 2 | +- |
M | layouts/html | | | 8 | +++++++- |
M | page | | | 21 | ++++++++++++++------- |
7 files changed, 1413 insertions(+), 9 deletions(-)
diff --git a/contents/documentation/construire.sh b/contents/documentation/construire.sh @@ -0,0 +1,702 @@ +#! page +title: Construire francium +description: "Comment construire francium de zéro" + +section: main + +# Comment vous aussi vous auriez pu construire francium + +Imaginez vouloir construire une site et être doté.e d’un outil qui traduit le +format dans lequel vous préférez écrire en html. Peut-être que vous aimez +écrire en markdown et utilisez pandoc, cmark[^1] ou même le [script initial de +John Gruber](https://daringfireball.net/projects/markdown/). Peut-être que vous +aimez écrire en asciidoc et utilisez asciidoctor. Peut-être que vous avez +votre propre format avec votre propre traducteur ! Comment, avec l’aide des +outils Unix, créer votre propre générateur de sites statiques ? + +## Générer une page + +### Les gabarits html et les métadonnées + +Vous avez un fichier index.md comme ceci : + + # Super document cool + + Blablabla + + * super liste + * trop cool + +et pouvez le convertir en faisant cmark index.md : + + <h1>Super document cool</h1> + <p>Blablabla</p> + <ul> + <li>super liste</li> + <li>trop cool</li> + </ul> + +Premier problème, si vous avez pour ambition d’avoir un site décemment +construit vous remarquerez qu’il manque de l’html. On pourrait vouloir ajouter +la balise `<html>` et `<meta>` pour l’encodage utf-8 par exemple. Ici +habituellement deux solutions s’offrent à vous. Soit vous comptez sur votre +traducteur pour le faire. C’est le cas par exemple de lowdown avec son option +`-s` (pour standalone) mais tous ne le font pas : + + <<-. lowdown -s + # titre + + [lien](katzele.netlib.re) + . + +qui donne + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1" /> + <title>Untitled article</title> + </head> + <body> + + <h1 id="titre">titre</h1> + + <p><a href="katzele.netlib.re">lien</a></p> + </body> + </html> + +soit vous utilisez un générateur de site existant. En réalité une troisième +s’offre à vous ! Résoudre ce problème à l’aide d’un outil que vous avez déjà +sous la main, le shell. + +Il existe en shell posix une syntaxe nommée here-document ou heredoc[^2]. Cette +syntaxe permet de créer des sortes de gabarits (ou templates ou layouts) de la +sorte : + + title="machin" + <<delim cat + blabla + le titre : $title + blabla + delim + +donne + + blabla + le titre : machin + blabla + +On notera que les variables shell appelées à l’intérieur sont étendues. Et bien +c’est également le cas des captures de commandes type `$(pwd)` ! On peut donc +imaginer l’utiliser pour insérer notre sortie de traducteur au sein d’un +gabarit html : + + title="Un article super" + <<delim cat + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1" /> + <title>$title</title> + </head> + <body> + $(cmark index.md) + </body> + </html> + delim + +qui donne + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1" /> + <title>Un article super</title> + </head> + <body> + <h1>Super document cool</h1> + <p>Blablabla</p> + <ul> + <li>super liste</li> + <li>trop cool</li> + </ul> + </body> + </html> + +Hop pas besoin d’outils extérieur. +Si l’on fait de ce code un script on pourrait l’exécuter pour générer l’html. +Evidemment ce serait limité puisque l’on aurait toujours la sortie du fichier +index.md. On peut donc décider de passer en argument le nom du fichier markdown +et le titre tant qu’à faire. On aurait donc un script du type : + + title="$1" + <<delim cat + [...] + $(cmark "$2") + [...] + delim + +Qu’on appelerait en faisant `./script "Un article super" ./index.md`. Si nos +besoins ne vont pas plus loin nous avons déjà quelque chose d’à peu près +fonctionnel. Pour rendre tout cela simple d’usage et mieux encapsuler +l’information nous allons pousser plus loin. + +Vous remarquerez ici que l’information du titre réside dans votre tête, à +l’écriture de la commande et non pas, comme il est préférable, dans le document +lui-même. L’idéal serait qu’index.md puisse contenir toutes ses informations, +le markdown du corps de l’article mais également les méta-données afférentes. +C’est comme cela que fonctionnent la plupart des générateurs de site avec des +syntaxes propres. On voudrait pouvoir, par exemple, écrire : + + title: "Un super article" + ---- + + # Super document cool + [...] + +et que la variable title de notre script prenne pour valeur “Un super article”. +Pour ce faire on pourrait modifier notre script pour parser index.md et en +récupérer l’info que l’on souhaite. Par exemle + + title=$(grep '^title:' | cut -d':' -f2) + +donnerait la bonne valeur à la variable et + + $(sed -n '/----/,$ p` "$1" | grep -v '^----' | cmark) + +parserait uniquement la partie markdown en ométtant les méta-données. C’est +pourtant sur une autre solution que nous allons partir, une solution qui nous +permettera plus de flexibilité par la suite et surtout la possibilité de +dynamiquement créer certaines parties du contenu markdown. + +### le format “à la francium” et la prolifération des scripts shell + +Cette autre solution consiste à faire du document index.md lui même un script. Et oui, dans francium, si c’est pas une makefile, c’est un script shell. Comme le dit le meme : + + 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 + +A ce stade on peut renommer index.md en index.sh, ça fera plus sens. L’idée est +dorénavant que notre script devienne une sorte d’interpréteur d’index.sh. On +l’appelera dorénavant “page”. Il devra préparer le nécessaire pour que la +syntaxe de la page index.sh instancie les bonnes variables et génère le +nécessaire pour l’affichage final de l’html. + +Par exemple, on pourrait grâce à un alias, cacher derrière la syntaxe `title: "Un super article"` une fonction qui créé la variable title. Pour cela on peut écrire : + + alias title:="title" + title() title="$*" + +Ainsi, dans index.sh : + + title: "Un super article" + # devient + title "Un super article" + # devient + title="Un super article" + +index.sh a créé sa propre variable. Ce système est généralisable à n’importe +quelle métadonnée. Si vous testez cette articulation tel quel vous rencontrerez +un problème. En effet, l’alias déclaré dans l’interpréteur page n’est pas +disponible dans le script index.sh si on l’exécute en écrivant `./$1` et en +faisant `./page index.sh` par exemple. C’est parce que en le faisant de cette +manière là, index.sh est exécuté dans un sub-shell, sur un processus différent +ne partageant aucune variable, alias ou fonction en commun avec son parent. +Pour contourner ce problème on peut utiliser le built-in shell .[^3] qui prend en +argument le chemin d’un fichier. Cette fonction va dérouler le code du fichier +dans le script courant et l’exécuter comme s’il y avait été écrit. Le code dans +index.sh aura donc bien accès à ce qui a été déclaré dans l’interpréteur page. +Ainsi `./page index.sh` fera : + + alias title:="title" + title() title="$*" + + . "$1" + + <<delim cat + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1" /> + <title>$title</title> + [...] + delim + +deviendra + + alias title:="title" + title() title="$*" + + title: "Un super article" + + [...] + + <<delim cat + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1" /> + <title>$title</title> + [...] + delim + +et `title: "Un super article"` se déroulera comme décrit précedemment et ainsi +de suite. + +Super ! On sait comment gérer les métadonnées. En réalité on vient d’inventer +une sorte de [DSL](https://en.wikipedia.org/wiki/DSL) qui ressemble +volontairement beaucoup à du [YAML](https://en.wikipedia.org/wiki/YAML) très +simple. Cette syntaxe est devenu très commune dans les générateurs de sites +statiques. + +Maintenant qu’on a trouvé notre alternative à `title=$(grep '^title:' | cut +-d':' -f2)` il nous faut trouver celle à `$(sed -n '/----/,$ p “$1” | grep -v +‘—-’ | cmark)`. Si on ne le fait pas l’exécution d’index.sh aura vite fait de +nous faire remarquer que le premier mot de notre page n’est pas une commande. + +Pour cela utilisons la même logique que pour les métadonnées. Imaginons une +syntaxe qui nous convienne et créons, en amont dans l’interpréteur le +nécessaire pour que cette syntaxe soit comprise et génère le bon contenu. Pour +pouvoir dire “attention, ce qui suit c’est du markdown” on peut réutiliser les +heredoc. Quelque chose de la sorte devrait générer l’html : + + title: "Un article super" + + <<delim cmark + # Ceci est du markdown + + blabla + delim + +Sauf qu’il nous faut capturer la sortie de cmark pour pouvoir ensuite +l’afficher au bon endroit dans le heredoc template qui suit dans l’interpréteur +page. On pourrait le mettre dans une variable en l’entourant d’une capture de +commande : + + corps=$(<<delim cmark + # Ceci est du markdown + + blabla + delim + ) + +et dans le template faire + + <main> + $(echo "$corps") + </main> + +mais vous conviendrez que ça n’est pas très élégant (et peut-être sensible au +quoting hell ?). On va donc opter pour mettre le résultat dans un fichier +temporaire. + + <<delim cmark > A + # Ceci est du markdown + + blabla + delim + [..] + <main> + $(cat A) + </main> + +ce qui permet d’adopter une syntaxe plus sympathique à l’aide d’un nouvel alias : + + section="<<endsection cmark > A" + [...] + section + # Ceci est du markdown + + blabla + endsection + +En ajoutant un petit `rm` A à la fin du script page on peut générer notre page +html en faisant `./page index.sh` sans souci. index.sh pourra se lire +convenablement bien et contiendra les infos à son propos en son sein. La +totalité du fichier jusqu’ici est : + + title: "Un super titre" + + section + # Ceci est du markdown + + blabla + endsection + +Avec ces éléments nous avons, à mon avis, tous les éléments d’un générateur de +site très simples. Afin d’organiser un peu les choses on pourrait déporter le +heredoc du layout dans un fichier à part, déclarant une fonction `layout`, +exécuté avec le builtin . et dont la fonction serait appelé à la fin. Cela +permet de séparer le layout du reste, le “fond” et la “forme” d’une certaine +manière. + +On a donc un fichier de layout, nommé html et dans le dossier layouts : + + layout { + <<@@ cat + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1" /> + <title>$title</title> + </head> + <body> + $(cat A) + </body> + </html> + @@ + } + +Le fichier index.sh comme décrit juste au dessus et le script page : + + alias title:="title" + title() title="$*" + + . "$1" + + . layout/html + layout + rm A + +Si les sources sont dans contents et les fichiers cibles dans public il +suffirait ensuite de créer un script qui appellerait `./page X.sh > X.html` sur +toutes les pages sh nécessaires, avec `X` le nom du fichier pour, construire le +site. + +Il nous reste quelques améliorations à apporter à notre générateur. + +### L’encapsulation et les sections + +Premièrement, il manque une information dans le fichier index.sh, celle de son +interpréteur. De fait, le fichier est un script ne s’exécutant correctement que +s’il est passé en argument d’un autre[^4]. Il serait bon de renseigner cette +information dans le fichier. Pour ce faire nous allons lui ajouter le shebang : + + #! page + +Ainsi il est possible de l’exécuter en faisant directement `./index.sh` ce qui en +réalité, du fait du fonctionnement du shebang, fera `./page ./index.sh` ce qui +revient à ce que nous faisions à la main jusque là. Cette façon de faire est, +selon moi, plus élégante, mais permet également de savoir que cette page a été +écrite pour être interprétée par un script nommé page ce qui, à défaut de +l’avoir, est toujours une bonne information à prendre. Ce système peut être +utilisé pour créer des typologies de pages (article, notes etc) qui seraient +générées de manières différentes. + +En réalité dans francium c’est le shebang + + #! /usr/bin/env ./page + +qui est utilisé pour des raisons obscures de compatibilité avec les *BSD et les +mac[^5]. + +Deuxièmement, comment faire si l’on souhaite, sur une même page, écrire deux +blocs de markdown qui doivent aller à deux endroits différents dans le layout. +Ce besoin est très courant dans les pages avec une structure plus complexe, du +type à avoir des div un peu partout, de façon à avoir une présentation moins +linéaire à l’aide de css. Pour répondre à ce besoin que l’on a estimé être +suffisamment important pour être intégré au générateur dans sa version la plus +simple il faut ajouter un peu de complexité dans l’interpréteur page. + +On souhaiterait pouvoir écrire dans index.sh : + + section: truc + ## Ce markdown va aller dans la section truc du layout + endsection + + section: bidule + ## Ce markdown va aller dans la section bidule du layout + endsection + +et par exemple dans le layout : + + layout { + <<@@ cat + [...] + <div id="joli-id-pour-du-css"> + $(show truc) + </div> + [...] + <div id="autre-id-pour-du-css"> + $(show bidule) + </div> + @@ + } + +On sent intuitivement qu'il faut passer une sorte d’argument à notre alias +section[^6]. Il faudrait pouvoir, sur la base de cet argument, stocker les données +de chacune des sections pour pouvoir les appeler séparément dans le layout. +Pour pouvoir traiter cette donnée comme un argument l’alias ne suffira plus, il +faudra passer par une fonction qu’on pourrait par exemple nommer `save` : + + alias section:="<<endsection save" + save() cat >> "$1" + +Ainsi dans index.sh : + + section: truc + blabla + endsection + + # Devient + + <<endsection save truc + blabla + endsection + + # Puis + + <<endsection cat >> truc + blabla + endsection + +On peut ainsi ouvrir et fermer autant de sections que l’on veut, y compris +plusieurs fois la même grâce à l’opérateur de redirection `>>` qui concatène +plutôt que ne remplace. +Il faut dorénavant que la fonction que l’on appelle dans le layout pour +“injecter” les données d’une section à un endroit particulier fasse la +traduction du format vers de l’html. On écrit donc une fonction `show` comme ceci +: + + show() cmark "$1" + +Cette fonction va donner tout le contenu enregistré dans la section qu’on lui +passe en argument (main, footer, comme vous voulez) à `cmark` et en ressortira de +l’HTML. + +Afin d’éviter que les fichiers ne se marchent sur les pieds si l’on a plusieurs +articles, de polluer l’espace de travail et de potentiellement engorger la +mémoire de votre ordinateur on peut faire en sorte que tout cela se produise +dans un dossier temporaire, sur des fichiers temporaires tous détruits une fois +la génération finie. Pour cela on créé au début de page un dossier temporaire +de travail avec `mktemp`, on dit au shell de le supprimer si le processus reçoit +le signal `EXIT` (une fois qu’il termine quoi) : + + tmpdir=$(mktemp -d) + trap "rm -rf $tmpdir" EXIT + +Il ne nous manque plus qu’à adapter `save` et `show` pour prendre en compte ce +nouveau dossier : + + save() cat >> "$tmpdir/$1" + show() cmark "$tmpdir/$1" + +Et voilà, à une exception près[^7] vous avez recréé absolument tout Francium dans +sa version non étendue. Bravo ! + +## Automatiser la génération : le makefile + +Il y aurait pleins de manières de partir de cet existant et d’automatiser la +création d’un site de plusieurs fichiers .sh. Un simple script shell pourrait +faire l’affaire. Cependant, pour des raisons pédagogique et, potentiellement de +performances, nous avons opté pour make. + +Make est un programme spécifiquement créé pour gérer la construction de +logiciels. Initialement fait pour compiler des programmes en C à une époque où +les ressources étaient assez rares, make permet à l’utilisateurice de déclarer +les règles de dépendances entre les différents éléments de son logiciel. make +créera avec ces règles un graph de dépendances lui permettant, lorsqu’il est +appelé, de ne recréer que le strict nécessaire ainsi économisant du temps de +calcul. Sur le principe la compilation de logiciels et la construction d’un +site statique ne sont pas différents. On peut donc faire usage de make pour +orchestrer la génération de notre site. + +Tout le nécessaire pour que make puisse fonctionner doit être inscrit dans un +fichier nommé makefile à la racine du projet. + +Francium utilise Gnu Make et quelques syntaxes lui sont très spécifiques. A +l’avenir un effort sera peut-être consenti pour génériciser la syntaxe. + +### Le but + +Le but est que make fasse automatiquement les appels aux articles et place +leurs sorties dans les bons fichiers de destinations. Par exemple, + + ./contents/index.sh > public/index.html + +Et ainsi pour tous les fichiers .sh qui existent dans l’arborescence à +l’intérieur de contents. + +Dans un second temps on souhaite qu’il copie bêtement tous les autres fichiers +présents dans l’arborescence comme les images : + + cp contents/super_image.jpg public/super_image.jpg + +Dans notre cas tout simple les fichiers .css et le favicon seront gérés de la +même manière que tous les images n’étant pas des .sh. + +### Lister nos fichiers sources + +La première étape est de lister toutes les sources de notre site. On souhaite faire des choses différentes selon que le fichier soit un .sh ou pas alors on créé deux variables. Dans sources on met la liste des fichiers sh, dans annexes les autres : + + sources != find contents -type f -name '*.sh' + annexes != find contents -type f -not -name '*.sh' + +La syntaxe `!=` dit à make que ce qui suit est une commande à faire exécuter +par le shell et non pas des fonctions make. On utilise donc ici le find que +vous pourriez utiliser dans votre terminal en temps normal. + +### Créer les cibles + +Une fois ces deux listes obtenues, on cherche à créer deux nouvelles listes +contenant les chemins des fichiers correspondants à faire servir par le serveur +web. On les appellera fichiers cibles. Par exemple, si l’on a le chemin +“contents/blog/article.sh” dans la variable sources, il faudra créer le chemin +“public/blog/article.html”. Autrement dit on remplace contents par public et +l’extension .sh par l’extension .html. Pour les autres fichiers seul le premier +dossier du chemin est à changer. + +Pour le faire on fait usage des “substitutions references” de GMake dont la +syntaxe est : + + variablecréée = ${variableinitiale:abc%uvw=efg%xyz} + +Ici, pour toutes les lignes dans la variableinitiale, make cherchera les +caractères `abc` et `uvw` et attribuera tout ce qu’il y a entre à `%`. Il +remplacera ensuite tous les `abc` par `efg` et les `uvw` par `xyz` en +conservant la partie `%`. Ainsi, si l’on reprend notre exemple précédent on +identifie que la partie commune (`%`) est `blog/article` et qu’il faut changer +ce qu’il y a avant et après. On peut donc écrire : + + pageshtml = ${sources:contents/%.sh=public/%.html} + annexescibles = ${annexfiles:contents/%=public/%} + +Vous voyez que pour les annexes pas besoin de modifier l’extension donc pas +besoin de la partie après le `%`. On a donc dorénavant dans `pageshtml` et +`annexescibles` la liste des chemins des cibles. + +### Écrire les règles + +C’est maintenant que la partie intéressante de make commence, les règles ! La +syntaxe générale d’une règle est la suivante : + + cible : liste dépendances ; commandes + +ou + + cible : liste dépendances + commandes + +Pour chacun des chemins de cibles construits précédemment make va chercher une +règle permettant de construire le fichier en question. Pour cela il cherche une +règle ayant pour cible le même chemin. Une fois qu’il a trouvé une règle qui +correspond, il vérifie si la cible existe. + + * Si elle n’existe pas il cherche à construire toutes ses dépendances puis + exécute la commande. + * Si la cible existe mais que certaines de ses dépendances n’existent pas il + va les construire d’abord et passer au point suivant. + * Si la cible existe déjà et que les dépendances existent il vérifie si ses + dépendances ont été modifiées après la dernière modification de la cible. + Si oui alors make suppose que la cible n’est pas à jour (ses sources sont + plus récentes qu’elle même) et make relance la commande. + +A noter que tout cela se fait de façon récursive. Quand make tente de créer une +dépendance il suit les mêmes règles. Si la dépendance n’existe pas il faut donc +qu’il existe une règle pour la créer. + +Pour créer une page html la règle pourrait être la suivante : + + public/blog/article.html : contents/blog/article.sh layouts/html + mkdir -p public/blog; contents/blog/article.sh > public/blog/article.html + +Vous noterez que la cible dépend de layouts/html de façon à ce qu’elle soit reconstruite si le layout change. + +Vous pourriez penser “mais on ne va pas écrire les règles pour toutes les pages +non ?” et vous auriez raison. Il est possible d’écrire des règles génériques +pouvant matcher plusieurs chemins de plusieurs cibles. Par exemple, la règle +suivante conviendra pour créer tous les fichiers html : + + public/%.html : contents/%.sh layouts/html + @mkdir -p $(shell dirname $@) + $< > $@ + +De la même manière qu’auparavant on généricise les chemins à l’aide de `%`. On +récupère le chemin du dossier du fichier cible avec dirname et on fait usage +des variables automatiques `$<` et `$@` faisant références respectivement à la +première dépendance et la cible. Pour éviter que la commande de création du +dossier de destination s’affiche dans la console lorsque l’on construira le +site on peut la préfixer d’un `@`. + +Pour les autres fichiers, de façon similaire : + + public/% : contents/% + @mkdir -p $(shell dirname $@) + cp $< $@ + +Si vous écrivez un makefile de la sorte et tenter de l’exécuter vous vourrez +qu’il ne créera pas tout le site. Make créé les cibles qu’on lui donne en +argument. `make public/index.html` déclenchera la règle correspondant à cette +cible si elle existe. Cela dit sans argument make créé uniquement la cible de +la première règle qu’il rencontre dans le makefile, dans l’ordre du fichier. +Comment, en sachant cela, forcer la création de toutes les cibles dans les +variables pageshtml et annexescibles ? + +En utilisant les propriétés des règles décrites précédemment. + + * Si make n’a pas d’argument, la première règle du fichier est déclenchée. + * Si la cible d’une règle n’existe pas, il va essayer de la créer. On peut + donc en déduire que si la commande de la règle ne créer pas la cible, la + règle sera toujours déclenchée. + * Make cherche d’abord à créer toutes les dépendances d’une cible avant de + créer la cible. + +On en conclu que si l’on écrit une règle qui ; + + * Précède toutes les autres + * A une commande qui ne créé pas de fichier ayant pour chemin la cible + (aucune commande fera très bien l’affaire) + * A pour dépendances toutes les cibles que l’on souhaite construire. + +Alors lorsque l’on lancera make, il cherchera à construire toutes ces cibles à +chaque fois. + +Cette règle est très courante dans les makefiles et est généralement nommée par +convention “all”, mais elle pourrait s’appeler “toto”. Pour lister les +dépendances on peut utiliser les variables déjà existantes : + + all: ${pageshtml} ${annexescibles} + +En utilisant les mêmes propriétés nous allons écrire une règle qu’il faudra +appeler volontairement en passant sa cible en argument à make, se déclenchera +toujours, et exécutera une commande. Cette règle permettra de nettoyer le +dossier de destination “public” : + + clean:; rm -r public/* + +Si elle n’est pas première dans le fichier et que la cible clean n’est une +dépendance d’aucune autre règle, elle ne se déclenchera qu’en faisant `make +clean`. Puisque la commande ne créé pas de fichier ayant pour chemin la cible +alors elle se déclenchera toujours. Cela dit, puisqu’elle n’a pas non plus de +dépendances, s’il se trouve qu’un jour un fichier “clean” existe à la racine du +projet, il sera considéré comme toujours à jour. Aucune dépendance ne pourra +être potentiellement plus récente que lui et la règle ne se déclenchera plus. +C’est pour palier ce genre de scénarios qu’il existe une directive `.PHONY` qui +permet de lister ce genre de règles[^8]. Ainsi make saura qu’il faut, pour ces +règles, ignorer la préexistence de la cible. + +Et voilà, vous avez réécrit le makefile de francium tel qu’il existe aujourd’hui ! + +[^1]: que l’on utilisera pour les exemples dans ce document +[^2]: documentée ici https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04 +[^3]: oui le nom de la fonction est un point final `.`. +[^4]: quand bien même la syntaxe a été écrite de façon à ce qu’un·e humain·e puisse le comprendre +[^5]: Voir: https://www.in-ulm.de/~mascheck/various/shebang/#interpreter-script ou le commit 4bd895 +[^6]: auquel on a ajouté un : pour ressemble aux autres déclarations +[^7]: la ligne [ "$1" ] || set - que je ne m’explique pas +[^8]: même s’il est très improbable qu’un fichier all ou clean se faufile dans votre projet, on sait jamais. + + diff --git a/contents/documentation/histoire.sh b/contents/documentation/histoire.sh @@ -0,0 +1,183 @@ +#! page +title: Histoire de francium +description: "Histoire et nature de francium" + +section: main + +``` +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 + +Je discutais un jour avec une personne du contenu que l'on consommait sur +internet. Le dialogue était à peu près le suivant, elle commence : + +A - "Je suis abonné à plusieurs newsletters de journaux, de blogs, de revues +etc"\ +B - "Ah j'aime pas trop les newsletter, perso j'utilise des flux rss quand ils +existent"\ +A - *souriant je crois un peu nerveusement* "Ah ouais ? C'est pas vieux et +presque mort les flux rss ? Je pensais que plus personne n'utilisait ça."\ +B - "Bah c'est plus vraiment à la mode mais c'est encore presque partout et je +le préfère aux newsletter parce que *blablabla*" + +J'ai repensé plusieurs fois à cet échange depuis. Je n'ai pas été surpris pas +le manque de considération pour des technologies pensées comme vieillissantes, +obsolètes, démodées, remplacées. J'ai été cependant marqué par le fait que +cette personne percevait les flux rss comme plus vieux et donc moins digne +d'intérêt que les mails. Pourtant les mails (entre 27 et 50 ans) sont bien plus +anciens que les flux rss (23 ans). Il y a donc autre chose à l'œuvre, quelque +chose qui modifie notre perception de l'ancienneté d'une technologie +indépendamment de son âge réel. On peut imaginer pleins de facteurs pouvant +l'expliquer, le taux d'adoption en est un assez évident, comme si l'on +commençait à décompter l'âge d'une techno qu'à partir du déclin de son +utilisation. Je pense qu'il y en au moins un autre. Il se trouve que cette +personne écrit une newsletter et qu'elle utilise le service Substack pour le +faire. Substack est une plateforme proposant des services pour construire et +publier des newsletter monétisables. L'outil profite d'une certaine hype, +construit par défaut des newsletter avec tous les codes esthétique du web et +des pages webs associées. J'imagine que ce qui explique en partie que cette +personne ne voit pas la publication et l'agrégation de contenu web à travers +des mails comme une pratique obsolète contrairement aux flux rss est le fait +qu'elle le fait à travers un service qui a techniquement, mais surtout +socialement, repackagé la pratique. On n'envoie plus des mails à la papa, "on a +un Substack". La corolaire dit donc qu'une plateforme de la silicon valley ou +un projet open source à la mode pourrait relancer la popularité des flux rss +sans modifier quoi que ce soit à la techno. + +Ce phénomène, qui s'il en est vraiment un doit déjà être connu et porter un nom +que j'ignore, se retrouve à mon avis avec medium et la pratique d'avoir un blog +ainsi que jekyl/hugo et le fait de construire des sites statiques plutôt qu'une +single page app. + +On peut se réjouir de cette résurgence des sites statiques pour de multiples +raisons. On peut regretter - pas trop fort mais quand même - que cela ait +nécessité l'apparition de nouveaux logiciels pour motiver l'industrie à s'y +remettre. Cela semble être la démonstration parfaite que parfois, peut-être +même souvent, ce que la technologie facilite et sa façon de se présenter à nous +(voir le concept d'affordance, des outils de génération de sites statiques ont +toujours existé) a un impact conséquent sur les comportements humains jusqu'à +créer à posteriori les idées et justifications morales de son utilisation. +Autrement dit, on (du moins je) voyait peu d'articles faisant la promotion des +sites statiques avant l'apparition de ces outils. C'est dorénavant assez +fréquent avec une mention presque systématique de ces outils de là à presque +oublier pourquoi un site statique est dans certains cas préférable. + +Autre constat, ces outils destinés à produire des sites simples, le sont assez +rarement eux-mêmes. Évidemment cela dépend du référentiel choisi. On aura du +mal à argumenter qu'hugo est aussi lourd et complexe à dégainer que React. Mais +au regard des fonctionnalités essentielles pour un générateur de site statique, +il est possible d'argumenter qu'hugo est un logiciel trop complexe et faisant +trop de choix pour vous. On pourrait épiloguer là dessus, pour une autre fois +et une autre personne peut-être. + +Si ces outils ont relancé l'intérêt pour les sites statiques, Francium souhaite +à son tour profiter de l'intérêt nouveau pour les sites statiques afin de +relancer l'intérêt pour une certaine approche du développement d'outils +numériques, que l'on choisit à tort ou à raison d'appeler convivialiste. Plus +concrètement cette envie s'est cristallisée courant 2022 à l'Université de +Strasbourg autour du besoin de générer des sites statiques pour le domaine de +la recherche. L'une des utilisations identifiées était la création de page +personnelles pour les chercheureuses. Pour en faire une démonstration il avait +été décidé de faire la page de Marguerity Perey, chercheuse française ayant +travaillé à l'université de Strasbourg et ayant découvert... le francium.\ +Ce projet initial de générer des pages personnelles de chercheureuses n'est pas +mort. Un template html et une feuille de style adéquate, à l'identité visuelle +Unistra, pourrait aider à le concrétiser. + +C'est finalement la page perso de Marc Chantreux aujourd'hui hors ligne qui +sera le premier site généré et publié grâce à Francium. A date du 11 janvier +2023 le site généré par ce dépôt est le seul en ligne généré par Francium. Le +socle du projet a été conçu et développé par Marc Chantreux. Après la mise en +ligne de ce site le développement s'est étendu à d'autres membres du collectif +Kaztele. + +Il y aurait bien d'autres choses à dire sur la genèse du projet, d'où le titre +de cette rubrique, *Une* histoire de Francium. J'invite les autres parties +prenantes à écrire la leur. + +## Sur la nature de Francium + +Un jour Marc et moi sortions de plusieurs heures de discussions pendant +lesquelles nous avons plusieurs fois fait référence à Francium comme un outil +atomique, se suffisant à lui même. En disant ça nous mettions peut-être dans la +tête de nos interlocuteurs l'image d'un simple couteau qui tient dans la main, +dont les contours sont nettes et la forme plus ou moins identique pour tous ses +utilisateurices. En sortant nous nous sommes partagés une intuition commune : +cette image n'est pas celle qui se formait dans nos têtes quand on parlait de +Francium. Il est compliqué de définir le périmètre exact de ce qu'est Francium. + +Où est-ce que l'outil commence, où est-ce qu'il se termine ? Qu'est-ce qui +relève du générateur et qu'est-ce qui relève du contenu du site ? Ces +interrogations se retrouvent dans certains choix techniques que le projet est +amené à prendre. Ce dépôt permet aujourd'hui de versionner à la fois Francium +(sans savoir ce que c'est exactement) et le contenu du site de Katzele. Si nous +voulions créer un dépôt Francium pour d'autres projets nous devrions répondre à +ces questions pour détricoter l'un de l'autre. + +Pourquoi n'est-ce pas trivial ? + +Prenons en exemple atomic, le script permettant de générer des flux atom. + +Premier point d'accroche, tous les sites n'ont pas besoin d'un flux atom. Bien +que ce soit souvent utile et qu'atomic soit léger, l'inclure dans le dépôt +revient à penser que tous les projets, ou au moins une majorité, ont intérêt à +avoir un script de génération de flux atom. + +Second point, si l'on fait le choix de l'inclure par défaut, tous les flux ne +veulent pas y inclure les mêmes informations. Au delà de la spécification des +flux rss/atom, chaque projet peut vouloir mettre quelque chose de différent +dans les balises. Par exemple la balise "content" est très libre, et son +contenu peut éventuellement être mis en page avec de l'html. Autre exemple, un +flux annonçant des évènements dans le futur voudra sûrement inclure la date +dans le titre, la spécification atom n'ayant pas prévue de balise pour +renseigner la sortie d'un contenu dans le futur. La seule date prévue est celle +de publication du contenu qui ici est l'annonce au présent de la tenue de +l'évènement dans le futur. Il tombe donc sous le sens qu'aucun script atomic ne +se ressemblera. Quel doit donc être l'atomic par défaut ? Le minimum vital ? +Un script générant un flux orienté annonce d'évènements ou publications +d'articles ? + +Troisième point, qui découle du précédent, un projet pourrait vouloir générer +plusieurs flux aux formes différentes. Il pourrait alors vouloir plusieurs +atomic. Ce qui pose la question, qu'est-ce que l'on appel atomic ? Le script +par défaut tel que fourni dans le dépôt source s'il existe un jour ? La version +actuelle maintenue pour le site de Katzele ? L'idée de générer un flux atom via +du shell ? Bref on en a pas fini. + +Nous pourrions décliner ces questions pour toutes les parties de Francium. Pour +revenir à l'échange avec Marc, il avait d'avantage mûri la question que moi. +Francium ne devrait pas être pensé comme, un outil indivisible mais une comme +armature intellectuelle soutenant des outils, certains pré existants, d'autres +créés pour l'occasion. D'ailleurs pour le site de Katzele sed est un outil +autant nécessaire qu'atomic même si l'un a été développé pour et l'autre non.\ +Si l'on voulait pousser cette idée d'armature intellectuelle jusqu'au bout nous +pourrions dire que Francium est un système décrit à travers de la documentation +et non pas ses implémentations. Il n'existerait donc pas de sous-ensemble de ce +dépôt que l'on pourrait raisonnablement appelé Francium. Ce dépôt ne serait que +la première implémentation de Francium, celle sous une forme qui rend les +services dont le collectif Katzele a besoin à un instant T. + +Il existera probablement un jour un dépôt Francium dont le contenu aura été le +résultat de choix plus ou moins raisonnables, fait en fonction des projets qui +veulent utiliser Francium sur le moment[^1]. Ce sera certainement pour le mieux. Si +le concept un peu prétentieux d'armature intellectuelle nous sert à quelque +chose ce sera de faire sens de cette tension : construire un outil +convivialiste qui respecte autant que possible l'autonomie des personnes qui +l'utilisent en minimisant les choix qu'il véhicule et vouloir le publier +facilement n'est pas naturel. La première caractéristique incite à la +construction d'une armature, l'autre à celle d'un outil boite noire.\ +Tracer le contour optimisant la convivialité et la facilité de publication +étant hasardeux, on le fera à main levée et on compensera comme il se doit, en +conversant entre humains, en vivant ensemble. + +[^1]: c'est aujourd'hui le cas [ici](http://git.bebou.netlib.re/francium) diff --git a/contents/documentation/usage.sh b/contents/documentation/usage.sh @@ -0,0 +1,415 @@ +#! page +title: Utiliser francium +description: "Comment utiliser francium" + +section: main + +# Comment utiliser Francium + +Ce document existe pour apprendre à utiliser Francium sans pour autant lire +toute la documentation se trouvant aujourd'hui dans [cet +article](construire.html). + +A noter, Francium est conçu pour être modifiable et même inciter à l'être. +Ainsi ce document documente comment utiliser Francium dans sa version +"minimale". Des cas de modifications relativement simples seront couverts à la +fin de ce document. + +Il ne faut pas s'attendre à pouvoir modifier Francium facilement sans aucune +compétence en make/markdown/shell/html. L'idée est de faire de Francium un +logiciel favorisant l'apprentissage des ces technologies dont on estime +qu'elles constituent un socle de compétences de bases en informatique. On +pourrait évidemment débattre de ce que l'on inclu dans ce socle ou pas. + +## Dépendances + +En l'état Francium nécessite + + * de choisir un ou plusieurs formats dans lesquels écrire le site (du + markdown par ex) + * un ou plusieurs logiciels qui feront la traduction de ce ou ces formats + vers de l'html (cmark/lowdown/pandoc etc) + * un interpréteur shell POSIX (sauf bash pour le moment) + * GNU Make >3.8 (pour le moment) + +Pour la suite de ce document nous partons du principe que le site est écrit en +markdown. + +## Générer le site + +Francium utilise GNU Make pour orchestrer la génération du site. Les règles de +génération sont écrites dans le fichier `makefile`. Pour lancer la génération +faire + + make + +Il est possible d'accélérer le processus en parallélisant avec l'option `-j`. +Pour purger les fichiers produits faire + + make clean + +Il n'est pas toujours nécessaire de faire un `clean` avant de faire un `make`, +les fichiers seront réécrits. La génération du site va transposer les fichiers +et l'arborescence source - dans `./contents` - vers la destination - le dossier +`./public`. Ainsi avec l'arborescence + + ./contents + ├── archives + │ └── index.sh + ├── articles + │ └── youtube + │ ├── arguments-to-plumber.patch + │ ├── display_author.patch + │ └── index.sh + ├── index.sh + └── notes + └── laconvivialite + └── index.sh + +`make` génère l'arborescence + + ./public + ├── archives + │ ├── index.html + ├── articles + │ └── youtube + │ ├── arguments-to-plumber.patch + │ ├── display_author.patch + │ ├── index.html + ├── index.html + └── notes + └── laconvivialite + └─── index.html + +Pour chaque fichier présent dans `./contents` le `makefile` a une règle expliquant à +`make` ce qu'il faut faire. Sans rentrer dans les détails, les fichiers `.sh` +sont transformés en `.html` et copiés dans une arbo identique recrée sous +`./public`. + +## Créer le contenu + +L'exemple précédant se base sur le contenu du site Katzele mais vous voulez +évidemment faire le votre. Imaginons partir de zéro. + +### Template HTML + +Il nous faut au moins un template HTML qui structurera nos pages. Ce sera +l'échaffaudage pour nos pages. Ce template devra se trouver dans le dossier +`./layouts/html`. + +Prenons celui-ci comme exemple : + + layout() { + <<@@ cat + <!DOCTYPE html> + <html> + <head> + <title>${title?La page dont le chemin s'affiche au dessus nécessite un titre}</title> + ${STYLE:+<link rel="stylesheet" href=\"$STYLE\" />} + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width,initial-scale=1.0"> + <meta name="description" content="$description" /> + <meta name="author" content="$author" /> + </head> + <body> + <main> + $(show main) + </main> + </body> + </html> + @@ + } + +Les lignes `layout() <<@@ cat` et à la fin `@@` déclarent une fonction shell +qui contient un heredoc. Si vous voulez en savoir plus lisez [cet +article](construire.html) ou lisez le manuel de dash. Vous pouvez faire +abstraction sinon. + +Le contenu qui se trouve entre ces deux lignes est un mélange d'HTML pur, de +variables shell et d'expansion de variables shell. Je ne vais pas les +expliciter ici. Ce template convient pour générer des pages très simples, +sans header ni footer, simplement le corps de la page que l'on écrit en +markdown. Si cela vous convient vous pouvez ne pas y toucher. Par défaut la +feuille de style qui sera utilisée est `./contents/style.css`. Elle contient le +thème de Katzele, vous pouvez la modifier à votre guise. + +Pour d'éventuelles modifications du template ce qu'il faut à minima retenir est +que vous pouvez ici ajouter de l'HTML comme bon vous semble et avoir recours à +la commande `show nom_de_section` pour ajouter des sections que vous +renseignerez en markdown dans vos fichiers sources. Si vous voulez des exemples +de modification voir plus loin dans ce document. Pour des exemples de sites +aboutis voir [la galerie](/#galerie). + +### Fichier source markdown + +Les fichiers sources des pages doivent comporter l'extension `.sh` et être +exécutables. Ils doivent commencer par la ligne + + #! /usr/bin/env ./page + +pour être préprocessés par le script `page`. Ils doivent ensuite contenir un +ensemble de métadonnée. En l'état Francium propose + + * `title: "titre de la page"` pour renseigner le contenu de la balise `<title>`, à + savoir ce qui s'affiche dans le titre de l'onglet de votre navigateur + * `author: "nom de l'auteurice"` pour suivre qui a rédigé la page. Avec le + template présenté auparavant cette donnée ne se retrouvera nul par dans + l'HTML. Nous verrons un exemple de modification plus tard pour l'intégrer. + * `publication: "date de publication de la page"` pour suivre la date de publication. + Elle peut ensuite être réutilisée dans la génération du site. Voir le + fichier CONSTRUIRE pour un exemple. + * `description: "description du contenu"` pour alimenter la balise meta `description`, + à savoir ce qui s'affichera comme contenu dans le résultat des moteurs de + recherche par exemple. + +On renseigne ces métadonnées en appelant, dans le fichier sh, les différentes +"variables". Par exemple pour une page d'accueil + + title: "Page d'accueil de mon site" + author: moi + publication: 2023-06-21 + description: "Site de machin chose, bidule à chouette à truc muche" + +Il faut ensuite écrire le contenu markdown. Pour cela faire appel à +l'instruction `section:` marquant le début du markdown. Il faut mettre à la +suite de cette instruction la section du template dans laquelle on veut que le +contenu qui suive aille. Dans notre exemple de template il n'y a qu'une section +(marquée par la commande `$(show main)`) qui remplira bêtement la balise `main`, +unique balise du body. C'est le mot clef suivant `show` et non pas le nom de la +balise HTML qu'il faut retenir et faire correspondre avec ce que l'on va écrire +dans le fichier markdown. Il est naturel que la balise et le nom de la section +soient identiques mais cela n'est pas nécessaire. Pour y mettre du contenu nous +pouvons donc écrire : + + section: main + # Le site de machin chose + Salut ! + + ## Ma vie mon oeuvre + + J'ai travaillé ici, là-bas et accompli cela + + * premier truc + * second truc + endsection + +Il faut fermer l'instruction `section:` avec un `endsection`. Au final notre +document ressemble à : + + #! /usr/bin/env ./page + title: "Page d'accueil de mon site" + author: moi + publication: 2023-06-21 + description: "Site de machin chose, bidule à chouette à truc muche" + section: main + # Le site de machin chose + Salut ! + + ## Ma vie mon œuvre + + J'ai travaillé ici, là-bas et accompli cela + + * premier truc + * second truc + endsection + +Si ce fichier se nomme `index.sh` et se trouve à la racine du dossier `./contents` +alors exécuter `make` génèrera ce `index.html` dans `./public` : + + <!DOCTYPE html> + <html> + <head> + <title>Page d'accueil de mon site</title> + <link rel="stylesheet" href="style.css" /> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width,initial-scale=1.0"> + <meta name="description" content="Site de machin chose, bidule à chouette à truc muche" /> + <meta name="author" content="moi" /> + </head> + <body> + <main> + <h1>Le site de machin chose</h1> + <p>Salut !</p> + <h2>Ma vie mon oeuvre</h2> + <p>J'ai travaillé ici, là-bas et accompli cela</p> + <ul> + <li>premier truc</li> + <li>second truc</li> + </ul> + </main> + </body> + </html> + +Dernière astuce, en dehors des blocs `section: nom_de_section ... endsection` +vous pouvez exécuter du shell. Ainsi il est possible, avec votre langage +préféré, de générer du markdown. Cela peut être pratique quand l'on veut +générer quelque chose en fonction d'un contenu qui change souvent et dont on ne +connaît pas, à priori, la teneur. Par exemple un plan de site. Pour ce faire +écrivez le code que vous souhaitez et pipez le dans la commande `save` suivi +du nom de la section dans laquelle vous voulez que le contenu apparaisse. +Ainsi, en reprenant la fin du document : + + J'ai travaillé ici, là-bas et accompli cela + + * premier truc + * second truc + endsection + + echo "[Un autre site cool](lien_vers_site_cool)" | save main + +Ajoutera un lien dans la section main + + <li>premier truc</li> + <li>second truc</li> + </ul> + <p><a href="lien_vers_site_cool">Un autre site cool</a></p> + </main> + </body> + </html> + +Cela peut être pratique pour générer du contenu dynamiquement en fonction +d'autres morceaux du site, de la date etc. + +Voilà, à partir de là si vous savez écrire du markdown et que vous n'avez pas +besoin d'autre chose que des pages simplistes comme celles générées avec le +template fourni vous avez les cartes en main pour créer votre site avec +Francium. Cela dit l'esprit de l'outil est qu'il est de nature "hackable" avec +des compétences que l'on juge, dans le collectif, comme étant de bonnes +candidates pour être des compétences "socles" dans l'informatique. + +En dessous nous voyons quelques cas élémentaires de modifications qui +pourraient vous intéresser ou vous mettre sur la bonne piste. Pour des exemples +plus aboutis voir [la galerie](/#galerie). + +## Modifier francium + +Admettons que vous vouliez apporter les modifications suivantes à l'existant : + + * Gestion d'une métadonnée "langue" car le site est bilingue + * Ajouter une section au template + +### Ajouter une métadonnée + +Vous l'avez peut-être remarqué, il existe une balise `<html lang="fr">` dans +notre template. Cette balise sert à déclarer la langue du contenu qui suit. +Cela permet entre autre aux lecteurs d'écrans de lire correctement le contenu +de la page. Si vous tenez un site bilingue vous pourriez vouloir spécifier la +langue article par article et non pas de façon figée dans le template. + +Pour cela ajoutons une métadonnée qui nous utiliserons au début des articles. +Pour ajouter une métadonnée il nous faut modifier le fichier `page` qui +contient le code pour les rendre opérantes. Dans ce fichier, ajouter une +métadonnée revient à déclarer un nouvel alias et une fonction correspondante. +En ce basant sur ce qui existe pour `title:` : + + alias lang:="lang" + lang() lang="$*" + +Dorénavant quand on écrira `lang: fr" dans un fichier, la variable `lang` prendra +pour valeur "fr". Il suffit ensuite de l'appeler au bon endroit dans le template + + layout() <<@@ cat + <!DOCTYPE html> + <html lang="$lang"> + <head> + +Hop, nous pouvons dorénavant déclarer la langue d'un article. Nous pourrions +mettre un petit filet pour nous assurer de ne pas oublier d'un déclarer un : + + <html lang="${lang?Langue de l'article non déclarée}"> + +Si la variable est vide (parce que nous aurions oublié de renseigner `lang:` dans +un article) alors la génération du site va se terminer et le message d'erreur +sera affiché. Alternativement il est possible de choisir une valeur par +défaut comme ceci : + + <html lang="${lang:-fr}"> + +### Ajouter une section au template + +Admettons que nous souhaitons ajouter un footer et un aside dont nous voulons +maitriser le contenu. Rien de plus simple, il suffit de créer les balises +qui vont bien et d'appeler la commande `show` avec les noms des sections. + + layout() <<@@ cat + <!DOCTYPE html> + <html lang="fr"> + <head> + <meta charset="utf-8"> + <title>${title?La page dont le chemin s'affiche au dessus nécessite un titre}</title> + <meta name="viewport" content="width=device-width,initial-scale=1.0"> + ${STYLE:+<link rel=\"stylesheet\" href=\"$STYLE\"/>} + <meta name="description" content="$description"> + </head> + <body> + <main id="main" class="main"> + $(show main) + </main> + <aside id="aside" class="aside"> + $(show aside) + </aside> + <footer id="footer" class="footer"> + $(show footer) + <p>$author</p> + </footer> + </body> + </html> + @@ + +Au passage nous mettons le nom de l'auteurice, se trouvant dans la variable +`$author` grâce à l'instruction `author:`, dans le footer. +Dans les sources d'une page il faudrait ensuite appeler `section:` avec les noms de +sections : + + section: main + # Titre de l'article + blablalba + endsection + + section: aside + truc que l'on raconte dans l'aside + endsection + + section: footer + contenu du footer + endsection + +A noter, si vous en avez une utilité quelconque, il est possible d'ouvrir et de +fermer les `section:` à votre guise. Le contenu d'une section sera généré dans +l'ordre d'apparition dans le document mais les sections n'interfèrent pas entre +elles. + +Il est donc possible d'écrire : + + section: main + # Titre + azdazda + endsection + + section: footer + machin + endsection + + section: main + bidule + endsection + + section: footer + truc + endsection + +cela reviendrait à écrire + + + section: main + # Titre + azdazda + machin + endsection + + ection: footer + bidule + truc + endsection + +Pareil avec les appels à la commande `save nom_de_section` suite à un pipe. diff --git a/contents/index.sh b/contents/index.sh @@ -5,10 +5,91 @@ description: "Francium est un générateur de site statique mettant l'accent sur section: main +Un générateur de site statique nommé après l'élement chimique +[francium](https://fr.wikipedia.org/wiki/Francium) découvert par la chimiste +[Marguerite Perey](https://fr.wikipedia.org/wiki/Marguerite_Perey). + ## Philosophie +francium est un logiciel ayant pour ambition : + + * d'être petit et simple + * de faire peu de suppositions sur vos besoins + * d'être portable (testé sur Linux, *BSD et MacOs) + * de ne nécessiter que les dépendances dont *vous* avez besoin + * de vous laisser écrire dans le·s langage·s de markup de votre choix + * d'être aussi extensible que possible + * d'être sobre en ressource + +Afin de satisfaire ces propriétés la version canonique de francium offre très +peu de fonctionnalités. Elle propose plutôt une implémentation très simple d'un +système de templating en shell POSIX depuis lequel artisanalement construire son +site. Les contributeurs à l'outil disent parfois de francium qu'il est davantage +un "échafaudage intellectuel" qu'un logiciel ou framework aux contours bien +définis. + +En ce sens la plupart des sites construit avec francium l'étendent pour y +inclure de nouvelles fonctionnalités au gré de leurs besoins. Pour trouver des +exemples jetez un coup d'œil à la [galerie](#galerie). Vous pouvez copier-coller +du code que vous y trouverez ou, mieux encore, prendre contact avec la ou les +personnes derrière un site qui vous plait pour échanger sur la façon dont +francium pourrait vous être utile ! + ## Se lancer +Pour générer le site par défaut de francium vous devez télécharger le code : + + $ git clone git://bebou.netlib.re/francium + +et construire le site : + + $ make + chmod +x contents/index.sh + mkdir -p public; contents/index.sh > public/index.html + ---------------------------- + Première exécution de francium, merci d'aller modifier le code juste en dessous + de ce paragraphe dans le fichier "page". Cela vous permettra de choisir un ou + plusieurs transcripteurs pour votre site. Si une ou plusieurs des lignes déjà + présentes vous conviennent vous pouvez la ou les décommenter en retirant le "#" + devant. Vous pouvez ensuite supprimer ce bloc de code et relancer make :) + ---------------------------- + Compris ? [y/n] + +Lisez bien le message. +Si vous insérez `y` vous serez inviter à faire les modifications sinon vous +serez invité à contacter katzele@framalistes.org. +Quoi qu'il arrive vous verrez en suite les erreurs, vous pouvez les ignorer : + + Bonne édition :) + + make: *** [makefile:69 : public/index.html] Erreur 1 + make: *** Suppression du fichier « public/index.html » + +Ouvrons le script page et, comme indiqué, supprimez le code entre : + + ################# + # SUPPRIMEZ DE LA + + et + + # A DE LA + ######### + +puis juste en dessous choisissez (ou écrivez) l'une des fonctions `show` en +fonction de ce en quoi vous voulez écrire le site. Par exemple, si vous voulez +écrire les pages en markdown vous pouvez décommenter la ligne `show() lowdown +"$tmpdir/$1"`. + +Il vous suffit de relancer la construction du site : + + $ make + chmod +x contents/index.sh + mkdir -p public; contents/index.sh > public/index.html + mkdir -p public; cp contents/favicon.png public/favicon.png + mkdir -p public; cp contents/style.css public/style.css + +Le résultat se trouvera dans le dossier `public` ! :) + ## Galerie endsection @@ -17,4 +98,14 @@ cat db/galerie.tsv | tsv2anything ./layouts/galerie | save main +section: main + +## Documentation + +[Pour savoir d'où vient francium et les questions que l'on se pose sur ses frontières](documentation/histoire.html) + +[Explication complète du code de francium](documentation/construire.html) + +[Guide sur l'utilisation de francium et des modifications élémentaires](documentation/usage.html) +Pour des exemples de sites existant utilisant francium voir [la galerie](/#galerie). diff --git a/contents/style.css b/contents/style.css @@ -115,7 +115,7 @@ h1, h2, h3 { h1, .h1-like { font-size: var(--space-2xl, 3.375rem); - line-height: 1.44; + line-height: 1.14; } h2, .h2-like { diff --git a/layouts/html b/layouts/html @@ -21,11 +21,17 @@ layout() <<@@ cat <nav id="menu" aria-label="menu principal"> <ul> <li id="nom"><a href="/">francium</a></li> - $(makenav) + <li><a href="/#philosophie">Philosophie</a></li> + <li><a href="/#se-lancer">Se lancer</a></li> + <li><a href="/#galerie">Galerie</a></li> + <li><a href="/#documentation">Documentation</a></li> </ul> </nav> </header> <main id="page"> + $( echo "$file" | grep -q "documentation" \ + && { echo "<details><summary>Table des matières</summary>";show tdm;echo "</details>"; } + ) $(show main) </main> <footer> diff --git a/page b/page @@ -30,6 +30,8 @@ description() description="$*" alias publication:=":" +file="$1" + show() lowdown $tmpd/$1 tsv2anything() { @@ -45,13 +47,18 @@ tsv2anything() { done } -makenav() { - grep '^##' contents/index.sh | sed -E "s/^## //" > $tmpd/A - < $tmpd/A tr -d "éà·'ùçè" | - tr ' [A-Z]' '-[a-z]' | - paste -d'\n' - $tmpd/A | - xargs -d'\n' printf '<li><a href="/#%s">%s</a></li>\n' -} +grep -E "^##+" "$file" > $tmpd/titles +< $tmpd/titles lowdown | + grep -v '^$' | + cut -d'"' -f2 | + sed -E 's/^/(#/;s/$/)/' > $tmpd/slugs +sed -E 's/^##/ /g;' $tmpd/titles | + sed -E 's/#/ /g' | + sed -E 's/ (\w)/[\1/;s/$/]/' | + sed -E 's/([^* ])/* \1/' | + paste - $tmpd/slugs | + sed '$ a - - -' | + save tdm . layouts/html