脚注
脚注解决的是一类很具体的问题:正文要一气呵成,但某些信息(出处、版本、术语全称)又必须留在手边。脚注把这类信息从行文里摘出来放到文末,正文里只留一个可点的标记。想细看的人点一下就跳过去,不想看的人也不会被拦在半路。
引用写作 [^标签],脚注内容写作 [^标签]: 内容。标签是引用和内容之间的关联键,两边写一样就行:
这是正文的脚注引用[^note]
[^note]: 这里是脚注内容。
<p>这是正文的脚注引用<sup><a href="#user-content-fn-note" id="user-content-fnref-note" data-footnote-ref aria-describedby="footnote-label">1</a></sup></p>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label">Footnotes</h2>
<ol>
<li id="user-content-fn-note">
<p>这里是脚注内容。 <a href="#user-content-fnref-note" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>
注意上面这段 HTML 的两处分工:正文里的引用变成了一个上标小链接,而脚注内容被收进了文末的 <section data-footnotes> 里,末尾还挂了一个跳回原文的箭头。
脚注定义写在哪里都一样
不管你把 [^note]: ... 写在正文的哪个位置,渲染时它都会被搬到文档末尾,按引用出现的顺序重新编号。定义写在正文中间、写在文末,得到的 HTML 完全一样。所以脚注定义统一写在文档末尾,读源码时最省心。
编号按引用出现的顺序
编号是渲染时自动生成的,和标签名没有任何关系。下面这行正文里先引用了 b、后引用了 a,于是 b 是 1 号、a 是 2 号;脚注区也按这个顺序排列:
甲[^b] 乙[^a]
[^a]: 甲的脚注
[^b]: 乙的脚注
<p>甲<sup><a href="#user-content-fn-b" id="user-content-fnref-b" data-footnote-ref aria-describedby="footnote-label">1</a></sup> 乙<sup><a href="#user-content-fn-a" id="user-content-fnref-a" data-footnote-ref aria-describedby="footnote-label">2</a></sup></p>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label">Footnotes</h2>
<ol>
<li id="user-content-fn-b">
<p>乙的脚注 <a href="#user-content-fnref-b" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
<li id="user-content-fn-a">
<p>甲的脚注 <a href="#user-content-fnref-a" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>
脚注内容可以写多段
脚注内容按块级语法解析,可以用行内语法,也可以写成多段——第二段起缩进四个空格:
正文[^a]
[^a]: 第一段。
第二段。
<p>正文<sup><a href="#user-content-fn-a" id="user-content-fnref-a" data-footnote-ref aria-describedby="footnote-label">1</a></sup></p>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label">Footnotes</h2>
<ol>
<li id="user-content-fn-a">
<p>第一段。</p>
<p>第二段。 <a href="#user-content-fnref-a" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>
标签不能带空格
标签里有空格时,脚注语法不成立,整段会被当成链接引用来解析——这是最容易误判的一种情况,因为页面上看起来还是有链接:
正文[^a b]
[^a b]: 内容
<p>正文<a href="%E5%86%85%E5%AE%B9">^a b</a></p>
没有定义的引用会原样显示
引用了但没写对应定义的标签,不会被删掉,也不会被当成脚注,而是原封不动留在正文里:
正文[^missing]
<p>正文[^missing]</p>
脚注是 GFM 扩展,不是 CommonMark 的语法。 规范正文里没有脚注这一节,只有 GitHub 和一批博客引擎实现了它。同一份源码放到纯 CommonMark 渲染器上,[^note] 会原样显示。另外,渲染器写死在脚注区里的那个小标题是英文 Footnotes——中文页面用屏幕阅读器时,会读出一个英文词。
| 写法 | 实际渲染 | 原因 |
|---|---|---|
标签写成 [^a b] | 变成普通链接 | 标签不能带空格 |
标签写成 [^] | 变成普通链接 | 标签不能为空 |
| 引用了没定义的标签 | 原样留在正文 | 缺少对应定义 |
| 同一个标签引用两次 | 两条引用共用一个脚注 | 脚注可被多次引用 |
| 脚注定义写在正文中间 | 仍然渲染在文末 | 定义位置不影响结果 |
把下面这句话改写成 Markdown,要求:加一处脚注引用,指向一条脚注;脚注内容里用行内代码写出版本号;脚注定义放在正文之后。
本工具从 1.0 版本开始支持表格语法。
解题思路:
脚注由两部分组成:正文里的引用 [^标签],和脚注定义 [^标签]: 内容。标签两边必须一致,且不能含空格。编号由渲染器自动生成,不用手写。脚注内容按块级语法解析,所以可以放进行内代码。
详细步骤:
- 在正文末尾加上引用标记,写成
[^ver]。标签用纯字母,别加空格,否则会被解析成链接。 - 空一行,另起一行写脚注定义,写成
[^ver]: 表格语法属于 GFM 扩展……。 - 脚注内容里把版本号写进行内代码,写作
`1.0`。 - 脚注定义放在正文之后,渲染时它同样会出现在文末的脚注区。
- 检验:渲染后正文末尾出现一个上标脚注标记,文末多出一条编号为 1 的脚注,内容里的版本号是等宽字体。
最终答案:
本工具从 1.0 版本开始支持表格语法[^ver]
[^ver]: 表格语法属于 GFM 扩展,`1.0` 之前的版本会把它当作普通段落。读完这一页,你应当能写出引用和定义两半,能解释脚注为什么总在文末、编号为什么按出现顺序排,能一眼看出标签带空格时它其实变成了链接,也能在看到 [^xxx] 原样显示时想到缺少定义。
