CommunityRédaction et éditiongithub.com

mgubi/texmacs

Lire, écrire, convertir et composer des documents GNU TeXmacs (.tm). Utilisez cette compétence pour toute tâche impliquant un fichier .tm, l'application TeXmacs, la conversion LaTeX/beamer en TeXmacs natif, les présentations TeXmacs (style beamer, écrans), le plugin TikZ ou l'exportation TeXmacs vers PDF en mode headless.

Qu'est-ce que texmacs ?

Cette compétence fournit un guide pratique pour les agents IA travaillant avec GNU TeXmacs, un éditeur de documents scientifique. Elle couvre la lecture et l'écriture de fichiers .tm (format arbre sérialisé, encodage Cork/Latin-1), l'exécution headless de TeXmacs pour la conversion LaTeX↔TeXmacs, l'exportation PDF et HTML, et la gestion des présentations (screens). Elle détaille également l'écriture de packages de style TeXmacs et de plugins personnalisés, avec des scripts prêts à l'emploi dans `scripts/`. La compétence insiste sur les pièges à éviter (encodages, format du fichier, signature des exports PDF) et encourage les contributions pour maintenir la connaissance à jour. Elle supporte les plateformes macOS et Linux, avec des exemples concrets en Scheme et Python.

Compatible avec✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/mgubi/texmacs-skill/tree/HEAD

Installed? Explore more Rédaction et édition skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Documents TeXmacs

Un guide pratique pour les agents travaillant avec GNU TeXmacs, rassemblé lors de la conversion de notes de cours et de présentations, de l'écriture de packages de style et de l'audit de longs manuscrits mathématiques. Gardez-le vivant : ajoutez ce qui est nouvellement appris dans les « Pièges » et maintenez les scripts dans scripts/ fonctionnels. Les ajouts spécifiques à un projet appartiennent à une compétence locale séparée qui pointe ici ; la section « Conventions (obligatoires) » s'applique partout. Source : https://github.com/mgubi/texmacs-skill. Dernière mise à jour : 2026-11-04.

Maintenir cette compétence à jour

Cette compétence est destinée à être installée comme un clone git (généralement ~/.claude/skills/texmacs). Avant de travailler sur des documents TeXmacs :

  • Mettez-la à jour : exécutez git -C <chemin de la compétence> pull --ff-only (si SSH vers GitHub échoue, tirez depuis https://github.com/mgubi/texmacs-skill.git main). Si le clone a des modifications locales ou des commits non poussés, informez l'utilisateur au lieu de tirer par-dessus.
  • Contribuez en retour : lorsque vous apprenez quelque chose de nouveau sur TeXmacs, ajoutez-le ici (généralement dans « Pièges », ou corrigez un script), commitez-le dans le clone et poussez-le sur GitHub (ou ouvrez une pull request si vous ne pouvez pas pousser), afin que chaque installation en bénéficie. Le matériel spécifique au projet reste dans le projet.

Le format de fichier

  • Un fichier .tm est un arbre sérialisé : <tag|arg1|arg2> en ligne, <\tag>…</tag> (avec <|tag> entre les arguments) pour les arguments en bloc, les paragraphes sont séparés par des lignes vides, l'indentation est uniquement pour la mise en page. Dans les chaînes, \<alpha\> est un symbole, <less>/<gtr> sont </>, \| est une barre littérale, <#89AB…> sont des données brutes hexadécimales (images intégrées).

  • Encodage : les chaînes sont encodées en Cork (T1), pas en UTF‑8. Les lettres latines accentuées coïncident principalement avec les octets Latin‑1 (é = 0xE9, à = 0xE0, ö = 0xF6), mais par exemple le tiret demi-cadratin = 0x15, le tiret cadratin = 0x16, § = 0x9F; tout autre caractère Unicode est écrit <#XXXX> (point de code hexadécimal). N'écrivez pas <#XX> vous-même comme un jeton autonome : il est lu comme des données brutes (voir « Écrire des packages de style »). Conséquences : ne modifiez jamais un .tm avec des outils UTF‑8 (les outils Édition/Écriture les refusent ou les corrompent). Lisez/écrivez avec Python encoding='latin-1', newline='', ou mieux passez par la route stree ci-dessous et laissez TeXmacs écrire le fichier.

  • Écrire un fichier .tm à la main : copiez exactement ce squelette. Les éléments de niveau supérieur sont séparés par des lignes vides ; sans elles, TeXmacs ne conserve que l'en-tête <TeXmacs|…> et ignore silencieusement tout le reste (le dump stree est (document (TeXmacs "2.1.5")), le PDF est vide, et il n'y a aucune erreur) :

    <TeXmacs|2.1.5>
    
    <style|<tuple|article|british>>
    
    <\body>
      Premier paragraphe avec <math|x<rsup|2>>.
    
      Deuxième paragraphe.
    </body>
    
    <\initial>
      <\collection>
        <associate|font|TeX Gyre Pagella>
      </collection>
    </initial>
    

    Dans <\body>, les paragraphes (et les blocs de tout <\tag>…</tag>) sont également séparés par des lignes vides ; un seul saut de ligne continue le même paragraphe. Fermez chaque balise de bloc sur sa propre ligne, échappez les symboles sous la forme \<alpha\> et les <, >, | littéraux dans le texte sous la forme <less>, <gtr>, \|, et conservez le fichier en Cork/Latin-1 (écrivez-le avec Python, pas avec printf ou l'outil Écriture, dès qu'il contient un caractère non ASCII).

  • Préférez la génération à l'écriture manuelle. Pour tout ce qui dépasse quelques lignes, construisez le stree en Python (scripts/latex2tm/stree.py) et laissez TeXmacs le sérialiser (tm-undump dans dump.scm) ; ou écrivez le fragment, faites un tm-dump et assemblez l'arbre. Lorsque vous écrivez à la main, vérifiez le résultat avant de l'utiliser : faites un tm-dump et confirmez que le corps a le nombre de paragraphes attendu, ou composez-le et confirmez que le texte PDF n'est pas vide et est complet (mutool draw -F txt). Un PDF vide ou court, ou un dump avec un énorme nœud, signifie une erreur de formatage, pas un bug de TeXmacs.

  • Gros fichiers : les présentations intègrent des images sous forme de données brutes (10+ Mo). Supprimez les séquences <#…> avant la lecture : re.sub(r'<#[0-9A-F]{200,}>', '<#HEX>', s).

