Ir al contenido
OneKitly

Pegar una tabla en un pull request: qué se rompe y los dos caracteres que lo rompen

Publicado el 29/7/2026 · 15 min de lectura · Herramientas para desarrolladores

Daniel Okonkwo

Daniel OkonkwoDesarrollador front-end y redactor de Tecnología en OneKitly

Rendimiento web · Formatos de archivo

Verificado con 4 fuentes

Ver perfil
En resumen

Una celda de tabla Markdown admite todo menos dos caracteres. La barra vertical cierra la celda, así que hay que escribirla \| — el conversor lo hace por ti: pega USB-C | 2 m y devuelve USB-C \| 2 m, que GitHub muestra como una sola celda. El salto de línea cierra la fila, y para él no existe ningún escape: una celda con un retorno de carro real es imposible en la sintaxis de tablas de GFM, así que la herramienta lo sustituye por la etiqueta HTML <br>, lo único que funciona. Bajo la cabecera va la fila separadora, y es obligatoria: una línea de cabecera sin una hilera de guiones debajo no es una tabla, y GitHub la pinta como un párrafo con barras. Esa fila lleva además la alineación: --- deja el valor por defecto del motor, :-- alinea a la izquierda, --: a la derecha, :-: centra, y un dos puntos en cualquier otro sitio no hace nada. La fila separadora debe tener exactamente tantas celdas como la cabecera, o la tabla no se reconoce en absoluto. Los espacios que cuadran las columnas son puramente cosméticos: | a | b | y |a|b| producen un HTML idéntico byte a byte, de ahí el interruptor «Rellenar columnas» y que se pueda quitar sin riesgo. Un detalle sobre el escape, porque aquí la salida correcta parece equivocada: la contrabarra se escapa antes que la barra. Una celda que ya contiene x \| y sale como x \\\| y, donde \\ es una contrabarra literal y \| una barra literal, así que GitHub muestra la única celda x \| y. Escapar solo la barra daría x \\| y —una contrabarra literal seguida de un corte de celda real— y la columna se partiría. Todo está en el orden, y por eso una tabla Markdown existente puede volver a pasar por el conversor CSV y salir intacta.

Una tabla Markdown prohíbe exactamente dos caracteres dentro de una celda: la barra vertical y el salto de línea. Aquí está qué hace cada uno, cómo los trata un conversor, por qué el escape debe aplicarse en el orden correcto, y por qué el relleno nunca importa.

Dos caracteres, y solo dos

Casi todo atraviesa una celda de tabla Markdown sin daño. Acentos, ideogramas, emoji, acentos graves, asteriscos, corchetes, símbolos de moneda, comillas: nada de eso significa nada para el analizador de tablas, que solo busca dos cosas. La barra vertical termina una celda. El salto de línea termina una fila. Esa es toda la gramática, y cualquier problema que tengas pegando una tabla en un pull request será uno de esos dos caracteres apareciendo donde el analizador no lo esperaba.

La barra vertical tiene escape. Escribe \| y el analizador lee una barra literal en lugar de un límite de columna. El conversor lo aplica por ti: sus propios datos de ejemplo contienen la celda USB-C | 2 m, y pasar el ejemplo da la fila | Câble | USB-C \| 2 m | 9.90 |, que es una fila de tres celdas y no de cuatro. Dale una celda que sea solo una barra y obtienes \| a solas, todavía una celda. Esta parte es sólida, y es la que más fallan las tablas escritas a mano: un comando de shell en una tabla de documentación —ps | grep node— gana una columna en silencio y empuja cada valor un puesto a la derecha, un defecto que un revisor pasa por alto porque la tabla sigue pareciendo una tabla.

El salto de línea no tiene escape, y esta es la parte que conviene interiorizar: una celda con un retorno de carro no es solo incómoda en la sintaxis de tablas de GFM, es imposible. La fila termina en el salto, punto. Hay exactamente dos salidas honestas. Sustituir la ruptura por la etiqueta HTML <br>, que GitHub permite dentro de una celda y que el conversor aplica: un campo CSV entrecomillado que diga «línea uno\nlínea dos» sale como línea uno<br>línea dos en una sola celda. O aceptar que ese contenido no pinta nada en una tabla y ponerlo en una lista o un párrafo debajo. Todo lo demás es ilusión: no hay truco de contrabarra, ni barra doblada, ni marcador de continuación.

La fila separadora no es un adorno

GitHub Flavored Markdown llama a la hilera de guiones bajo la cabecera la fila delimitadora, y la especificación no deja lugar a dudas: está hecha de celdas cuyo único contenido son guiones, con un dos puntos opcional al principio, al final, o en ambos. Sin ella no hay tabla. Una línea de cabecera y tres líneas de datos sin guiones entre medias se muestran como cuatro párrafos de texto con barras dentro, y por eso una tabla que se veía bien en un editor y se rompió en el pull request casi siempre perdió esa línea en un copiar y pegar.

