한글 조사 때문에 마크다운 굵게가 안 먹는 이유, CommonMark right-flanking
닫는 별표 앞이 문장부호이고 바로 뒤에 조사가 붙으면 CommonMark 규칙상 굵게가 닫히지 않습니다. 영어에서는 드러나지 않는 이 규칙이 한국어 문서에서만 깨지는 이유와 해결, 검증 방법을 정리했습니다.
한국어 릴리즈 노트를 마크다운으로 써서 GitHub 에 올렸는데, 딱 네 줄만 ** 가 별표 그대로 화면에 나왔습니다.
공통점은 하나였습니다. 굵게 닫는 ** 바로 앞이 문장부호이고, 바로 뒤에 한글 조사가 붙어 있었습니다.
**중국어(간체, 번체)**가 추가되었습니다 ← 안 먹음
**"다운로드 실패"**로 막히던 ← 안 먹음
**[자세히 보기]**를 누르면 ← 안 먹음
**정상 케이스**가 추가되었습니다 ← 잘 됨버그가 아니라 명세입니다
CommonMark 명세대로 동작한 결과입니다. ** 가 강조를 닫으려면 right-flanking delimiter run 이어야 하는데, 조건이 이렇습니다.
(1) 앞이 공백이 아니고, 그리고 (2a) 앞이 문장부호가 아니거나, (2b) 앞이 문장부호면서 뒤가 공백이나 문장부호여야 한다.
(간체, 번체)**가 를 대입해 보겠습니다. 앞이 ) 라서 (2a) 탈락, 뒤가 가 라는 문자라서 (2b) 도 탈락입니다. 닫는 기호로 인정받지 못하고 리터럴 ** 가 됩니다.
영어에서는 이 규칙이 거의 드러나지 않습니다. **(bold)** and 처럼 조사 대신 공백이 오니 (2b) 를 항상 만족하거든요. 조사가 공백 없이 달라붙는 한국어와 일본어에서만 선택적으로 터집니다. 그래서 "영어 문서는 멀쩡한데 번역본만 깨진다"는 모양으로 나타납니다.
문장부호를 강조 밖으로 뺍니다
닫는 ** 앞을 일반 문자로 만들면 됩니다.
**"다운로드 실패"**로 → "**다운로드 실패**"로
**[자세히 보기]**를 → **자세히 보기**를
**중국어(간체, 번체)**가 → **중국어(간체, 번체)** 7개 언어가세 번째처럼 괄호를 살려야 하면 뒤에 공백과 단어를 넣어서 (2b) 를 만족시키거나, 조사를 강조 안에 포함시킵니다(**중국어(간체, 번체)가**). <strong> 태그로 우회할 수도 있지만 마크다운 문서에 HTML 을 섞게 됩니다.
눈으로 찾지 않습니다
규칙이 미묘해서 육안 검토는 놓칩니다. 렌더러에 통과시켜서 렌더 결과에 ** 가 남았는지로 판정하는 게 확실합니다.
# GitHub 렌더러로 실제 변환한 뒤 살아남은 ** 를 찾는다
curl -s -X POST https://api.github.com/markdown \
-d "$(jq -Rs '{text: ., mode: "gfm"}' < note.md)" \
| grep -n '\*\*'CI 에 한 줄로 걸어 두면 번역본이 늘어나도 자동으로 걸러집니다.