import type { Breakpoint } from './types'; import type { Token } from '../core/types'; type TcCandidateConfig = { tcPunctuations: string[]; balanceRange: number; }; /** * 计算 BALANCE 的 idealPos 列表(确定性简化版)。 * * - N=tokens.length * - targetLines=min(maxLines,N) * - lineIndex in 1..targetLines-1: * idealPos=round(N*lineIndex/targetLines) */ export function computeTcIdealPositions(tokens: Token[], maxLines: number): number[] { const n = tokens.length; const targetLines = Math.max(1, Math.min(maxLines | 0, n)); const ideals: number[] = []; for (let lineIndex = 1; lineIndex <= targetLines - 1; lineIndex++) { const idealPos = Math.round((n * lineIndex) / targetLines); ideals.push(idealPos); } // 去重并排序(稳定) ideals.sort((a, b) => a - b); return ideals.filter((v, idx) => idx === 0 || v !== ideals[idx - 1]); } /** * TC 候选断点生成: * - 标点后:kind=PUNCT,priority=30 * - 空格后:kind=SPACE,priority=20 * - BALANCE:kind=BALANCE,priority=5(围绕 idealPos ± balanceRange) * * 注意:BALANCE 断点允许生成在短语 span 内,是否可用交给评分阶段强惩罚淘汰。 */ export function generateTcCandidates(tokens: Token[], maxLines: number, config: TcCandidateConfig): { candidates: Breakpoint[]; idealPositions: number[] } { const n = tokens.length; if (n <= 1) return { candidates: [], idealPositions: [] }; const punctSet = new Set(config.tcPunctuations); const candidates: Breakpoint[] = []; // PUNCT / SPACE(扫描 token) for (let i = 0; i < n; i++) { const t = tokens[i]?.text ?? ''; const pos = i + 1; // 只允许行内断点 if (pos < 1 || pos > n - 1) continue; if (punctSet.has(t)) { candidates.push({ pos, kind: 'PUNCT', priority: 30 }); } if (t === ' ') { candidates.push({ pos, kind: 'SPACE', priority: 20 }); } } // BALANCE const idealPositions = computeTcIdealPositions(tokens, maxLines); const range = Math.max(0, config.balanceRange | 0); if (range > 0 && idealPositions.length > 0) { for (const ideal of idealPositions) { for (let pos = ideal - range; pos <= ideal + range; pos++) { if (pos < 1 || pos > n - 1) continue; candidates.push({ pos, kind: 'BALANCE', priority: 5 }); } } } return { candidates, idealPositions }; }