Cuatro formas de celda separadora significan cuatro cosas distintas, y el conversor ofrece las cuatro como ajuste de alineación. Un --- pelado deja la alineación al motor, lo que en la práctica quiere decir a la izquierda en todos los motores que alguien usa. Un dos puntos al principio, :---, fuerza izquierda. Un dos puntos al final, ---:, fuerza derecha, y es el que quieres en cualquier columna de números. Dos puntos en ambos extremos, :---:, centra. Un dos puntos en medio de los guiones no es alineación y no es válido: la celda tiene que ser dos puntos, guiones, dos puntos, en ese orden, y nada más. Pon la herramienta en derecha y una tabla de dos columnas sale con | -----: | ---: | debajo, y cada número de la columna cuadra por su última cifra en el resultado.

Una regla atrapa la mayoría de los fallos silenciosos: la fila separadora debe tener exactamente tantas celdas como la cabecera, o la tabla no se reconoce en absoluto. La especificación lo dice sin rodeos, y el modo de fallo es el peor posible: no obtienes una tabla rota, no obtienes tabla. Una cabecera de cuatro columnas sobre una separadora de tres se muestra como texto literal, barras incluidas. Es exactamente lo que pasa cuando alguien añade una columna a mano y se olvida de los guiones. El conversor no puede cometer ese error porque construye ambas filas a partir del mismo recuento de columnas, lo que es un argumento decente a favor de generar la tabla en vez de editarla.

El relleno es para ti, no para GitHub

El conversor tiene un interruptor «Rellenar columnas», activado por defecto, y no cambia nada de la tabla renderizada. Activado, una tabla de dos columnas sale como | Item | Qty |, | ------ | --- |, | Widget | 3 |, con las celdas cuadradas. Desactivado obtienes | Item | Qty |, | --- | --- |, | Widget | 3 |, desigual. GitHub produce un HTML idéntico con ambas. Los espacios existen para que un humano leyendo el diff vea las columnas, y por ninguna otra razón. Quita el relleno cuando la tabla es ancha y lo que se va a leer es el diff; déjalo cuando el fichero se edita a mano.

Hay una trampa que conviene conocer si tus datos no son latinos. El relleno se calcula contando caracteres, y un carácter no es una columna. Dale al conversor una celda con dos emoji: cuenta dos, rellena a dos, y la fuente deja de cuadrar en un editor donde cada emoji ocupa dos columnas de ancho fijo. Lo mismo pasa con texto chino, japonés y coreano, y en sentido contrario con una é escrita como e más acento combinante, que son dos caracteres en una sola columna. Nada de esto afecta a la tabla renderizada, así que es un problema de legibilidad y no de corrección, pero si produces una tabla ancha de topónimos japoneses no esperes una fuente peinada.

Escapar el escape, y adivinar el delimitador

Un conversor que cambia cada barra por \| y se detiene ahí se equivoca en exactamente una entrada, y es la que aparece en cuanto vuelves a importar una tabla que escribiste tú: una celda que ya contiene \|. Escapa solo la barra y x \| y se convierte en x \\| y, donde la contrabarra duplicada es una contrabarra literal y la barra que va detrás vuelve a estar viva: la columna se parte y nada avisa. El orden tiene que ser el contrario. Este conversor escapa primero la contrabarra y después la barra, así que x \| y sale como x \\\| y, que parece una contrabarra de más y no lo es: GFM lee \\ como una contrabarra literal y \| como una barra literal, y muestra la única celda x \| y.

La consecuencia es que la ida y vuelta es segura. Convierte unos datos en una tabla Markdown, saca la tabla, guárdala como CSV, vuelve a meterla: las columnas que llevaban barras regresan tal y como salieron, y todo lo demás con ellas. Vale más de lo que parece, porque exportar una tabla renderizada a una hoja de cálculo y volver a importarla es algo corriente en cuanto una columna cambia de nombre. La herramienta hermana de este sitio, el generador de tablas Markdown, cierra el mismo círculo por el otro extremo: su analizador lee \| como una barra literal cuando el delimitador es la barra y le quita el escape a la entrada, así que una tabla pegada allí también vuelve idéntica.

