8.8.21

Mes expressions régulières

Suite d’un échange, ailleurs, sur les expressions régulières…

Petite table des matières

  1. Petite présentation du format Texinfo (texi)
  2. Emacs et sa localisation
  3. Les manuels d’Emacs
  4. Ces manuels dans OmegaT
  5. Le rôle des balises dans OmegaT
  6. Petite présentation des expressions régulières
  7. Le vif du sujet, enfin : définition des balises texi pour OmegaT

Texinfo

Hier, pris par un désir soudain de remuer des électrons toute la journée tout en restant calé sur mon canapé pendant presque 10 h d’affilée, parce que je le peux, j’ai avancé sur le chapitre « expressions régulières » du tome que j’écris au sujet d’OmegaT.

Et plutôt que d’écrire des choses qui ne servent vraiment à rien, j’ai décidé d’opter pour parler de choses qui ne servaient que partiellement à rien. Donc, j’ai choisi d’illustrer la partie regex, entre autres, avec le projet OmegaT de traduction en équipe des 2 millions de mots des manuels relatifs à l’éditeur de texte libre Emacs. Top classe non ?

Comme le format utilisé (Texinfo) est probablement utilisé par le projet GNU (récursion sur « Gnu is Not Unix », les parrains de Linux et consorts) à titre presque exclusif, et qu’il nécessite une conversion au format PO (dans po4a cette fois-ci) pour être traduisible dans nos Outils, il est peu probable que vous le rencontriez un jour. Mais c’est comme les chauves-souris dans les forêts chinoises, il faut toujours être prêt.

Et donc, l’intérêt de la manœuvre c’est qu’elle montre justement comment utiliser les expressions régulières pour pouvoir prendre en charge un format exotique quelconque, comme voulait le montrer un jeune homme sur LinkedIn l’autre jour dans son rapport sur les regex qui était cependant bourré d’approximation (surtout au sujet de la totalité des outils qu’il ne maîtrisait pas, c’est à dire tous, sauf Trados) et donc inutilisable. Dommage. Mais je digresse.

Donc, le format Texinfo.

Il est présenté dans Wikipedia de la manière suivante : https://fr.wikipedia.org/wiki/Texinfo

C’est émouvant de voir dans l’article un lien vers le premier numéro du GNU Bulletin, paru en 1986. Vive mes années lycée ! L’émotion est du même ordre que quand je vois en ligne les tout premiers numéros de Casus Belli (Ah, les Félys du numéro 2), mais j’étais au collège, et je digresse encore.

Et on trouve donc sur l’Encyclopédie, un lien vers un site apparemment mort depuis 2010, « Linux France », qui contient quand même une description du format : http://www.linux-france.org/article/memo/node79.html. Le site officiel en anglais propose une description complète des outils et du format qui mérite d’être lue pour comprendre qu’il ne s’agit pas ici d’un truc mal goupillé par des hippies du MIT, mais d’un projet extrêmement sérieux pour offrir au projet GNU un format de documentation stable et moderne (la dernière version au moment où j’écris ces mots a été publiée il y a deux mois). Le document est ici.

En tout cas, vous voyez le machin, c’est plein de @code{bidule} ou de @samp{truc} qui doivent être reproduits tels quels dans la traduction sinon c’est pas bon, et se taper ça caractère par caractère, ça ne va pas être efficace.

(retour en haut)

Emacs, et sa localisation

Le vénérable éditeur de texte qui fait tout sauf votre café et qui a fêté ses 45 ans cette année (la version 28 est en préparation) est, on peut le dire, un des principaux moteurs qui ont donné naissance au Mouvement de Libération des Logiciels dont on peut lire une brève histoire dans cet article de Wikipedia. Étant à moitié Breton, toutes ces choses là m’intéressent naturellement, mais la bête datant d’un autre âge, j’ai toujours eu du mal à m’y plonger vraiment, jusqu’à assez récemment.

