"Live Preview 는 decoration 엔진의 첫 역할: 소스 위에 모습을 렌더하고, 커서가 있는 곳엔 raw 마크업을 드러내."
역할 하나 — 소스 위에 모습을 렌더
Live Preview 는 세 역할 중 가장 눈에 띄고, 메커니즘적으론 가장 단순해. 마크다운 문법을 걷고, 각 구성물에 그 모습을 렌더하는 mark decoration 을 붙여. **fire** 는 bold 로 렌더하는 mark 를 받고, # 헤딩은 텍스트를 키우고 해시를 흐리게 하는 mark 를 받아. 삽입도 삭제도 없어 — 소스는 네가 친 마크다운 그대로, 렌더된 외투를 입었을 뿐.
active-line 드러내기
살아있게 느끼게 하는 동작이 active-line 드러내기야. 커서가 없는 줄에선 마크업이 렌더돼 (bold 는 bold 로, # 는 흐리게). 커서가 있는 줄에선 raw 마크업이 되돌아와 정확히 편집할 수 있어. decoration 집합을 커서 줄만 '렌더' 처리에서 빼고 다시 계산할 뿐이야. 깨끗한 문서를 읽고, 정확한 소스를 편집하고, 경계가 네 주의를 따라와.
function buildLivePreview(state) {
const cursorLine = state.doc.lineAt(state.selection.main.head).number;
const marks = [];
for (const node of parseMarkdown(state.doc)) {
if (node.line === cursorLine) continue; // active 줄엔 raw 마크업 드러냄
marks.push(renderMark(node)); // 그 외 어디서나 모습 렌더
}
return Decoration.set(marks, true);
}
전부 mark, mutation 없음
Live Preview 의 모든 조각이 안 바뀐 소스 위 mark decoration 이야. 그래서 다른 전부와 공존할 수 있어. 끄면 문서는 바이트 동일한 마크다운이고, 켜면 모델이 아니라 레이어를 더한 거야. 이게 또 다음 두 역할과 같은 엔진인 이유야 — voice underline 과 CMD+K 도 같은 '범위 계산, decoration 붙이기' 모양이고, 범위만 다르고, CMD+K 는 mark 대신 widget 일 뿐. 역할 하나는 soul 레이어 전체가 타는 메커니즘의 부드러운 입문이야.