CreaRack-SL

splitSentences: Troceado de markdown en frases

Firma

export function splitSentences(text: string): string[]

Propósito

Trocea texto markdown en “frases” (unidades atómicas) para que trimChunksBySentence pueda embeberlas y puntuar por similaridad. Es conservador: respeta estructuras que no deben partirse para mantener integridad semántica.

Comportamiento

Estructuras preservadas (no se trocean)

  1. Code blocks fenced (``` / ~~~): Un bloque entero = una unidad. Se trocean en el nivel de bloque, nunca dentro.
  2. Filas de tabla (| ... |): Cada fila = una unidad.
  3. Bullets / Numeradas (-, *, +, N.): Cada ítem = una unidad.
  4. Blockquotes (>): Cada línea = una unidad.
  5. Headings (#, ##, etc.): Cada línea = una unidad.

Partición en prosa

  • Parte por . / ! / ? seguidos de espacio y mayúscula o apertura (", ', (, ¿, ¡).
  • Protege antes de partir:
    • Abreviaturas: etc., Sr., Dra., p.ej, v.g, cf., vs., approx., min, max, seg, ms, kb, mb, gb, tb (lista ES/EN).
    • Decimales: 3.14, 1.5.
    • Versiones: v1.2.3.
    • IPs: 192.168.1.1.
  • Sustitución temporal: punto en abreviatura → placeholder Z9DOTZ9, partición, luego restauración.

Output

Array de strings, cada uno una frase/unidad. Sin vacías (filtradas).

Ejemplos

const ex1 = splitSentences("Hola. ¿Cómo estás?");
// ["Hola.", "¿Cómo estás?"]

const ex2 = splitSentences("La v.1.2.3 fue publicada.");
// ["La v.1.2.3 fue publicada."]  // no parte en los puntos de versión

const ex3 = `
function foo() {
  console.log("hola");
}

Explicación. Otro párrafo.
`;
// [
//   "function foo() {\n  console.log(\"hola\");\n}",
//   "Explicación.",
//   "Otro párrafo."
// ]

const ex4 = splitSentences("- Item 1\n- Item 2");
// ["- Item 1", "- Item 2"]

Detalles de implementación

Paso 1: Extraer code blocks

Usa regex /(\“[\s\S]?```|~~~[\s\S]?~~~)/gpara capturar bloques enteros y reemplazarlos por placeholdersZ9CODE${i}Z9`.

Paso 2: Separar por párrafos

Split por \n\s*\n (líneas en blanco). Cada párrafo se procesa por separado.

Paso 3: Detectar estructuras (por línea)

Si el párrafo contiene líneas que matchean /^\s*(?:[-*+]\s|\d+[.)]\s|\||>|#{1,6}\s)/, trátalas como estructurales: emite cada línea como unidad.

Paso 4: Prosa normal

  • Proteger puntos de abreviaturas / decimales / IPs.
  • Split por . / ! / ? seguidos de espacio + mayúscula/apertura.
  • Restaurar placeholders.
  • Trimear cada unidad.

Paso 5: Restaurar code blocks

Reemplazar placeholders Z9CODE(\d+)Z9 por el bloque original.

Fuentes de datos

  • Entrada: content de un ChunkMatch (texto markdown procedente del índice D1).
  • Salida: Array de strings, cada uno a embeberase.
  • Parámetros: Ninguno (determinista).

Notas

  • Performance: O(n) en longitud del texto. Dos pasadas de regex + split.
  • Seguridad: Usa placeholders improbables (Z9DOTZ9, Z9CODE${i}Z9) que no colisionan con prosa normal.
  • Internacionalización: Soporta abreviaturas ES/EN comunes. Lista amplible en SENT_ABBREV.
  • Casos edge: Si un párrafo es 100% un code block placeholder, detectado y emitido como unidad sin troceado.

Véase también

  • [[feature—biblioteca—arcrift-sentence-trimming]]
  • [[entity—functions—service—trim-chunks-by-sentence]]
  • [[entity—functions—service—retrieve]]