"GitHub에서는 됐는데요"

마크다운을 쓰다 보면 반드시 한 번은 겪습니다. GitHub README에서 완벽하게 보이던 문서를 사내 위키에 붙였더니 표가 통째로 글자로 나오고 체크박스는 대괄호가 그대로 보이고 줄바꿈은 전부 붙어버립니다.

문법을 틀린 게 아닙니다. 마크다운에는 표준이 하나가 아니기 때문입니다. 이 사실을 알고 나면 대응 방법도 명확해집니다.

표준이 여러 개인 이유

2004년 — 원조 마크다운

존 그루버가 만든 원조 마크다운은 명세가 산문으로 쓰인 설명 문서였습니다. "이렇게 쓰면 이렇게 됩니다" 수준의 안내였고 애매한 경우를 어떻게 처리할지는 정해두지 않았습니다.

예를 들어 이런 것들이 정의되어 있지 않았습니다.

  • 목록 안에 목록을 넣을 때 들여쓰기는 몇 칸인가
  • *강조* 안에 다시 *가 들어가면 어떻게 되는가
  • HTML 태그 안의 마크다운은 해석해야 하는가

그래서 도구를 만드는 사람마다 다르게 구현했습니다. 그리고 결정적으로, 원조 마크다운에는 표가 없습니다. 코드 블록도 백틱 세 개(```)가 아니라 네 칸 들여쓰기 방식만 있었습니다. 지금 우리가 당연하게 쓰는 것들 상당수가 나중에 각자 덧붙인 확장입니다.

2014년 — CommonMark

10년쯤 지나 "이대로는 안 되겠다"며 나온 것이 CommonMark입니다. 모호한 경우를 전부 정의한 엄격한 명세와 수백 개의 테스트 케이스를 갖췄습니다. 오늘날 대부분의 도구가 이걸 기반으로 삼습니다.

다만 CommonMark는 원조 마크다운의 범위를 엄밀하게 정의하는 것이 목표였습니다. 그래서 여전히 표가 없습니다. 취소선도, 체크리스트도 없습니다.

GFM — 우리가 실제로 쓰는 것

GitHub은 CommonMark를 기반으로 실무에서 필요한 것들을 얹어 GitHub Flavored Markdown(GFM)을 만들었습니다.

  • 표
  • 취소선 ~~취소선~~
  • 체크리스트 - [ ]
  • 주소를 그냥 적어도 링크가 되는 자동 링크
  • 각주 [^1]

우리가 "마크다운"이라고 부르며 쓰는 것은 사실 대부분 GFM입니다. 그리고 GFM은 표준이 아니라 GitHub의 방언입니다. 다른 플랫폼이 이걸 전부 지원해야 할 의무는 없습니다.

그리고 자체 방언들

여기에 아예 다른 길을 간 곳들도 있습니다. 슬랙의 mrkdwn이 대표적인데, 굵게를 별표 두 개가 아니라 하나로 씁니다.

마크다운처럼 생겼지만 마크다운이 아닙니다. 자세한 내용은 디스코드·슬랙 서식 정리에 따로 적어두었습니다.

실제로 갈리는 지점

주요 플랫폼에서 어떤 문법이 통하는지 정리하면 이렇습니다.

문법 GitHub 벨로그 티스토리 노션 Slack/Discord
제목 # ✅ ✅ ✅ ✅ Discord만
굵게 ** ✅ ✅ ✅ ✅ Slack은 * 하나
표 ✅ ✅ ✅ 붙여넣기만 ❌
체크리스트 - [ ] ✅ ✅ 대체로 ✅ ❌
취소선 ~~ ✅ ✅ ✅ ✅ Slack은 ~ 하나
코드 문법 강조 ✅ ✅ ✅ ✅ Discord만
HTML 태그 제한적 ✅ ✅ ❌ ❌
각주 [^1] ✅ 대체로 ❌ ❌ ❌
엔터 한 번 = 줄바꿈 파일은 ❌ / 이슈는 ✅ ✅ ✅ 새 블록 ✅

표에서 보이듯 완전히 같은 칸이 거의 없습니다. 아래에서 특히 자주 사고가 나는 것들만 짚겠습니다.

같은 문서를 직접 렌더해 본 결과

말로만 정리하면 와닿지 않아서, 자주 갈리는 문법 여덟 가지를 한 문서에 모아 렌더러 네 곳에 그대로 넣어 봤습니다. 아래가 테스트에 쓴 원문 전체입니다.

## 플랫폼 비교 테스트

**마크다운(Markdown)**을 쓰면 편합니다.
첫째 줄
둘째 줄 (엔터 한 번)

- [ ] 할 일
- [x] 끝난 일

> [!NOTE]
> 알림 상자

==형광펜== 그리고 ~~취소선~~

| 이름 | 값 |
|---|---|
| 가 | 1 |

<details><summary>접기</summary>

숨긴 **내용**
</details>

렌더 방법은 이렇습니다. 결과 화면만 비교할 수 있도록 앞의 세 곳은 같은 스타일시트(GitHub 마크다운 스타일)를 입혀 캡처했고, 접기는 눌러서 펼친 상태로 찍었습니다.

  • CommonMark — 표준 명세의 공식 자바스크립트 구현인 commonmark.js 0.31.2
  • GitHub — GitHub이 공개한 마크다운 렌더링 API의 gfm 모드
  • marked — 이 블로그 글을 HTML로 바꿀 때 쓰는 라이브러리. 버전 16.2.0, 기본 설정
  • 이지 마크다운 에디터 — 에디터에 원문을 텍스트로 붙여넣은 화면

commonmark.js 0.31.2로 렌더한 화면으로, 확장 문법이 모두 글자 그대로 보인다

GitHub 마크다운 API gfm 모드로 렌더한 화면으로, 일부 문법만 적용됐다

marked 16.2.0 기본 설정으로 렌더한 화면으로, 일부 문법만 적용됐다

이지 마크다운 에디터에 같은 원문을 붙여넣은 화면으로, 대부분의 문법이 적용됐다

캡처에서 확인한 결과를 표로 옮기면 이렇습니다.

문법 CommonMark GitHub API (gfm) marked 이지 마크다운 에디터
**마크다운(Markdown)**을 별표가 그대로 보임 별표가 그대로 보임 별표가 그대로 보임 굵게 적용
엔터 한 번 한 줄로 이어짐 줄이 바뀜 한 줄로 이어짐 줄이 바뀜
- [ ] 체크리스트 대괄호가 글자로 보임 체크박스 체크박스 체크박스
> [!NOTE] 일반 인용문 Note 알림 상자 일반 인용문 일반 인용문
==형광펜== 기호가 그대로 보임 기호가 그대로 보임 기호가 그대로 보임 형광펜 적용
~~취소선~~ 기호가 그대로 보임 취소선 취소선 취소선
표 파이프 기호가 글자로 보임 표 표 표
<details> 접기 접기 동작, 안쪽 굵게 적용 접기 동작, 안쪽 굵게 적용 접기 동작, 안쪽 굵게 적용 접기가 사라지고 일반 문단 두 개로 바뀜

여덟 줄 중 네 곳의 결과가 모두 같은 줄은 하나도 없습니다. 몇 가지는 따로 설명이 필요합니다.

GitHub API 결과는 github.com 화면과 다를 수 있습니다. 위 캡처는 API의 gfm 모드 결과입니다. 이 모드에서는 엔터 한 번이 줄바꿈이 됐는데, 이슈·댓글과 같은 방식입니다.

같은 원문을 API의 기본 모드(markdown)로 다시 렌더하면 세 줄이 한 줄로 이어졌고, 체크리스트와 [!NOTE]도 글자 그대로 나왔습니다. 저장소의 README 화면이 어느 쪽과 같은지는 이 캡처만으로는 단정하지 않겠습니다.

이지 마크다운 에디터는 문서 편집기라서 결과가 다릅니다. 붙여넣은 원문을 편집할 수 있는 문서로 바꾸기 때문에, 렌더러가 해석하지 못한 형광펜이나 조사 앞 굵게도 적용됩니다. 대신 <details> 접기는 지원하지 않아서 "접기"와 "숨긴 내용"이 일반 문단으로 풀립니다.

접기가 필요한 문서라면 에디터에서 다듬은 뒤 올릴 곳에서 직접 감싸야 합니다.

조사 앞 굵게가 풀리는 이유

세 렌더러가 모두 **마크다운(Markdown)**을을 굵게 처리하지 못했습니다. 버그가 아니라 CommonMark 명세의 규칙대로 동작한 결과입니다.

명세는 별표 묶음이 강조를 닫을 수 있는 조건을 정해 두었습니다. 오른쪽 측면 구분자(right-flanking delimiter run)여야 하는데, 별표 바로 앞이 문장부호라면 바로 뒤도 공백이나 문장부호여야 합니다.

닫는 괄호 )는 문장부호이고 그 뒤에 붙은 조사 을은 공백도 문장부호도 아닙니다. 그래서 뒤쪽 **는 닫는 기호로 인정받지 못하고 글자로 남습니다.

영어는 단어 뒤에 거의 항상 공백이 오니 이 규칙에 걸릴 일이 드뭅니다. 한국어는 조사가 바로 붙으니 괄호나 따옴표로 끝나는 말을 굵게 하면 쉽게 걸립니다. 같은 원리로 일본어·중국어도 문장부호 뒤에 공백 없이 글자가 이어지면 같은 문제가 생깁니다.

이 문제는 오래전부터 논의되고 있습니다.

  • CommonMark 포럼의 "Emphasis and East Asian text" 스레드는 2017년에 시작됐습니다. 2020년에는 *스크립트(script)*라고가 강조로 렌더되기를 기대한다는 한국어 예시가 올라왔습니다.
  • 2026년 8월에는 한·중·일 문자 옆에서 이 조건을 완화하자는 명세 PR #839가 올라왔습니다. 한국어 예시로 **마크다운(Markdown)**을을 들고 있습니다. 2026년 10월 확인 기준으로 아직 열려 있고, 명세 저자는 명세에 넣기 전에 실제 사용에서 검증하는 과정(field testing)이 중요하다는 의견을 남겼습니다.
  • 한국어만의 문제도 아닙니다. 닫는 괄호 뒤에 바로 글자가 오는 **)**a가 영어에서도 굵게가 되지 않는다는 이슈 #840도 같은 규칙 때문입니다.
  • 실제 저장소에서 겪은 사례도 있습니다. 한 공개 저장소는 GitHub이 한국어 조사 앞의 별표를 그대로 보여주는 문제를 겪고 해당 부분을 HTML <strong> 태그로 바꿔 해결했습니다.
  • 렌더러 쪽에서 이 조건을 완화하는 markdown-cjk-friendly 플러그인도 있습니다. marked용(marked-cjk-friendly)과 markdown-it용, remark용이 따로 나와 있습니다.

글을 쓰는 쪽에서 피하는 방법은 간단합니다. 아래 세 가지는 commonmark.js와 marked 모두에서 굵게로 렌더되는 것을 확인했습니다.

**마크다운(Markdown)을** 쓰면 편합니다.     ← 조사까지 굵게 안에 넣기
**마크다운(Markdown)** 을 쓰면 편합니다.    ← 조사 앞에 공백 (어색하지만 동작)
**마크다운**을 쓰면 편합니다.               ← 괄호를 빼기

참고로 위 테스트에서 이지 마크다운 에디터가 저장한 원문을 열어 보면 해당 줄이 **마크다운(Markdown**)을로 바뀌어 있었습니다. 닫는 괄호를 굵게 바깥으로 뺀 형태라서, 이 원문은 commonmark.js와 marked에서도 굵게로 렌더됩니다. 대신 괄호는 굵게에서 빠집니다.

사고 1. 줄바꿈 — 가장 흔합니다

같은 GitHub 안에서도 다릅니다. 저장소의 .md 파일에서는 엔터 한 번이 무시되지만 이슈와 댓글에서는 그대로 줄바꿈됩니다. 이슈에 쓰던 감각으로 README를 쓰면 문장이 전부 한 줄로 이어집니다.

대부분의 블로그 플랫폼은 엔터 한 번을 줄바꿈으로 처리해줍니다. 사람들이 그렇게 기대하기 때문입니다. 그래서 블로그에서 GitHub으로 옮길 때 줄바꿈이 사라지고 반대로 옮길 때는 예상보다 줄이 많이 벌어집니다.

대응법은 줄바꿈 정리 글에 자세히 적었지만 요약하면 문서 파일에는 명시적인 줄바꿈 문법을 쓰고 대화형 입력창에서는 그냥 엔터를 치면 됩니다.

사고 2. 표 — 되거나, 아예 안 되거나

표는 원조에도 CommonMark에도 없는 확장입니다. 그래서 지원 여부가 극단적으로 갈립니다. 지원하지 않는 곳에서는 파이프(|)와 하이픈이 그대로 글자로 노출됩니다.

노션은 조금 특이합니다. 마크다운 표를 붙여넣으면 노션의 표 블록으로 변환해주지만 노션 안에서 마크다운 표 문법을 타이핑한다고 표가 되지는 않습니다. 즉 "변환은 되지만 문법은 없는" 상태입니다.

메신저에는 표가 아예 없습니다. 슬랙에 표를 붙이면 파이프 기호 범벅이 되므로, 표로 정리한 내용을 공유해야 한다면 이미지로 캡처하거나 코드 블록으로 감싸 고정폭 정렬을 유지하는 편이 낫습니다. 표 자체의 한계에 대해서는 표 작성 가이드를 참고하세요.

사고 3. HTML — 허용 범위가 제각각

마크다운으로 안 되는 것들(이미지 크기, 가운데 정렬, 접기)은 결국 HTML로 해결합니다. 그런데 HTML 허용 범위가 플랫폼마다 다릅니다.

  • GitHub — 태그는 허용하되 style 속성과 스크립트는 제거합니다. 그래서 <img width>는 되고 글자 색은 안 됩니다
  • 일반 블로그 플랫폼 — 대체로 관대해서 인라인 스타일까지 통합니다
  • 노션·메신저 — HTML을 아예 받지 않아 태그가 글자 그대로 노출됩니다

HTML을 많이 쓴 문서일수록 옮길 때 많이 깨집니다. 여러 곳에 올릴 문서라면 HTML 사용을 최소한으로 줄이는 게 안전합니다.

사고 4. 굵게 기호

슬랙에서만 다르지만, 팀 채팅에 자주 쓰는 만큼 체감 빈도가 높습니다.

**굵게**   → 대부분의 플랫폼
*굵게*     → 슬랙

슬랙에 **굵게**를 쓰면 굵어지지 않고 별표가 그대로 보입니다. 반대로 다른 곳에 *굵게*를 쓰면 굵게가 아니라 기울임이 됩니다.

사고 5. 체크리스트

- [ ] 문법은 GFM 확장입니다. GitHub에서는 클릭으로 체크까지 되는 인터랙티브 요소지만 지원하지 않는 곳에서는 - [ ] 항목이 그대로 글자로 나옵니다.

회의록을 액션 아이템 체크리스트로 정리해 다른 곳에 올릴 때 자주 걸립니다. 자세한 내용은 체크리스트 정리 글에 있습니다.

그래서 어떻게 써야 할까

한 곳에만 올릴 문서

그 플랫폼 기준으로 마음껏 쓰면 됩니다. GitHub에만 둘 README라면 GFM 기능을 다 써도 좋습니다. 굳이 호환성을 걱정할 이유가 없습니다.

여러 곳에 올릴 문서 — 최소공통분모로

옮겨 다닐 문서라면 어디서나 통하는 것만 쓰는 편이 결과적으로 편합니다.

안전한 것들:

  • 제목 # ~ ###
  • 글머리 목록, 번호 목록
  • 굵게 **, 기울임 *
  • 인라인 코드와 코드 블록
  • 인용 >
  • 링크 [텍스트](주소)

주의가 필요한 것들:

  • 표 — 지원 여부 확인
  • 체크리스트 — GFM 계열에서만
  • HTML 전반 — 허용 범위 확인
  • 각주 — 지원하는 곳이 적음

옮기기 전 확인할 것

플랫폼을 옮길 때 다음 순서로 확인하면 대부분 걸러집니다.

  1. 화면 복사 대신 원문 복사 — 렌더된 화면을 복사하면 HTML이 딸려가 더 크게 깨집니다. .md 원문을 붙여넣으세요
  2. 표와 체크리스트부터 확인 — 가장 자주 깨지는 두 가지입니다
  3. 줄바꿈 확인 — 문단이 붙거나 과하게 벌어지지 않았는지
  4. 이미지 다시 올리기 — 상대 경로 이미지는 거의 항상 깨집니다. 옮긴 곳에서 다시 업로드하는 편이 확실합니다
  5. 링크 눌러보기 — 특히 목차의 앵커 링크는 플랫폼마다 규칙이 달라 잘 깨집니다

마무리

마크다운의 매력은 "어디서나 통한다"였는데, 실제로는 "어디서나 조금씩 다르게 통한다"에 가깝습니다. 표준화가 늦었고 그 사이 각자 필요한 걸 덧붙였기 때문입니다.

대응은 결국 두 가지입니다. 한 곳에 쓸 문서는 그 플랫폼에 맞춰 마음껏 쓰고 옮겨 다닐 문서는 안전한 문법만 쓴다. 그리고 옮긴 뒤에는 반드시 눈으로 한 번 확인하는 것입니다.

이지 마크다운 에디터로 초안을 잡고 마크다운 원문으로 내보내면, 화면 복사 때문에 생기는 문제만큼은 피할 수 있습니다. 플랫폼별 세부 사항은 노션 · 벨로그 · 티스토리 · 디스코드·슬랙 글에 각각 정리해두었습니다.