El delimitador se adivina en vez de declararse, y la adivinanza se hace sobre varios registros, no solo sobre la cabecera. La herramienta cuenta comas, puntos y coma, tabulaciones y barras fuera de comillas en hasta cinco registros, y un delimitador que da el mismo recuento en cada registro leído gana a uno que simplemente es más numeroso en el primero. Eso es lo que resuelve una cabecera como A|B|C,D: por sí sola parece tres columnas separadas por barras, pero pon debajo filas con comas y gana la coma, porque es su recuento el que se repite. Una exportación francesa cuya cabecera es Nom;Prénom se detecta como punto y coma en cualquier caso. Lo único que el primer registro sigue decidiendo solo es qué delimitadores son candidatos: una cabecera que no contiene ninguno de los cuatro no deja nada que dirimir, y la adivinanza recae en la coma. Si tu primera línea es rara, fija el delimitador a mano.

Un flujo que sobrevive a la revisión

Exporta los datos como CSV en vez de copiar celdas de una hoja de cálculo, porque las reglas de comillas de un fichero CSV son lo único que le dice al conversor dónde acaba un campo con una coma o un salto de línea. Pégalo, comprueba el separador que detectó, elige la alineación —derecha para números, por defecto para lo demás— y lee las dos primeras líneas de salida antes de copiar. Esas dos líneas son la cabecera y la fila separadora, y si tienen distinto número de barras nada se renderizará después.

Luego busca las tres celdas que dan guerra. Todo lo que lleve una barra: comprueba que salió como \| y no como un límite de columna vivo, y ten presente que una celda que ya llevaba una contrabarra la ve duplicada: \\\| es la salida correcta, no un escape de más. Todo lo que era multilínea: comprueba que se volvió <br> y decide si eso es de verdad lo que quieres en una tabla. Todo lo que esté vacío: una celda vacía es perfectamente legal y se muestra vacía, así que una fila de blancos en medio de tu tabla es dato, no daño. Si la tabla va a un repositorio y no a un comentario, súbela una vez con el relleno activado para que el primer revisor lea el diff, y no la reformatees nunca más: un cambio de solo espacios en una tabla son treinta líneas de ruido en un pull request que no dicen nada.

Qué hace el conversor con cada celda problemática y qué renderiza GitHub
Contenido de la celdaLo que emite la herramientaResultado
USB-C | 2 mUSB-C \| 2 mCorrecto: una celda con una barra visible
Un campo entrecomillado con un retorno de carro reallínea uno<br>línea dosCorrecto: lo único que permiten las tablas GFM; un salto real es imposible
x \| y (ya escapado)x \\\| yCorrecto: la contrabarra se escapa primero, GitHub muestra la única celda x \| y
Un campo vacíoNada entre las barrasCorrecto: una celda vacía es legal y se muestra vacía
Una fila con menos campos que la cabeceraRellenada con celdas vacías hasta la fila más anchaCorrecto: una tabla irregular no se renderizaría, así que la herramienta la cuadra
Dos emojiRellenada como si midiera dos columnasSolo cosmético: ocupan cuatro; la tabla renderizada no se ve afectada
CSV a tabla MarkdownConvierte un CSV en una tabla Markdown, comillas incluidas: un campo puede contener el delimitador, un salto de línea o una barra vertical sin romper la tabla. Coma, punto y coma (Excel francés), tabulación o barra — detectado o forzado.Probar la herramienta

Preguntas frecuentes

