본문 바로가기
C.W.K.
Stream
Lesson 02 of 05 · published

역할 하나 — Live Preview

~11 min · live-preview, mark-decoration, job-one, cm6

Level 0식은 초고
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Live Preview 는 decoration 엔진의 첫 번째 역할이야. 소스 위에 모습을 렌더하되 커서가 놓인 곳에선 raw 마크업을 드러내지."

역할 하나 — 소스 위에 모습을 렌더

Live Preview 는 세 역할 중에 제일 눈에 띄면서 메커니즘은 제일 단순해. 마크다운 문법을 훑으면서 각 구성 요소에 그 모습을 렌더할 mark decoration 을 붙이는 게 전부야. **fire** 에는 bold 로 렌더하는 mark 가 붙고, # 헤딩에는 텍스트를 키우고 해시를 흐리게 하는 mark 가 붙어. 뭘 넣지도 지우지도 않아. 소스는 네가 친 마크다운 그대로고 그 위에 렌더된 겉옷만 걸친 셈이야.

커서 줄만 드러내기

이걸 살아 있게 느끼게 만드는 동작이 커서 줄만 드러내기야. 커서가 없는 줄에선 마크업이 렌더돼. 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;   // 커서 줄에선 raw 마크업 드러냄
    marks.push(renderMark(node));             // 나머지 줄에선 모습 렌더
  }
  return Decoration.set(marks, true);
}

전부 mark, 문서 변경은 없음

Live Preview 를 이루는 조각은 전부 손대지 않은 소스 위의 mark decoration 이야. 그래서 다른 모든 것과 나란히 있을 수 있어. 꺼버리면 문서는 바이트까지 똑같은 마크다운이고, 켜면 모델이 아니라 레이어가 하나 얹힌 거지. 다음 두 역할이 같은 엔진을 쓰는 이유도 여기 있어. voice underline 도 CMD+K 도 '범위를 계산하고 decoration 을 붙인다' 는 같은 모양이거든. 범위가 다르고, CMD+K 만 mark 대신 widget 을 쓸 뿐이야. 첫 번째 역할은 soul 레이어 전체가 올라탈 메커니즘을 부담 없이 소개하는 자리인 셈이야.

Code

Live Preview — 커서 줄만 빼고 어디서나 mark·typescript
import { Decoration } from "@codemirror/view";

function buildLivePreview(state) {
  const cursorLine = state.doc.lineAt(state.selection.main.head).number;
  const marks = [];

  for (const node of parseMarkdown(state.doc)) {
    // 커서가 놓인 줄에선 raw 마크업을 드러내서 정확히 편집하게 해.
    if (node.line === cursorLine) continue;
    // 나머지 줄에선 mark decoration 으로 모습을 렌더하고.
    marks.push(renderMark(node)); // 예: bold, 흐린 #, 커진 헤딩
  }

  return Decoration.set(marks, /* 정렬 */ true);
}

// 소스는 그대로야. 이걸 꺼도 바이트까지 똑같은 마크다운이 남아.

External links

Exercise

## The **fire** catches 라는 줄을 놓고, 커서가 없을 때와 있을 때 Live Preview 가 뭘 하는지 범위 단위로 설명해봐. 어느 문자 범위에 mark 가 붙고 어느 게 드러나는지 적어보는 거야. 두 상태의 소스 문자열이 완전히 같고 decoration 집합만 다르다는 걸 확인해.
Hint
커서가 없으면 ## 에 흐리게 하는 mark 가 붙고, 헤딩 텍스트는 커지고, **fire** 는 별표를 숨긴 채 bold 로 렌더돼. 커서가 있으면 mark 가 하나도 안 붙고 raw ## The **fire** catches 가 그대로 보여서 편집할 수 있고. 문자열은 똑같은데 decoration 집합만 둘로 갈리는 거야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.