바닐라 Markdown만으로 기술 블로그를 쓰려고 하면 금방 한계에 부딪힌다. 제목, 굵은 글씨, 링크, 코드 블록까지는 좋은데, 다이어그램을 그리거나 수식을 넣거나 경고 박스를 만들려고 하면 방법이 없다. 2편에서 WYSIWYG를 버리고 Markdown을 택한 이유를 썼는데, 그건 시작일 뿐이었다. 진짜 문제는 표준 Markdown이 기술 글쓰기에 필요한 것의 절반도 커버하지 못한다는 데 있었다.

GFM 너머

GitHub Flavored Markdown이 테이블, 취소선, 작업 리스트 같은 걸 추가해주긴 한다. 초기에는 이 정도면 되겠지 싶었다. 그런데 실제로 글을 써보면 빈자리가 계속 눈에 밟혔다. 시퀀스 다이어그램은 이미지로 만들어서 올려야 하고, ML 글에 수학 공식을 넣으려면 외부 서비스를 끌어와야 하고, 경고 문구는 굵은 글씨로 때울 수밖에 없고. 그래서 목록을 하나 만들었다 — "Postlark가 지원해야 할 Markdown 확장 10가지."

한번 연 김에 10개

원래 Callout 하나만 추가하려고 파서 코드를 열었다. 경고 박스, 팁 박스 같은 거. 그런데 손대기 시작하니 하나가 다음 하나를 불렀다.

최종 목록:

  1. 헤딩 앵커 — 모든 제목에 자동 ID와 링크 생성

  2. 목차[TOC] 마커 하나로 자동 생성

  3. 각주[^1] 스타일의 학술 레퍼런스

  4. 수식 — 인라인 $...$과 블록 $$...$$, KaTeX 렌더링

  5. Mermaid — 텍스트로 쓰는 플로차트와 시퀀스 다이어그램

  6. Callout — NOTE, TIP, WARNING, CAUTION, IMPORTANT 다섯 타입

  7. 이모지:rocket: 같은 숏코드를 유니코드 이모지로 변환

  8. 작업 리스트 — 체크박스 커스텀 스타일링

  9. 코드 블록 강화 — 파일명 표시, 줄번호, diff 하이라이팅

  10. 구문 강조 — highlight.js 기반 언어별 색상

코드 블록에 구문 강조를 넣으니까 파일명 표시가 필요해졌고, 파일명 표시를 넣으니까 diff 하이라이팅까지 하고 싶어졌다. 기능 하나가 다음 기능의 필요성을 만들어내는 체인 반응. 결국 한 커밋에 10개가 전부 들어갔다.

이 중에서 실무적으로 가장 많이 쓰이는 건 Callout이다. GitHub 스타일의 > [!WARNING] 문법으로 경고나 팁을 넣을 수 있는데, 기술 문서에서 이게 없으면 중요한 정보가 본문에 묻혀버린다. 거의 매 글마다 하나씩은 들어가게 된다. Mermaid는 빈도가 낮지만 아키텍처 설명할 때 이미지 파일 없이 텍스트만으로 다이어그램을 그릴 수 있다는 게 핵심이고, "모든 것이 텍스트"라는 Markdown 철학과 정확히 맞아떨어진다.

세 곳 동기화

구현보다 어려운 건 일관성이었다. Markdown이 렌더링되는 곳이 세 군데 — 콘텐츠를 처리하는 서버, 대시보드의 미리보기 패널, 독자가 보는 블로그 페이지. 셋이 같은 결과물을 보여줘야 한다. 미리보기에서 예쁘게 나왔는데 발행하니까 깨지면 블로거 입장에서 최악이니까. 파서 설정 동기화에 CSS까지, 다크 모드 조합까지 포함하면 작업량이 기능 수의 세 배가 된다.

감사 도구를 먼저 만든 게 살렸다

커밋 히스토리를 들여다보면 재미있는 순서가 보인다. 10개 확장을 구현하기 직전에 Markdown 감사(audit) 도구를 먼저 만들었다. 파서 설정과 CSS를 전수검사하고, 세 렌더링 표면의 결과가 일치하는지 자동으로 확인하는 도구다.

이게 없었으면 꽤 오래 고생했을 거다. 확장 10개를 넣고 감사를 돌렸더니 버그가 7개 터졌다.

대시보드에서 목차가 아예 렌더링되지 않았다. 작업 리스트의 체크박스 스타일이 서버 출력과 달랐다. 각주 처리 정규식이 탐욕적 매칭을 해서 중첩 div가 깨졌다. 그리고 취소선 — GFM 기본 기능인 취소선의 CSS가 세 곳 어디에도 없었다. 10개 확장과 관계없이 원래부터 빠져 있던 거였는데, 감사를 안 돌렸으면 발견 못 했을 문제다.

빠르게 많이 넣으면 빠르게 부서진다. 다만 검증 도구가 먼저 있었기 때문에 "어디가 어떻게 깨졌는지"를 체계적으로 파악할 수 있었다. "기능 먼저, 테스트 나중에"가 아니라 "검증 먼저, 기능 나중에." 이 순서가 맞다는 걸 이번에 확실히 체감했다.

나중에 YouTube 임베드도 따로 추가했다. URL을 한 줄에 붙여넣으면 반응형 16:9 비디오로 변환하는 기능인데, 트래킹 쿠키를 쓰지 않는 도메인을 적용했다. 이런 작은 결정들이 쌓여서 플랫폼의 방향이 만들어진다.