💾 Archived View for unbon.cafe › lejun › posts › 20230716_geminiReCite.gmi captured on 2023-07-22 at 16:17:59. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
Je viens de terminer l'articulation – programmation serait un bien grand mot – d'un script qui, je l'espère me fera gagner beaucoup de temps dans la maintenance de ma capsule Gemini : GeminiReCite ; Tout ce qui suit est à priori de la paraphrase de ce qui est dit sur le dépot[1].
En une phrase, le script me permet – et aux personnes structurant de la même manière – de renuméroter les liens au sein de leurs fichiers GemText.
Le format GemText[2] défini un lien comme étant une ligne débutant par la séquence `=>`, ce qui correspond simplement à l'expression régulière `^=>`.
Au delà de quoi il n'existe aucune consigne particulière quand à la manière de faire référence à ces liens au sein du corps de texte, ce qui est particulièrement déroutant pour les personnes habituées aux Markdowns permettant les liens à même le texte.
Une solution courante dans le milieu académique où le papier est encore largement utilisé – Ce qui implique d'utiliser d'autres méthodes que les liens hypertextes – est d'utiliser un format de citation avec une bibliographie explicite – que ce soit en fin de document ou pied de page. C'est le format que j'utilise ici ubiquitairement, bien que m'étant éloigné de mon style APA[3] de cœur pour le IEEE[4], où :
Bien qu'efficace (pour ce que ça vaut, c'est à priori le style principal sur Gopher), cela à un inconvénient majeur quand comme dans mon cas on a tendance à reprendre d'anciens contenus pour y insérer des références. On se retrouve alors à devoir manuellement décaler les nombres, ce qui n'est pas des plus attrayants ni productif.
J'ai ainsi monté un script Bash pour automatiser tout ça, et m'économiser un temps précieux sur la maintenance de ma capsule.
Le script proposé a été uniquement construit autour de ma manière de structurer mon contenu, à savoir :
Ce script ne saurait ainsi être la solution miracle à tous les problèmes, mais reste une base solide pour bricoler à partir de rien. À l'heure actuelle seulement la première condition fait l'objet d'une vérification au lancement du programme, la deuxième pourrait faire l'objet d'une évolution, tandis que la troisième semble à priori impossible.
Le script fait uniquement appel à `sed` pour les modifications, `cat` et `grep` sont utilisés pour les fonctions auxiliaires de vérification.
L'idée d'un script m'est venue courant mois de juin avant d'être temporairement laissée de côté. La difficulté principale étant l'insertion successive de nombres incrémentiels – Ça peut paraître anodin, mes compétences n'ont probablement pas aidé.
Il n'y a pas eu de réel choix à propos du langage. Bash me semblait être le plus simple, sans qu'il n'y ait de réelle question de performance pour une opération à si petite échelle. Les puristes pourraient en faire un programme compilé en C.
La première étape était de mettre en place une forme de sécurité, je me connais, et il est fort probable que sur un malentendu j'utilise un crochet pour autre chose qu'une référence (ex : une gamme de valeurs).
links=$(cat $@ | grep -c '=>') echo "$links link(s) found" references=$(cat $@ | grep -c '\[.*\]') echo "$((references-links)) reference(s) found in text ($references in total)" if [ $((references-links)) -lt $links ] then echo "Unequal references-to-links count. Can't process file auto-magically." echo "Some links may be unused." exit elif [ $((references-links)) -gt $links ] then echo "Unequal references-to-links count. Can't process file auto-magically." echo "Some links may be used more than once." exit fi echo "References-to-links count check passed. Proceeding…"
Pour cela j'ai simplement compté le nombre de liens au sein du fichier, ainsi que le nombre de paires de crochets, pour les comparer – Le second étant censé être le double du premier puisque apparaissant à la fois dans le corps de texte, et le texte de lien. Selon le résultat de la comparaison, un message permet d'aiguiller sur l'erreur, ou d'indiquer la validation de l'étape.
sed -i 's/\[.*\]/[]/g' $@
Toutes les références sont d'abord nettoyées ne laissant qu'une paire de crochet. Cette étape est particulièrement importante puisque permet la suite du code sans trop se casser la tête. C'est en partie cette étape qui implique que la bibliographie soit déjà en ordre.
insert=1 cycle=1 while [ $cycle -ne 3 ] do sed -i "0,/\[\]/{s/\[\]/\[$insert\]/}" $@ if [ $insert -eq $links ] then insert=1 cycle=$((cycle+1)) else insert=$((insert+1)) fi done
Le cœur du programme, une boucle est créée au sein de laquelle est inséré un nombre incrémentiel au sein de chaque paire de crochet. C'est la partie qui m'a demandé le plus de réflexion, notamment par la gestion de deux compteurs en parallèle, ainsi que par l'absence de maîtrise de `sed` ayant tendance à faire un remplacement global là où j'aurais attendu un remplacement du premier élément trouvé uniquement.
Pour le remplacement, `sed` s'obstinait à réaliser un remplacement global, alors même que l'option globale n'était pas indiquée – Une lecture plus approfondie est à prévoir. La solution, était simplement de préfixer la séquence de substitution par `0,/addr2/` où le programme est effectivement borné du début du fichier jusqu'à l'expression régulière correspondant à `addr2` incluse. Avoir nettoyé les anciennes références me permet ainsi de distinguer facilement les références traitées – remplies – des non traitées – une simple paire de crochets. À noter l'usage de doubles guillemets, pour indiquer la présence d'une variable à interpréter comme telle plutôt qu'une séquence de caractères.
En ce qui concerne l'incrémentation, j'ai utilisé deux variables d'une part pour le nombre à insérer (augmentant à chaque remplacement), et d'autre part pour mettre fin au programme qui autrement tournerait en boucle – À défaut d'être élégant, ça marche. Le nombre à insérer augmente à chaque remplacement jusqu'à atteindre le nombre de liens détectés en amont, suite à quoi il est remis à 1, et le compteur de cycle augmente. Le compteur de cycle de cycle, permet ainsi de réaliser une passe pour le corps de texte, suivie d'une autre pour la bibliographie avant de quitter la boucle.
Sur la foulée, j'ai rendu le script plus sérieux en :
À priori c'est tout ce que je compte en faire pour l'instant, et voit difficilement comment l'améliorer au delà d'une touche d'interactivité. Peut-être en profiter pour monter un second script pour corriger la date suite à une modification du contenu, mais cela serait clairement à portée individuelle puisqu'il n'existe aucune spécification officielle à ce sujet.
[2] A quick introduction to "gemtext" markup, Solderpunk 2019