arthur.bebou

Le site arthur.bebou.netlib.re - retour accueil

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

index.sh (24008B)


      1 #! page
      2 
      3 title: Étendre Francium \: Quelques exemples pratiques
      4 description: Regardons ce que cela coûte d\'étendre Francium à travers l\'implémentation de plusieurs besoins
      5 author: Arthur Pons
      6 publication: 2023-11-17
      7 
      8 sectionmd: main
      9 
     10 Francium ne comporte pas beaucoup de fonctionnalités. La base de code est
     11 petite et faite de façon à "avoir la main" au maximum d'endroits possibles via
     12 la ligne de commande. L'idée sous-jacente est que cela permettrait d'étendre
     13 facilement les fonctionnalités comme souhaité. Dans cet article tentons
     14 d'implémenter plusieurs fonctionnalités pour vérifier ou infirmer cette
     15 hypothèse.
     16 
     17 ## Tags
     18 
     19 Beaucoup de générateur de sites statiques offrent la possibilité de tagger
     20 certains articles. Cela permet de les regrouper par thème, de favoriser la
     21 navigation et la découvrabilité du contenu. On retrouve souvent les tags
     22 inscrits sur les articles, sur la page d'accueil et sur leur propres pages.
     23 Tentons, en partant d'une version minimale de Francium, d'implémenter une telle
     24 fonctionnalité.
     25 
     26 Il est à noter qu'il y aurait pleins de façons différentes de le faire, je
     27 n'en documente ici qu'une seule[^1] ayant ses avantages et ses désavantages.
     28 
     29 ### Tagger un article
     30 
     31 Admettons que nous avons des articles dans notre dossier `src/articles` :
     32 
     33 	./src/articles/article4.md
     34 	./src/articles/article3.md
     35 	./src/articles/article2.md
     36 	./src/articles/article1.md
     37 
     38 Ces articles n'ont pour le moment qu'un seul type de "métadonnée", le titre du
     39 document. Il est renseigné avec `title: titre du document` dans chacun des
     40 fichiers. Pour ajouter des tags nous pourrions faire le choix de les ajouter
     41 directement dans les fichiers, pour qu'ils se suffisent à eux même, en créant un
     42 nouveau type de métadonnée `title:AGS`. Les valeurs pourraient être délimitées par
     43 des virgules comme ceci :
     44 
     45 	title:AGS musique,youtube,sobriété
     46 
     47 Et hop, nous avons taggué la page. La première chose qui devrait vous venir à
     48 l'esprit est que si l'on bosse sur un gros site nous voulons probablement
     49 réutiliser un tag déjà existant sans pour autant tous les avoir en tête. Pour
     50 aider à la tâche[^2] on peut imaginer un script listant tous les tags :
     51 
     52 azdjazdazd
     53 
     54 	grep -Ihrm1 "^title:AGS" src/* |
     55 		cut -d' ' -f2 |
     56 		tr ',' '\n' | sort -u
     57 
     58 
     59 > Pour `grep`, `-I` empêche de scanner les fichiers binaires, `-h` permet de ne
     60 > pas afficher les noms des fichiers même s'il y en a plusieurs, `-r` permet de
     61 > faire une recherche récursive dans `src` et `-m1` de s'arrêter sur le premier
     62 > résultat plutôt que de scanner les fichiers dans leur totalité. Techniquement
     63 > il est possible d'ajouter le `title:AGS` après le contenu de l'article auquel cas
     64 > si l'article parle lui même de `title:AGS` et le mentionne en tout début de ligne
     65 > le script pourrait casser mais cela paraît très très peu probable. Le `cut`
     66 > permet de se débarrasser du `title:AGS`, le `tr` d'avoir un tag par ligne et le
     67 > `sort -u` de supprimer les doublons.
     68 
     69 Imaginons un autre script permettant de construire la ligne nécessaire dans les
     70 documents en se basant sur un sélection de tags :
     71 
     72 	paste -s -d',' | xargs printf "%title:AGS %s\n"
     73 
     74 > `paste -s` permet de "sérialiser" le collage. Autrement dit, avec une seule
     75 > source de donnée (ici stdin), cela va coller toutes les lignes les une avec
     76 > les autres. `-d` permet de choisir le délimiteur. Le `xargs printf` permet
     77 > d'insérer le résultat dans une chaîne de caractère passée en premier argument
     78 > de `printf`. En l'occurence faut bien échapper le `%` avec un autre. Le
     79 > second argument du `printf` (c'est à dire note liste de tag) se placera là où
     80 > on trouve le `%s`.'
     81 
     82 Avec ces deux scripts à notre portée, si l'on est en train d'éditer un document
     83 on peut les exécuter dans vim et facilement le tagguer avec des tags dont on
     84 saura qu'ils existent déjà exactement sous cette forme à travers le site. La
     85 commande `:r!commande1` insérera quelque chose du type :
     86 
     87 	data
     88 	musique
     89 	sobriété
     90 	youtube
     91 
     92 Là où le curseur se trouve. On peut ensuite supprimer les tags que l'on ne
     93 souhaite pas. Finalement on sélectionne ce que l'on souhaite et on filtre avec
     94 `commande2` pour obtenir :
     95 
     96 	title:AGS data,youtube
     97 
     98 Si vous acceptez d'ajouter une petite dépendance à quelque chose comme `fzy` ou
     99 `fzf` on peut même avoir une jolie interface pour sélectionner ses tags en
    100 lançant :
    101 
    102 	:r!commande1 | fzy -m | commande2
    103 
    104 On sélectionne ses tags avec la tabulation, on appuie sur entrée et hop voilà.
    105 
    106 ### L'afficher quelque part
    107 
    108 Si l'on tente de construire le site à ce stade on obtiendra comme quoi `title:AGS` n'est
    109 pas une commande. Il faut déclarer l'alias et choisir quoi lui faire faire dans
    110 le script qui gère ces pages. En plus du script de base `common` nous allons
    111 créé un script `article` pour gérer notre cas particulier. Cela fait sens si l'on
    112 ne tagguera que des articles. Pour la suite il faudra donc que chaque document que
    113 l'on souhaite tagguer commence par `#! page` pour que cela soit pris en compte.
    114 Dans `article` on appel `common` pour avoir les alias et fonctions communes à toutes
    115 les pages et on spécifie le petit nouveau `title:AGS` avec :
    116 
    117 	#! /bin/sh
    118 
    119 	. ./common
    120 
    121 	alias title:AGS="tags"
    122 	tags() tags="$*"
    123 
    124 Ici on décide d'instancier la variable `$tags` contenant la liste des tags mais
    125 nous aurions pu faire n'importe quoi d'autre. Dorénavant nous avons deux choix
    126 pour les afficher sur un article. Soit on créer un nouveau layout html dans
    127 lequel on intègre les tags soit on les injecte dans le markdown juste avant qu'il
    128 soit traduit en html. Chaque méthode à ses avantages et inconvénients.
    129 
    130 > L'ajouter au layout est peut-être un peu plus "propre" dans le sens que le
    131 > code s'exécute une seule fois et pas à chaque appel de `save_md`. Cependant
    132 > impossible d'insérer les tags au milieu du contenu markdown écrit à la main. 
    133 
    134 Si l'on veut l'ajouter au layout on peut créer un nouveau layout en ajoutant par exemple :
    135 
    136 	<meta name="keywords" content="$tags" />
    137 	# Et plus loin
    138 	<div class="tags">
    139 		<p>tags : $(echo "$tags" | tr ',' '\n' | sed 'p' | xargs printf "<a href='/tags/%s.html'>%s</a> - " | sed -z 's/ - $//')</p>
    140 	</div>
    141 
    142 > Dans `$tags` la liste des tags séprarés par des virgules. On les met tous sur
    143 > une ligne différente avec `tr`, on les double avec `sed` puis on a à nouveau
    144 > recours à la technique du `xargs` + `printf` pour générer les liens html.
    145 > Finalement on retire le ` - ` qui traîne à la fin. Il a fallu doubler les
    146 > lignes puisque que pour chaque tag on fait appel à son nom deux fois dans la
    147 > commande `printf` qui créer le lien (voir les deux `%s`). Sachant que chaque
    148 > `%s` "consomme" un argument, si l'on ne doublait pas les lignes on aurait des
    149 > liens type `<a href='tags/1.html'>2</a>`. `sed 'p'` double les lignes parce
    150 > que le comportement par défaut de `sed` est, après avoir exécuté toutes les
    151 > commandes, d'imprimer ce qu'il a dans son "pattern space" (c'est à dire ce
    152 > sur quoi il travail, généralement la ligne courante). La commande sed `p`
    153 > imprime le pattern space. Cet appel à sed va donc, pour chaque ligne,
    154 > l'imprimer puis, à la sortie du script pour la ligne courante, imprimer le
    155 > pattern space. On se retrouvera donc avec un doublon de chaque ligne.
    156 
    157 et en appelant le nouveau layout dans `article` :
    158 
    159 	. lib/htmltags
    160 
    161 Alternativement on peut surcharger le `save_md` de `common` pour insérer, par
    162 exemple juste après le titre principal, la liste des tags :
    163 
    164 	save_md() {
    165 		taglinks=$(echo "$tags" | tr ',' '\n' | sed 'p' | xargs printf "[%s](/tags/%s.html)\ - " | sed -z 's/ - $//')
    166 		cat |
    167 		sed -E "
    168 	/^# .+/ s+$+\
    169 	\n\
    170 	tags : $taglinks \n\
    171 	\n\
    172 	------------\n\
    173 	+" |
    174 		lowdown >> "$the/$1"
    175 	}
    176 
    177 > On met dans la variable `taglinks` la même chose que ce que l'on avait généré
    178 > dans le layout mais version markdown. Ensuite on fait un coup de `sed` qui,
    179 > pour toutes les lignes commençant le titre principal, ajoute juste après le
    180 > bloc qui suit. Ce n'est pas super lisible mais j'ai tenté de faire de mon
    181 > mieux en échappant les nouvelles lignes avec un `\` de façon à ce que ça
    182 > ressemble au plus près à ce qui est réellement inséré dans le flux.
    183 
    184 Un petit coup de make et hop on devrait voir les tags affichés sur les articles.
    185 J'ai à chaque fois créé des liens avec l'idée de créer ensuite des pages de tags.
    186 
    187 ### Les pages des tags
    188 
    189 Chaque tags pourrait avoir sa page, listant les articles concernés. Cette partie
    190 est la plus hasardeuse de mon exploration. Je ne la trouve pas satisfaisante et
    191 je ne sais pas comment faire autrement.
    192 
    193 Il serait délicat de créer à la main chaque page, d'autant plus qu'elle n'a
    194 pas vocation à contenir du contenu écrit par des humain·e·s. Je propose donc
    195 d'avoir un script qui, basé sur les tags existant dans les articles, va créé
    196 les sources des pages des tags. Au prochain make ces pages seront convertie
    197 en html comme toutes les autres. Le script en question pourrait être :
    198 
    199 	#! /bin/sh
    200 
    201 	mkdir -p src/tags
    202 	for tag in $( grep -Ihrm1 "^title:AGS" src/* | cut -d' ' -f2 | tr ',' '\n' | sort -u)
    203 	do
    204 
    205 	<<. cat > src/tags/$tag.md ; chmod +x src/tags/$tag.md
    206 	#! page
    207 	title: 'Tag $tag'
    208 
    209 	sectionmd: main
    210 	# $tag
    211 
    212 	Articles concernés :
    213 	%
    214 
    215 	grep -lIrm1 '^title:AGS.*musique.*$' src/* |
    216 		xargs grep -Hm1 '^title: ' |
    217 		sed -E 's/([^:]*)[^ ]+ (.+)$/\2\n\1/' |
    218 		sed 's/^"//;s/"$//;s/^src//;s/md$/html/' |
    219 		xargs -d'\n' printf '  * [%s](%s)\n' |
    220 		save_md main
    221 	.
    222 
    223 	done
    224 
    225 > On créé le dossier `tags`. On récupère la liste des tags (comme dans la
    226 > commande1) et on boucle dessus avec une heredoc. Le heredoc contient le
    227 > "template" du fichier permettant de générer la page des tags. On insère les
    228 > noms des tags avec la variable `$tag` qui est celle récupérée par la boucle
    229 > `for`. Le contenu du heredoc est mis dans le fichier `src/tags/...md` dont on
    230 > modifie les droits d'exécution. Pour récupérer les articles concernés on fait
    231 > un `grep` sur la présence du tag en cours dans les fichiers de `src` avec
    232 > `-l` pour n'avoir que les noms des fichiers (pas besoin de la valeur des
    233 > tags, juste de savoir qu'il y a celui qu'on veut), `-I`, `-r` et `-m1` sont
    234 > expliqués plus tôt dans l'article. Pour chacun des fichiers ayant matchés il
    235 > nous faut son titre, on fait donc un combo `xargs grep` sur la métadonnée du
    236 > titre en prenant bien soin de mettre un `-H` pour que le nom du fichier
    237 > apparaisse même s'il n'y a qu'un seul résultat. Un peu (pas mal) de `sed`
    238 > pour arranger les résultat comment on le veut, encore un `xargs` + `printf`
    239 > pour créer les liens au format makrdown et on sauve tout ça dans la section
    240 > main.
    241 
    242 Le script fonctionne très bien, là où il ne m'offre pas satisfaction est
    243 l'intégration avec le makefile. En effet, les pages de tags étant toutes générées
    244 depuis le même script il n'est pas possible de créer des dépendances différentes.
    245 Si l'une doit être modifiée elles devront toutes l'être. De toute façon, les tags
    246 ne vivant que dans les articles eux même il ne serait de toute façon pas possible
    247 de savoir quelle page de tag remettre à jour à la modif d'un article puisque l'on
    248 ne sait pas *qu'est-ce* qui a été modifié dans l'article. Est-ce que c'était
    249 les tags ? Si oui, qu'est-ce qui a été supprimé / ajouté ? Dans le doute, la seule
    250 solution vaguement convenable serait de reconstruire ces pages à chaque
    251 build du site. Ce n'est pas forcément très coûteux mais c'est un peu bête
    252 d'utiliser `make` pour en arriver là. De plus, si l'on utilise la parallélisation
    253 des règles avec `-j` il est possible que `make` ne reconstruise pas certaines pages
    254 de tags s'il tente de déclencher ces règles *avant* que le script générant les
    255 fichiers sources ait terminé.
    256 
    257 Peut-être qu'une solution serait de faire vivre les tags en dehors des articles,
    258 avec un fichier `tags` listant les tags et vivant à côté de son article :
    259 
    260 	src/articles/
    261 	└── article1
    262 	    ├── index.html
    263 	    └── tags
    264 
    265 Auquel cas il serait possible de créer des règles ayant du sens. Ce système à
    266 le désavantage de devoir maintenir un lien entre les deux fichiers, que ce soit
    267 à travers leurs emplacements dans l'arborescence, leurs noms, éventuellement
    268 une entête dans le fichier `tags` etc. Ces liens semblent tous un peu plus
    269 délicats à maintenir, migrer, porter, faire évoluer que celui d'avoir les tags
    270 écrits à l'intérieur du document que l'on souhaite tagguer. 
    271 
    272 Et si l'on veut maintenant voir tous les tags, mettons sur la page d'accueil ?
    273 
    274 ### Aperçu général des tags
    275 
    276 Mettons que nous voulons voir la liste des tags avec le nombre d'articles
    277 associés à côté. On peut ajouter le script suivant au fichier :
    278 
    279 	grep -hrm1 "^title:AGS" src/* |
    280 		cut -d' ' -f2 |
    281 		tr ',' '\n' |
    282 		sort | uniq -c |
    283 		sed -E 's/^ *([0-9]+*) (.+)$/\2\n\2\n\1/' |
    284 		xargs printf "  * [%s](/tags/%s.html) - %s articles\n" |
    285 		save_md main
    286 
    287 > Toujours la même chose pour récupérer les tags, mais au lieu de retirer les
    288 > doublons on les compte avec `uniq -c`. Avec sed on réarrange le contenu de
    289 > façon à avoir sur deux lignes le nom du tag et la troisième le nombre
    290 > d'articles associés. Finalement un dernier combo `xargs` + `printf` pour
    291 > créer la liste comme on veut et hop on enregistre.
    292 
    293 ## Programmation de la publication
    294 
    295 Il y a plus d'un an de cela Derek voulait pousser un article en cours
    296 d'écriture sur le dépôt git pour le partager avec nous sans pour autant qu'il
    297 apparaisse sur la page d'accueil puisque non fini. Pour implémenter cela nous
    298 avons choisi d'ajouter une date de publication dans les articles.
    299 
    300 ### Ajout de la donnée
    301 
    302 Dans les articles, quelques chose sous la forme suivante pour publication le 13 juillet 2023 :
    303 
    304 	publication: 2023-07-13
    305 
    306 ### Condition d'apparition en fonction de la date
    307 
    308 Le simple fait d'ajouter la donnée ne change rien mais on peut dorénavant
    309 l'utiliser pour conditionner l'apparition des pages en fonction de cette date.
    310 Par exemple, si l'on souhaite lister toutes les articles dans le dossier
    311 `articles` :
    312 
    313 	find src/articles/ -type f -name 'index.md' |
    314 		xargs grep -Hm3 '^title:\|^author:\|^publication:' |
    315 		paste - - - |
    316 		sed -Ee 's,src/(.*).md:title: "?([^"]*)"?	src/.*.md:author: (.*)	src/.*publication: (.*),* \4 - [\2](\1.html),'\
    317 			 -e 's,([0-9]{4})-([0-9]{2})-([0-9]{2}),\1/\2/\3,' |
    318 		sort -rn
    319 
    320 alors il suffit d'ajouter une commande `awk` faisant comparant les dates au
    321 format `yyyy-mm-dd` quelque part dans le pipeline :
    322 
    323 	find src/articles/ -type f -name 'index.md' |
    324 		xargs grep -Hm3 '^title:\|^author:\|^publication:' |
    325 		paste - - - |
    326 		awk -F'\t' -v now="publication: "$(date -I) '{if(substr($3,length($3)-12,13)<=now){print $0}}' |
    327 		sed -Ee 's,src/(.*).md:title: "?([^"]*)"?	src/.*.md:author: (.*)	src/.*publication: (.*),* \4 - [\2](\1.html),'\
    328 			 -e 's,([0-9]{4})-([0-9]{2})-([0-9]{2}),\1/\2/\3,' |
    329 		sort -rn
    330 
    331 pour ne voir apparaître que les articles dont la date de publication est
    332 antérieur à aujourd'hui. Le tour est joué en une seule ligne de code.
    333 
    334 ### Limitations
    335 
    336 Évidemment ce système permet uniquement de contrôler la présence
    337 ou non d'un article quelque part dans une liste. Cela n'empêche
    338 pas de pouvoir voir les sources dans le dépôt git si celui-ci
    339 est publique ni de tomber totalement par hasard dessus si l'on
    340 trouve l'url (très peu probable cependant). Pour empêcher ce
    341 second scénario il faudrait implémenter quelque chose au niveau
    342 de makefile.
    343 
    344 ## Bilinguisme
    345 
    346 J'ai eu à implémenter un site en version bilingue anglais<->français récemment,
    347 voilà comment j'ai fait. [Le dépôt du site en
    348 question](https://gitlab.in2p3.fr/adele) et [son url](adele.helpdesk).
    349 
    350 L'idée est que les fichiers sources continennent dans leurs noms la langue de
    351 destination. Je crois que d'autres systèmes fonctionnent comme ça. Par exemple
    352 `contact.fr.sh` est la source de `contact.html` en français et `contact.en.sh`
    353 la source de `contact.html` en anglais.
    354 
    355 Dans le makefile on récupère les fichiers sources et avec une petite commande
    356 sed on créer le chemin de la cible en prenant compte de la langue
    357 
    358     sources      != find contents -type f -name '*.sh'
    359     html         != echo "${sources}" | sed -E 's,contents/([^.]+)\.(en|fr)\.sh,public/\2/\1.html,g'
    360 
    361 Ainsi on a
    362 
    363 | sources | cibles |
    364 |---|---|
    365 | `contents/contact.fr.sh` | `public/fr/contact.html` |
    366 | `contents/contact.en.sh` | `public/en/contact.html` |
    367 | `contents/apropos.fr.sh` | `public/fr/apropos.html` |
    368 | `contents/apropos.en.sh` | `public/en/apropos.html` |
    369 
    370 La commande sed est un peu moche et ne gère pas des langues arbitraires parce
    371 que j'ai eu la flemme d'écrire une expression régulière généraliste. Sans un
    372 système plus complexe il faudra toujours que la page s'appelle de la même
    373 manière dans les deux langues. Pas de "about.html" en anglais donc. Au pire
    374 cela empêche une personne qui parle anglais de deviner les noms des pages et de
    375 trouver toute seule `site.com/en/about.html`. Si les urls des sites étaient
    376 assez standardisée pourquoi pas mais en l'état ça ne me semble pas être un gros
    377 problème.
    378 
    379 Il nous faut ensuite générer des liens sur les pages permettant de passer d'une
    380 langue vers une autre. Pour cela il nous faut, lorsque l'on génère une version,
    381 construire l'url de l'autre pour l'insérer dans la page. On peut modifier
    382 `page` de la sorte :
    383 
    384     destination=$(echo "$@" |
    385         sed -E 's,contents/([^.]+)\.(en|fr)\.sh,public/\2/\1.html,g' |
    386         sed -E 's,^public,,')
    387     echo "$@" | grep -q ".fr." && autre="en" || autre="fr"
    388     destinationautre=$(echo "$destination" | sed "s,/../,/$autre/,")
    389 
    390 On reproduit le traitement du makefile pour connaître l'url de destination[^3],
    391 on retire la partie `public` puis on met la langue opposée dans une variable
    392 puis on construit le chemin vers l'article de l'autre version en fonction
    393 de la langue récupérée.
    394 
    395 Dans le layout on ajoute là où l'on souhaite voir le lien apparaître :
    396 
    397 	<a href="$destinationautre">$autre</a>
    398 
    399 
    400 En l'état tout fonctionne bien sauf la page d'accueil servie par défaut,
    401 généralement index.html. En effet avec notre système toutes les pages
    402 html se retrouveront sous les dossiers fr ou en mais jamais à la racine.
    403 
    404 Pour contourner ce problème on peut à nouveau modifier le makefile de
    405 façon à ce que le fichier `index.fr.sh` (ou `index.en.sh` en fonction
    406 de la langue par défaut de votre site) génère à la fois `/fr/index.html`
    407 et `/index.html` :
    408 
    409 
    410     all: public/index.html ...
    411 
    412     public/index.html : contents/index.fr.sh page common
    413         mkdir -p $(shell dirname $@)
    414         $< > $@
    415 
    416 On ajoute l'index.html de la racine dans les dépendances de la règle all puis
    417 une règle personnalisée pour cette page qui ne dépend pas directement de son
    418 clône dans le dossier source mais de index.fr.sh ou index.en.sh selon la langue
    419 par défaut.
    420 
    421 Notre site intègre une gestion basique du bilinguisme ! Il ne reste plus qu'à
    422 tout traduire !
    423 
    424 ## S'auto-référencer dans un article
    425 
    426 J'ai récemment entrepris la rédaction d'une [longue page se faisant fréquemment
    427 référence à elle même](http://bebou.netlib.re/faq). Pour renvoyer vers une
    428 autre page du site ou pire, renvoyer vers un titre spécifiquement, il faut faire
    429 preuve d'une mémoire colossale et d'une implémentation mentale de l'algorithme
    430 de génération des identifiants de titre de votre traducteur markdown -> html.
    431 
    432 J'ai donc entrepris de créer un script permettant de lister toutes les options
    433 et d'en choisir une. Ce script a pour dépendance fzy pour l'interface de choix
    434 et ne fonctionnera qu'après une première construction du site puisqu'il va
    435 chercher les données dans l'html et non pas dans les sources.
    436 
    437 Il faut d'abord mettre dans une variable la totalité des éléments
    438 ayant un attribut `id` et les titres de tous les articles[^4] :
    439 
    440     link=$(find public -type f -iname '*.html' |
    441     xargs grep -Er '(<title>|id=")' |
    442         cut -b7- |
    443         fzy)
    444 
    445 find liste tous les fichiers html, xargs grep permet de chercher toutes les
    446 lignes contenant `<title>` ou `id="` dans chacun de ces fichiers puis cut
    447 supprime le nom du dossier public. Le format de sortie est comme ceci :
    448 
    449 	/youtube/index.html:	<title>Guide de survie en territoire youtubesque</title>
    450 	/youtube/index.html:	<h2 id="pourquoi-">Pourquoi ?</h2>
    451 	/youtube/index.html:	<h2 id="pour-les-smartphones">Pour les smartphones</h2>
    452 
    453 Ensuite, le traitement sera différent selon si notre sélection est un
    454 identifiant vers lequel renvoyer ou le titre d'une page entière. Pour
    455 tester cela on utilise des grep :
    456 
    457 	if $(echo "$link" | grep -q 'id='); then
    458 		[...]
    459 	else $(echo "$link" | grep -q '<title>'); then
    460 		[...]
    461 	fi
    462 
    463 Si l'on veut faire un lien vers un titre en particulier page on choisit la ligne
    464 contenant la balise titre correspondante et le traitement est comme suit :
    465 
    466 	if $(echo "$link" | grep -q 'id='); then
    467 		echo "$link" |
    468 			sed -E 's,:.+id=",#,;s/index.html//' |
    469 			cut -d'"' -f1
    470 	else $(echo "$link" | grep -q '<title>')
    471 		[...]
    472 	fi
    473 
    474 On remplace tout ce qui se trouve entre le chemin du fichier et la première
    475 apostrophe par un `#`, on retire l'index.html (optionnel) et on ne
    476 garde que ce qu'il y a à gauche de l'apostrophe restante. L'avant-après :
    477 
    478 	/youtube/index.html:	<h2 id="pour-les-smartphones">Pour les smartphones</h2>
    479 	/youtube/#pour-les-smartphones
    480 
    481 Si l'on veut faire un lien vers une page, on choisit la ligne qui contient
    482 sa balise titre et le traitement sera le suivant :
    483 
    484 	if $(echo "$link" | grep -q 'id='); then
    485 		[...]
    486 	else $(echo "$link" | grep -q '<title>'); then
    487 		echo "$link" |
    488 			cut -d':' -f1 |
    489 			sed 's/index.html//'
    490 	fi
    491 
    492 On ne garde que le chemin du fichier dans lequel on a trouvé la balise avec cut
    493 et on supprime index.html (toujours optionnel).  L'avant-après :
    494 
    495 	/youtube/index.html:	<title>Guide de survie en territoire youtubesque</title>
    496 	/youtube/
    497 
    498 Le script final :
    499 
    500     link=$(find public -type f -iname '*.html' |
    501 		xargs grep -Er '(<title>|id=")' |
    502 			cut -b7- |
    503 			fzy)
    504 
    505     if $(echo "$link" | grep -q 'id='); then
    506         echo "$link" |
    507             sed -E 's,:.+id=",#,;s/index.html//' |
    508             cut -d'"' -f1
    509     else $(echo "$link" | grep -q '<title>'); then
    510         echo "$link" |
    511             cut -d':' -f1 |
    512             sed 's/index.html//'
    513     fi
    514 
    515 Si on veut l'utiliser dans vim à la volée en mode insertion on peut
    516 utiliser cette macro :
    517 
    518     inoremap <buffer> (-l <ESC>:r!./slug<CR>kgJEa
    519 
    520 En tapant rapidement sur `(-l` en mode insertion fzy s'ouvrira, on fait son
    521 choix et hop on continue à écrire derrière le lien nouvellement inséré.
    522 
    523 ## Conclusion
    524 
    525 J'espère avoir démontré qu'étendre Francium est raisonnablement facile pour une
    526 personne sachant développer. Le résultat final et surtout la base nécessaire à
    527 pouvoir permettre une telle implémentation me semble petite et gérable sur le
    528 long terme. Le compte du nombre de lignes de code est délicat, est-ce que l'on
    529 compte les parties "template", est-ce que chaque pipe compte comme une ligne,
    530 chaque commande sed comme une autre ? En tout cas on peut remarquer qu'il est
    531 possible de factoriser une quantité non négligeable du code écrit.
    532 Pour les tags je dirais qu'il y a environ une trentaine de lignes importantes,
    533 une dizaine pour le bilinguisme. Ce n'est pas négligeable, surtout quand on
    534 considère la relative crypticité de certaines commandes mais **tout** est
    535 devant vos yeux. La totalité de l'implémentation a été décrite ici.
    536 
    537 [^1]: du moins pour commencer, peut-être que j'en ferai d'autres à l'avenir
    538 [^2]: et à condition d'utiliser vim mais vraiment essayez. Passez en atelier les mardi après-midi à l'atrium sur le campus de l'Unistra pour vous faire aider :)
    539 [^3]: Peut-être qu'on pourrait le factoriser pour éviter d'avoir à le modifier à au moins deux endroits.
    540 [^4]: J'ai choisi la balise `<title>` parce que c'est celle qui me permet le plus facilement d'identifier le contenu d'un article
    541 
    542