Cependant, si mon utilisation quotidienne d’Emacs a été tardive, les questions qui relèvent de sa localisation me turlupinent depuis bien plus longtemps. Je m’étais donc commis d’office « responsable de la traduction des manuels Emacs » dans la vénérable association Traduc.org qui elle aussi est très inactive depuis bientôt 10 ans et je n’ai cessé de pousser le dossier dans la liste de discussion du développement d’Emacs (et voici un courriel qui parle de ça et qui est plus vieux que ma fille cadette, collégienne aujourd’hui, et qui date de 3 ans après ma version française d’OmegaT). Dix ans plus tard, en mai 2017, je proposais du code correctif pour le paquet package.el afin de remplacer les expressions qui généraient de l’anglais automatiquement (genre : si le nombre de paquets est supérieur à 1, ajoute un « s » à « paquet ») pour qu’un jour on puisse avoir une localisation possible dans d’autres langues. Le code, après multiples corrections, fut accepté en juin 2018. À ce rythme là, je me donne 20 ans pour aboutir à quelque chose dans ce domaine.

Mais je ne suis pas ici pour vous parler de mes à moitié cuites initiatives passées, mais bien pour présenter ma toute dernière : la mise en place d’une structure stable pour la traduction des manuels d’Emacs, la première étape d’icelle étant bien sûr trouver une solution pour qu’OmegaT puisse prendre en charge les fichiers de manière confortable, et bien sûr de manière synchrone, avec les membres éventuels d’une équipe de traducteurs qui ne manqueraient pas alors de se rameuter, et ça commence par trouver le moyen de simplifier le processus de traduction le plus possible, avec des définitions de balises « statiques » et validables pour OmegaT.

(retour en haut)

Les manuels d’Emacs

Comme écrit plus haut, les manuels d’Emacs sont écrits en format Texinfo. Ils sont accessibles directement dans le dépôt officiel du code, sur la forge savannah.gnu.org.

En voici un, le fichier basic.texi, qui à la ligne 11 décrit l’utilisation de base d’Emacs :

Here we explain the basics of how to enter text, make corrections, and save the text in a file. If this material is new to you, we suggest you first run the Emacs learn-by-doing tutorial, by typing @kbd{C-h t} (@code{help-with-tutorial}).

La prise en charge des fichiers .texi dans OmegaT n’est pas impossible. Il suffit d’ajouter l’extension .texi aux paramètres du filtre LaTeX avec Préférences > Filtres de fichiers. Mais les segments vont ainsi contenir des chaînes telles que les termes qui vont figurer dans les index qui gagneraient à être traduits séparément. C’est là que la conversion au format PO va nous aider.

Voici un segment en .texi avec en caractères gras la partie destinée à l’index :
@cindex insertion @cindex graphic characters You can insert an ordinary @dfn{graphic character} (e.g., @samp{a}, @samp{B}, @samp{3}, and @samp{=}) by typing the associated key.

Et voici le même segment, après conversion en PO :
You can insert an ordinary @dfn{graphic character} (e.g., @samp{a}, @samp{B}, @samp{3}, and @samp{=}) by typing the associated key.

Sachant que les deux termes destinés à l’index sont dans des segments indépendants et que la partie « code » (les deux @cindex) n’est pas considérée comme étant à traduire dans le fichier PO.

La commande pour mouliner tout ça et convertir du .texi en .po ressemble à ça :
for i in *.texi ; do po4a-gettextize -f texinfo -M utf8 -m "$i" -p "$i".fr.po ; done

Le fichier org.texi n’arrive pas au bout à cause d’un problème dans la conversion, mais il est possible d’utiliser le fichier org.org pour passer au format PO.

Avec tout ça en place, on peut mettre tous les fichiers PO dans le dossier source d’un projet OmegaT, et charger l’ensemble pour voir ce que ça donne.

(retour en haut)

OmegaT

Ceux qui ne connaissent pas OmegaT sont invités à lire le site dédié en diagonale. En quelques mots, OmegaT est un outil de traduction assistée par ordinateur, pour traducteurs professionnels. Donc moi, par exemple, et j’utilise justement OmegaT depuis bientôt 20 ans.

Pour info, dans OmegaT, ledit projet qui est hébergé sur la forge de Chapril, ici, a le volume suivant:

Segments Mots Caractères
(avec espaces)
Fichiers
Total : 164 573 1 880 16811 814 531 180

Donc, à peu près 12 000 000 de caractères, pour 1 900 000 mots, dans 165 000 segments. À 500 mots par jour, à l’heure du pastis, pépère, j’en ai pour 11 ans.

