You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
senzapaura_es/scripts/db/escansion.mjs

79 lines
2.6 KiB

Ejemplos de versos en la ficha, y dónde escuchar cada obra La ficha decía que el bolero va en octosílabo y endecasílabo alternados sin enseñar nunca uno. Un taller que describe la métrica y no la muestra está pidiendo que se la imaginen. `verso` es la estrofa y no el verso suelto —la rima y la alternancia de medidas no se ven en menos de dos versos— y `verso_linea` lleva cada uno con su escansión: `silabas` es la métrica y no la del diccionario, así que la sinalefa mete dos palabras en una casilla —«za⁀a»—, que es justo lo que en un texto corrido no se ve. `medida` va aparte porque un verso agudo suma una sílaba y uno esdrújulo resta una: «yo respondo con el son» tiene siete casillas y es un octosílabo. Los diez ejemplos son originales, escritos para enseñar, y entran marcados con `fuente = 'ejemplo'`. Ninguno es cita: para eso está `obra_referencia.cita`, y dos CHECK lo sostienen —un verso «cita» sin obra, o uno «propio» sin canción, no entran—. La escansión se comprueba antes de cargarla, contra la ley del acento final, y el sembrador aborta si algo no cuadra. Un ejemplo mal contado enseña a contar mal y eso no lo detecta ningún tipo ni ningún lint: por eso la comprobación está en su propio módulo, con nueve pruebas. `obra_referencia_enlace` sustituye a la columna `enlace`, que era texto suelto y solo daba sitio para uno; una obra está en Spotify **y** en YouTube. Comparte el vocabulario `PLATAFORMAS` con los enlaces de las canciones. De momento son búsquedas y no grabaciones concretas: una URL inventada manda a un 404 con pinta de dato bueno, y los enlaces exactos llegarán en el JSON de la ficha. De paso, dos cosas que se vieron al montarlo: - El orden de la ficha cambia. Primero lo que se usa para escribir —ejemplos, rasgos, temática— y después lo que sitúa el género. Es un taller: quien abre la página viene a escribir una letra. - `repeat(auto-fit, minmax(24rem, 1fr))` desbordaba ochenta píxeles en un móvil de 320, porque la rejilla pone la columna aunque no quepa. Ahora es `min(24rem, 100%)`, en los tres sitios donde estaba. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 month ago
/**
* Comprueba que la escansión de un verso cuadre.
*
* Vive aparte del sembrador porque es la única garantía de que el taller no
* enseñe una cuenta falsa, y eso hay que poder probarlo sin una base de datos
* delante. Un ejemplo mal escandido es peor que ningún ejemplo: quien aprende
* a contar sílabas con él aprende mal.
*
* La ley del acento final, que es de donde sale todo esto: un verso se mide
* hasta su última sílaba tónica más una. Si acaba en palabra llana —lo
* normal— la cuenta es la que se ve; si acaba en aguda suma una, y si acaba en
* esdrújula resta una. Por eso «yo respondo con el son» tiene siete casillas y
* es un octosílabo.
*/
/**
* @param {{ silabas: string[], tonicas: number[], medida: number, texto?: string }} linea
* @returns {string | null} qué falla, o `null` si cuadra.
*/
export function fallosDeEscansion(linea) {
const casillas = linea.silabas.length;
if (casillas === 0) return 'no tiene sílabas';
if (linea.tonicas.length === 0) return 'no tiene ninguna sílaba tónica';
if (linea.tonicas.some((t) => !Number.isInteger(t) || t < 1 || t > casillas)) {
return `una tónica cae fuera de las ${casillas} sílabas`;
}
if ([...linea.tonicas].sort((a, b) => a - b).join() !== linea.tonicas.join()) {
return 'las tónicas no van en orden';
}
const ultima = linea.tonicas.at(-1);
const porElAcento = {
[casillas]: casillas + 1, // aguda
[casillas - 1]: casillas, // llana
[casillas - 2]: casillas - 1 // esdrújula
};
// Con la tónica más atrás no hay verso: en castellano no hay palabras
// sobresdrújulas al final de verso que se cuenten así.
if (!(ultima in porElAcento)) {
return `la última tónica está en ${ultima} y hay ${casillas} sílabas: demasiado atrás`;
}
if (porElAcento[ultima] !== linea.medida) {
return (
`${casillas} casillas con la última tónica en ${ultima} ` +
`miden ${porElAcento[ultima]}, no ${linea.medida}`
);
}
return null;
}
/**
* Recorre la semilla entera y devuelve todo lo que no cuadra, con su sitio.
*
* @param {{ generos: Record<string, {titulo: string, lineas: object[]}[]> }} semilla
* @returns {string[]}
*/
export function revisarSemilla(semilla) {
const problemas = [];
for (const [genero, ejemplos] of Object.entries(semilla.generos)) {
for (const ejemplo of ejemplos) {
for (const [i, linea] of ejemplo.lineas.entries()) {
const fallo = fallosDeEscansion(linea);
if (fallo) {
problemas.push(
`${genero} · «${ejemplo.titulo}» · verso ${i + 1}: ${fallo} — «${linea.texto}»`
);
}
}
}
}
return problemas;
}

Powered by TurnKey Linux.