Exécuter TeXmacs en mode headless

Binaire (macOS) : /Applications/TeXmacs.app/Contents/MacOS/TeXmacs ; sur Linux texmacs. Testé avec 2.1.4 et 2.1.5. scripts/latex2tm/run.sh contient le chemin ; ajustez-le là.

  • Conversion : TeXmacs -headless -c in.tex out.tm -q (importation LaTeX), -c in.tm out.pdf -q (PDF du tampon actuel).
  • Scheme : TeXmacs -headless -x "(begin (load \"/abs/dump.scm\") … (quit-TeXmacs))". Enveloppez toujours le corps dans (catch #t (lambda () …) (lambda args (display args))) et terminez par (quit-TeXmacs) : une erreur laisse sinon le processus en suspens indéfiniment. Exécutez-le en arrière-plan et interrogez son PID (voir scripts/latex2tm/run.sh) ; tuez uniquement ce PID — ne faites jamais pkill TeXmacs (l'utilisateur peut avoir TeXmacs ouvert).
  • Les exécutions headless écrivent l'état propre de TeXmacs dans ~/.TeXmacs/system ; c'est normal.

API Scheme qui fonctionne en mode headless (scripts/latex2tm/dump.scm)

  • (tree-import (string->url f) "texmacs") / "latex", et (tree-export t (string->url f) "texmacs") : fichier ↔ arbre sans tampon.
  • (tree->stree t) / (stree->tree s) : s‑expressions. Écrivez-les avec (call-with-output-file f (lambda (p) (write s p))) — with-output-to-file ne redirige pas dans le Guile de TeXmacs. Guile écrit les caractères de contrôle sous forme d'échappements \xHH (gérés par scripts/latex2tm/stree.py).
  • Composition : (load-buffer u) (switch-to-buffer u) (export-buffer-main u (string->url pdf) "pdf" (list)) — l'exportation PDF est ce qui compose. (update-document "all") ne fait rien en mode headless (c'est une commande différée en veille) ; appelez (generate-all-aux) (update-current-buffer) directement pour remplir la table des matières / la bibliographie, exportez à nouveau, puis (buffer-pretend-modified u) (buffer-save u) pour stocker <\references>. Un nouveau fichier nécessite deux passages de composition, dans des processus séparés, chacun avec une exportation PDF réelle avant que toutes les références ne soient résolues (scripts/latex2tm/typeset.sh). Exportez toujours avec (list :overwrite) comme options : en mode headless, export-buffer-main demande sinon une confirmation pour remplacer un fichier existant, personne ne répond, et l'exportation est silencieusement ignorée (mgubi/texmacs#807). tm-typeset et tm-html dans dump.scm font cela.
  • Présentations (screens) : exportent uniquement l'écran actuel. Pour une vérification visuelle, construisez une copie de prévisualisation avec les écrans aplatis en pages séparées par new-page* (scripts/latex2tm/preview_slides.py) ; livrez la version écrans.
  • Vérifiez la sortie avec mutool draw -r 60 -o p%d.png file.pdf et magick montage … -tile 4x1 -geometry +4+4 ; le texte avec mutool draw -F txt -o - file.pdf (comptez ? pour les références non résolues).

