Las listas de tareas en Markdown y qué se renderiza de verdad en cada sitio
Publicado el 2/7/2025 · 12 min de lectura · Herramientas de texto e idioma
Daniel Okonkwo — Desarrollador front-end y redactor de Tecnología en OneKitly
Rendimiento web · Formatos de archivo
Verificado con 4 fuentes
Una lista de tareas en Markdown — un elemento de lista que empieza por [ ] o [x] — no forma parte de CommonMark. Buscamos en la especificación CommonMark 0.31.2 del 28 de enero de 2024: las expresiones «task list» y «checkbox» aparecen cero veces. Las listas de tareas están definidas en la especificación GitHub Flavored Markdown 0.29-gfm del 6 de abril de 2019, sección 5.3, como extensión. Esa es toda la explicación de que el mismo fichero muestre casillas en GitHub y corchetes literales en otros sitios. Pasamos una línea, «- [ ] comprar leche», por cuatro renderizadores: solo el de sabor GitHub produjo un elemento input de tipo checkbox; la implementación de referencia de CommonMark y otras dos configuraciones produjeron un elemento de lista con el texto literal [ ] comprar leche. La regla del marcador es exacta y poco indulgente: una serie opcional de espacios, un corchete de apertura, o bien un espacio o bien la letra x en cualquier caja, un corchete de cierre y luego al menos un espacio antes del contenido. «- [x]comprar» sin espacio sale como texto en todas partes, «- []» sale como texto y «- [ ]» con dos espacios también. La misma prudencia vale para las tablas, el tachado y los enlaces automáticos, también extensiones, y para las notas al pie, que no están en ninguna de las dos especificaciones.
Las listas de tareas no están en CommonMark. Son una extensión de GitHub Flavored Markdown, y por eso el mismo fichero muestra casillas en un sitio y corchetes literales en otro. La regla exacta del marcador, qué hace el anidamiento y una tabla de qué es CommonMark, qué es GFM y qué no es ninguno — comprobado contra ambas especificaciones y cuatro renderizadores.
Una línea, cuatro renderizadores, dos documentos distintos
Tomamos una sola línea — un guion, un espacio, un par de corchetes vacío, un espacio y algo de texto — y la renderizamos de cuatro maneras. Con el análisis de sabor GitHub activado se convierte en un elemento de lista con un elemento input de tipo checkbox, deshabilitado. Con la misma biblioteca y el sabor desactivado, con la implementación de referencia de CommonMark y con una tercera biblioteca en su configuración por defecto, se convierte en un elemento de lista con los caracteres [ ] seguidos del texto. Nada falló. Cuatro renderizadores correctos produjeron dos documentos distintos a partir de un mismo fichero.
La razón está documentada, no es misteriosa. Buscamos «task list» y «checkbox» en la especificación CommonMark 0.31.2 del 28 de enero de 2024: ambas aparecen cero veces. La especificación GitHub Flavored Markdown 0.29-gfm del 6 de abril de 2019 tiene una sección 5.3 titulada «Task list items (extension)». La palabra extensión hace todo el trabajo en ese título: GFM es CommonMark más cinco añadidos con nombre, y un renderizador que solo implementa CommonMark no está roto cuando imprime tus casillas como corchetes. Es correcto.
La regla del marcador, carácter a carácter
La sección 5.3 de GFM define un elemento de lista de tareas como un elemento cuyo primer bloque es un párrafo que empieza por un marcador de lista de tareas seguido de al menos un espacio antes de cualquier otro contenido. El marcador es un número opcional de espacios, un corchete de apertura, o bien un espacio o bien la letra x en minúscula o mayúscula, y un corchete de cierre. Cada palabra de esa frase soporta peso, y los fallos son silenciosos: ejecutamos cada violación y todas salieron como texto ordinario en los cuatro renderizadores.
Omite el espacio tras el corchete de cierre y no pasa nada: «- [x]comprar leche» es texto. Pon dos espacios entre los corchetes y no pasa nada: el marcador admite exactamente un carácter. Deja los corchetes vacíos y no pasa nada. Usa cualquier letra que no sea x y no pasa nada. Aparta el marcador del principio del párrafo — «- comprar [ ] leche» — y no pasa nada. Quita la lista y «[ ] comprar leche» es un párrafo. Lo que sí funciona es más generoso de lo que se cree: la letra puede ser una X mayúscula, la viñeta puede ser un guion, un asterisco o un más, la lista puede ser numerada, y un tabulador cuenta como el espacio tras el corchete.
El anidamiento y la regla del primer bloque
Las listas de tareas se anidan libremente, y la especificación lo muestra con un ejemplo resuelto. Ejecutamos un elemento padre con dos hijos sangrados: casilla en el padre, lista anidada dentro del mismo elemento y casilla en cada hijo. Mezclar elementos marcados, sin marcar y viñetas normales en la misma lista también funciona: el elemento normal sigue normal y los marcados se vuelven casillas, que es lo que hace legible una lista de comprobación como un orden del día mixto.
El requisito de que el primer bloque sea un párrafo se incumple con facilidad. Pon una cita en cabeza — «- > [ ] citado» — y ningún renderizador produce casilla, ni siquiera el de sabor GitHub, porque el primer bloque es una cita y el marcador nunca tiene su oportunidad. Añade un segundo párrafo tras el marcado y la casilla sobrevive, colocada antes del primer párrafo, con el segundo siguiendo dentro del mismo elemento. No son rarezas de renderizador: se siguen directamente de la frase de la sección 5.3.
Las extensiones vecinas y una que no está en ninguna especificación
Las tablas son la sección 4.10 de la especificación GFM, también una extensión. Nuestra tabla de barras de tres líneas salió como un elemento table de verdad bajo el análisis de sabor GitHub y bajo los ajustes por defecto de otra biblioteca, y como un único párrafo de barras literales bajo la implementación de referencia de CommonMark. El tachado es la sección 6.5, y es más raro de lo que parece: la especificación permite una o dos virgulillas, así que ~aquí~ va tachado, pero tres o más no, así que ~~~no~~~ queda literal. Una biblioteca probada tachaba con dos virgulillas pero no con una, y emitía un elemento de texto tachado en vez del elemento de texto suprimido que muestra la espec. GFM. Dos renderizadores pueden ambos soportar el tachado y aun así discrepar en la entrada y en la salida.
Los enlaces automáticos vienen en dos formas y solo una es nativa. Una dirección entre ángulos es CommonMark y se convirtió en enlace en todos los renderizadores probados. Una dirección desnuda es la sección 6.9 de GFM, una extensión con sus propias reglas: se inserta el esquema http delante de una dirección www y la puntuación final queda fuera del enlace, así que «Visita www.commonmark.org.» enlaza la dirección y deja el punto fuera. Solo la configuración de sabor GitHub produjo esos enlaces; las demás dejaron el texto tal cual.
Las notas al pie son el caso instructivo, porque no están en ninguna de las dos especificaciones. La palabra footnote aparece exactamente una vez en la espec. de CommonMark y exactamente una vez en la de GFM, en la misma frase histórica de la introducción sobre implementaciones que añadieron convenciones para notas y tablas. Nuestros cuatro renderizadores dejaron [^1] como texto literal y convirtieron la línea de definición en un párrafo huérfano. GitHub sí representa notas al pie, y ahí está la trampa: una función que has visto funcionar no está por eso en el formato.
«Markdown» no es un formato
Dos especificaciones con números de versión distintos y cinco años entre ellas, más un juego de opciones por biblioteca, no son un formato único. Los desacuerdos bajan muy por debajo del nivel de las funciones. Ante un salto de línea duro, dos de nuestros renderizadores emitieron una etiqueta de salto autocerrada y dos la forma HTML5. Ante un elemento script en la fuente, dos lo pasaron tal cual a la salida y uno lo escapó como texto; la espec. GFM dedica una extensión entera, la sección 6.11, a filtrar nueve etiquetas concretas sustituyendo su ángulo de apertura por una entidad. Nada de esto es un error.
La regla práctica que se sigue es corta: escribe para el renderizador al que realmente apuntas, y sabe cuál es. Un README en una forja, un generador de sitios de documentación, un cliente de chat y un constructor de sitios estáticos son cuatro destinos con cuatro conjuntos de funciones, y un documento que se ve bien en uno no ofrece garantía alguna sobre los demás. Si el destino es desconocido, quédate dentro de CommonMark: títulos, énfasis, listas, código, enlaces, enlaces automáticos entre ángulos y citas son iguales en todas partes.
Prueba la ida y vuelta, y cuenta desde la fuente
La prueba más barata de una lista de comprobación es aritmética. Escribimos una lista de sprint anidada de cinco elementos, dos marcados como hechos, los contamos desde la fuente markdown con un patrón que reconoce el marcador al principio de un elemento y salió 2 de 5. Renderizar el mismo documento con análisis de sabor GitHub y contar los elementos input marcados en el HTML también dio 2 de 5. Renderizarlo con la implementación de referencia de CommonMark dio cero elementos input — el documento está intacto, las casillas simplemente nunca fueron parte de ese dialecto.
Ese es el hábito que conviene conservar: cuenta desde la fuente, no desde el renderizado. El fichero markdown es el registro; el HTML es una interpretación suya, y cuál obtengas depende de una versión de biblioteca y de una bandera. Nuestro generador de listas escribe el marcador GFM exactamente como lo especifica la sección 5.3 — viñeta, espacio, corchete, un carácter, corchete, espacio — de modo que el fichero funciona donde la extensión está soportada y degrada a una lista con corchetes legible donde no lo está. Si necesitas que la casilla sobreviva en cualquier sitio, la alternativa honesta es una lista simple con la palabra «hecho».
| Función | ¿En CommonMark 0.31.2? | ¿En la espec. GFM 0.29? | Salida de la implementación de referencia | Salida de markdown-it por defecto |
|---|---|---|---|---|
| Lista de tareas - [ ] / - [x] | No — 0 menciones | Sí — sección 5.3, extensión | [ ] literal en el elemento de lista | [ ] literal en el elemento de lista |
| Tabla con barras | No | Sí — sección 4.10, extensión | Un párrafo de barras literales | Un elemento table de verdad |
| Tachado con dos virgulillas | No | Sí — sección 6.5, extensión | Virgulillas literales | Un elemento tachado, pero s en vez de del |
| Tachado con una virgulilla | No | Sí — una o dos virgulillas | Virgulillas literales | Virgulillas literales — exige dos |
| URL desnuda convertida en enlace | No | Sí — sección 6.9, extensión | Texto plano | Texto plano en las configuraciones probadas |
| Enlace automático entre ángulos | Sí — parte de la especificación base | Sí, heredado | Un enlace de verdad | Un enlace de verdad |
| Nota al pie [^1] | No | No — tampoco en la especificación | [^1] literal y una línea de definición huérfana | [^1] literal y una línea de definición huérfana |
| HTML crudo dejado pasar | Sí, por defecto | Sí, menos nueve etiquetas filtradas | Pasado tal cual | Escapado como texto |
Preguntas frecuentes
- ¿Por qué mis casillas salen como [ ] en vez de casillas?
- Porque el renderizador implementa CommonMark sin las extensiones de GitHub. Las listas de tareas son la sección 5.3 de la espec. GFM y no aparecen en ninguna parte de CommonMark 0.31.2. La segunda posibilidad es un marcador mal formado: el espacio tras el corchete de cierre es obligatorio, entre los corchetes va exactamente un carácter, y el marcador debe abrir el primer párrafo del elemento. Todos esos fallos salen como texto literal sin ningún aviso.
- ¿La x tiene que ser minúscula?
- No. La espec. GFM dice la letra x en minúscula o en mayúscula, y confirmamos que ambas producen una casilla marcada. Ninguna otra letra sirve: una o entre los corchetes salió como texto literal en todos los renderizadores probados. Tampoco puede haber dos caracteres — un marcador con dos espacios entre los corchetes no es un marcador.
- ¿Se pueden anidar las listas de tareas o usarlas en una lista numerada?
- Ambas cosas. La espec. GFM muestra listas de tareas anidadas libremente en un ejemplo resuelto, y nuestra ejecución produjo casilla en el padre y en cada hijo sangrado. Un elemento de lista numerada funciona igual — el marcador va tras el número y el punto. Lo que no funciona es un elemento cuyo primer bloque no sea un párrafo: una cita antes del marcador suprimió la casilla en todos los renderizadores.
- ¿Se pueden usar tablas y tachado en cualquier sitio?
- No. Ambas son extensiones GFM, secciones 4.10 y 6.5, y ninguna está en CommonMark. Nuestra tabla salió como tabla de verdad en dos configuraciones y como párrafo de barras literales en otra. El tachado es peor: la espec. GFM tacha el texto entre una o dos virgulillas pero no tres, mientras que otra biblioteca muy usada exigía dos y producía un elemento HTML distinto para el resultado.
- ¿Las notas al pie forman parte de GitHub Flavored Markdown?
- Según la especificación GFM publicada, no. La palabra footnote aparece en ella exactamente una vez, en una frase histórica de la introducción, y no hay ninguna sección sobre notas. El propio sitio de GitHub las representa igualmente, lo que ilustra bien la diferencia entre una especificación y un producto. Los cuatro renderizadores probados dejaron la llamada como texto literal y la definición como párrafo huérfano.
Artículos que podrían interesarte
Todas las guías →Herramientas relacionadas
Fuentes
- CommonMark — CommonMark Spec, version 0.31.2 (2024-01-28) — the core grammar, which contains no task lists, tables, strikethrough or footnotes
- GitHub — GitHub Flavored Markdown Spec, version 0.29-gfm (2019-04-06) — sections 4.10 Tables, 5.3 Task list items, 6.5 Strikethrough, 6.9 Autolinks, 6.11 Disallowed Raw HTML
- CommonMark — The CommonMark project — reference implementations and the Dingus for testing a document against the core spec
- GitHub Docs — Basic writing and formatting syntax — the features GitHub renders beyond its own published specification, including footnotes
¿Has detectado un error en este artículo?