본문 바로가기
C.W.K.
Stream
Lesson 01 of 04 · published

소스가 모델이야

~11 min · source, model, decorations, markdown

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

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

에디터가 문서를 쥐는 방식은 크게 두 가지야. WYSIWYG 에디터는 rich-text 트리를 쥐어. 헤딩은 노드고, bold 는 노드 안 텍스트에 붙는 서식 표시(mark)야. ** 나 # 같은 문자는 데이터로 아예 존재하지 않아. 트리에서 추론될 뿐이고, export 할 때 마크다운으로 다시 뱉어지지. Rekindle 은 정반대야. 모델이 마크다운 소스 문자열 그 자체거든. 헤딩 앞의 # 는 문서 안 실제 위치에 박혀 있는 진짜 문자야. 텍스트는 하나뿐이고, 그게 곧 소스야.

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

그럼 bold 는 어떻게 bold 로 보이는 걸까? decoration 레이어가 소스를 건드리지 않고 그 위에 모습만 칠해줘. **fire** 라는 단어는 별표까지 포함해서 모델 안에 문자 그대로 남아 있어. decoration 이 그걸 bold 로 렌더하고, 커서가 없는 줄에선 별표를 흐리게 하지. 변환되는 것도 없고, 잃는 것도 없고, 소스가 두 번째 표현에 밀려 버려지는 일도 없어.

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

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

이 선택이 아래쪽 전부를 결정해

소스를 모델로 삼는 건 겉모습 문제가 아니라 아키텍처를 결정하는 선택이야. 모델이 순수 마크다운 텍스트니까 디스크의 파일이 곧 진실이 되고 (트랙 7), diff 가 진짜 텍스트 diff 가 되고, grep 이 진짜 문자를 찾아내. voice underline 이든 CMD+K 든 모든 soul 기능이 독자 트리의 노드가 아니라 소스 상의 위치를 기준으로 동작해. 그러니 에디터 전체에서 따져야 할 표현이 딱 하나로 줄어. WYSIWYG 의 rich-text 트리였다면 네가 보는 것과 저장되는 것과 Pippa 가 읽는 것 사이에 번역 레이어가 끼어들어서, 하나가 아니라 셋을 계속 맞춰줘야 했을 거야.

Code

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

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

function detectVoiceIssues(doc: string): VoiceIssue[] {
  // 소스 텍스트를 문자 그대로 훑어서 밑줄 칠 범위를 반환해.
  // (트랙 4 에서 이 범위가 CM6 decoration 이 돼)
  return scan(doc);
}

// WYSIWYG 트리였다면 기능마다 트리와 렌더된 뷰와 마크다운 export
// 사이를 번역해야 했을 거야. 소스를 모델로 두면 그 세금이 사라져.

External links

Exercise

네가 쓰는 에디터에서 노트를 하나 열고 이렇게 물어봐. 이걸 저장한 다음 원본 파일을 일반 텍스트 뷰어로 열면, 그 문자들이 에디터가 편집하게 해주는 문자와 같을까? 줄에 커서를 올리거나 소스 보기로 바꿨을 때 보이는 그 문자들 말이야. 아니면 번역된 형태일까? 같으면 source 모델이야(Live Preview 처럼 렌더된 모습을 위에 칠해도 그건 안 바뀌어). 번역됐거나 바이너리면 rich-text 계열이야. 어느 쪽이 diff 와 grep 과 버전 관리를 자연스럽게 만드는지 확인해봐.
Hint
판별법은 이거야. 두 버전을 git diff 했을 때 변경 내용을 텍스트로 읽을 수 있어? source 모델은 깨끗하게 diff 가 나와. rich-text 나 바이너리 모델은 읽을 수 없는 diff 를 뱉고. 저장된 형태가 네가 편집한 형태가 아니니까 그래.

Progress

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

댓글 0

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

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