La semaine du 23 au 29 mars

| french

lundi 23

J'ai trouvé comment catégoriser les liens pour mon bulletin d'information Emacs News par commande vocale en utilisant Silero pour détecter l'activité vocale et Speaches pour transcrire les commandes. C'était un peu lent, mais c'était prometteur. Je pense que si je traite quelques commandes par lots, ce sera plus rapide.

Il faisait beau l'après-midi. J'ai emmené ma fille à son cours de gymnastique à vélo, où elle s'est bien amusée en s'exerçant à se laisser tomber sur le ventre après avoir fait une roue. Après cela, nous sommes allées à la boutique Healthy Moms Market pour acheter une boîte à lunch1 plus grande pour ma fille.

Les collections de CD audio Michel Thomas que j'ai empruntées à la bibliothèque pour apprendre le français étaient trop rayées pour être écoutées. Tant pis. J'ai déjà écouté la majorité d'un cours sur YouTube, mais les autres ressources semblaient utiles.

mardi 24

J'ai décortiqué le mot « grenouille », que j'ai dit au moins 37 fois lors du cours précédent.

(subed-record-extract-words "grenouille"  "/home/sacha/sync/recordings/processed/2026-03-20-raphael.json" "/home/sacha/proj/french/analysis/grenouille/index.vtt")
(my-subed-record-group-by-notes
  (nreverse
   (subed-record-sort-by-directive
    "#+NOTE"
    (subed-record-filter-skips
     (subed-parse-file "/home/sacha/proj/french/analysis/grenouille/index.vtt"))))
  "/home/sacha/proj/french/analysis/grenouille/grenouille"
  "/home/sacha/proj/french/analysis/grenouille/index.vtt" t)

Mais l'enregistrement numéro 10 ressemblait au numéro 4… Peut-être que, lorsque mon tuteur a répété le mot, il ne voulait pas dire que c'était une erreur, il m'a simplement encouragée à le répéter. Je dois penser à la façon de profiter du bilan de mon tuteur.

J'ai remarqué le /​ə/ comme dans le mot « je », le /​u/ dans la prononciation /​gʀənuj/ et la différence avec le mot « oui » /​ˈwi/. C'est difficile pour moi.

