脚注

脚注解决的是一类很具体的问题:正文要一气呵成,但某些信息(出处、版本、术语全称)又必须留在手边。脚注把这类信息从行文里摘出来放到文末,正文里只留一个可点的标记。想细看的人点一下就跳过去,不想看的人也不会被拦在半路。

基本写法

引用写作 [^标签],脚注内容写作 [^标签]: 内容。标签是引用和内容之间的关联键,两边写一样就行:

这是正文的脚注引用[^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>

常见坑

写法实际渲染原因
标签写成 [^a b]变成普通链接标签不能带空格
标签写成 [^]变成普通链接标签不能为空
引用了没定义的标签原样留在正文缺少对应定义
同一个标签引用两次两条引用共用一个脚注脚注可被多次引用
脚注定义写在正文中间仍然渲染在文末定义位置不影响结果

练习

把下面这句话改写成 Markdown,要求:加一处脚注引用,指向一条脚注;脚注内容里用行内代码写出版本号;脚注定义放在正文之后。

本工具从 1.0 版本开始支持表格语法。
脚注定义

解题思路: 脚注由两部分组成:正文里的引用 [^标签],和脚注定义 [^标签]: 内容。标签两边必须一致,且不能含空格。编号由渲染器自动生成,不用手写。脚注内容按块级语法解析,所以可以放进行内代码。

详细步骤:

  1. 在正文末尾加上引用标记,写成 [^ver]。标签用纯字母,别加空格,否则会被解析成链接。
  2. 空一行,另起一行写脚注定义,写成 [^ver]: 表格语法属于 GFM 扩展……。
  3. 脚注内容里把版本号写进行内代码,写作 `1.0`。
  4. 脚注定义放在正文之后,渲染时它同样会出现在文末的脚注区。
  5. 检验:渲染后正文末尾出现一个上标脚注标记,文末多出一条编号为 1 的脚注,内容里的版本号是等宽字体。

最终答案:

本工具从 1.0 版本开始支持表格语法[^ver]

[^ver]: 表格语法属于 GFM 扩展,`1.0` 之前的版本会把它当作普通段落。

小结

读完这一页,你应当能写出引用和定义两半,能解释脚注为什么总在文末、编号为什么按出现顺序排,能一眼看出标签带空格时它其实变成了链接,也能在看到 [^xxx] 原样显示时想到缺少定义。

更多课程

推荐课程

发现内容有问题?

告诉我们哪里需要改进。