C.W.K.
Stream
Lesson 01 of 04 · published

소스가 모델이야

~11 min · source, model, decorations, markdown

Level 0식은 초고
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"디스크의 문자가 에디터의 문자야. 나머지는 전부 그 위에 칠한 레이어야."

두 문서가 아니라 하나의 텍스트

에디터가 문서를 쥐는 방식은 두 가지야. WYSIWYG 에디터는 rich-text 트리를 쥐어. bold 가 노드, 헤딩이 노드, 그리고 **# 문자는 데이터로 존재하지 않아 — 추론되고, export 할 때만 마크다운으로 다시 뱉어져. Rekindle 은 반대로 해. 그 모델은 마크다운 소스 문자열 그 자체야. 네 헤딩의 # 는 문서 안 실제 offset 에 있는 진짜 문자야. 텍스트는 하나고, 그게 소스야.

렌더된 모습은 레이어지 모델 전환이 아냐

그럼 bold 는 어떻게 bold 로 보여? decoration 레이어가 소스를 안 바꾸고 그 위에 모습을 칠해. **fire** 라는 단어는 모델 안에서 다섯 더하기 넷 문자로 남아. decoration 이 그걸 bold 로 렌더하고 inactive 줄에선 별표를 흐리게 해. 아무것도 변환 안 되고, 아무것도 안 잃고, 소스가 두 번째 표현으로 버려지는 일이 없어.

모델 (디스크와 에디터에 있는 것):        The **fire** catches.
decoration 레이어 (저장 아님, 칠하기): The [bold 로 된 fire] catches.

# 모델은 절대 안 변해. 모든 decoration 을 꺼도
# 밑엔 바이트 동일한 마크다운이 그대로 있어.

왜 이게 하류 전부에 중요한가

source-as-model 선택은 화장이 아냐 — 아키텍처를 결정해. 모델이 순수 마크다운 텍스트라서, 디스크의 파일이 진실이고 (트랙 7), diff 가 진짜 텍스트 diff 고, grep 이 진짜 문자를 찾고, 모든 soul 기능 (voice underline, CMD+K) 이 독점 트리의 노드가 아니라 소스로의 offset 위에서 동작해. 추론할 표현이 딱 하나라서 에디터 전체가 단순해져. WYSIWYG 의 rich-text 트리라면 보는 것, 저장하는 것, Pippa 가 읽는 것 사이에 번역 레이어를 강제해 — 하나 대신 셋을 동기화 상태로 유지해야 해.

Code

하나의 모델, 그 위에 칠한 모습·text
모델 (디스크 AND 에디터):                The **fire** catches.
decoration 레이어 (저장 아님, 칠하기):  The [bold fire] catches.

# 모든 decoration 을 꺼도 바이트 동일한 마크다운이 그대로 있어.
# 표현은 하나. WYSIWYG 라면 셋을 줘:
#   보는 것  !=  저장하는 것  !=  Pippa 가 읽는 것.
soul 기능은 트리 노드가 아니라 소스 offset 위에서 동작해·typescript
// 모델이 소스 문자열 그 자체라서, voice-rule 매치는 그냥
// 문자 offset 의 범위야 — 독점 노드 순회가 필요 없어.
type VoiceIssue = { from: number; to: number; note: string };

function detectVoiceIssues(doc: string): VoiceIssue[] {
  // 문자 그대로의 소스 텍스트를 스캔; 밑줄 칠 문자 범위를 반환
  // (트랙 4 가 이 범위를 CM6 decoration 으로 바꿔)
  return scan(doc);
}

// WYSIWYG 트리라면 모든 기능이 트리, 렌더된 뷰, 마크다운 export
// 사이를 번역해야 해. source-as-model 은 그 세금을 지워.

External links

Exercise

네가 쓰는 에디터에서 노트를 열고 물어봐. 이걸 저장하고 raw 파일을 일반 텍스트 뷰어로 열면, 내가 보는 것과 동일할까 아니면 그것의 번역일까? 동일하면 source 모델이야. 번역됐으면 (또는 바이너리) rich-text/WYSIWYG 모델이야. 어느 쪽이 diff, grep, 버전 관리를 자연스럽게 만드는지 봐.
Hint
표식: 두 버전을 의미 있게 git diff 해서 변경을 텍스트로 읽을 수 있어? source 모델은 깨끗하게 diff 돼. rich-text/바이너리 모델은 못 읽는 diff 를 만들어. 저장된 형태가 편집한 형태가 아니거든.

Progress

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

댓글 0

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

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