L’ensemble des 180 fichiers source fait à peu près 37 Mo. Une fois chargé dans OmegaT, le contenu traduisible exporté qui contient la totalité des segments tels qu’ils apparaissent dans l’interface d’OmegaT fait 12 Mo. BBEdit ouvre le fichier en 2-3 secondes, Emacs presque instantanément, mais ne soyons pas mesquins, BBEdit me permet de faire des trucs complexes, simplement, parce que c’est dans les menus.

BBEdit me dit donc que les balises que j’ai définies avec l’expression que je vous présente plus bas sont présentes dans près de 100 000 « lignes » (ces lignes sont les segments traduisibles qu’OmegaT a exporté), donc bien plus de la moitié du document. Et une extraction des balises me donne un total de 2 210 000 caractères, pour 232 000 chaînes (dont près de 40 000 « uniques »).

Le volume de caractères représente dans l’état actuel de l’expression plus de 18 % du travail. C’est donc énorme. Vraiment. Et ça vaut donc le coup d’automatiser leur traitement.

Et c’est là qu’interviennent OmegaT et ses balises personnalisables avec les expressions régulières.

Je parle très peu d’OmegaT ici, mais en ce qui concerne sa rapidité de chargement initial, on est dans les 20-25 secondes selon qu’on charge les 180 fichiers en mode local ou en mode « équipe », c’est à dire synchronisé avec le dépot Chapril. La création des 180 fichiers cibles traduits, prend également une vingtaine de secondes.

(retour en haut)

Je balise

Les balises dans OmegaT servent à plusieurs choses:

  1. à identifier visuellement ce qui doit rester tel quel dans le texte cible.

    Par défaut OmegaT utilise un gris clair qui contraste avec le noir du texte à traduire et le vert de l’arrière-plan.

  2. à automatiser leur saisie dans le texte.

    OmegaT offre des raccourcis-clavier pour gérer les balises (C-t = insérer la balise suivante, S-C-t = insérer toutes les balises restantes), donc pas besoin de saisir leur totalité, économie de temps, réduction des risques d’erreur à la frappe.

  3. et à vérifier que les chaînes représentées par les balises sont intégralement reproduites dans la cible.

    Cette étape va nous permettre de vérifier que les modifications éventuelles ne sont pas des erreurs.

Omegat reconnaît déjà les balises de certains fichiers standards. Par exemple HTML, ou Microsoft Office, ou DocBook, etc. Et, quel que soit le format des fichiers source, il propose également la possibilité de définir des balises supplémentaires, qui se rajouteront à celles de l’original le cas échéant.

En définissant correctement les balises de ce projet, la saisie directe des 2 230 000 caractères, avec toutes les erreurs et les oublis qu’elle pourrait comporter, pourra donc être remplacée par au plus 232 000 utilisations du raccourci clavier C-t. En bref, j’économise près de 18 % des 11 ans de travail prévus = 2 ans de vie. C’est pas rien, sachant que la définition des balises m’a coûté au plus 3 jours de travail.

Et c’est là que ça devient fun.

(retour en haut)

Régulières expressions

Les expressions régulières, c’est un amour de jeunesse. Et comme tous les amours de jeunesse, ça n’est jamais parfait, mais ça reste toujours un peu, quelque part. Ma première fois, c’était en 96, à la Librairie Avicenne, à Paris, en face de Jussieu. Le web commençait tout juste à naître au grand public, et mon boulot était de mettre le catalogue de la librairie sur le web. 6000 titres. Exportés de FileMaker. Traités dans BBEdit Lite (déjà). Et c’est là que j’ai dû me taper le manuel pour voir comment gérer la conversion entre des fichiers texte et du HTML pour éviter de tout écrire à la main. Le manuel de BBEdit est ma référence principale encore aujourd’hui quand il s’agit de regex.

Au final, Avicenne a été la deuxième librairie française a avoir un site internet (c’est moi qui l’a écrit), la première étant la Librairie Interférence, toujours en face de Jussieu, dont le propriétaire, M. Benech, est la personne qui m’avait dit quelques mois auparavant « Jean-Christophe, il y a un truc intéressant qui vient d’apparaître, ça s’appelle le web et vous devriez vous acheter un modem. »

Mais revenons à nos expressions. Il y a plein de tutoriels partout sur le web, allez les voir et revenez quand vous voulez. Si vous lisez l’anglais, profitez de celui que j’ai écrit et qui est disponible sur mon blog d’à côté :

