/* Multi-sentence ::gloss blocks. The system prompt tells the tutor it may put several sentences in one gloss block, each closed by its own "=" line. lib/blocks.js parse() sets `en` when it meets "=" but never closes the block, so every sentence's parts pile into one run-on line and only the last translation survives. lib/ ships unchanged, so the fix lives here, at the call site: split the block on its "=" lines and parse each sentence as its own single-sentence block. The output is exactly what parse() would have produced if it closed the block, so nothing downstream has to know. (If lib/blocks.js is ever revised, the one-line fix there is `cur = null` after setting `en`, and this module can go. test/lib/blocks.test.ts pins the current behaviour so the change is visible when it happens.) */ import { parse } from "@lib/blocks.js"; import type { GlossBlock, ParsedMessage } from "@lib/blocks.js"; const GLOSS_BLOCK = /::gloss\s*\n([\s\S]*?)(?:\n::|$)/; /** Split a gloss block's body into one chunk per "=" line. */ function splitSentences(body: string): string[] { const out: string[] = []; let current: string[] = []; for (const line of body.split("\n")) { const l = line.trim(); if (!l || l.startsWith("::")) continue; current.push(l); if (l.startsWith("=")) { out.push(current.join("\n")); current = []; } } // A trailing sentence with no "=" is still worth rendering. if (current.length) out.push(current.join("\n")); return out; } /** * parse(), with multi-sentence gloss blocks split correctly. * Use this everywhere instead of calling parse() directly. */ export function parseMessage(text: string): ParsedMessage { const parsed = parse(text); if (!parsed.gloss) return parsed; const match = text.match(GLOSS_BLOCK); if (!match?.[1]) return parsed; const sentences = splitSentences(match[1]); if (sentences.length < 2) return parsed; // the common case; nothing to fix const blocks: GlossBlock[] = []; for (const s of sentences) { const one = parse(`::gloss\n${s}\n::`); if (one.gloss) blocks.push(...one.gloss); } return blocks.length ? { ...parsed, gloss: blocks } : parsed; } export type { GlossBlock, ParsedMessage };