GitHub Markdown Math : Règles de rendu et solutions de contournement
GitHub rend les mathématiques Markdown en deux étapes :
- Côté serveur (
cmark-gfm+ sanitizer mathématique) : trouve les délimiteurs$ ... $et$$ ... $$, applique le déséchappement des backslashs CommonMark pour la ponctuation ASCII, et rejette les macros LaTeX interdites avant d'émettre des balises<math-renderer>. - Côté client (
<math-renderer>+MathJax.tex2mml) : convertit le TeX en MathML et l'injecte dans la page pour le rendu natif MathML Core du navigateur.
Les deux étapes contiennent des bugs qui cassent le LaTeX ordinaire. Les règles ci-dessous sont des solutions de contournement pour ces bugs.
Quand utiliser cette compétence
- Rédiger ou modifier des mathématiques dans un fichier
.mdqui sera lu sur GitHub. - Corriger des équations qui s'affichent écrasées, en rouge, ou sous forme de texte
$$brut sur GitHub. - Pas nécessaire pour les fichiers qui passent uniquement par LaTeX, Pandoc, Jupyter, MkDocs ou VS Code. Si un fichier est lu dans les deux environnements, les remplacements ci-dessous sont du TeX/MathJax ordinaire, donc ils s'affichent correctement ailleurs.
Flux de travail
- Pendant la rédaction, suivez les règles 1 à 4 ci-dessous.
- Avant de valider, exécutez le script de vérification sur les fichiers Markdown modifiés (voir Script). Exécutez-le sans
--checkpour les corriger directement. - Vérifiez le résultat avec
git diff. Le script est basé sur des regex, traitez donc sa sortie comme un brouillon. Le rendu ne peut pas être vérifié localement ; en cas de doute, prévisualisez sur GitHub.
Référence rapide
| Au lieu de | Écrivez | Pourquoi |
|---|---|---|
\tag{2.1} | \qquad\text{(2.1)} | \tag écrase l'équation dans une bande verticale |
\operatorname{Foo} | \mathrm{Foo} | operatorname est bloqué par le sanitizer |
\mathrm{Im} D_t | \mathrm{Im}\thinspace D_t | restaure l'espacement des opérateurs |
\hbox{...}, {\rm ...} | \text{...}, {\mathrm{...}} | les macros plain-TeX sont bloquées |
\{, \} | \lbrace, \rbrace | CommonMark transforme \{ en { |
\\ sur une seule ligne | \cr | CommonMark transforme \\ en \ |
\, | \thinspace | CommonMark transforme \, en , |
\,, | , | rendrait une double virgule |
q_* (plusieurs * dans un bloc) | q_\ast | les * appariés deviennent de l'emphase Markdown |
1. N'utilisez jamais \tag{...} (empêche l'écrasement vertical sur 1 caractère)
- Bug :
MathJax.tex2mmlsérialise toute équation contenant\tag{2.1}sous la forme<mtable displaystyle="true"><mlabeledtr><mtd>.... Le navigateur MathML Core a supprimé<mlabeledtr>, donc Chromium/Blink et Firefox ne le traitent pas comme une ligne de tableau et compriment l'équation dans une colonne d'un seul caractère de large. - Solution : placez
\qquad\text{(2.1)}à la fin de l'équation d'affichage à la place. Pour un prime dans l'étiquette, utilisez le′Unicode dans\text{(3.3′)}plutôt qu'un\tag{3.3$'$}$imbriqué.
<!-- Cassé sur GitHub (écrasé dans une colonne verticale) -->
$$
\partial_t \mathcal{Q} + \partial_x \mathcal{J} = 0 \tag{2.1}
$$
<!-- Fonctionne sur GitHub -->
$$
\partial_t \mathcal{Q} + \partial_x \mathcal{J} = 0 \qquad\text{(2.1)}
$$
2. N'utilisez jamais \operatorname{...}, \hbox{...} ou {\rm ...} (empêche les erreurs de macros interdites)
- Bug : le sanitizer côté serveur de GitHub bloque
\operatornameet\operatorname*avec le messageThe following macros are not allowed: operatorname. - Solution :
- Remplacez
\operatorname{Foo}par\mathrm{Foo}. Lorsqu'il est suivi directement par une lettre ou une macro backslash (par exemple\operatorname{Im} D_tou\operatorname{pr} v), ajoutez\thinspace(\mathrm{Im}\thinspace D_t) pour conserver l'espacement des opérateurs. - Remplacez le plain-TeX
\hbox{...}par\text{...}, et{\rm ...}par{\mathrm{...}}.
- Remplacez
<!-- Cassé sur GitHub ("The following macros are not allowed: operatorname") -->
$\operatorname{diag}(1, -1)$ and $\operatorname{Im} D_t$
<!-- Fonctionne sur GitHub -->
$\mathrm{diag}(1, -1)$ and $\mathrm{Im}\thinspace D_t$
3. Faites en sorte que les délimiteurs, l'espacement et les sauts de ligne survivent au déséchappement CommonMark
- Bug : avant que les mathématiques n'atteignent
<math-renderer>, l'analyseur Markdown de GitHub applique le déséchappement des ponctuations ASCII CommonMark à l'intérieur de$ ... $et$$ ... $$:\{devient{et\}devient}. Cela provoque une erreurMissing or unrecognized delimiter for \leftsur\left\{, et supprime silencieusement les accolades des crochets de Poisson\{F, G\}.\\(lorsqu'il n'est pas suivi d'un saut de ligne) devient\. Cela casse les matrices et cas sur une seule ligne comme\begin{pmatrix} 0 & 1 \\ -1 & 0 \end{pmatrix}en\-1, donnant des erreurs rouges de macros non définies.\,,devient,,(une double virgule) et\,devient,(une virgule littérale avantdx).- Les
*appariés à l'intérieur d'un bloc mathématique (par exempleU_+(z - 2q_*), \quad z = w + Dq_*) peuvent être analysés comme de l'emphase Markdown<em>.
- Solution :
- Utilisez
\lbraceet\rbraceau lieu de\{et\}(ajoutez un espace si une lettre suit :\lbrace F, G\rbrace). - Utilisez
\crau lieu de\\pour les sauts de ligne dans les matrices et environnements sur une seule ligne, ou placez un saut de ligne immédiatement après\\dans les blocs multi-lignes$$...$$. - Utilisez
\thinspaceau lieu de\,(avec un espace final avant les lettres :dt\thinspace dx), et remplacez\,,par,. - Utilisez
\ast(q_\ast) au lieu de*(q_*) lorsqu'une équation contient plusieurs astérisques.
- Utilisez
<!-- Cassé sur GitHub -->
Crochet de Poisson en ligne $\{F, G\} = 0$, ensemble $\left\{ x : x > 0 \right\}$, intégrale $\int dx\,dy$, matrice $\bigl(\begin{smallmatrix} 0 & 1 \\ -1 & 0 \end{smallmatrix}\bigr)$.
<!-- Fonctionne sur GitHub -->
Crochet de Poisson en ligne $\lbrace F, G\rbrace = 0$, ensemble $\left\lbrace x : x > 0 \right\rbrace$, intégrale $\int dx\thinspace dy$, matrice $\bigl(\begin{smallmatrix} 0 & 1 \cr -1 & 0 \end{smallmatrix}\bigr)$.
4. Formatez les limites des blocs $$ ... $$ pour cmark-gfm
- Bug : lorsqu'une équation contient plusieurs caractères
_ou*,cmark-gfmne parvient pas à reconnaître les blocs$$ ... $$dans trois situations, laissant du texte$$brut et mettant en italique le texte entre underscores :- Blocs
$$ ... $$de premier niveau sans lignes vides avant et après. - Blocs multi-lignes
$$\begin{aligned} ... \end{aligned}$$où$$se trouve sur la même ligne que\begin{aligned}au lieu d'être sur sa propre ligne. - Blocs multi-lignes
$$...$$indentés à l'intérieur d'éléments de liste (1. ...ou- ...) ou de blockquotes (> ...).
- Blocs
- Solution :
-
Mathématiques d'affichage de premier niveau : placez les
$$ouvrants et fermants sur leurs propres lignes à la colonne 0, avec une ligne vide avant et après :$$ \begin{aligned} a &= b + c, \\ d &= e + f. \end{aligned} \qquad\text{(1.1)} $$ -
Mathématiques d'affichage dans des éléments de liste ou des blockquotes : gardez toute l'équation sur une seule ligne sous la forme
$$\displaystyle ...$$(utilisez\crpour les sauts de ligne dans les environnements), entourée de lignes vides :1. Dans un élément de liste numérotée : $$\displaystyle S_d = \int_{\mathbb{R}} dt\thinspace \mathcal{L}_d(\phi_t, \psi_t) \qquad\text{(1.2)}$$
-
Script
scripts/fix_github_math.py applique les règles ci-dessus aux fichiers Markdown. Il ne réécrit que le contenu de $...$ et $$...$$, laisse les blocs de code et le code en ligne intacts, ne touche pas aux fichiers sans mathématiques, et est idempotent. Exécutez-le depuis n'importe où :
# Vérifier sans modifier (sort avec le code 1 si un fichier nécessite des modifications ; utilisable dans CI ou un hook pre-commit)
python3 ~/.claude/skills/github-markdown-math/scripts/fix_github_math.py --check chemin/vers/fichier.md
# Corriger sur place
python3 ~/.claude/skills/github-markdown-math/scripts/fix_github_math.py chemin/vers/fichier.md
Si cette compétence est installée dans un projet à la place (.claude/skills/github-markdown-math/), utilisez ce chemin.
Limitations
- Il est basé sur des regex, donc vérifiez le diff. Il ne peut pas non plus confirmer que GitHub rend le résultat correctement.
\operatorname{...}n'est converti que lorsque son argument n'a pas d'accolades imbriquées.\thinspacen'est ajouté après\mathrm{...}que pour une liste fixe de noms (Im,im,pr,graph,Div,ker,dim,deg,span,spec,End,Re,tr,rank) ; ajoutez-le manuellement pour les autres.- Parmi les astérisques, seul
q_*est réécrit enq_\ast; vérifiez les autres*manuellement (règle 3). - Les équations dans les blockquotes sont traitées à un niveau de profondeur (
>), pas imbriquées (> >). - Une ligne avec deux signes de devise (
$5 and $10) peut être lue comme une mathématique en ligne. Cela est inoffensif sauf si le texte entre eux contient une séquence de backslash que les règles réécrivent. - Les règles décrivent le comportement de GitHub tel qu'observé. Si GitHub corrige l'un de ces bugs, la solution de contournement correspondante devient inutile.