Introduction to regular expressions

Une fois que vous avez une petite idée de ce à quoi servent ces expressions, vous pourrez apprécier plus pleinement la suite de ce document.

(retour en haut)

Définitions

Rentrons, enfin, après 1983 mots, dans le vif du sujet.

Je n’ai pas eu une approche très systématique pour définir ces balises. J’ai commencé par ce qui apparaissait dans le premier fichier, puis je suis passé au second, etc. J’ai dû faire plusieurs passages pour rationaliser ou simplifier certaines expressions trop complexes, j’ai dû en abandonner d’autres. Et j’ai fait des corrections en écrivant ces lignes. Rien n’est inscrit dans la pierre, et ça va continuer à évoluer.

La version actuelle se trouve ici : https://gist.github.com/brandelune/46faceb4c81bfee7c938282cc6dfe17c

Et au moment où j’écris ces lignes, la définition a cette valeur:

\(?(@code\{[^\}]*\}+|@command\{[^\}]*\}+|@kbd\{[^\}]*\}+|@key\{[^\}]*\}+|@file\{[^\}]*\}+|@url\{[^\}]*\}+|@uref\{[^\}]*\}+|@email\{[^\}]*\}+|@[^\{\s]*[\{\}\(\)]*|\)?\})\)?|[CM]-[^\s\}]*[ \da-zA-Z-\.]*|^[a-zA-X]$|^[a-zB-Z] |^[a-zA-Z]+(-[a-z]+)+$|(?<=,\s)[a-z-]+(?=\})|\(?(?<=[^\w][\W\{])[a-z]+(-[a-z]+)+\)?|,\s(?=[a-z-]+\})|([A-Z]){2,}|(https:/|~)((/|\\)[^\}\;\n\s\"\<,]+)|``|''|,,+

On est d’accord, c’est très moche, même en couleur.

Mais c’est sous cette forme qu’on va les mettre dans les préférences d’OmegaT, dans Préférences > Traitement des balises, comme le montre la copie d’écran suivante :

Avec une mise en forme différente, ça donne ceci (et ça me permet de corriger des erreurs qui n’apparaîtront plus à la mise en ligne…) avec des commentaires explicatifs en plus, pour votre plus grand plaisir.


      \(?
         (
          @code\{[^\}]*\}+|
          @command\{[^\}]*\}+|
          @kbd\{[^\}]*\}+|
          @key\{[^\}]*\}+|
          @file\{[^\}]*\}+|
          @url\{[^\}]*\}+|
          @uref\{[^\}]*\}+|
          @email\{[^\}]*\}+|
          @[^\{\s]*[\{\}\(\)]*|
          \)?\}
         )
      \)?|
      [CM]-[^\s\}]*[ \da-zA-Z-\.]*|^[a-zA-X]$|
      ^[a-zB-Z] |
      ^[a-zA-Z]+(-[a-z]+)+$|
      (?<=,\s)[a-z-]+(?=\})|
      \(?(?<=[^\w][\W\{])[a-z]+(-[a-z]+)+\)?|
      ,\s(?=[a-z-]+\})|
      ([A-Z]){2,}|
      (https:/|~)((/|\\)[^\}\;\n\s\"\<,]+)|
      ``|
      ''|
      ,,+

On commence par la possibilité qu’une balise soit précédée d’une parenthèse ouvrante \(, donc présente 0 ou 1 fois ?. Cette parenthèse est souvent présente dans le document et la poser ici dans la définition d’une balise nous permettra de ne pas avoir à la saisir lors de la traduction.

\(?

Ensuite on a un groupe qui commence avec «(». Le groupe est composé d’une liste de définitions séparées par | qui veut dire « ou ». On a donc une expression complexe qui décrit « la balise 1 ou la balise 2 ou la balise 3, etc. »

(

À partir d’ici et pendant 8 lignes, on a des balises clairement identifiées par leur nom. Elles commencent par une @, suivie du nom de la balise, command par exemple, suivi de l’expression \{[^\}]*\}+| qui veut dire:

  • une accolade ouvrante \{,
  • suivie de « tout sauf une accolade fermante » [^\}],
  • présent 0 fois ou plus *, il s’agit du contenu encadré dans la source par les accolades,
  • suivi d’une accolade fermante \}
  • présente 1 fois ou plus +

Comme expliqué plus haut, le | est la séparation entre les balises, il veut dire « ou », ce qu’OmegaT va interpréter comme « tout ce qui correspond à la première définition, ou à la seconde, ou à la troisième »… Toutes ces définitions contiennent le contenu du code entre accolades, qui ne sera donc pas traduisible par défaut, par exemple, @code{add-global-abbrev}.

  • @code\{[^\}]*\}+|
  • @command\{[^\}]*\}+|
  • @kbd\{[^\}]*\}+|
  • @key\{[^\}]*\}+|
  • @file\{[^\}]*\}+|
  • @url\{[^\}]*\}+|
  • @uref\{[^\}]*\}+|
  • @email\{[^\}]*\}+|

