feat(M01): 50-2 원문 패널 — 마크다운 기호 벗김 · 출처 항 · 주 강조

- 서버 원문 조각에서 역슬래시 · 인용 머리 · 글 안 주석 벗김(원본 자료 손 안 댐)
- 출처 항 · 주 번호(3-4-2 1 · 9-7-1 주⑥)를 source() 답에 실음 — 그 조각 hit 표시
- 패널이 그 항을 옅은 바탕 + 막대로 강조 · 보이게 스크롤 · 머리에 「1항」 · 「주⑥」
- 시험 3 추가 · 화면 시나리오 50-2

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK
This commit is contained in:
2026-10-05 18:42:15 +09:00
co-authored by Claude Sonnet 5.5
parent 3e572ef210
commit 2d954a14dd
5 changed files with 201 additions and 5 deletions
@@ -26,15 +26,24 @@ interface Block {
text?: string;
p?: string;
table?: string[][];
/** 출처가 가리킨 항 · 주 — 강조 */
hit?: boolean;
}
interface Found {
number: string;
matched: string;
file: string;
blocks: Block[];
item?: string;
}
function blockNode(b: Block): HTMLElement {
const node = rawNode(b);
if (b.hit) node.classList.add("m01lab-src__hit");
return node;
}
function rawNode(b: Block): HTMLElement {
if (b.table)
return el("div", {
className: "m01-logic__scroll",
@@ -89,11 +98,20 @@ export function createSourceView(): SourceView {
...found.flatMap((f) => [
el("p", {
className: "m01-logic__muted m01lab-src__file",
text: f.matched === f.number ? f.file : `${f.file} · ${ts("Near", f.number)}`,
text: [
f.file,
f.matched === f.number ? "" : ts("Near", f.number),
f.item ? (/^\d+$/.test(f.item) ? `${f.item}항` : f.item) : "",
]
.filter(Boolean)
.join(" · "),
}),
...f.blocks.map(blockNode),
]),
);
requestAnimationFrame(() =>
body.querySelector(".m01lab-src__hit")?.scrollIntoView({ block: "center" }),
);
});
};