Markdown 은 HTML 의 superset, 그 결과로...
CommonMark 는 inline HTML 과 block HTML 을 둘 다 받아줘. inline 태그 (<span>, <kbd>, <sub>, <sup>, <abbr>, <cite>) 는 Markdown 강조가 먹는 자리면 어디서든 먹어. block 태그 (<div>, <table>, <details>) 는 앞뒤로 빈 줄을 둬야 비로소 블록으로 대접받고.
유용한 HTML
- 이미지 크기 — Markdown 에는 width 속성이 없어서
<img src="..." width="400" alt="...">를 써야 해. - 접을 수 있는 섹션 —
<details><summary>Click</summary>...</details>. GitHub 에서 그대로 접히고 펴져. - 키보드 단축키 —
<kbd>Cmd</kbd>+<kbd>K</kbd>라고 쓰면 진짜 키 모양으로 찍혀. - 아래/윗첨자 —
H<sub>2</sub>O,x<sup>2</sup>. - 복잡한 테이블 — GFM 테이블로 안 되는 게 있으면 (rowspan, colspan, 셀 안에 블록)
<table>로 내려가.
XSS 경고
사이트가 사용자가 쓴 Markdown 을 렌더링한다면 (댓글, 위키, 포럼) 출력 HTML 을 반드시 sanitize 해야 해. 안 하면 댓글에 적힌 <script>alert(1)</script> 가 페이지의 진짜 스크립트 태그가 돼버려. GitHub 는 위험한 태그를 알아서 떼어내지만, 정적 사이트 생성기는 안 그러는 쪽이 많아. 작성자를 믿는다고 가정하고 만들었거든. 내가 쓰는 렌더러가 어느 쪽인지는 알고 써야 해.
원칙: 믿을 수 있는 사람이 쓴 Markdown 이면 HTML 을 뭘 넣든 괜찮아. 모르는 사람이 쓴 Markdown 이면 서버에서 sanitize 하는 게 필수야 (rehype-sanitize, DOMPurify, bleach, sanitize-html). '클라이언트에서 sanitize 하면 되지' 는 리팩토링 한 번에 터지는 XSS 취약점이고.