Files
Aislo/M01_MasterData/logic/M01_MasterData_logic_source_notes.ts
T
eomsangdonandClaude Sonnet 5.5 5e6037270e fix(833-1): 원문 패널 표 깨짐 — 표 맨 아래 비고 · [주] · ※ 서술 줄을 표 밖 글로 · 서술 칸 줄바꿈
- 새 순수 계산 logic/M01_MasterData_logic_source_notes.ts (서술 줄 가르기 · 줄바꿈 칸 판정) · 원문 글 · 차례 그대로
- 원문 표 2,573 · 폭 420 기준 서술 줄 때문에 넘친 표 138 → 0 · 넘침 1,228 → 1,020
- 시험 test_833_1_source_notes (보기 + 전수 글 보존)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-15 10:06:06 +09:00

44 lines
2.0 KiB
TypeScript

/* =============================================================================
* M01_MasterData_logic_source_notes.ts
* 원문 표 맨 아래 서술 줄(비고 · [주] · ※ …) 가르기 — 순수 계산(화면 · fetch 없음 · PLAN 833-1)
* 표 끝에 이어 붙은 서술 줄 = 표 밖 글로 · 글 순서 · 내용은 그대로 · 위쪽 줄(표 몸 · 묶음 머리)은 안 건드림
* ========================================================================== */
/** 표 밖으로 나가는 서술 줄 하나 — `label` = 「비고」 · 「[주]」 머리(없으면 빈 글) */
export interface NoteLine {
label: string;
text: string;
}
const LABEL = /^(비고|\[?주\]?\)?|※|참고)\s*\d*$/;
const MARK = /^(※|-|∙|·|\[주\]|주\)|비고|참고)/;
const LONG = 30;
/** 한 줄이 서술 줄이면 글 — 아니면 null (머리 줄 · 숫자 줄 · 묶음 머리(짧은 한 칸)는 아님) */
export function noteLine(row: string[]): NoteLine | null {
if (row.length < 2) return null;
const full = row.map((c, k) => [k, c.trim()] as const).filter(([, c]) => c);
if (full.length === 1) {
const [[, text]] = full;
return MARK.test(text) || text.length >= LONG ? { label: "", text } : null;
}
if (full.length === 2 && full[0][0] === 0 && LABEL.test(full[0][1]))
return { label: full[0][1], text: full[1][1] };
return null;
}
/** 표 → 몸 줄 + 맨 아래 이어 붙은 서술 줄 — 머리(첫 줄)는 늘 몸 */
export function splitTableNotes(table: string[][]): { rows: string[][]; notes: NoteLine[] } {
let end = table.length;
while (end > 1 && noteLine(table[end - 1])) end--;
return {
rows: table.slice(0, end),
notes: table.slice(end).map((r) => noteLine(r) as NoteLine),
};
}
/** 칸 글이 줄바꿈 대상 — 한 줄이 30자 이상(서술 칸) · 한 칸짜리 표(글 상자) · 숫자 칸은 안 접음 */
export function wrapCell(text: string, cols: number): boolean {
return cols === 1 || text.split("\n").some((l) => l.length >= LONG);
}