Ensuite, on a une définition générique pour les balises qui commencent avec une @, mais dont le contenu ne doit pas faire partie de la balise elle-même, car il est traduisible, par exemple, le contenu de la table des matières, ou les parties en gras ou en italique.

La @ est suivie de « tout sauf une accolade ouvrante et une espace » [^\{\s], présent 0 fois ou plus *, suivi de « une accolade ouvrante ou fermante, [\{\} ou une parenthèse ouvrante ou fermante » \(\)], présente 0 fois ou plus *, suivie de la séparation « ou » entre balises.

@[^\{\s]*[\{\}\(\)]*|

Cette balise générique n’est pas automatiquement fermée puisque son contenu dans la source est traduisible, mais l’accolade de fermeture apparaît séparément, avec la dernière partie du groupe :

\)?\}

On voit bien ici que «buffer» est accessible à la traduction, alors que @var{ et } sont grisés parce que définis en tant que balises.

Le groupe s’achève ici, avec le « ) »

)

et on trouve ici la parenthèse fermante \), présente ou non ? qui clôt cette définition un peu complexe.

\)?|

Ces définitions nous permettent d’obtenir les balises complexes suivantes :

  • (@code{inverse-add-global-abbrev})
  • @kbd{C-u - C-x a g}
  • @samp{ et }, qui enserrent une chaîne traduisible
  • @xref{ et }, qui enserrent une référence à une autre partie du manuel
  • @raisesections, qui n’enserre rien

On va passer maintenant à des choses différentes, et en premier aux définitions de commandes et de raccourcis clavier dans Emacs, qui sont par définition non traduisibles, donc parfaits pour devenir des balises statiques.

Un raccourci type est de la forme : C-x a g

ce qui veut dire Control-x suivi de a puis de g

ou encore : M-x define-global-abbrev

qui veut dire Meta-x pour lancer la commande define-global-abbrev.

Définir une balise qui couvre l’essentiel des cas de figure a pris du temps, et j’aboutis à ceci :

[CM]-[^\s\}]*[ \da-zA-Z-\.]*|

qui peut se comprendre de la manière suivante :

  • soit C, soit M, suivi d’un tiret [CM]-, suivi de
  • « tout sauf une espace et une accolade fermante » présentes 0 fois ou plus [^\s\}]*, suivi de
  • « soit une espace, soit un chiffre, soit une lettre minuscule, soit une lettre majuscule, soit un tiret, soit un point », présents 0 fois ou plus [ \da-zA-Z-\.]*
  • et on retrouve la clôture de définition | qui nous permet de passer à la définition suivante.

En reprenant ces deux définitions, on retrouve bien les deux raccourcis clavier que j’ai présentés quelques lignes plus haut, et on peut en imaginer beaucoup d’autres, comme par exemple :

  • C-M-/
  • M-g M-g
  • C-x 5 2

etc.

Les 3 définitions qui suivent représentent des chaînes de caractères très probablement non traduisibles. Par exemple :

^[a-zA-z]$|

représente une lettre seule dans un segment (c’est-à-dire entre le début du segment représenté par ^ en début de définition, et sa fin représentée par $), en général,il s’agira d’une touche à enfoncer pour lancer une commande.

^[a-zB-Z] |

Cette définition est similaire, mais ne définit qu’une lettre en début de segment suivie par une espace, là encore, très probablement une touche à enfoncer pour lancer une commande. Remarquez que j’ai retiré le « A » majuscule de la série en la définissant à partir de « B », pour éviter les phrases qui commencent par l’article anglais « A ».