(subed-record-compile-subtitle-list
 (mapcar (lambda (o)
           (setf (elt o 3)
                 (format "%s: %s"
                         (subed-record-get-directive "#+NOTE" (elt o 4))
                         (elt o 3)))
           o)
         (nreverse
          (subed-record-sort-by-directive
           "#+NOTE"
           (subed-record-filter-skips
            (subed-record-filter-for-directive
             "#+NOTE"
             (subed-parse-file "/home/sacha/proj/french/analysis/grenouille/index.vtt"))))))
 "/home/sacha/proj/french/analysis/grenouille/grenouille-compiled.opus"
 nil
 '(:interleaved "/home/sacha/proj/french/chime.opus"))

Mon tuteur m'a donné de nouvelles phrases :

  • Ma compagne m’accompagne à la campagne avec une autre compagne.
  • Une tortue têtue marche dessus sous une pluie continue.

Je me suis concentrée sur la différence entre « compagne » et « campagne. »

(let ((my-lang-words-for-review-context-function 'my-lang-words-for-review-phrase-context))
  (my-lang-words-for-review "La semaine du 16 au 22 mars"))

Les points pour réviser ma prononciation :

  • nous avons acheté des nouilles instantanées.
  • qui proposait la boîte à déjeuner qu'elle voulait
  • donc si elle veut être assortie, alors nous serons assorties.
  • J'ai cherché dans le groupe de précaution COVID et j'ai trouvé une recommandation
  • Ma fille a également réalisé une pancarte avec son nom et quelques Pokémon.
  • qui fournit les appareils Holter pour lancer les démarches.
  • J'ai actualisé mon script pour réserver des livres à la bibliothèque.
  • pour rechercher la cause de ses symptômes.
  • Elle aime bien le skee-ball et elle a obtenu son meilleur score jusqu'à présent.
  • donc je l'ai emmenée au magasin de tissus du centre-ville.
  • Dans un autre magasin à proximité
  • … et un gloss à lèvres.
  • Mon mari a installé deux lumières à côté du lit mezzanine de ma fille parce
  • mais après avoir gratté le dessus
  • J'ai cousu une housse de protection
  • mon mari a préparé des nouilles ramen aux wontons.
  • Je me suis assise sur le porche et j'ai réécrit mon journal et mes notes sur l'IA en français.
  • qu'elle avait mal au ventre.
  • Je leur ai donné des guimauves et elles (et le grand-père d'une amie de ma fille) les ont fait griller sur des brochettes.
  • nous avons cousu ensemble.
  • La bosse près du piercing de ma fille a commencé à saigner et suppurer.
  • elle dormait probablement sur le côté.
  • J'ai participé à la réunion virtuelle OrgMeetup.
  • grâce à la reconnaissance vocale.

Pendant la conversation, j'ai pu lui décrire la bibliothèque de Toronto que j'adore tellement. La bibliothèque de Toronto est l'une des plus grandes au monde. Chaque quartier a sa propre bibliothèque, et on peut réserver jusqu'à 50 livres pour les faire envoyer à la bibliothèque à proximité. La bibliothèque offre aussi énormément de livres électroniques, ce qui est très pratique.

(subed-record-extract-all-approximately-matching-phrases
   (split-string (org-file-contents "/home/sacha/proj/french/analysis/virelangues-2026-03-13/phrases.txt") "\n")
   "/home/sacha/sync/recordings/processed/2026-03-24 12-29-53-sacha.json"
   "/home/sacha/proj/french/analysis/virelangues-2026-03-13/2026-03-24-raphael-script.vtt")

Ma fille était grincheuse avec moi et vis-à-vis de l'école aujourd'hui. L'école a une remplaçante, ce qu'elle n'aime jamais. Elle a aussi eu l'impression que je l'avais pressée pendant la pause déjeuner parce que je n'avais pas voulu être en retard pour mon cours.

Elle n'a pas trouvé son ordinateur qui était sur le banc devant la salle de bains. Je pense qu'elle n'a pas cherché bien loin. Elle n'a pas demandé à mon mari de l'aider à chercher. Elle a simplement séché les cours. J'ai reprogrammé mon prochain cours avec mon tuteur pour qu'il commence à 12h45 au lieu de 12h30. De toute façon, puisqu'elle a décidé de sécher les cours, j'ai proposé de faire une promenade au parc ou de coudre la couverture de pique-nique. Elle a fermement décidé d'être grincheuse. Les turbulences font partie de la vie avec un enfant.

L'appareil Holter était arrivé, mais ce n'était pas un bon moment pour le lui mettre.

mercredi 25

J'ai travaillé comme consultante. J'ai eu trois tâches à accomplir et je les ai finies, donc j'étais satisfaite. J'ai terminé les cours de formation, j'ai configuré des paramètres pour permettre à un autre développeur de vérifier mon logiciel avant la mise à jour du système, et j'ai fait un prototype d'affichage vidéo qui est plus moderne que la version actuelle.

Ma fille n'a pas voulu sortir pour jouer à cause de l'appareil Holter qu'elle doit porter pendant deux semaines. Heureusement, la mère de son ami m'a envoyé une invitation à jouer ensemble à Minecraft. Ma fille a joué avec son ami sur son serveur Minecraft Java. Ils ont commencé un nouveau monde, donc je les ai rejoints pour aider à assembler des ressources. Nous avons établi notre base sur une montagne. J'ai coupé des épicéas, j'ai miné un conduit jusqu'à la couche moins 54 et j'ai commencé une ferme de blé et de canne à sucre. Ma fille et son ami ont exploré des cavernes, combattu beaucoup de monstres, et décoré notre base. Elle a aimé jouer avec un ami qui coopérait avec elle, ce qui est différent des griefers dans son club Minecraft à l'école. ( Elle a dit que s'il se conduisait mal, elle pouvait parler avec la mère de son ami. )

J'ai participé à la réunion virtuelle Emacs Berlin, qui se tenait sur mon serveur. Malheureusement, j'ai raté le courriel de l'hôte indiquant que son code de modérateur ne fonctionnait pas parce que j'étais concentrée sur mon travail, donc j'ai corrigé le problème environ une heure après le début de la réunion virtuelle. Néanmoins, la réunion s'est bien déroulée. Après ça, j'ai mis à jour mon serveur BigBlueButton pour les réunions virtuelles, juste au cas où cela pourrait aider.

J'étais tellement fière de ma fille, qui porte l'appareil Holter quoiqu'il soit pénible. Elle peut même gérer la batterie elle-même, et elle a déjà remarqué un épisode de palpitations. Elle a dit qu'elle détestait l'appareil Holter, mais elle voulait capturer des données pour que la cardiologue puisse analyser ses symptômes.

jeudi 26

J'ai dépoussiéré mon serveur Minecraft pour inviter l'ami de ma fille après les cours. Il fallait que je configure quelques règles sur le pare-feu et le routeur. Après avoir un peu tourné en rond, j'ai vérifié que je pouvais me connecter en dehors de notre réseau. J'ai aussi installé CraftyController pour gérer le serveur via une interface web. Ma fille et moi avons joué sur une carte de parkour Minecraft jusqu'à ce que la mère de son ami m'ait envoyé un message, puis ma fille et son ami ont joué indépendamment.

J'ai appelé l'entreprise qui nous a envoyé le Holter cardiaque pour demander conseil car les patchs démangeaient tellement ma fille. Après avoir confirmé qu'ils recevaient les données de ma fille et demandé des conseils, je suis allée à la pharmacie pour acheter une crème barrière.

Une fois que je suis rentrée, ma fille jouait à Minecraft toute seule. Elle a dit qu'elle avait construit une poubelle en utilisant un cactus, un coffre, et un entonnoir ; que son ami avait placé son épée dans la poubelle ; qu'il y avait un désaccord d'une certaine sorte, et qu'ensuite son ami avait fait exploser toutes les choses avec de la TNT, malgré leur accord de ne pas faire de griefing… De toute façon, j'ai envoyé un message à la mère de son ami au cas où elle aurait compris un peu plus que moi. Peut-être que leurs styles de jeu ne sont pas compatibles pour l'instant. C'est la vie.

J'ai mis la nouvelle crème barrière sur la peau de ma fille et nous avons appliqué de nouveaux patchs pour le Holter cardiaque. Nous avons reconnecté les électrodes. L'entreprise a dit qu'elle pouvait faire une pause si c'était nécessaire.

Ma fille s'est demandé comment faire des bracelets d'amitié, donc j'ai cherché du fil et lui ai montré comment les nouer.

Analyse de mon journal

J'ai mis à jour mon analyse de journal et j'ai utilisé l'IA Claude pour visualiser les données. Depuis novembre, j'ai écrit plus de 300 mots à presque chaque entrée sur plus de 140 entrées.

02_words_per_session.png

À mon étonnement, je trouve constamment de nouveaux mots pour décrire ma vie quotidienne, même si cette sorte de petite vie peut ennuyer autrui. Je prends soin de ma fille, je l'emmène à quelques endroits, je bidouille ma configuration d'Emacs, je réfléchis… C'est simple, mais c'est la mienne.

Il y a une légère diminution au fur et à mesure que je développe mon vocabulaire et que je m'habitue aux expressions figées.

01_cumulative_vocab.png

C'est plus facile de s'en rendre compte si l'on regarde le pourcentage des nouveaux lemmes en fonction des mots écrits, qui semble être d'environ 5 %.

06_vocab_efficiency.png

Je pense que je dois faire un effort pour utiliser plus d'adjectifs pour décrire davantage mes expériences, mais même lorsque j'écris en anglais, je suis attirée par la précision du verbe ou du nom juste. Si j'écris sur des choses qui sont semblables les unes aux autres, ou si je veux peindre un tableau d'une scène, les adjectifs seront plus nécessaires.

05_pos_usage.png

Ma sœur est devenue une écrivaine merveilleuse, mais elle ne donne pas dans le langage fleuri. Elle écrit avec son cœur sur des choses douloureusement claires et tout l'humour qu'elle peut trouver en aimant passionnément la vie et sa famille. Je n'ai pas besoin d'atteindre cette qualité d'écriture pour le moment; je n'ai pas la moitié de la sagesse qu'elle a dû acquérir. Je suis contente de consigner ma journée sachant qu'un jour j'oublierai les détails.

Les logiciels sont surtout écrits par l'IA Claude :

Un brouillon pour le Carnaval d'Emacs

Le thème du Carnaval d'Emacs ce mois-ci est « les erreurs et les idées reçues ». C'est difficile de penser à une chose qui est clairement une erreur, mais il y a certainement des choses que je ne fais pas efficacement.

Ma configuration est très volumineuse car je pense que mes petites modifications sont utiles seulement pour moi. Elles sont trop spécifiques, trop idiosyncratiques. J'apprécie les autres gens qui créent des bibliothèques ou même des packages que beaucoup d'autres utilisent, mais de mon côté, je ne me sens pas capable de le faire pour l'instant. Même soumettre des correctifs en amont et participer à la discussion qui s'ensuit parfois demande plus de persistance que je n'en ai.

L'avantage de garder mes modifications dans ma configuration est que même si je ne suis pas sûre, je pourrais essayer quelque chose, développer un prototype préliminaire, et changer d'avis si nécessaire. Quand je les publie dans une bibliothèque ou un package, j'ai l'impression que je dois peaufiner mes idées. C'est difficile de s'en tenir à une idée.

Ma situation préférée est quand j'écris mon essai dans un article, et qu'il inspire une autre personne qui implémente sa propre version, voire une nouvelle bibliothèque ou un nouveau package.

En revanche, si j'apprends à partager mon code, je peux aider plus de personnes, et je peux aussi apprendre de plus de personnes et plus de conversations.

Beaucoup de mes modifications sont brèves et faciles à copier de mes articles, mais il y a quelques collections qui dépendent des autres fonctions, ce qui les rend difficiles à copier. Les fonctions sont dispersées dans plusieurs articles sur mon blog. Par exemple, mes fonctions pour apprendre une langue ( particulièrement le français ) et pour contrôler Emacs par la voix deviennent plutôt complexes. Elles sont aussi exportées vers ma configuration, mais le fichier Emacs Lisp est difficile à parcourir si on veut les copier. Je peux copier le code dans un fichier maintenant que Org Mode peut l'extraire vers des fichiers multiples, mais si je consacre un peu de temps à remplacer le préfixe « my- » par celui de la bibliothèque et à les copier sur le dépôt, on peut le cloner et télécharger des mises à jour. Même si personne ne l'utilise, le fait de le peaufiner et de le documenter me sera utile un jour.

Donc il est possible que ce soit une erreur que je commette souvent sur Emacs : je pense que mes fonctions sont trop idiosyncratiques et trop préliminaires, donc je les ai laissées dans ma configuration. Mais si j'y consacre du temps pour extraire le code vers une bibliothèque, j'en bénéficierai peut-être à long terme.

Prot avait baissé ses tarifs de coaching. Quant au développement des packages, il est prolifique. J'apprends bien avec mon tuteur en français, donc cela vaut peut-être la peine de consacrer de l'argent et du temps pour améliorer cette compétence. Certes, c'est juste pour le plaisir, mais c'est aussi important pour moi que je m'entraîne à apprendre avec l'aide des autres au lieu de trébucher toute seule. Je peux aussi écrire davantage, participer aux réunions virtuelles ou même diffuser en direct. J'ai toujours plus de choses à apprendre, ce qui est merveilleux.

vendredi 27

J'ai recommencé à dessiner des moments quotidiens comme je l'avais fait il y a quelques années quand ma fille était plus jeune. Quand je suis tombée sur les dessins dans ma liste « En ce jour » (en fait le format RSS que j'avais ajouté à mon agrégateur), le dessin me manquait. Depuis le début de l'année scolaire, je dessinais une note pour la boîte à lunch de ma fille chaque jour de classe parce que ma fille voulait « l'expérience complète d'écolière » malgré le fait d'aller à l'école à distance. Je dessinais quelques Pokémon et d'autres centres d'intérêt de ma fille. Ça m'est enfin venu à l'idée de combiner des Pokémon et nos moments. Jusqu'à la semaine précédente, je les ai dessinées sur des fiches bristol. Je me suis remémoré que notre imprimante peut traiter les fiches bristol, donc j'ai utilisé Procreate sur mon iPad pour dessiner un moment de notre vie quotidienne et je l'ai imprimé pour l'insérer dans sa boîte à lunch.

Voilà :

2026-03-24-05 Holter monitor - I already detest every minute #moment #daily.jpg

2026-03-25-03 Mom used Dig, it's super-effective #moment #daily.jpg

2026-03-26-06 Try as ya might, ya'll never catch Meowth wid dat kind of parkour #moment #daily.jpg

Ugh, mon OBS n'a pas enregistré mon côté du rendez-vous avec mon tuteur, donc je ne peux pas ajouter les extraits à Comparing pronunciation recordings across time. Ce n'est pas grave, je dois les réenregistrer. C'est la deuxième fois que cela se produit. Redémarrer mon ordinateur résout les problèmes, mais si je ne détecte pas le problème tôt, je n'ai pas le temps de redémarrer avant mon rendez-vous. J'ai un autre profil sur OBS qui se connecte directement à mon microphone au lieu du récepteur audio virtuel, ce qui sera peut-être plus fiable. Je dois aussi enregistrer une sauvegarde sur mon téléphone la prochaine fois.

J'ai envoyé une message et d'argent à Prot pour du coaching. Voilà, je m'y engage.

View Org source for this post

La semaine du 16 au 22 mars

| french

lundi 16

J'ai emmené ma fille chez le dentiste pour un nettoyage. L'hygiéniste a pensé que la douleur pouvait être due au fait que de nouvelles dents poussaient. J'ai laissé ma fille décider si elle voulait du fluor. Au début, elle a décliné, mais elle a changé d'avis et elle a dit oui. Après cela, elle s'en est plainte, mais au moins, elle l'a fait. En guise de récompense, nous avons acheté des nouilles instantanées.

J'étais trop optimiste quant à la météo parce qu'il faisait beau le matin. Quand je faisais du vélo, j'avais un peu froid. J'ai emmené ma fille dans la boutique qui proposait la boîte de déjeuner qu'elle voulait, et elle a confirmé son choix. Ensuite, j'ai emmené ma fille à son cours de gymnastique. Nous sommes arrivées si tôt que le gymnase était encore fermé à clé. Heureusement, son entraîneur est arrivé et il nous a ouvert la porte. Une fois rentrées, j'ai bu un chocolat chaud pour me réchauffer.

Nous avons réussi à faire des sons pour la machine à espresso en jouet avec l'aide de l'IA Claude. Au début, nous avons essayé d'utiliser un signal analogique, mais le micro:bit ne pouvait pas envoyer un véritable signal analogique. Au lieu de cela, il utilisait la modulation de largeur d'impulsion (pulse-width modulation), qui était un peu difficile à lire du côté de l'Arduino, peut-être en raison de l'écart de tension. Ensuite, nous avons essayé de varier la durée d'impulsion, ce qui était plus facile à détecter du côté de l'Arduino. Du côté du micro:bit, j'ai dû gérer les rebonds du bouton-poussoir pour rendre la logique plus fiable.

Ma fille a adoré sa nouvelle boîte de déjeuner. Elle l'a remplie de collations.

Après le dîner, nous avons cousu ensemble. La pochette Pokémon prend vraiment forme maintenant. Je ne sais pas trop si je dois laisser les passants en l'état ou si je dois découdre les coutures et les intégrer directement aux lignes de couture. Ma fille a préféré l'option d'attacher une sangle à la pochette pour faire un sac à bandoulière, ou de la détacher pour glisser la pochette au fond de son sac à dos.

mardi 17

Il faisait froid, donc nous sommes restés à la maison et nous avons travaillé sur notre projet de machine à espresso en jouet. Ça fonctionne bien. Nous avons enregistré un son pour l'eau et un autre son pour le lait, nous les avons copiés sur l'Arduino et nous avons modifié notre logiciel pour jouer les sons. Notre fille était très heureuse. Elle m'a vendu deux tasses de café.

J'ai eu un cours avec mon tuteur où je me suis exercée aux virelangues. Les mots difficiles sont : grenouille, fouille, feuille et broussailles. Ma fille s'est jointe à moi et elle a essayé des mots.

Ma fille aime bien quand nous portons des chaussures ou des vêtements similaires. Heureusement, je peux porter des chaussures pour enfants et nous pouvons coudre nos propres vêtements, donc si elle veut être assortie, alors nous serons assorties. Cette année, elle a choisi des Crocs Pokémon. Nos sandales flamboyantes Pokémon sont arrivées aujourd'hui. Elles sont très roses. Très très roses.

Mon mari avait rendez-vous chez le dentiste pour son nettoyage. Il a dit que l'hygiéniste dentaire portait un masque procédural, mais elle a changé pour un masque N95 parce qu'elle s'est souvenue que notre famille prend des précautions contre la COVID. Je pense que je vais changer de dentiste parce qu'elle a baissé brièvement son masque en parlant, ce qui signifie que nos niveaux de précaution sont différents. La clinique dentaire est le seul endroit où nous devons retirer nos masques. J'ai cherché dans le groupe de précaution COVID et j'ai trouvé une recommandation pour une clinique dentaire à proximité où le personnel porte normalement des masques N95. Je vais y aller pour mon prochain nettoyage. Ma fille veut voir l'hygiéniste dentaire qui nettoie les dents de mon mari, parce qu'il la recommande vivement.

On m'a appelée au sujet de l'examen Holter que la cardiologue de ma fille a prescrit. Elle nous a dit qu'il fallait que ma fille porte l'appareil Holter pendant deux semaines. Ma fille a fait un blocage, donc j'ai refusé l'appareil. Après réflexion, elle a négocié certaines contreparties comme beaucoup de livres de la bibliothèque et de nouveaux jouets pour les étapes en cours de route. Je suis tellement fière d'elle parce qu'elle a décidé de privilégier la santé au confort et qu'elle a essayé son propre système de motivation. Je sais que ces choses sont difficiles, mais elle prend ses propres décisions.

OBS n'a pas enregistré mon côté de l'audio, donc je ne peux pas l'analyser.

mercredi 18

J'ai eu une réunion virtuelle avec mes clients pour discuter du nouveau prototype qu'ils veulent que je crée. Je pense que c'est possible. Cette semaine est chargée puisque ma fille est en vacances. Je vais y travailler la semaine prochaine. J'ai probablement quelques extraits de code que je peux combiner.

J'ai emmené ma fille au Musée d'art contemporain pour une activité gratuite avec ses amies. Nous avons sculpté des figurines dans du papier aluminium. Ma fille a également réalisé une pancarte avec son nom et quelques Pokémon. J'ai aussi dessiné et colorié un Pikachu et un Qulbutoké (Wobbuffet en anglais).

Mon mari a utilisé Claude pour l'aider sur un projet de chambre de pousse à levain. Il a dit que l'IA était très utile pour échanger des idées. Il a réussi à connecter un Arduino Uno à un afficheur. Nous avons appris des choses sur les effets Seebeck et Peltier, qui sont utiles pour gérer la température du levain.

J'ai appelé l'entreprise qui fournit les appareils Holter pour lancer les démarches. L'appareil arrivera la semaine prochaine ou la semaine suivante. Nous avons besoin de beaucoup de livres comme promis. J'ai actualisé mon script pour réserver des livres à la bibliothèque.

jeudi 19

Ma fille a passé une mauvaise nuit, donc elle et moi étions un peu fatiguées quand nous nous sommes réveillées. J'ai reçu un message du père de son amie pour nous inviter à aller patiner ensemble, mais je me suis dit que la patinoire serait fermée parce qu'il faisait trop chaud pour préserver la glace.

Ma fille voulait aller à l'aquarium depuis le début des vacances. Il faisait beau. C'était un jour parfait pour faire du vélo. Nous sommes tous allés à l'aquarium Ripley's pour le visiter avec une amie de ma fille et son père. Elles ont aimé les requins et les raies. Mon mari en a profité pour faire quelques photos. Je me suis amusée à découvrir les poissons qui ont des noms intéressants comme le sigan magnifique (magnificent rabbitfish), le nason élégant (elegant unicornfish), le dollar des sables excentrique (eccentric sand dollar), et le miroir à bandes (stripey).

Pour le dîner, j'ai préparé des burgers et des frites. Il faisait froid, donc les burgers ont pris plus de temps à cuire au barbecue. Mon mari a préparé de la salade de chou.

Je me suis rendu compte que l'accéléromètre de mon téléphone ne fonctionne pas, ce qui explique pourquoi mes photos ne tournent pas automatiquement et que je ne peux pas faire de la réalité augmentée. C'est ma faute. Je ne veux pas remplacer mon téléphone pour l'instant. Peut-être d'ici deux ans.

vendredi 20

Pendant mon cours avec le tuteur, je me suis exercée aux virelangues et à lire à voix haute presque toutes mes entrées de journal depuis lundi. Malheureusement, le cours précédent n'était pas enregistré, donc je ne peux pas les comparer. Du côté positif, j'ai finalement appris comment configurer OBS pour enregistrer des pistes séparées, ce qui facilitera leur analyse et leur extraction la semaine prochaine.

(subed-record-extract-all-approximately-matching-phrases
   (split-string (org-file-contents "/home/sacha/proj/french/analysis/virelangues-2026-03-13/phrases.txt") "\n")
   "/home/sacha/sync/recordings/2026-03-20-raphael.json"
   "/home/sacha/proj/french/analysis/virelangues-2026-03-13/2026-03-20-raphael-script.vtt")

La pluie s'est arrêtée, donc j'ai emmené ma fille au centre médical pour faire une radiographie que la médecin avait prescrite pour rechercher la cause de ses symptômes. Après cela, ma fille a joué dans la salle de jeux. Elle aime bien le skee-ball et elle a obtenu son meilleur score jusqu'à présent. Elle s'est aussi rendu compte que le jeu de pêche lui a donné plus de jetons que le skee-ball ou d'autres jeux qu'elle aime, et puisqu'elle aime le jeu de pêche, elle a gagné suffisamment de jetons pour obtenir beaucoup de bonbons.

Nous avions le temps, donc je l'ai emmenée au magasin de tissus du centre-ville. Nous n'avons pas trouvé de tissu pour maillot de bain de la couleur que ma fille voulait, mais elle a trouvé du tissu vichy rouge pour coudre une couverture de pique-nique qu'elle voulait depuis longtemps. Dans un autre magasin à proximité, elle a acheté de la crème solaire, des élastiques, et un gloss à lèvres.

Ma fille a encore fait quelques peintures en utilisant du ruban pour masquer des zones. J'étais ravie de voir qu'elle s'est amusée grâce à l'art.

samedi 21

Nous avons fait les courses ensemble. Ma fille voulait acheter la collation Nutella Go depuis longtemps, donc elle et moi avons continué notre chemin un peu plus loin que la maison et nous sommes allées au magasin du coin.

J'ai réfléchi à une interface pour écouter et enregistrer un mot isolé que je veux pratiquer. Je pense que la forme d'onde n'est pas très utile dans cette situation.

Mon mari a installé deux lumières à côté du lit mezzanine de ma fille parce qu'elle aime lire à l'heure du coucher.

Il a aussi encadré le dessin que ma fille avait peint hier soir. Elle a essayé de photocopier son dessin, mais comme prévu, la peinture argentée est devenue simplement grise. C'est une bonne chose que l'artiste aime bien peindre. Nous pourrons ainsi avoir chacun notre original.

Pour le dîner, mon mari et moi avons préparé des spaghettis à la sauce carbonara et au bacon. Après ça, nous avons préparé des petits pains aux haricots rouges. Ma fille s'est bien amusée à jouer avec la pâte. Les pains étaient délicieux. J'ai brûlé une fournée, mais après avoir gratté le dessus, c'était acceptable.

J'ai un peu mal à la tête, donc je me suis ménagée.

dimanche 22

Il pleuvait, donc nous sommes restés à la maison.

Ma fille a attaché ses dessins au mur avec du ruban adhésif. Elle m'a dicté leurs titres et explications, et nous les avons imprimés et affichés comme dans un musée.

J'ai cousu une housse de protection pour l'un des radiateurs en utilisant la majeure partie de ma toile restante.

J'ai essayé de préparer une autre pâte à petits pains aux haricots rouges comme hier, mais la pâte ne s'étirait pas. J'ai pensé qu'elle était trop travaillée, donc je l'ai donnée à ma fille pour qu'elle s'amuse avec et j'ai préparé une autre fournée. Cette fois, elle s'étirait un peu mieux. Je suppose que pour cette recette, le pétrissage à la main est meilleur qu'à la machine.

Ma fille et moi avons aidé mon mari à accrocher un grand dessin brodé dans l'escalier. Malheureusement, il a fait tomber le petit niveau de sa plateforme improvisée sur ma tête, mais ce n'était pas grave. Après ça, j'ai porté mon casque de vélo.

J'étais très fatiguée, donc j'ai fait une sieste. Ma fille a essayé de me réveiller pour des biscuits et du chocolat chaud, mais j'ai continué à dormir. Tant pis pour moi.

Pour le dîner, mon mari a préparé des nouilles ramen aux wontons. C'était le plat parfait pour ce genre de journée.

J'ai fini les petits pains aux haricots rouges après le dîner. À mon soulagement, ils étaient réussis.

J'ai emprunté un livre électronique en français à la bibliothèque qui correspond à la série d'émissions que j'avais vues. J'ai besoin de chercher quelques mots dans le dictionnaire, mais c'est un autre petit pas en avant. Le livre électronique que j'ai emprunté a des DRM, donc je ne peux pas télécharger l'EPUB directement. Si je cherche des livres du domaine public, je peux utiliser une bibliothèque JavaScript pour afficher les EPUB dans une page et traiter les clics pour traduire les mots et sauvegarder un historique.

View Org source for this post

Categorizing Emacs News items by voice in Org Mode

| speech, speech-recognition, emacs, org

I'm having fun exploring which things might actually be easier to do by voice than by typing. For example, after I wrote some code to expand yasnippets by voice, I realized that it was easier to:

  1. press my shortcut,
  2. say "okay, define interactive function",
  3. and then press my shortcut again,

than to:

  1. mentally say it,
  2. get the first initials,
  3. type in "dfi",
  4. and press Tab to expand.

Another area where I do this kind of mental translation for keyboard shortcuts is when I categorize dozens of Emacs-related links each week for Emacs News. I used to do this by hand. Then I wrote a function to try to guess the category based on regular expressions (my-emacs-news-guess-category in emacs-news/index.org, which is large). Then I set up a menu that lets me press numbers corresponding to the most frequent categories and use tab completion for the rest. 1 is Emacs Lisp, 2 is Emacs development, 3 is Emacs configuration, 4 is appearance, 5 is navigation, and so on. It's not very efficient, but some of it has at least gotten into muscle memory, which is also part of why it's hard to change the mapping. I don't come across that many links for Emacs development or Spacemacs, and I could probably change them to something else, but… Anyway.

2026-03-23_20-38-33.png
Figure 1: Screenshot of my menu for categorizing links

I wanted to see if I could categorize links by voice instead. I might not always be able to count on being able to type a lot, and it's always fun to experiment with other modes of input. Here's a demonstration showing how Emacs can automatically open the URLs, wait for voice input, and categorize the links using a reasonably close match. The *Messages* buffer displays the recognized output to help with debugging.

Screencast with audio: categorizing links by voice

This is how it works:

  1. It starts an ffmpeg recording process.
  2. It starts Silero voice activity detection.
  3. When it detects that speech has ended, it use curl to send the WAV to an OpenAI-compatible server (in my case, Speaches with the Systran/faster-whisper-base.en model) for transcription, along with a prompt to try to influence the recognition.
  4. It compares the result with the candidates using string-distance for an approximate match. It calls the code to move the current item to the right category, creating the category if needed.

Since this doesn't always result in the right match, I added an Undo command. I also have a Delete command for removing the current item, Scroll Up and Scroll Down, and a way to quit.

Initial thoughts

I used it to categorize lots of links in this week's Emacs News, and I think it's promising. I loved the way my hands didn't have to hover over the number keys or move between those and the characters. Using voice activity detection meant that I could just keep dictating categories instead of pressing keyboard shortcuts or using the foot pedal I recently dusted off. There's a slight delay, of course, but I think it's worth it. If this settles down and becomes a solid part of my workflow, I might even be able to knit or hand-sew while doing this step, or simply do some stretching exercises.

What about using streaming speech recognition? I've written some code to use streaming speech recognition, but the performance wasn't good enough when I tried it on my laptop (Lenovo P52 released in 2018, no configured GPU under Linux). The streaming server dropped audio segments in order to try to catch up. I'd rather have everything transcribed at the level of the model I want, even if I have to wait a little while. I also tried using the Web Speech API in Google Chrome for real-time speech transcription, but it's a little finicky. I'm happy with the performance I get from either manually queueing speech segments or using VAD and then using batch speech recognition with a model that's kept in memory (which is why I use a local server instead of a command-line tool). Come to think of it, I should try this with a higher-quality model like medium or large, just in case the latency turns out to be not that much more for this use case.

What about external voice control systems like Talon Voice or Cursorless? They seem like neat ideas and lots of people use them. I think hacking something into Emacs with full access to its internals could be lots of fun too.

A lot of people have experimented with voice input for Emacs over the years. It could be fun to pick up ideas for commands and grammars. Some examples:

What about automating myself out of this loop? I've considered training a classifier or sending the list to a large language model to categorize links in order to set more reasonable defaults, but I think I'd still want manual control, since the fun is in getting a sense of all the cool things that people are tinkering around with in the Emacs community. I found that with voice control, it was easier for me to say the category than to look for the category it suggested and then say "Okay" to accept the default. If I display the suggested category in a buffer with very large text (and possibly category-specific background colours), then I can quickly glance at it or use my peripheral vision. But yeah, it's probably easier to look at a page and say "Org Mode" than to look at the page, look at the default text, see if it matches Org Mode, and then say okay if it is.

Ideas for next steps

I wonder how to line up several categories. I could probably rattle off a few without waiting for the next one to load, and just pause when I'm not sure. Maybe while there's a reasonably good match within the first 1-3 words, I'll take candidates from the front of the queue. Or I could delimit it with another easily-recognized word, like "next".

I want to make a more synchronous version of this idea so that I can have a speech-enabled drop-in replacement that I can use as my y-or-n-p while still being able to type y or n. This probably involves using sit-for and polling to see if it's done. And then I can use that to play Twenty Questions, but also to do more serious stuff. It would also be nice to have replacements for read-string and completing-read, since those block Emacs until the user enters something.

I might take a side-trip into a conversational interface for M-x doctor and M-x dunnet, because why not. Naturally, it also makes sense to voice-enable agent-shell and gptel interactions.

I'd like to figure out a number- or word-based completion mechanism so that I can control Reddit link replacement as well, since I want to select from a list of links from the page. Maybe something similar to the way voicemacs adds numbers to helm and company or how flexi-choose.el works.

I'm also thinking about how I can shift seamlessly between typing and speaking, like when I want to edit a link title. Maybe I can check if I'm in the minibuffer and what kind of minibuffer I'm in, perhaps like the way Embark does.

It would be really cool to define speech commands by reusing the keymap structure that menus also use. This is how to define a menu in Emacs Lisp:

(easy-menu-define words-menu global-map
  "Menu for word navigation commands."
  '("Words"
     ["Forward word" forward-word]
     ["Backward word" backward-word]))

and this is how to set just one binding:

(keymap-set-after my-menu "<drink>"
  '("Drink" . drink-command) 'eat)

That makes sense to reuse for speech commands. I'd also like to be able to specify aliases while hiding them or collapsing them for a "What can I say" help view… Also, if keymaps work, then maybe minor modes or transient maps could work? This sort of feels like it should be the voice equivalent of a transient map.

The code so far

(defun my-emacs-news-categorize-with-voice (&optional skip-browse)
  (interactive (list current-prefix-arg))
  (unless skip-browse
    (my-spookfox-browse))
  (speech-input-cancel-recording)
  (let ((default (if (fboundp 'my-emacs-news-guess-category) (my-emacs-news-guess-category))))
    (speech-input-from-list
     (if default
         (format "Category (%s): " default)
       "Category: ")
     '(("Org Mode" "Org" "Org Mode")
       "Other"
       "Emacs Lisp"
       "Coding"
       ("Emacs configuration" "Config" "Configuration")
       ("Appearance" "Appearance")
       ("Default" "Okay" "Default")
       "Community"
       "AI"
       "Writing"
       ("Reddit" "Read it" "Reddit")
       "Shells"
       "Navigation"
       "Fun"
       ("Dired" "Directory" "Dir ed")
       ("Mail, news, and chat" "News" "Mail" "Chat")
       "Multimedia"
       "Scroll down"
       "Scroll up"
       "Web"
       "Delete"
       "Skip"
       "Undo"
       ("Quit" "Quit" "Cancel" "All done"))
     (lambda (result text)
       (message "Recognized %s original %s" result text)
       (pcase result
         ("Undo"
          (undo)
          (my-emacs-news-categorize-with-voice t))
         ("Skip"
          (forward-line)
          (my-emacs-news-categorize-with-voice))
         ("Quit"
          (message "All done.")
          (speech-input-cancel-recording))
         ("Reddit"
          (my-emacs-news-replace-reddit-link)
          (my-emacs-news-categorize-with-voice t))
         ("Scroll down"
          (my-spookfox-scroll-down)
          (my-emacs-news-categorize-with-voice t))
         ("Scroll up"
          (my-spookfox-scroll-up)
          (my-emacs-news-categorize-with-voice t))
         ("Delete"
          (delete-line)
          (undo-boundary)
          (my-emacs-news-categorize-with-voice))
         ("Default"
          (my-org-move-current-item-to-category
           (concat default ":"))
          (undo-boundary)
          (my-emacs-news-categorize-with-voice))
         (_
          (my-org-move-current-item-to-category
           (concat result ":"))
          (undo-boundary)
          (my-emacs-news-categorize-with-voice))))
     t)))

It uses Spookfox to control Firefox from Emacs:

(defun my-spookfox-scroll-down ()
  (interactive)
  (spookfox-js-injection-eval-in-active-tab "window.scrollBy(0, document.documentElement.clientHeight);" t))

(defun my-spookfox-scroll-up ()
  (interactive)
  (spookfox-js-injection-eval-in-active-tab "window.scrollBy(0, -document.documentElement.clientHeight);"))

(defun my-spookfox-background-tab (url &rest args)
  "Open URL as a background tab."
  (if spookfox--connected-clients
      (spookfox-tabs--request (cl-first spookfox--connected-clients) "OPEN_TAB" `(:url ,url))
    (browse-url url)))

It also uses these functions for categorizing Org Mode items:

(defun my-org-move-current-item-to-category (category)
    "Move current list item under CATEGORY earlier in the list.
  CATEGORY can be a string or a list of the form (text indent regexp).
  Point should be on the next line to process, even if a new category
  has been inserted."
    (interactive (list (completing-read "Category: " (my-org-get-list-categories))))
    (when category
      (let* ((col (current-column))
             (item (point-at-bol))
             (struct (org-list-struct))
             (category-text (if (stringp category) category (elt category 0)))
             (category-indent (if (stringp category) 2 (+ 2 (elt category 1))))
             (category-regexp (if (stringp category) category (elt category 2)))
             (end (elt (car (last struct)) 6))
             (pos (point))
             s)
        (setq s (org-remove-indentation (buffer-substring-no-properties item (org-list-get-item-end item struct))))
        (save-excursion
          (if (string= category-text "x")
              (org-list-send-item item 'delete struct)
            (goto-char (caar struct))
            (if (re-search-forward (concat "^ *- +" category-regexp) end t)
                (progn
                  ;; needs a patch to ol.el to check if stringp
                  (org-list-send-item item (point-at-bol) struct)
                  (org-move-item-down)
                  (org-indent-item))
              (goto-char end)
              (org-list-insert-item
               (point-at-bol)
               struct (org-list-prevs-alist struct))
              (let ((old-struct (copy-tree struct)))
                (org-list-set-ind (point-at-bol) struct 0)
                (org-list-struct-fix-bul struct (org-list-prevs-alist struct))
                (org-list-struct-apply-struct struct old-struct))
              (goto-char (point-at-eol))
              (insert category-text)
              (org-list-send-item item 'end struct)
              (org-indent-item)
              (org-indent-item))
            (recenter))))))

(defun my-org-guess-list-category (&optional categories)
  (interactive)
  (require 'cl-lib)
  (unless categories
    (setq categories
          (my-helm-org-list-categories-init-candidates)))
  (let* ((beg (line-beginning-position))
         (end (line-end-position))
         (string (buffer-substring-no-properties beg end))
         (found
          (cl-member string
                     categories
                     :test
                     (lambda (string cat-entry)
                       (unless (string= (car cat-entry) "x")
                         (string-match (regexp-quote (downcase (car cat-entry)))
                                       string))))))
    (when (car found)
      (my-org-move-current-item-to-category
       (cdr (car found)))
      t)))

For the speech-input functions, experimental code is at https://codeberg.org/sachac/speech-input .

View Org source for this post

2026-03-23 Emacs news

| emacs, emacs-news

: Removed elecxzy comment-dwim, whoops.

Might be a good opportunity to set up better auto-saves, with buffer-guardian.el inspiring an update to super-save 0.5. Also, there were a couple of interesting experiments embedding Chromium (Reddit) or native macOS views in Emacs (Reddit), and one about embedding Emacs in a webpage (Reddit).

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View Org source for this post

La semaine du 9 au 15 mars

| french

lundi 9 mars

Il faisait très beau et le soleil brillait. Je me suis assise sur le porche et j'ai réécrit mon journal et mes notes sur l'IA en français.

Après l'école, ma fille n'a pas voulu aller à son cours de gymnastique parce qu'elle avait mal au ventre. Elle est restée un petit moment, puis nous sommes allées au parc avec le réchaud de camping, des guimauves, et des biscuits au chocolat pour faire des s-mores. J'ai envoyé des messages à ses amies, mais je n'ai pas reçu de réponse. Néanmoins, si personne ne peut venir, nous pouvons toujours nous en préparer. Par coïncidence, personne n'a reçu mon message à temps, mais toutes ses amies nous ont trouvées. J'ai donné des guimauves aux filles et au grand-père d'une amie de ma fille. Nous les avons fait griller sur des brochettes. On s'est régalés. C'était une fête d'anniversaire inattendue, parce que ses amies étaient tombées malades juste avant la fête planifiée le mois précédent.

Après un dîner de burgers et de frites, nous avons cousu ensemble. Ma fille et moi avons travaillé sur la pochette Pokémon et mon mari a réparé un sac d'épicerie.

La bosse près du piercing de ma fille a commencé à saigner et suppurer. Normalement, elle dormait sur le dos, mais elle n'a pas pu contrôler sa position pendant son sommeil et de temps en temps, elle dormait probablement sur le côté. Je l'ai nettoyée avec une solution saline.

mardi 10 mars

Ma fille était de mauvaise humeur parce que l'école avait une remplaçante et qu'elle avait quelques douleurs. Elle n'a pas voulu participer en classe l'après-midi.

J'avais un rendez-vous avec mon tuteur, pendant lequel j'ai pratiqué ma prononciation à l'aide de mes notes sur l'IA. J'ai mis les mots que je prononce mal en gras. Après le rendez-vous, j'ai écrit des fonctions pour extraire les mots gras avec leurs contextes et les enregistrer dans mes notes au format Org Mode pour les revoir. Ma prochaine étape est de rendre plus facile l'écoute des mots enregistrés.

J'ai aussi travaillé sur mon serveur de synthèse vocale qui est compatible avec speechd. Kokoro TTS est trop lent pour un usage général, mais sa qualité est meilleure que celle d'espeak, donc je veux l'utiliser pour les textes longs pour lesquels une brève pause avant le début n'est pas un problème. Le serveur Kokoro FastAPI utilise l'interface de synthèse vocale d'OpenAI, donc si je l'implémente pour Kokoro, les autres services comme OpenAI fonctionnent aussi.

Ma fille s'est endormie sur le canapé. Elle n'a pas voulu être portée à l'étage.

mercredi 11 mars

Ma fille s'est plainte de quelques symptômes, ma pauvre chérie. Elle a mal à la tête, au ventre et à un genou. Elle ne dort pas mieux… Elle ne va pas mieux. Elle semble traverser une période difficile. Je ne m'attends pas à grand-chose aujourd'hui.

J'ai participé à la réunion virtuelle OrgMeetup. J'ai présenté mes fonctions pour mettre un lien vers le fichier audio et l'écouter, mettre un lien automatique à partir de mes favoris, et télécharger et convertir les éléments de mes notes partagées avec mon tuteur sur Google Docs. J'ai aussi envoyé un correctif pour l'opération « sentence-at-point » dans Org Mode. J'ai travaillé davantage sur mon serveur speechd-ai qui est capable de se connecter aux serveurs compatibles avec le service de synthèse vocale d'OpenAI, mais ça ne fonctionne pas encore complètement.

Ma fille a raté la première partie de son cours à cause de problèmes de santé, mais elle a rejoint le cours à temps pour obtenir un score parfait au test de français. Elle a aussi travaillé le piano pendant le cours de musique. Elle était très fière de ses accomplissements. Elle s'est amusée à essayer quelques expressions en français. « Je suis une pomme de terre de canapé » dit-elle. Ce n'est pas l'expression idiomatique. ( Mon tuteur dit qu'il n'utilise ni cette expression ni « une patate de canapé. » Il pense que « pantouflarde » est peut-être mieux. ) Mais c'est bien qu'elle joue et lance des idées.

Après le dîner, ma fille et moi avons fait une sortie pour activer le PokéStop dans le coin. Très brève, mais au moins, elle a marché.

J'ai imprimé ses devoirs parce qu'elle préfère travailler sur papier plutôt que sur l'écran. Je l'ai aussi aidée à rassembler quelques informations pour son projet d'affiche.

J'ai trouvé que la reconnaissance vocale était utile quand ma fille a voulu un câlin pendant qu'elle faisait autre chose. Elle dit souvent, « Tu es toute chaude. » Mes bras sont trop courts pour taper pendant un câlin. Eh bien, je peux lui donner un câlin tandis que je saisis mes pensées, grâce à la reconnaissance vocale. Elle est curieuse de l'IA, donc de temps en temps, j'utilise la reconnaissance pour interroger l'IA ensemble.

Ma fille a essayé de demander à l'IA de corriger des bugs dans l'histoire interactive sur des farces de Pokémon. Elle était censée suivre le temps pendant l'aventure, mais les totaux étaient erronés. Je suis ravie de voir qu'elle remarque des erreurs et explique à l'IA les changements qu'elle veut.

jeudi 12 mars

Ma fille a voulu acheter une nouvelle boîte à lunch qui ne permet pas aux liquides de se mélanger, parce que nos boîtes actuelles ont de petits trous sous les cloisons et ses craquelins étaient tous mous de temps en temps. Malheureusement, je l'ai emmenée à l'ancienne adresse du magasin, qui a déjà fermé. Elle devra attendre une autre promenade.

Je me suis perdue dans les détails du travail sur le serveur de synthèse vocale qui est compatible avec speechd.

J'ai créé des fonctions pour rassembler mes tentatives de virelangues dans plusieurs fichiers.

vendredi 13 mars

Elle est venue se blottir contre moi toute la nuit. Elle a accaparé toutes les couvertures. Néanmoins, je l'aime encore.

Mon tuteur m'a donné de nouveaux virelangues pour travailler sur ma prononciation.

  • Mon oncle peint un grand pont blanc.
    {mɔ̃n ˈɔ̃kl pˈɛ̃ œ̃ ɡʁˈɑ̃ pˈɔ̃ blˈɑ̃.}
  • Un singe malin prend un bon raisin rond.
    {œ̃ sˈɛ̃ʒ malˈɛ̃ pʁˈɑ̃t œ̃ bˈɔ̃ ʁɛzˈɛ̃ ʁˈɔ̃.}
  • Dans le vent du matin, mon chien sent un bon parfum.
    {dɑ̃ lə vˈɑ̃ dy matˈɛ̃, mɔ̃ ʃjˈɛ̃ sˈɑ̃ œ̃ bˈɔ̃ paʁfˈœ̃.}
  • Le soin du roi consiste à joindre chaque coin du royaume.
    {lə swˈɛ̃ dy ʁwˈa kɔ̃sˈist a ʒwˈɛ̃dʁ ʃak kwˈɛ̃ dy ʁwajˈom.}
  • Dans un coin du bois, le roi voit trois points noirs.
    {dɑ̃z œ̃ kwˈɛ̃ dy bwˈa, lə ʁwˈa vwˈa tʁwˈa pwˌɛ̃ nwˈaʁ.}
  • Le feu de ce vieux four chauffe peu.
    {lə fˈø də sə vjˈø fˈuʁ ʃˈof pˈø.}
  • Deux peureux veulent un peu de feu.
    {dˈø pøʁˈø vˈœlt œ̃ pø də fˈø.}
  • Deux vieux bœufs veulent du beurre.
    {dˈø vjˈø bˈø vˈœl dy bˈœʁ.}
  • Elle aimait marcher près de la rivière.
    {ɛl ɛmˈɛ maʁʃˈe pʁɛ də la ʁivjˈɛʁ.}
  • Je vais essayer de réparer la fenêtre.
    {ʒə vˈɛz esɛjˈe də ʁepaʁˈe la fənˈɛtʁ.}
  • Le bébé préfère le lait frais.
    {lə bebˈe pʁefˈɛʁ lə lˈɛ fʁˈɛ.}
  • Charlotte cherche ses chaussures dans la chambre.
    {ʃaʁlˈɔt ʃˈɛʁʃ se ʃosˈyʁ dɑ̃ la ʃˈɑ̃bʁ.}
  • Un chasseur sachant chasser sans son chien est-il un bon chasseur ?
    {œ̃ ʃasˈœʁ saʃˈɑ̃ ʃasˈe sɑ̃ sɔ̃ ʃjˈɛ̃ ɛtil œ̃ bˈɔ̃ ʃasˈœʁ ?}
  • Le journaliste voyage en janvier au Japon.
    {lə ʒuʁnalˈist vwajˈaʒ ɑ̃ ʒɑ̃vjˈe o ʒapˈɔ̃.}
  • Georges joue du jazz dans un grand bar.
    {ʒˈɔʁʒ ʒˈu dy ʤˈaz dɑ̃z œ̃ ɡʁˈɑ̃ bˈaʁ.}
  • Un jeune joueur joue dans le grand gymnase.
    {œ̃ ʒˈøn ʒwˈœʁ ʒˈu dɑ̃ lə ɡʁˈɑ̃ ʒimnˈaz.}
  • Le compagnon du montagnard soigne un agneau.
    {lə kɔ̃panjˈɔ̃ dy mɔ̃tanjˈaʁ swˈaɲ œ̃n anjˈo.}
  • La cigogne soigne l’agneau dans la campagne.
    {la siɡˈɔɲ swˈaɲ lanjˈo dɑ̃ la kɑ̃pˈaɲ.}
  • La grenouille fouille les feuilles dans la broussaille.
    {la ɡʁənˈuj fˈuj le fˈœj dɑ̃ la bʁusˈaj.}
  • La vieille abeille travaille dans la broussaille.
    {la vjˈɛj abˈɛj tʁavˈaj dɑ̃ la bʁusˈaj.}

J'ai ajouté une version grasse de la police de caractères Open Sans sur mon site, qui aide à remarquer le contraste entre les mots gras et les mots normaux.

J'ai besoin de corriger un petit bug dans mon correctif pour Org Mode.

Ma fille m'a aidée à déneiger le trottoir et la terrasse en bois. La neige était lourde à cause de la pluie verglaçante.

Après le dîner, ma fille et moi avons cousu ensemble. Elle a voulu fabriquer un petit sac à remplir de riz et de lavande, comme sa peluche d'axolotl chauffante. J'ai aussi continué à coudre le sac Pokémon.

samedi 14 mars

Ma fille a voulu m'aider à préparer des crêpes pour le petit-déjeuner. Elle a réussi à préparer des crêpes toute seule la fois précédente. Mais les deux premières crêpes ont collé à la poêle. Je me demande si ce n'était pas à cause de l'ajout de lait supplémentaire pour finir le carton de lait, et s'il vaut mieux que nous suivions un peu plus la recette la prochaine fois. J'ai essayé de gratter les morceaux collés avec la spatule à crêpes en bois, mais une partie était bien collée. Elle m'a demandé si elle pouvait l'essayer aussi. J'ai dit que non parce que j'ai enlevé tous les morceaux faciles et j'ai voulu ajouter de l'eau pour ramollir le reste. J'étais stressée car je devais aussi attendre un appel du médecin à propos des symptômes de ma fille. Elle n'a pas voulu écouter « non ». Elle est devenue très grincheuse parce qu'elle a eu l'impression que je l'avais critiquée. Elle est partie furieuse et elle était fâchée contre moi toute la journée, sauf quelques brefs moments. Je lui ai écrit un message pour lui présenter mes excuses. Avec le recul, peut-être que j'aurais mieux fait de la laisser essayer la prochaine fois. Mais c'est aussi important d'apprendre que si nous cuisinons ensemble, de temps en temps, il faut que je dise « non » ou « pas pour le moment. » De toute façon, elle s'est déridée le soir.

J'ai analysé les enregistrements du rendez-vous d'hier. Mon code pour chercher des correspondances approximatives entre la liste des phrases et la transcription était très utile.

(subed-record-extract-all-approximately-matching-phrases
   phrases
   "/home/sacha/sync/recordings/2026-03-13-raphael.json"
   "/home/sacha/proj/french/analysis/virelangues/2026-03-13-raphael-script.vtt")
(my-subed-record-analyze-file-with-azure
  (subed-record-filter-skips
   (subed-parse-file
    "/home/sacha/proj/french/analysis/virelangues/2026-03-13-raphael-script.vtt"))
 "~/proj/french/analysis/virelangues-2026-03-13/2026-03-13-all"
 "/home/sacha/proj/french/analysis/virelangues/2026-03-13-raphael-script.vtt")
File ID Comments All Acc Flu Comp Conf  
▶️ 1 X: pont 83 94 79 86 86 Mon oncle peint un grand pont blanc. {pont}
▶️ 2 X: peint 92 94 89 100 87 Mon oncle peint un grand pont blanc. {peint}
▶️ 3 X: pont 93 99 90 100 86 Mon oncle peint un grand pont blanc. {pont}
▶️ 4 X: raisin 76 82 70 88 87 Un singe malin prend un bon raisin rond. {raisin}
▶️ 5 C'est mieux 68 75 80 62 87 Un singe malin prend un bon raisin rond.
▶️ 6 X: parfum 75 92 62 100 89 Dans le vent du matin, mon chien sent un bon parfum. {parfum}
▶️ 7 X: parfum 71 99 53 100 89 Dans le vent du matin, mon chien sent un bon parfum. {parfum}
▶️ 8 Ouais, c'est ça 83 94 78 91 89 Dans le vent du matin, mon chien sent un bon parfum.
▶️ 9 ok 75 86 63 100 89 Le soin du roi consiste à joindre chaque coin du royaume.
▶️ 10 Ouais, c'est bien 80 94 72 91 88 Dans un coin du bois, le roi voit trois points noirs.
▶️ 11 Ouais, c'est ça, parfait 83 94 74 100 88 Dans un coin du bois, le roi voit trois points noirs.
▶️ 12 Mm hmm 95 94 94 100 84 Le feu de ce vieux four chauffe peu.
▶️ 13 Ouais, parfait 90 92 87 100 86 Le feu de ce vieux four chauffe peu.
▶️ 14   82 93 78 86 84 Deux peureux veulent un peu de feu.
▶️ 15 Ouais 77 85 88 71 86 Deux peureux veulent un peu de feu.
▶️ 16 X: bœufs 84 84 91 83 86 Deux vieux bœufs veulent du beurre. {bœufs}
▶️ 17   77 78 75 83 85 Deux vieux bœufs veulent du beurre.
▶️ 18 Ouais, parfait 92 94 89 100 89 Elle aimait marcher près de la rivière.
▶️ 19 Ok, c'est bien 93 98 89 100 90 Je vais essayer de réparer la fenêtre.
▶️ 20 X: le bébé 75 86 70 83 85 Le bébé préfère le lait frais. {le bébé}
▶️ 21 Ouais, c'est bien 88 94 82 100 88 Le bébé préfère le lait frais.
▶️ 22 Okay 83 87 76 100 89 Le bébé préfère le lait frais.
▶️ 23 X: cherche 74 77 81 71 88 Charlotte cherche ses chaussures dans la chambre. {cherche}
▶️ 24   77 92 70 86 90 Charlotte cherche ses chaussures dans la chambre.
▶️ 25 Voila, c'est ça 88 95 83 100 88 Un chasseur sachant chasser sans son chien est-il un bon chasseur ?
▶️ 26 Tu est forte 81 77 94 82 88 Un chasseur sachant chasser sans son chien est-il un bon chasseur ?
▶️ 27 Oui 92 95 93 91 89 Un chasseur sachant chasser sans son chien est-il un bon chasseur ?
▶️ 28 Okay 91 90 94 91 88 Un chasseur sachant chasser sans son chien est-il un bon chasseur ?
▶️ 29 X: au Japon 76 85 86 71 87 Le journaliste voyage en janvier au Japon. {au Japon}
▶️ 30 X: en janvier 92 89 95 100 92 Le journaliste voyage en janvier au Japon. {en janvier}
▶️ 31 Ouais 91 88 92 100 91 Le journaliste voyage en janvier au Japon.
▶️ 32 X: jazz 90 93 93 88 88 Georges joue du jazz dans un grand bar. {jazz}
▶️ 33 X: dans un 84 85 83 88 85 Georges joue du jazz dans un grand bar. {dans un}
▶️ 34 C'est bien (X: dans un) 91 88 94 100 88 Georges joue du jazz dans un grand bar. {dans un}
▶️ 35 X: dans le grand gymnase 87 86 92 88 88 Un jeune joueur joue dans le grand gymnase. {dans le grand gymnase}
▶️ 36 C'est bien 88 87 94 88 85 Un jeune joueur joue dans le grand gymnase.
▶️ 37   77 84 68 100 89 Le compagnon du montagnard soigne un agneau.
▶️ 38 Ouais, c'est ça 85 93 78 100 89 Le compagnon du montagnard soigne un agneau.
▶️ 39   95 94 96 100 91 Le compagnon du montagnard soigne un agneau.
▶️ 40 X: cigogne 74 81 77 71 89 La cigogne soigne l’agneau dans la campagne. {cigogne}
▶️ 41   85 88 84 86 89 La cigogne soigne l’agneau dans la campagne.
▶️ 42   69 76 83 62 87 La grenouille fouille les feuilles dans la broussaille.
▶️ 43 grenouille 71 80 68 75 86 La grenouille fouille les feuilles dans la broussaille.

J'ai aussi ajouté les dernières tentatives à l'article « Comparing pronunciation recordings across time. »

Je pense que c'est mieux que de lire mon journal à voix haute pendant le rendez-vous parce que les phrases me permettent de me concentrer sur les sons difficiles, et mon nouveau code m'aide à suivre ma progression au fil des sessions. Ça signifie que mon journal contient peut-être des erreurs, mais ce n'est pas un problème. Selon ce long fil sur les IA sur Hacker News, c'est mieux d'être humain malgré mes erreurs.

J'ai modifié « subed-waveform » et « subed-record » pour afficher les étendues audio que je coupe. Si j'ajoute une fonction pour me permettre de faire glisser le curseur sur la forme d'onde pour créer ou ajuster la directive de coupe, je pense que ce sera très pratique.

J'ai ajouté des raccourcis clavier à mon tableau d'enregistrements de virelangues en français. Maintenant, je peux naviguer vers l'enregistrement suivant ou vers l'enregistrement précédent dans la même phrase ou entre les phrases. Je peux aussi sauter entre les enregistrements de la même phrase avec les chiffres 1 à 9, ce qui facilite tellement la comparaison entre deux versions.

Mon mari a retrouvé un peu plus de son énergie, donc il a fabriqué une machine à espresso en jouet que ma fille réclamait depuis longtemps au lieu d'en acheter une sur eBay pour environ 90 dollars. Il a utilisé du carton et du bois pour la construire. La machine en jouet était merveilleuse. Ma fille était très heureuse.

dimanche 15 mars

J'ai écrit du code JavaScript pour jouer un enregistrement en boucle avec une pause de deux fois sa longueur dans mes notes sur les virelangues. Ça facilite la pratique sur mon téléphone. En plus de mes extraits du rendez-vous précédent avec mon tuteur, j'ai aussi ajouté des références audio qui sont générées par les synthèses vocales de Google Traduction, de Kokoro, et d'Azure. Je préfère celles de Google Traduction au début parce qu'elles sont plus lentes, mais je pense que je peux configurer les autres services pour parler à la même vitesse. Je les ai utilisées pour travailler sur ma prononciation. Ma prochaine étape est d'inclure les phonèmes pour aider à remarquer les différences entre les voyelles.

J'ai préparé des crêpes épaisses pour le petit-déjeuner. Ma fille m'a aidée avec certaines étapes de la préparation.

Nous avons travaillé sur la machine à espresso en carton. Ma fille et moi avons utilisé le petit ordinateur micro:bit pour faire fonctionner des boutons, jouer des sons, et afficher les nombres et les animations en utilisant MicroPython. J'ai commencé avec l'interface Web, mais Ampy est mieux pour téléverser le code sur le micro:bit parce que je peux tout faire sans clics.

Ma fille a choisi cinq boutons et elle a dessiné des animations pour chaque commande :

  • Moudre
  • Eau
  • Lait
  • Vapeur
  • Café

Je suis particulièrement fière que le bouton pour l'eau simule le chauffage de l'eau en affichant la progression sur un afficheur à quatre chiffres à sept segments ( bien sûr plus rapidement qu'en vrai ), suivi d'une animation. Le logiciel simule aussi le refroidissement de l'eau après un certain temps. Le micro:bit a un thermomètre, donc si ma fille le veut, nous pouvons changer le logiciel pour utiliser la vraie température ambiante.

J'ai découpé des ouvertures dans le tableau de bord en carton et j'ai utilisé de la colle chaude pour coller les éléments. Mon mari a utilisé deux aimants pour coller le tableau de bord au châssis de la machine. Ça marche ! Ma fille s'est très bien amusée en préparant du café pour nous.

Voici le code : https://github.com/wjyoung65/toy_espresso_machine

Je veux essayer d'ajouter un module MP3 et une petite enceinte pour jouer un son de meilleure qualité. Ma fille a enregistré quelques sons de la préparation du café comme le bruit de l'eau qui coule ou qui bouillonne.

Mon mari a dépoussiéré un vieux petit ordinateur Arduino avec lequel son autre fille et lui avaient commencé un projet il y a plusieurs années. Il a réussi à diffuser des sons dans les écouteurs. Si nous pouvons nous connecter au micro:bit, la machine à espresso en jouet peut diffuser les sons que ma fille a enregistrés. J'ai hâte de l'essayer.

View Org source for this post

2026-03-16 Emacs news

| emacs, emacs-news

Security reminder: If you use kubernetes-el, don't update for now, and you might want to check your installation if you updated it recently. The repo was compromised. (Analysis, Reddit discussion, lobste.rs) If you use Emacs 31, please consider enabling package-review-policy.

There were a number of lively conversations around Emacs Solo (142 comments on HN), Emacs and Vim in the age of AI (52 comments on Reddit, 138 on HN), and agent-shell 0.47 (62 on Reddit). Also, Prot has posted the video and text of his talk Computing in freedom with GNU Emacs (YouTube 42:40, Video with Q&A, more links in the community section).

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View Org source for this post

Org Mode: Export HTML, copy files, and serve the results via simple-httpd so that media files work

Posted: - Modified: | emacs, org

: Update Oh, ignore all of this! For some reason, when I export the regular Org Mode way, my media files work. Maybe it was just a weird hiccup!

In Org Mode, when you use "Export to HTML - As HTML file and open", the resulting HTML file is loaded using a file:// URL. This means you can't load any media files. In my post about pronunciation practice, I wanted to test the playback without waiting for my 11ty-based static site generator to churn through the files.

simple-httpd lets you run a web server from Emacs. By default, the httpd-root is ~/public_html and httpd-port is 8085, but you can configure it to be somewhere else. Here I set it up to create a new temporary directory, and to delete that directory afterwards.

(use-package simple-httpd
  :config
  (setq httpd-root (make-temp-file "httpd" t))
  :hook
  (httpd-stop . my-simple-httpd-remove-temporary-root)
  (kill-emacs . httpd-stop))

(defun my-simple-httpd-remove-temporary-root ()
  "Remove `httpd-root' only if it's a temporary directory."
  (when (file-in-directory-p httpd-root temporary-file-directory)
    (delete-directory httpd-root t)))

The following code exports your Org buffer or subtree to a file in that directory, copies all the referenced local files (if they're newer) and updates the links in the HTML, and then serves it via simple-httpd. Note that it just overwrites everything without confirmation, so if you refer to files with the same name, only the last one will be kept.

(with-eval-after-load 'ox
  (org-export-define-derived-backend 'my-html-served 'html
    :menu-entry
    '(?s "Export to HTML and Serve"
         ((?b "Buffer"  my-org-serve--buffer)
          (?s "Subtree" my-org-serve--subtree)))))

(defun my-org-serve--buffer (&optional async _subtreep visible-only body-only ext-plist)
  (my-org-export-and-serve nil))

(defun my-org-serve--subtree (&optional async _subtreep visible-only body-only ext-plist)
  (my-org-export-and-serve t))

;; Based on org-11ty--copy-files-and-replace-links
;; Might be a good idea to use something DOM-based instead
(defun my-html-copy-files-and-replace-links (info &optional destination-dir)
  (let ((file-regexp "\\(?:src\\|href\\|poster\\)=\"\\(\\(file:\\)?.*?\\)\"")
        (destination-dir (or destination-dir (file-name-directory (plist-get info :file-path))))
        file-all-urls file-name beg
        new-file file-re
        unescaped)
    (unless (file-directory-p destination-dir)
      (make-directory destination-dir t))
    (unless (file-directory-p destination-dir)
      (error "%s is not a directory." destination-dir))
    (save-excursion
      (goto-char (point-min))
      (while (re-search-forward file-regexp nil t)
        (setq file-name (or (match-string 1) (match-string 2)))
        (unless (or (string-match "^#" file-name)
                    (get-text-property 0 'changed file-name))
          (setq file-name
                (replace-regexp-in-string
                 "\\?.+" ""
                 (save-match-data (if (string-match "^file:" file-name)
                                      (substring file-name 7)
                                    file-name))))
          (setq unescaped
                (replace-regexp-in-string
                 "%23" "#"
                 file-name))
          (setq new-file (concat
                          (if info (plist-get info :permalink) "")
                          (file-name-nondirectory unescaped)))
          (unless (org-url-p file-name)
            (let ((new-file-name (expand-file-name (file-name-nondirectory unescaped)
                                                   destination-dir)))
              (condition-case err
                  (when (or (not (file-exists-p new-file-name))
                            (file-newer-than-file-p unescaped new-file-name))
                    (copy-file unescaped new-file-name t))
                (error nil))
              (when (file-exists-p new-file-name)
                (save-excursion
                  (goto-char (point-min))
                  (setq file-re (concat "\\(?: src=\"\\| href=\"\\| poster=\"\\)\\(\\(?:file://\\)?" (regexp-quote file-name) "\\)"))
                  (while (re-search-forward file-re nil t)
                    (replace-match
                     (propertize
                      (save-match-data (replace-regexp-in-string "#" "%23" new-file))
                      'changed t)
                     t t nil 1)))))))))))

(defun my-org-export-and-serve (&optional subtreep)
  "Export current org buffer (or subtree if SUBTREEP) to HTML and serve via simple-httpd."
  (interactive "P")
  (require 'simple-httpd)
  (httpd-stop)
  (unless httpd-root (error "Set `httpd-root'."))
  (unless (file-directory-p httpd-root)
    (make-directory httpd-root t))
  (unless (file-directory-p httpd-root)
    (error "%s is not a directory." httpd-root))
  (let* ((out-file (expand-file-name (concat (file-name-base (buffer-file-name)) ".html")
                                     httpd-root))
         (html-file (org-export-to-file 'my-html-served out-file nil subtreep)))
    ;; Copy all the files and rewrite all the links
    (with-temp-file out-file
      (insert-file-contents out-file)
      (my-html-copy-files-and-replace-links
       `(:permalink "/") httpd-root))
    (httpd-start)
    (browse-url (format "http://localhost:%d/%s"
                        httpd-port
                        (file-name-nondirectory html-file)))))

Now I can use C-c C-e (org-export-dispatch), select the subtree with C-s, and use s s to export a subtree to a webserver and have all the media files work. This took 0.46 seconds for my post on pronunciation practice and automatically opens the page in a browser window. In comparison, my 11ty static site generator took 5.18 seconds for a subset of my site (1630 files copied, 214 files generated), and I haven't yet hooked up monitoring it to Emacs, so I have to take an extra step to open the page in the browser when I think it's finished. I think exporting to HTML and serving it with simple-httpd will be much easier for simple cases like this, and then I can export to 11ty once I'm done with the basic checks.

This is part of my Emacs configuration.
View Org source for this post