Un exemple de glossaire visualisé avec Cosma

2021-09-14

Je propose une réutilisation du glossaire sur les humanités numériques de Digit_Hum, avec un petit making-of.

La semaine dernière, l’équipe bordelaise d’HyperOtlet a publié la version 1.0 de Cosma. Dans le billet que j’ai rédigé parallèlement pour présenter le logiciel, je mentionne que nous avons mis en ligne une démonstration. Il s’agit d’une partie de la documentation utilisateur de Cosma, adaptée sous forme de fiches.

Une opportunité se présente aujourd’hui de montrer un autre exemple d’utilisation de Cosma, plus concret. Le programme de recherche Digit_Hum a annoncé une mise à jour significative de son glossaire sur les humanités numériques via la liste DH. En consultant le site, j’ai immédiatement pensé que ce glossaire ferait un exemple parfait pour illustrer l’un des cas d’usage de Cosma, à savoir l’élaboration d’un glossaire sous forme de fiches terminologiques densément interreliées.

Le site de Digit_Hum mentionnant la licence Creative Commons BY-NC-ND (réutilisation possible avec attribution, sans commercialisation ni modification), j’ai pris la liberté de récupérer les données directement via le site pour les transformer en fiches au format texte, puis réaliser un cosmoscope, accessible à l’adresse suivante : https://www.arthurperret.fr/digithum-glossaire-hn.html

Les notices transformées sont en ligne sur un dépôt GitHub.

Ce n’est pas la première « conversion Cosma » que je fais sur un glossaire : vers la fin du développement, j’ai pioché dans ma bibliothèque pour en tirer quelques exemples nous permettant de tester le logiciel. Mais cette fois-ci, les données sont sous licence libre, ce qui me permet de partager publiquement la démonstration. J’espère qu’elle donnera envie à d’autres personnes de se lancer sur Cosma !

En coulisses : un peu de text wrangling…

Pour les personnes curieuses, je termine ce billet par un résumé du processus d’extraction et de préparation des données. Cela vous donnera une idée du bricolage qui m’a permis de passer d’un glossaire présenté sous forme de site web dynamique (HTML + JavaScript) à une collection de fiches au format requis par Cosma (Markdown + YAML + identifiants de type horodatage).

Sur le site Digit_Hum, chaque notice est stockée dans une page HTML différente, avec des noms comme application ou resolveur_de_liens. Les URL ressemblent à ceci :

https://digithum.huma-num.fr/ressources/glossaire/notices/?terme=resolveur_de_liens

Les noms des pages sont tous listés dans le code source de la page du glossaire. Les récupérer via une expression régulière est très simple, via la capture de groupe (rechercher quelque chose comme terme=([^"]+)", extraire \1). On les stocke dans un fichier filenames.txt, un nom par ligne.

Ensuite, on met à profit cette liste pour télécharger la page HTML de chaque notice via curl :

while read filename
  do curl "https://digithum.huma-num.fr/ressources/glossaire/notices/?terme=$filename" > notices/$filename.html
done < filenames.txt

Dans chaque notice HTML, on peut retrouver le titre de l’entrée de glossaire et les paragraphes de contenu. On remarque que les liens entre notices se font sur la base des noms de fichier. Pour pouvoir récupérer d’un coup titre, paragraphes et nom de fichier via une seule expression régulière par la suite, on peut insérer le nom de fichier dans le contenu, à la sauvage :

for f in *.html
  do echo $f >> $f
done

Ce qui permet d’écrire une grosse expression régulière d’apparence crasseuse mais qui fonctionne en fait de manière très basique. Une recherche sur tous les fichiers :

<!-- CONTENU -->\s+<div style="[^"]*">\s*([^\t]+)\t*</div><br/>\s*<div style="[^"]*">\s*([^\t]+)\t*</div>\s+<!-- ## -->\s+</div>\s+</body>\s+</html>([^\.]+)\.html

Et on extrait le résultat suivant dans un unique notices.txt :

---\ntitle: \1\nfilename: \3\n...\n\n\2\n

Un exemple de ce que cela donne :

---
title: 4CAT - Capture and Analysis Toolkit
filename: 4cat
...

4CAT est un outil permettant de créer et d’analyser des fichiers de données à partir d’une variété de forums et de plateformes web.

Site web : <https://4cat.oilab.nl/login/?next=%2F>

Puis c’est un nettoyage rapide que je ne détaille pas (enlever les espaces spéciaux, transformer les quelques balises em ou strong en Markdown, convertir les liens internes en liens avec doubles crochets pour Cosma…). Tout se passe dans un seul et unique fichier, ce qui est plus simple.

À l’aide d’un tableur, on génère rapidement 435 identifiants uniques de la forme 20210914180100, et on profite d’avoir un bon éditeur de texte sous la main (BBEdit) pour copier-coller en colonnes (eh oui !) et se constituer un index.csv avec titre, nom de fichier et identifiant pour chaque fiche.

Arrive la grosse astuce. On se sert des capacités de script du terminal pour lire chaque ligne de notre tout nouveau index.csv d’une part, et insérer le bon identifiant au bon endroit dans les données présentes dans notices.txt d’autre part :

while read line; do
  sep=','
  val='([^,]+)'
  if [[ $line =~ $val$sep$val$sep$val ]] ; then
    title=${BASH_REMATCH[1]}
    filename=${BASH_REMATCH[2]}
    id=${BASH_REMATCH[3]}
    sed -i '' "s/\[\[$filename\]\]/\[\[$id\]\]/g" notices.txt
  fi
done < index.csv

Pour remplacer les noms de fichier par les identifiants dans les liens, on reprend le même script en changeant simplement la huitième ligne :


    sed -i '' "s/^id: $filename/id: $id\nfilename: $filename/g" notices.txt

Il ne reste plus qu’à scinder le fichier en 435 morceaux grâce à la présence du délimiteur d’en-tête YAML :

csplit -k -n 3 notices.txt /^---$/ {435}

Puis les renommer correctement grâce au nom de fichier qu’on avait pris soin d’insérer dans le contenu :

for file in *; do
  mv -f "$file" "$(gsed -nr 's/^filename: ([^\n]+)$/\1/p' "$file").md";
done

Et le tour est joué : https://github.com/infologie/digithum-glossaire-hn/tree/main/notices Enfin, presque : j’ai commis une ou deux bévues dans le processus, ce qui m’a obligé à corriger plusieurs séries de fiches à la main. Mais l’idée générale reste valable, et montre la richesse de la philosophie Unix : un outil génère des données, qui sont transmises à un autre outil pour une première transformation, puis un autre, et ainsi de suite. Les experts du terminal souriront probablement en parcourant ces lignes. Les néophytes seront peut-être effrayés par le caractère abscons et légèrement foutraque du processus. Mais je souhaitais partager mon émerveillement devant les possibilités ouvertes par l’informatique en matière de bricolage textuel.