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 depuishttps://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
.tmest 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 Pythonencoding='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 avecprintfou 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-undumpdansdump.scm) ; ou écrivez le fragment, faites untm-dumpet assemblez l'arbre. Lorsque vous écrivez à la main, vérifiez le résultat avant de l'utiliser : faites untm-dumpet 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 (voirscripts/latex2tm/run.sh) ; tuez uniquement ce PID — ne faites jamaispkill 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-filene redirige pas dans le Guile de TeXmacs. Guile écrit les caractères de contrôle sous forme d'échappements\xHH(gérés parscripts/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-maindemande sinon une confirmation pour remplacer un fichier existant, personne ne répond, et l'exportation est silencieusement ignorée (mgubi/texmacs#807).tm-typesetettm-htmldansdump.scmfont 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 parnew-page*(scripts/latex2tm/preview_slides.py) ; livrez la version écrans. - Vérifiez la sortie avec
mutool draw -r 60 -o p%d.png file.pdfetmagick montage … -tile 4x1 -geometry +4+4; le texte avecmutool 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),\ringest écrit\mathring(#607) etequations-baseest écritaligned(#611). Il remplace la liaison detmhtml-mathjax-formula*dans(convert html tmhtml)(module-variable+variable-set!; les aides internes commecork->htmlviamodule-ref) et étendlatex-mathjaxavectm-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 contenudiv.max-toc. Le packagemax-html-slidesdonne le visualiseur de diapositives ettmhtml-mytitle/myframed/myframed-2. -
resources/contientmax-html.css/jsetmax-html-slides.css/js, à copier à côté des pages. Les packages de document<use-package|max-html>et assignent à nouveau le tuple complethtml-extra-css(fichier du plugin en premier) :mergene 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?)dansscripts/latex2tm/dump.scm(préférencestexmacs->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 liensdoc.tm#labeldeviennentdoc.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é deNAME. L'exportateur l'utilise à la place deNAME. 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 lehide-preambledu document sont développées avant l'exportation et leurs variantestmhtml-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 listefoo. 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 detoc-main-*/toc-1…5disparaissent et leurs variantestmhtml-ne sont jamais vues. Seule la macro externetable-of-contentspeut avoir un rendutmhtml-. 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'indentationpar-leftest perdue. Chaque entrée se termine par<a href="#auto-N">page</a>. Recette du panneau latéral (package du pluginmax-html) :tmhtml-table-of-contents→div.max-tocfixe à 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 : uneqrefdans un titre est aussi un lien) ; marquez les entrées de niveau paragraphe en redéfinissanttoc-3…5avec un<with|font-size|0.92|…>imbriqué et sélectionnezp:has(> font). Régénérez la TDM (deux passages de composition) après avoir modifié les macrostoc-*. -
Mise en évidence de la section actuelle dans le panneau : nécessite JavaScript :
max-html.js(plugin), attaché avechtml-extra-javascript-srcdans le package ; il mappe chaque lien#auto-Nde 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 grasp.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.tsdans TeXmacs) : définisseztmhtml-render-theorem→<html-div-class|theorem|<render-enunciation|…>>ettmhtml-render-enunciationavec<html-class|enunciation-name|which>; théorème, proposition, lemme, corollaire et définition utilisentrender-theorem, tandis que les remarques et les preuves utilisentrender-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-namedans un rouge foncé atténué, sortie MathJax viamjx-container {color: …}; réinitialisezbdans le panneau TDM. -
L'exportation HTML transforme chaque
enumerate-alpha|Alpha|romanen 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 danshtml-extra-javascript(elle s'exécute avant la<script>MathJax) :window.MathJax = {tex: {macros: {ring: [String.fromCharCode(92) + 'mathring{#1}', 1]}}}. -
MathJax :
aligneddans uneequationest pré-développé par l'exportateur HTML enequations-baseet atteint MathJax sous la forme\begin{equationsbase}(mgubi/texmacs#611). Corrigé par le plugin ; l'alternative au niveau de la page estenvironments: {equationsbase: […aligned…]}dans cette configuration. -
Vérifiez toutes les formules d'une exportation avec
scripts/mathjax-check/:npm install [email protected]dans un dossierdeps/temporaire, puispython3 extract.py HTMLDIR formulas.json(utilise un analyseur HTML :<brut dans\(t < \infty\))est du texte, comme dans les navigateurs) etnode check.js deps/node_modules formulas.json. Il rend chaque formule sans le packagenoundefined(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 chaquehref="…#x"interne a unid="x"correspondant. -
Diapositives : une image avec
width=100%réduite par unmax-heightcss reste à gauche de son paragraphe ; centrez-la avecdiv.toggle img.image {display: block; margin: 0 auto}. -
Firefox headless : la préférence
content-overridedu mode sombre dansuser.jsn'a pas pris effet ; pour changer le mode sombre, utilisezexport MOZ_ENABLE_WAYLAND=1etexport WAYLAND_DISPLAY=wayland-0. -
Pour les grandes exportations HTML, utilisez
nodepour les opérations asynchrones (par exemple,mkdir -p output && node scripts/batch-html.mjs).