Exportation HTML

Faites la personnalisation HTML à l'intérieur de TeXmacs : les packages de style (ou un plugin) définissent les variables de l'exportateur et donnent des rendus tmhtml- des macros ; un site web est construit en exportant un répertoire (tmweb-convert-dir) avec TEXMACS_HOME_PATH pointant vers le dossier du plugin du site et (style-clear-cache). Ne post-traitez pas le HTML généré avec des scripts.

Rassemblez les correctifs génériques dans un seul plugin (ci-dessous appelé max-html, lié comme ~/.TeXmacs/plugins/max-html), et conservez les paramètres spécifiques au document dans le package du document. Un tel plugin contient :

  • progs/max-html/fixes.scm, chargé au démarrage, corrige l'exportation MathJax. Les étiquettes dans les formules obtiennent des ancres (#617), \ring est écrit \mathring (#607) et equations-base est écrit aligned (#611). Il remplace la liaison de tmhtml-mathjax-formula* dans (convert html tmhtml) (module-variable + variable-set! ; les aides internes comme cork->html via module-ref) et étend latex-mathjax avec tm-define … (former x).

  • Le package max-html (articles) donne des théorèmes encadrés, des étiquettes de liste et le panneau latéral de contenu div.max-toc. Le package max-html-slides donne le visualiseur de diapositives et tmhtml-mytitle/myframed/myframed-2.

  • resources/ contient max-html.css/js et max-html-slides.css/js, à copier à côté des pages. Les packages de document <use-package|max-html> et assignent à nouveau le tuple complet html-extra-css (fichier du plugin en premier) : merge ne fonctionne pas, car l'exportateur lit la variable non évaluée. Les polices sont des variables CSS (--max-text-font, --max-slide-font).

  • Les correctifs génériques pour l'exportation HTML vont dans le plugin. Les éléments spécifiques au document (polices, favicon, macros de présentation) vont dans le package du document.

  • Exportation : (tm-html in out mathjax?) dans scripts/latex2tm/dump.scm (préférences texmacs->html:mathjax|css|images, puis (export-buffer-main u (string->url "x.html") "html" (list))). Exportez le .tm composé (les <\references> stockées donnent les numéros). Les liens doc.tm#label deviennent doc.html#label ; les images deviennent <base>-N.png à côté de la page ; MathJax 3 provient de jsdelivr.

  • Variables de style lues par l'exportateur (définissez-les dans un package de style) : html-css (remplace le css en ligne par défaut), html-extra-css (tuple de feuilles de style supplémentaires, css par défaut conservé), html-extra-javascript-src (tuple, différé), html-extra-javascript, html-head-javascript(-src), html-head-favicon, html-title, html-doc-title, html-site-version.

  • Rendus HTML des macros : définissez tmhtml-NAME à côté de NAME. L'exportateur l'utilise à la place de NAME. Aides de balisage pour cela : html-div-class|class|body (bloc), html-class|class|body (span en ligne), html-style, html-div-style, html-attr, html-tag, html-javascript. Cela ne fonctionne que pour les macros définies dans un package de style : les macros assignées dans le hide-preamble du document sont développées avant l'exportation et leurs variantes tmhtml- sont ignorées. Mettez donc les macros de présentation dans un package.

  • Un package foo.ts à côté du document est trouvé lorsque le tuple de style liste foo. Après avoir modifié un package, appelez (style-clear-cache) (TeXmacs met en cache les environnements de style dans ~/.TeXmacs/system/cache), sinon les anciennes définitions sont utilisées.

  • Table des matières (et autres listes générées) : les entrées sont écrites dans les données auxiliaires déjà développées (write évalue son argument), donc les wrappers autour de toc-main-*/toc-1…5 disparaissent et leurs variantes tmhtml- ne sont jamais vues. Seule la macro externe table-of-contents peut avoir un rendu tmhtml-. Marqueurs qui survivent au développement et à l'exportation : <b> (sections en gras), <with|font-size|…> → <font style=…>, font-shape → <i>/petites capitales, color → <font color> ; l'indentation par-left est perdue. Chaque entrée se termine par <a href="#auto-N">page</a>. Recette du panneau latéral (package du plugin max-html) : tmhtml-table-of-contents → div.max-toc fixe à gauche ; masquez et étirez le lien de page avec .max-toc p a[href^="#auto-"] {position:absolute; inset:0; font-size:0} (sélectionnez par href : un eqref dans un titre est aussi un lien) ; marquez les entrées de niveau paragraphe en redéfinissant toc-3…5 avec un <with|font-size|0.92|…> imbriqué et sélectionnez p:has(> font). Régénérez la TDM (deux passages de composition) après avoir modifié les macros toc-*.

  • Mise en évidence de la section actuelle dans le panneau : nécessite JavaScript : max-html.js (plugin), attaché avec html-extra-javascript-src dans le package ; il mappe chaque lien #auto-N de l'entrée au titre avec cet id, marque le dernier titre au-dessus de 25 % de la fenêtre (p.toc-current, et son parent en gras p.toc-current-section) et fait défiler le panneau pour le garder visible.

  • Théorèmes encadrés (articles web de Joris van der Hoeven, par exemple texmacs.org/joris/fftcomp ; le modèle est styles/article/texmacs/tmarticle.ts dans TeXmacs) : définissez tmhtml-render-theorem → <html-div-class|theorem|<render-enunciation|…>> et tmhtml-render-enunciation avec <html-class|enunciation-name|which> ; théorème, proposition, lemme, corollaire et définition utilisent render-theorem, tandis que les remarques et les preuves utilisent render-remark. Le css de Joris (texmacs.org/css/theme-dark-colored.css) est .theorem {border: 1px solid; border-left: 1em solid; padding: 0 1em} ; une couleur atténuée et une barre de .5em fonctionnent également bien (max-html.css). Ceci est uniquement HTML ; le PDF est inchangé. Couleurs (également comme dans le thème de Joris) : h1…h6, strong, b, dt, .enunciation-name dans un rouge foncé atténué, sortie MathJax via mjx-container {color: …} ; réinitialisez b dans le panneau TDM.

  • L'exportation HTML transforme chaque enumerate-alpha|Alpha|roman en une simple <ol> (étiquettes décimales). Correctif : tmhtml-enumerate-alpha → <html-div-class|enum-alpha|<enumerate|…>> plus .enum-alpha > ol > li::marker {content: "(" counter(list-item, lower-alpha) ") "}.

  • MathJax : le convertisseur écrit l'accent anneau <abovering> sous la forme \ring{…} (package LaTeX accents), qui manque à MathJax (mgubi/texmacs#607). Corrigé par le plugin. Une alternative au niveau de la page est une configuration MathJax en ligne dans html-extra-javascript (elle s'exécute avant la <script> MathJax) : window.MathJax = {tex: {macros: {ring: [String.fromCharCode(92) + 'mathring{#1}', 1]}}}.

  • MathJax : aligned dans une equation est pré-développé par l'exportateur HTML en equations-base et atteint MathJax sous la forme \begin{equationsbase} (mgubi/texmacs#611). Corrigé par le plugin ; l'alternative au niveau de la page est environments: {equationsbase: […aligned…]} dans cette configuration.

  • Vérifiez toutes les formules d'une exportation avec scripts/mathjax-check/ : npm install [email protected] dans un dossier deps/ temporaire, puis python3 extract.py HTMLDIR formulas.json (utilise un analyseur HTML : < brut dans \(t < \infty\)) est du texte, comme dans les navigateurs) et node check.js deps/node_modules formulas.json. Il rend chaque formule sans le package noundefined (qui dans le navigateur montre silencieusement les macros non définies en rouge) et regroupe les erreurs. Il ne voit pas les formules vides (comptez \(\displaystyle \) séparément) ni les liens morts : vérifiez également que chaque href="…#x" interne a un id="x" correspondant.

  • Diapositives : une image avec width=100% réduite par un max-height css reste à gauche de son paragraphe ; centrez-la avec div.toggle img.image {display: block; margin: 0 auto}.

  • Firefox headless : la préférence content-override du mode sombre dans user.js n'a pas pris effet ; pour changer le mode sombre, utilisez export MOZ_ENABLE_WAYLAND=1 et export WAYLAND_DISPLAY=wayland-0.

  • Pour les grandes exportations HTML, utilisez node pour les opérations asynchrones (par exemple, mkdir -p output && node scripts/batch-html.mjs).

Skills associés