^[a-zA-Z]+(-[a-z]+)+$|

Ici, on a une définition qui va identifier un caractère en début de segment ^, élément de la liste a-z ou A-Z [a-zA-Z], présent une ou plusieurs fois +, suivi par un groupe ( composé par un tiret - suivi par un caractère élément de la liste [a-z], présent une ou plusieurs fois +), le tout présent une ou plusieurs fois + et qui finit en fin de segment $.

Cette définition va nous servir à identifier des commandes posées dans le document comme élément de l’index, par exemple, et en tout cas non traduisibles, par exemple :

  • add-global-abbrev
  • next-screen-context-lines
  • backup-by-copying-when-privileged-mismatch

etc.

La définition qui suit utilise un élément un peu complexe que j’utilise ici pour la première fois. Il s’agit de positionner la définition un peu comme plus haut avec ^ et $, mais en définissant soi-même l’ancrage.

(?<=,\s)[a-z-]+(?=\})|

Ici on a deux ancrages : [a-z-]+ doit être après ,\s (donc une virgule et une espace) et avant une accolade fermante \}. L’ancrage n’est pas compris dans la balise. C’est-à-dire que la balise définie ici est seulement [a-z-]+, donc une série de mots en minuscule séparés par des tirets, à la condition que cette série soit correctement positionnée. On va ainsi définir des balises du type :

calendar-holiday-marker
dans la chaîne
@xref{Calendar Customizing, calendar-holiday-marker}.

ce qui correspond à 3 balises, en combinaison avec les définitions ci-dessus :

  • @xref{
  • calendar-holiday-marker
  • }

Le traducteur a donc la possibilité d’insérer automatiquement la première balise, de traduire le contenu de la balise, d’insérer la virgule, d’insérer la seconde balise, et d’insérer l’accolade fermante. On voit ici l’intérêt d’avoir défini plus tôt des balises génériques « ouvertes ».

Les définitions continuent avec:

