Lucía lleva la web del club de montaña de su barrio. Hay un tablón donde los socios dejan avisos, y la portada enseña los últimos con una vista previa: 80 caracteres y unos puntos suspensivos. La primera versión era lo que escribiríamos casi todos:
texto.length > 80 ? texto.slice(0, 80) + '…' : texto
Funcionó una semana. Luego alguien escribió «Salida del domingo confirmada, venid con la familia 👨👩👧 y crema solar» y la portada mostró un rombo con una interrogación justo antes de los puntos suspensivos.
Primer arreglo: contar code points
Lucía abrió el proyecto en Elffuss Code, pegó la función y el aviso roto, y le preguntó a la IA del editor qué estaba pasando. La explicación fue directa: .length y .slice cuentan unidades UTF-16, no caracteres. Muchos emojis ocupan dos, y el corte había caído entre las dos mitades de uno. Le propuso usar Array.from(texto), que recorre el texto por code points.
El rombo desapareció. En su lugar, la vista previa enseñaba 👨👩: la familia, sin la hija.
Segundo arreglo: lo que tú ves no es lo que cuenta el código
Ese emoji no es un carácter. Son cinco code points: hombre, unión invisible (ZWJ), mujer, ZWJ, niña. El navegador los dibuja como uno solo, pero Array.from los ve como cinco, y el corte había caído después del segundo ZWJ. Lucía se lo contó a la IA y esta vez la respuesta fue Intl.Segmenter con granularity: 'grapheme', que parte el texto en lo que una persona entiende por «un carácter»: grafemas.
Lo interesante vino después. Le pidió casos de prueba y la IA le sacó varios que no se le habían ocurrido:
- Banderas: 🇪🇸 son dos indicadores regionales. Si cortas entre ellos, sale una letra suelta dentro de un recuadro.
- Tildes descompuestas: una «é» copiada de un PDF puede venir como «e» más un acento combinable. Si cortas en medio, la palabra se queda sin tilde.
- Tonos de piel: 👍🏽 son dos code points, y si los separas queda el pulgar amarillo y un cuadradito marrón.
La función final mide y corta por grafemas, y además retrocede hasta el último espacio para no dejar una palabra a medias. Sigue sin llegar a veinte líneas.
Por qué no lo pegó en un chat cualquiera
Los casos que de verdad rompían la portada no eran inventados: eran avisos reales del tablón, con nombres de socios, teléfonos para compartir coche y algún «no puedo ir, tengo médico». Para reproducir el fallo, Lucía necesitaba pegar justo esos textos. Con un asistente en la nube, eso es mandar a un servidor ajeno mensajes que escribió otra gente y que no le pertenecen.
En Elffuss Code el modelo corre en el propio navegador. Los avisos, la función y las preguntas a medias («¿por qué sale la familia incompleta?») se quedaron en su pantalla. Ni cuenta, ni cuota, ni pensarse dos veces qué podía pegar.
La lección, para quien la quiera: si tu texto lo escriben personas, «carácter» casi nunca significa lo que mide .length.
Abre Elffuss Code y pon a prueba tu función de truncar con tus propios textos: el editor y la IA corren en el navegador y nada de lo que pegues sale de tu dispositivo.
Abrir Code →