¿Puedo poner un salto de línea dentro de una celda de tabla Markdown?
Uno real, no. El salto de línea es lo que termina una fila, así que la sintaxis de tablas no tiene forma de expresar una celda que lo contenga: no existe una secuencia de escape como \| para la barra. El apaño que GitHub acepta es la etiqueta HTML <br>, que es lo que sustituye este conversor: un campo CSV entrecomillado con una ruptura pasa a ser una celda que dice línea uno<br>línea dos. Dos límites honestos. Los motores que filtran HTML mostrarán la etiqueta como texto literal, y una celda con tres o cuatro <br> suele indicar que el contenido quiere ser una lista bajo la tabla y no una celda dentro.
Mi tabla se muestra como texto plano con barras. ¿Qué he roto?
Casi siempre la fila separadora. O falta del todo, o tiene un número de celdas distinto del de la cabecera: la especificación exige que la cabecera coincida con la fila delimitadora en número de celdas, y si no coincide la tabla no se reconoce y cae a párrafo. Cuenta las barras de la línea uno y la línea dos de tu tabla; deben ser iguales. La otra causa frecuente es una línea en blanco entre la cabecera y la separadora, que cierra el bloque antes de empezar. Una tercera, más rara: las celdas separadoras solo pueden contener guiones y dos puntos opcionales en los bordes, así que un espacio-guion-espacio perdido o una raya pegada por la autocorrección de un editor invalida la fila.
¿Importan los espacios que cuadran las columnas?
No. | a | b | y |a|b| producen el mismo HTML en GitHub, y el interruptor «Rellenar columnas» existe solo para que la fuente se lea bien en un editor. El relleno sí tiene un coste real en un repositorio: como el ancho de cada columna es el de su valor más largo, editar una celda puede cambiar el relleno de toda la columna, y un cambio de una palabra se convierte en un diff que toca todas las filas. Si la tabla vive en un fichero versionado y se edita a menudo, generarla sin relleno da diffs más limpios. Si se escribe una vez y la leen humanos en el fichero crudo, deja el relleno.
¿Puedo usar negrita, enlaces o código dentro de una celda?
Sí: el formato en línea funciona con normalidad dentro de las celdas, así que **negrita**, un [enlace](https://example.com) y un `fragmento de código` se renderizan. Las construcciones de bloque no: ni títulos, ni listas, ni bloques de código delimitados, ni tablas anidadas, porque todos necesitan saltos de línea que la fila no puede contener. La trampa es un fragmento de código con una barra, como `ps | grep node`. Los acentos graves no protegen una barra del analizador de tablas: la celda se parte primero y el código se interpreta después, así que igualmente hay que escribir `ps \| grep node`. Es uno de los pocos casos en que hay que escapar a mano, porque el conversor solo escapa las barras que ve en los datos de origen.
¿Por qué mi CSV francés salió en una sola columna?
Porque la línea de cabecera no le dio nada que contar al detector, y es la cabecera la que decide qué delimitadores entran siquiera en liza. La herramienta cuenta comas, puntos y coma, tabulaciones y barras fuera de comillas en los primeros registros, y un recuento que se repite gana a otro que solo es el mayor en la línea uno; pero un delimitador que no aparece en el primer registro ni siquiera es candidato. Una hoja de cálculo francesa o alemana exporta con puntos y coma, ya que la coma es el separador decimal, y una cabecera Nom;Prénom se detecta bien. Una cabecera de una sola palabra sin separador, no: no hay nada que contar, la adivinanza recae en la coma y el archivo entero llega como una columna. Pon la opción Delimitador en Punto y coma a mano. El mismo remedio sirve para una exportación tabulada pegada desde un terminal, donde las tabulaciones pueden haberse convertido en espacios por el camino y ya no queda de verdad ningún delimitador que encontrar.

Artículos que podrían interesarte

Todas las guías
TutorialConstruir una tabla Markdown desde cero, sin contar guiones a manoLo más pequeño que sigue siendo una tabla son dos líneas: una fila de cabecera y una fila delimitadora. Aquí está por qué la segunda es obligatoria en GitHub Flavored Markdown, dónde las tablas de barras no existen en absoluto, y qué hace un generador que teclear a mano no puede.GuíaTransponer una tabla cuyas filas deberían haber sido columnasQué le pasa a la fila de cabecera, a las filas de longitud desigual, a los tipos — y la única cosa con la que se confunde habitualmente transponer y que no puede hacer.ExplicaciónDe CSV a JSON: los cinco casos que rompen cualquier conversorDelimitadores entrecomillados, saltos de línea incrustados, tipos ambiguos, cabeceras duplicadas y codificación. Cada caso se pasó por el conversor y aquí está la salida exacta, incluidos los dos que no salva.TutorialMarkdown: guía para principiantesDa formato a texto plano con unos símbolos: # para títulos, ** para negrita, - para listas. Aquí tienes qué es markdown, la sintaxis básica, por qué está en todas partes y los trucos.ExplicaciónPunto y coma, tabulación, barra: elegir un delimitador que sobreviva al viajePor qué el idioma de quien lee decide el delimitador, qué hace el conversor con el entrecomillado al cambiar, qué es realmente la primera línea sep=, y el recuento de celdas entrecomilladas en la misma exportación escrita de cinco maneras.ExplicaciónPor qué tu CSV rompe los acentos y las fechas en ExcelTres averías completamente distintas se esconden tras la misma frase. Una es la codificación, otra el separador, otra Excel adivinando tipos mientras abre el archivo, y el remedio es distinto en cada caso. Así se distinguen en cinco segundos.

Herramientas relacionadas

Esto describe cómo se comportan un formato de archivo y un motor de renderizado, comprobado contra la especificación citada y contra el código de la herramienta tal y como está hoy. Los motores discrepan: GitHub, GitLab, un generador de sitios estáticos y la vista previa de tu editor son cuatro implementaciones distintas, y lo que funciona en una puede no funcionar en otra. Nada de esto garantiza nada sobre tu cadena de publicación: prueba el resultado donde vaya a publicarse de verdad, y trata cualquier herramienta, esta incluida, como algo que se comprueba y no como algo en lo que se confía.

Fuentes

¿Has detectado un error en este artículo?