\(?(?<=[^\w][\W\{])[a-z]+(-[a-z]+)+\)?|

qui enclôt entre 2 parenthèses potentielles une balise ancrée à gauche par la définition :

(?<=[^\w][\W\{])

qui veut dire « pas un caractère qui soit un élément de mot » (\w est défini comme étant en gros [a-z-A-Z0-9_]) suivi par « un caractère qui n’est pas un élément de mot ou une accolade ouvrante » [\W\{].

Cet ancrage sert à positionner une chaîne similaire à ce que nous avons vu deux définitions plus haut, mais avec seulement des minuscules, et est potentiellement fermée par une parenthèse.

La définition va nous permettre de créer des balises avec des chaînes du type suivant :

calendar-today-visible-hook

et

calendar-mark-today)

dans

(add-hook 'calendar-today-visible-hook 'calendar-mark-today)

L’anglais utilise souvent le tiret pour lier des mots. Certaines chaînes « balisées » par cette définition seront donc à traduire, par exemple :

command-line

dans

command-line argument

ou encore

learn-by-doing

dans

If you are new to Emacs, we recommend you start with the integrated, learn-by-doing tutorial, before reading the manual.

mais comme la plupart de ces chaînes représentent des commandes, j’ai pensé qu’il était préférable de les définir en tant que balises.

,\s(?=[a-z-]+\})|

Cette balise utilise un ancrage à droite pour identifier une virgule et une espace, à condition qu’elles soient placées à gauche d’un groupe de mots en minuscules séparés par des tirets. Il s’agit de la virgule qui ancrait à gauche la définition plus haut, et poser l’ensemble « ,  » en tant que balise, va nous permettre des insertions et une validation automatiques.

([A-Z]){2,}|

On passe ici à une balise composée d’au moins 2 lettres majuscules.

(https:/|~)((/|\\)[^\}\;\n\s\"\<,]+)|

Puis on arrive à des URLs ou à des chemins de fichier locaux (qui commencent par ~. Pour finir par ces définitions triviales qui vont nous éviter des saisies de guillemets ou de séquences de virgules (2 ou plus, séquence présente dans les définitions de liens bibliographiques).

``|
''|
,,+

Vous remarquez que la dernière définition n’a pas besoin du |, puisqu’il n’y a plus de choix possible. Si vous souhaitez rajouter des définitions, n’oubliez pas de rajouter cette séparation.

Voilà, nous sommes arrivés au bout de cette longue liste de définition de balises et j’arrive avec elles à « verrouiller » environ 2 230 000 lettres. Ça valait le temps passé à les définir. Et ça le vaudra de manière plus réaliste dans un projet de traduction réel avec des définitions le plus souvent bien moins complexes.

(retour en haut, si vous n’avez pas encore tout lu...)

7.8.21

Un café !

L’autre jour, j’ai trouvé un magasin de café qui vend aussi à ses clients des grains non torréfiés. J’en ai pris 100 grammes. Du brésilien. Et à la maison j’ai essayé avec une poêle Téfal, le seul truc que j’avais dispo. Ça a marché plutôt bien, au-delà du gaspillage de gaz. Les grains avaient une couleur sable foncé. Passé au moulin à main, filtre, eau chaude, et hop, un truc bien slow-life avec les moyens du bord, mais un peu pisse d’âne, comme aurait dit papi, enfin je crois.

Bon, je sais qu’avec le réchauffement climatique, boire du café brésilien torréfié au gaz de ville au Japon, et écrire ce truc sur un blog qui va faire tourner un serveur pour rien, ça fait un peu tueur en série. Pour compenser, je vous le dis, je suis allé acheter le café en vélo (et on s’est coupé deux veines début mars pour acheter une hybride d’occase qui nous fait du 3 litres aux 100).

J’avais quand même mal au cœur. Le gaz, ça ne doit pas servir à chauffer l’air, surtout en été. Alors j’ai cherché un truc. Et au Japon (et sans doute ailleurs), il existe un accessoire domestique qui sert à faire griller des graines pour la cuisine (sésame) ou pour les boissons (mugi). C’est comme une petite casserole, mais en filet métallique aux mailles serrées, avec un couvercle dans le même matériau, fixé à un bord, et qui se verrouille sur la poignée en se fermant. Vous savez sûrement comment ça s’appelle en français, moi non.

J’ai essayé le machin hier. Dans la semi-obscurité de l’appartement dans l’après-midi. Le résultat a été très torréfié… Un peu noir même. Mon café favori, Minami, nous sert des grains comme ça. Il faut aimer. Nous, on est plutôt habitués à des saveurs plus douces. Des grains plutôt marron clair.

Alors j’ai essayé de nouveau aujourd’hui. Première différence, la cuisine n’a pas été enfumée. C’est un progrès d’autant plus qu’on a eu les gens de l’entretien qui sont passés la semaine dernière pour vérifier nos détecteurs de fumée, et ils marchent au poil. Deuxième différence, j’avais allumé la lumière à côté du gaz et j’ai donc pu voir l’évolution de la torréfaction en live, et j’ai pu ainsi arrêter au moment où les grains commençaient à prendre une teinte chemin de terre un peu humide, juste quelques minutes après le début de la manip. Une estimation au nez de la consommation de gaz, un dixième de ce que j’ai eu lors de ma première tentative. Le truc est bon, avec un arrière-goût fruité, et même Yuto a dit que c’était plus buvable qu’hier.

Victoire donc du « fait à la maison » (si l’on s’autorise à omettre du processus l’extraction et l’acheminement du gaz), et commentaire de la voisine « Jean-Christophe super slow-life » ou un truc comme ça. Et là, illumination. Ce que je fais, ça n’est pas du slow-life. C’est du total-normal-life. Je ne vais pas jusqu’à faire pousser mon café tout seul (et j’aurais du mal sous ces latitudes), mais ces 20 minutes passées à faire autre chose que trimer ou regarder Twitter, c’est normal, et c’est même un peu comme ça que je me rappelle une époque pas si lointaine où on savait déjà que le café instantané c’était dégueulasse, et qu’on pouvait prendre un livre ou aller se promener pour remplir un vide (ou était-ce l’inverse ? on remplissait le vide du porte-monnaie avec des trucs chiants, ça n’a pas changé, pour passer le reste du temps à passer le temps et regarder les abeilles butiner).

Pour conclure cette journée bien avancée, je vais aussi me faire 2 litres de liquide vaisselle et 4 litres de lessive. Ah, et on a acheté l’autre jour un pot à faire du compost, pour les noyaux d’avocat sur le balcon. À dans 5 ans donc (non, je blague), quand on n’aura plus à manger des trucs importés du Mexique.