GitHub Markdown Math: Reglas de Representación y Soluciones Alternativas
GitHub renderiza matemáticas en Markdown en dos etapas:
- Lado del servidor (
cmark-gfm+ sanitizador de matemáticas): encuentra los límites de$ ... $y$$ ... $$, aplica el desescapado de barras invertidas de CommonMark a la puntuación ASCII y rechaza macros LaTeX no permitidas antes de emitir etiquetas<math-renderer>. - Lado del cliente (
<math-renderer>+MathJax.tex2mml): convierte TeX a MathML y lo inyecta en la página para el diseño nativo del navegador MathML Core.
Ambas etapas tienen errores que rompen LaTeX ordinario. Las reglas siguientes son soluciones para esos errores.
Cuándo usar esta habilidad
- Al escribir o editar matemáticas en un archivo
.mdque se leerá en GitHub. - Al corregir ecuaciones que se renderizan aplastadas, rojas o como texto
$$sin procesar en GitHub. - No es necesaria para archivos que solo pasan por LaTeX, Pandoc, Jupyter, MkDocs o VS Code. Si un archivo se lee en ambos lugares, las sustituciones siguientes son TeX/MathJax ordinarios, por lo que aún se renderizan en otros sistemas.
Flujo de trabajo
- Mientras escribes, sigue las reglas 1 a 4 a continuación.
- Antes de confirmar, ejecuta el script de verificación en los archivos Markdown modificados (consulta Script). Ejecútalo sin
--checkpara corregirlos en su lugar. - Revisa el resultado con
git diff. El script se basa en expresiones regulares, por lo que trata su salida como un borrador. La renderización no se puede verificar localmente; si tienes dudas, previsualiza en GitHub.
Referencia rápida
| En lugar de | Escribe | Por qué |
|---|---|---|
\tag{2.1} | \qquad\text{(2.1)} | \tag aplasta la ecuación en una columna vertical |
\operatorname{Foo} | \mathrm{Foo} | operatorname está bloqueado por el sanitizador |
\mathrm{Im} D_t | \mathrm{Im}\thinspace D_t | restaura el espaciado de operador |
\hbox{...}, {\rm ...} | \text{...}, {\mathrm{...}} | las macros de plain-TeX están bloqueadas |
\{, \} | \lbrace, \rbrace | CommonMark convierte \{ en { |
\\ en una sola línea | \cr | CommonMark convierte \\ en \ |
\, | \thinspace | CommonMark convierte \, en , |
\,,\, | , | se renderizaría como una doble coma |
q_* (varios * en un bloque) | q_\ast | los pares de * se convierten en énfasis de Markdown |
1. Nunca uses \tag{...} (evita el aplastamiento vertical de 1 carácter)
- Error:
MathJax.tex2mmlserializa cualquier ecuación que contenga\tag{2.1}como<mtable displaystyle="true"><mlabeledtr><mtd>.... El navegador MathML Core eliminó<mlabeledtr>, por lo que Chromium/Blink y Firefox no lo tratan como una fila de tabla y comprimen la ecuación en una columna de 1 carácter de ancho. - Solución: pon
\qquad\text{(2.1)}al final de la ecuación display en su lugar. Para una prima en la etiqueta, usa el carácter Unicode′dentro de\text{(3.3′)}en lugar de un$\tag{3.3$'$}$anidado.
<!-- Roto en GitHub (aplastado en una columna vertical) -->
$$
\partial_t \mathcal{Q} + \partial_x \mathcal{J} = 0 \tag{2.1}
$$
<!-- Funciona en GitHub -->
$$
\partial_t \mathcal{Q} + \partial_x \mathcal{J} = 0 \qquad\text{(2.1)}
$$
2. Nunca uses \operatorname{...}, \hbox{...} o {\rm ...} (evita errores de macros no permitidas)
- Error: el sanitizador del lado del servidor de GitHub bloquea
\operatornamey\operatorname*con el mensajeThe following macros are not allowed: operatorname. - Solución:
- Reemplaza
\operatorname{Foo}con\mathrm{Foo}. Cuando va seguido directamente de una letra o una macro con barra invertida (por ejemplo,\operatorname{Im} D_to\operatorname{pr} v), añade\thinspace(\mathrm{Im}\thinspace D_t) para mantener el espaciado de operador. - Reemplaza el plain-TeX
\hbox{...}con\text{...}, y{\rm ...}con{\mathrm{...}}.
- Reemplaza
<!-- Roto en GitHub ("The following macros are not allowed: operatorname") -->
$\operatorname{diag}(1, -1)$ and $\operatorname{Im} D_t$
<!-- Funciona en GitHub -->
$\mathrm{diag}(1, -1)$ and $\mathrm{Im}\thinspace D_t$
3. Haz que los delimitadores, espacios y saltos de línea sobrevivan al desescapado de CommonMark
- Error: antes de que las matemáticas lleguen a
<math-renderer>, el analizador Markdown de GitHub aplica el desescapado de puntuación ASCII de CommonMark dentro de$ ... $y$$ ... $$:\{se convierte en{y\}se convierte en}. Esto provocaMissing or unrecognized delimiter for \leften\left\{, y elimina silenciosamente las llaves de los corchetes de Poisson\{F, G\}.\\(cuando no va seguido de un salto de línea) se convierte en\. Esto rompe matrices de una sola línea y casos como\begin{pmatrix} 0 & 1 \\ -1 & 0 \end{pmatrix}convirtiéndolos en\-1, dando errores rojos de macro no definida.\,,\,se convierte en,,(una doble coma) y\,se convierte en,(una coma literal antes dedx).- Los pares de
*dentro de un bloque matemático (por ejemploU_+(z - 2q_*), \quad z = w + Dq_*) pueden interpretarse como énfasis Markdown<em>.
- Solución:
- Usa
\lbracey\rbraceen lugar de\{y\}(añade un espacio si le sigue una letra:\lbrace F, G\rbrace). - Usa
\cren lugar de\\para saltos de fila en matrices y entornos de una sola línea, o pon un salto de línea inmediatamente después de\\dentro de bloques$$...$$multilínea. - Usa
\thinspaceen lugar de\,(con un espacio final antes de letras:dt\thinspace dx), y reemplaza\,,\,con,. - Usa
\ast(q_\ast) en lugar de*(q_*) cuando una ecuación contenga varios asteriscos.
- Usa
<!-- Roto en GitHub -->
Inline Poisson bracket $\{F, G\} = 0$, set $\left\{ x : x > 0 \right\}$, integral $\int dx\,dy$, matrix $\bigl(\begin{smallmatrix} 0 & 1 \\ -1 & 0 \end{smallmatrix}\bigr)$.
<!-- Funciona en GitHub -->
Inline Poisson bracket $\lbrace F, G\rbrace = 0$, set $\left\lbrace x : x > 0 \right\rbrace$, integral $\int dx\thinspace dy$, matrix $\bigl(\begin{smallmatrix} 0 & 1 \cr -1 & 0 \end{smallmatrix}\bigr)$.
4. Formatea los límites de bloques $$ ... $$ para cmark-gfm
- Error: cuando una ecuación contiene varios caracteres
_o*,cmark-gfmno reconoce los bloques$$ ... $$en tres situaciones, dejando texto$$sin procesar y poniendo en cursiva el texto entre guiones bajos:- Bloques
$$ ... $$de nivel superior sin líneas en blanco antes y después. - Bloques
$$\begin{aligned} ... \end{aligned}$$multilínea donde$$está en la misma línea que\begin{aligned}en lugar de en su propia línea. - Bloques
$$...$$multilínea indentados dentro de elementos de lista (1. ...o- ...) o blockquotes (> ...).
- Bloques
- Solución:
-
Matemáticas display de nivel superior: pon el
$$de apertura y cierre en sus propias líneas en la columna 0, con una línea en blanco antes y después:$$ \begin{aligned} a &= b + c, \\ d &= e + f. \end{aligned} \qquad\text{(1.1)} $$ -
Matemáticas display dentro de elementos de lista o blockquotes: mantén toda la ecuación en una sola línea como
$$\displaystyle ...$$(usa\crpara saltos de fila dentro de entornos), rodeada de líneas en blanco:1. Dentro de un elemento de lista numerada: $$\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 aplica las reglas anteriores a archivos Markdown. Reescribe solo el contenido de $...$ y $$...$$, deja intactos el código encerrado en bloques de código y en línea, no toca archivos sin matemáticas y es idempotente. Ejecútalo desde cualquier lugar:
# Verificar sin modificar (termina con 1 si algún archivo necesita cambios; utilizable en CI o un hook pre-commit)
python3 ~/.claude/skills/github-markdown-math/scripts/fix_github_math.py --check ruta/a/archivo.md
# Corregir en su lugar
python3 ~/.claude/skills/github-markdown-math/scripts/fix_github_math.py ruta/a/archivo.md
Si esta habilidad está instalada en un proyecto en su lugar (.claude/skills/github-markdown-math/), usa esa ruta.
Limitaciones
- Se basa en expresiones regulares, por lo que debes revisar el diff. Tampoco puede confirmar que GitHub renderice el resultado correctamente.
\operatorname{...}se convierte solo cuando su argumento no tiene llaves anidadas.\thinspacese añade después de\mathrm{...}solo para una lista fija de nombres (Im,im,pr,graph,Div,ker,dim,deg,span,spec,End,Re,tr,rank); agrégalo manualmente para otros.- De los asteriscos, solo
q_*se reescribe aq_\ast; verifica otros*manualmente (regla 3). - Las ecuaciones en blockquote se manejan a un nivel de profundidad (
>), no anidadas (> >). - Una línea con dos signos de moneda (
$5 and $10) puede interpretarse como matemáticas en línea. Esto es inofensivo a menos que el texto entre ellos contenga una secuencia de barra invertida que las reglas reescriban. - Las reglas describen el comportamiento observado de GitHub. Si GitHub corrige uno de estos errores, la solución correspondiente se vuelve innecesaria.