Markdown 转义字符:反斜杠、实体与行内代码
在任何 ASCII 标点前面加一个反斜杠,Markdown 就把它当普通文字,\*不是斜体\* 会显示星号,\# 不是标题 会显示井号;行内代码和代码块里不需要转义,因为那里什么都不解析。妙言和标准 CommonMark 唯一不太一样的地方是美元符号,它的公式渲染也会读这个字符,所以写价格要多留意。
反斜杠能转义哪些字符
CommonMark 允许在下面这 32 个字符前面加反斜杠,别的都不行。
! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
反斜杠后面是字母、数字、空格或非 ASCII 字符时,它只是一个反斜杠,\A 和 \3 会原样显示;要显示反斜杠本身就写两个 \\。行尾的反斜杠不是转义,而是硬换行。被转义的字符失去 Markdown 含义,包括 \<(不是标签)、\[(不是链接)、\`(不是代码)和 \&(不是实体)。
什么时候真的需要
句子中间的大多数标点都无害,容易出问题的是下面这些。
星号。 * 在单词中间也能开启强调,按规范 5*6*78 会把 6 渲染成斜体,要显示星号就写 5\*6\*78。
下划线。 CommonMark 不允许在单词内部用 _ 强调,所以 snake_case_name 会原样显示,规范自己也说这类名字最好放进行内代码。同一行里两个下划线都贴在词边,比如 _draft 和 final_ 中间夹着别的文字,可能配成强调,这时才需要 \_。
行首的数字加点。 2024. was a good year 会变成有序列表,因为列表标记是一到九位数字加 . 或 )。只有以 1 开头的列表才能打断段落,所以多半出现在段落开头,写成 2024\. was a good year。
行首的井号、加号、减号和大于号。 \# 不是标题、\- 不是列表、\+ 不是列表、\> 不是引用 能让这一行保持文字,只需要给第一个字符加反斜杠。
方括号和尖括号。 \[不是链接](/foo) 保持原样。<div> 是原始 HTML,而妙言的渲染器会放行原始 HTML,所以正文里裸写的 <div> 可能直接消失在页面里,要写 \<div> 或 <div>。
表格里的竖线。 GFM 表格里 | 会结束单元格,放在反引号里也一样,要写 \|,GFM 规范的示例里普通文字、行内代码和粗体里都能用。Markdown 语法速查与 GFM 差异的表格一节也提到了这一点。
波浪线。 ~~文字~~ 是删除线,要显示两个波浪线就写 \~\~。
用 HTML 实体代替
&、<、# 这类实体同样能显示字面字符。数字引用是一到七位十进制数字,或 &#x 加一到六位十六进制数字,常用的是用 写不换行空格,或者用 < 确保标签不会被解析。
它有个限制,规范说实体不能代替表示结构的符号,所以 *foo* 会显示字面星号而不是强调,* foo 也不是列表项。这样实体就可以当作 * 的转义使用,而在行内代码和代码块里实体同样不被识别,ö 会原样显示。
用代码当转义
行内代码是最简单的转义,反引号里每个字符都是字面的,包括反斜杠,\* 写在代码里会显示反斜杠和星号。文件名 my_file_name.md、正则、shell 通配符和价格都适合放进去;代码里要放反引号,就用更长的一串反引号包住,多行内容用围栏代码块。
转义在自动链接(<https://example.com?find=\*>)和原始 HTML 属性里不生效,但在链接地址、链接标题和围栏代码块的信息串里生效。
妙言里的美元符号
妙言用 KaTeX 渲染公式,$...$ 是行内公式,$$...$$ 是块级公式,每次预览都会运行,所以正文里的美元符号可能开启一个公式。普通价格有两层保护,Swift 这一层把 $ 后面跟数字、可选小数部分、再接一个不是字母、数字或数学运算符的字符判为货币,预览脚本里有类似的规则,所以 costs $5 or $10. 保持文字。
保护在字母和运算符处就停了,$5M and $10M 会被读成两个美元符号之间的公式,$5-10 也可能被当成数学。反斜杠在这里帮不上忙,\$ 是普通的 Markdown 转义,解析器会先把它变成裸的 $,等预览脚本和 KaTeX 扫描美元符号时已经看不到反斜杠,\$5M and \$10M 照样会变成公式。更稳妥的做法有两个,把金额放进行内代码,比如 $5M,或者改写成 500 万美元,公式处理会跳过行内代码和围栏代码块。公式那一侧的用法见 Markdown 里写 LaTeX 公式。
不同渲染器的差异
转义由 CommonMark 定义,所以上面的反斜杠规则在 GitHub 和其他符合规范的解析器里一致,差别在于什么算语法。GFM 增加了表格和删除线,所以 | 和 ~ 在 GFM 里要转义,严格的 CommonMark 里不用。美元符号公式不属于这两个标准,妙言会渲染,别的工具不一定,大量出现 $ 的笔记在不同工具里看起来可能不同。原始 HTML 也是一处分歧,妙言放行,有些托管平台会去掉,所以 \<div> 是哪里都能用的写法。
检查结果
打开预览,看有没有不想显示的反斜杠,以及消失的语法;少了一个词多半是尖括号被当成标签,凭空出现的列表多半是数字加点,某个字符还是不对,就把它包进行内代码,确认是不是解析器造成的。
常见问题
代码块里要转义吗?
不用,行内代码和代码块里反斜杠转义不生效,写了反斜杠就会显示出来。
怎么显示一个反斜杠?
写两个 \\。
为什么编号的那一行变成了列表?
以数字加点开头的行就是列表标记,把点转义,写成 2024\.。
