0%

【专题】Markdown特殊字符和转义

转义

转义不是 Markdown 独有的概念。当语言或系统涉及处理字符串时都会存在转义。

Markdown 使用 \ 作为转义字符,可以转义以下字符:

1
2
3
4
5
6
7
8
9
10
11
12
\  backslash  
`  backtick
*  asterisk
_  underscore
{} curly braces
[] square brackets
() parentheses
#  hash mark
+  plus sign
-  minus sign (hyphen)
.  dot
!  exclamation mark

\ 会失效

当然理论上\ 可以转义任何字符,如果该字符不是特殊字符也会原样输出。这里的理论上,其实说的是转义直接出现在正文中。但如果转义出现在某些特殊结构中,转义则未必会如意料进行。

比如,在表格中试图使用 \| 来转义表示 |。有的渲染器可以得到你想要的效果,但是有的不会—— | 是表格的列定界符,于是会多出一列。

其他转义方法

如果 \ 转义不生效了,那么就需要使用其他一些处理方法:

  • 内容放在行内代码中
  • 用 HTML 字符实体表示

行内代码

行内代码,用反引号 ` 括起来的内容会原样输出。唯一的问题是,行内代码内容是以“代码”样式显示的。如果内容并非代码的概念,使用行内代码并不合适。

【注意】

  1. 不要将下文中的 HTML 字符实体放在行内代码中,会原样输出。
  2. 行内代码中出现反引号 ` 是另一个麻烦,下文会单独讨论。

HTML 字符实体

Markdown 兼容 HTML,因此当然可以使用 HTML 字符实体。并且这是终极解决方案,即任何 Markdown 语法范围内无法转义的字符,最终都可以用字符实体。

【注意】
既要……又要……
上文提及,字符实体放在行内代码中会原样输出。那么,既必须使用字符实体,又要以行内代码样式显示怎么办?
解决方案是,行内代码不要使用 Markdown 语法,使用 HTML 标签 <code>

Obsidian 在编辑视图下不会渲染字符实体。

特殊字符

下面会逐一说明一些常见的特殊符号的处理方式。

笔者常用的 Markdown 编辑器是 Obsidian,博客用的 Hexo,所以大多从这两方面来比较渲染效果。

反引号 `

反引号是行内代码的定界符,所以需要转义。

场景一:正文中

可用转义方法:

1
2
\`       Markdown 转义
&#96; HTML 字符实体

场景二:行内代码中

【方法一】Markdown 转义

反引号是可以置于反引号括起来的行内代码中的。但是,为了内容中的反引号不意外“截断”行内代码,应注意:

  • 行内代码左右两侧的反引号为任意数量都是合法的,只要开闭配对即可。
  • 假设内容中最多有 n 个连续反引号,就应该用 n+1 个反引号括起来(有建议说,应总使用偶数个反引号)。
  • 内容中的反引号紧临边界时,最好插入一个空格隔开,否则可能被边界“吸收”而不显示(具体行为与渲染器有关)。

【方法二】字符实体

这里要使用字符实体,就不能使用反引号括起来了,否则会原样输出。

应该使用 <code> 标签包裹行内代码内容。

竖线 |

可用转义方法:

1
2
\|        Markdown 转义
&#124; HTML 字符实体

| 并没有什么特殊,除非它出现在表格中。由于它是表格列的定界符,如果单元格内容中有一个 | 就可能会解析多出一列。

区别讨论
在 Obsidian 中,使用 \| 转义就足够了。
但是,发布到 Hexo 就会多出一列。
所以,为了统一,最佳实践是使用字符实体。

抑扬符

可用转义方法:

1
2
\^       Markdown 转义
&#94; HTML 字符实体

为什么要转义 ^?
一个可能的解释是:避免解析为上标。但是,并非所有渲染器支持上标语法。
另一个笔者遇到过的问题是 [^0-9] 在某些渲染器中被转换为一个脚注。

花括号 {}

1
2
{    &#123;
} &#125;

严格地说,在 Markdown 中,花括号不需要特殊转义处理。

但是,当 Markdown 文档发布到诸如 Hexo 博客中时,就可能会出问题。

因为,渲染引擎可能支持形如 {{variable}} 这样的动态代码——即使置于行内代码中也不保险。

最佳实践:使用字符实体转义。

参考