Pandoc 引文标点位置控制:`notes-after-punctuation` 元数据深度解析
2026/9/21 16:05:13 网站建设 项目流程

Pandoc 引文标点位置控制:notes-after-punctuation元数据深度解析

【免费下载链接】pandocUniversal markup converter项目地址: https://gitcode.com/gh_mirrors/pa/pandoc

导读

在使用 pandoc 的--citeproc处理脚注式(note style)或上标数字式引文时,"引文标记应该放在逗号、句号之前还是之后"是一个典型的排版细节问题:英文排版惯例通常是脚注序号紧跟标点之后(works,[1]),而许多作者却习惯写成works[1],。Pandoc 通过 YAML 元数据字段notes-after-punctuation提供了精确控制,其行为差异由 test/command/7826.md 中的五个命令测试用例完整覆盖。本文将基于该测试文档展开,结合 src/Text/Pandoc/Citeproc.hs 的源码实现与 MANUAL.txt 的官方说明,逐条剖析该选项在 AMA、芝加哥全注释(Chicago full note)与作者-日期等不同引文风格下的真实行为,帮助你彻底掌握引文与标点的排布规则。

为什么需要控制引文与标点的相对位置

在学术写作中,引文标记(脚注序号、上标数字或括号引用)通常出现在句子末尾。不同引文风格对标点相对位置有不同约定:

  • 数字上标风格(如 AMA、Vancouver):上标引文号通常写在句号、逗号之后,例如In recent works,^(1,2)
  • 脚注风格(如 Chicago full note):脚注序号通常紧跟标点之后(美式排版惯例),例如recent works,[1]
  • 作者-日期风格(如 APA、Chicago author-date):括号引文属于句子成分的一部分,一般不随标点移动

Pandoc 的 citeproc 模块需要针对这些差异提供可配置行为,而notes-after-punctuation正是控制"引文标记是否移动到其后标点之后"的开关。它同时影响两类内容:脚注引用([^1])和上标形式的数字引文(^(1,2))。

测试文档7826.md全景:五个场景一个开关

test/command/7826.md 是一个 pandoc 命令测试(command test)文件,其格式为:%开头的命令行 + 输入文档(以^D结束)+ 期望输出。五个用例共用同一句输入文本:

In numerous recent works [@item1; @item2], statistician Foo and Bar have criticized XXX.

所有用例都使用pandoc -t plain --citeproc,并设置了bibliography: command/biblio.bibsuppress-bibliography: truesuppress-bibliography的作用是隐藏文末参考文献列表,使测试输出只聚焦于正文中引文标记的位置变化。下面逐一分析五个场景。

场景一:AMA 上标风格 +notes-after-punctuation: true

bibliography: command/biblio.bib suppress-bibliography: true csl: command/american-medical-association.csl notes-after-punctuation: true

输入works [@item1; @item2], statistician(引文后跟逗号),输出为:

In numerous recent works,^(1,2) statistician Foo and Bar have criticized XXX.

开启该选项后,上标^(1,2)从逗号之前被移动到逗号之后,得到符合 AMA 排版惯例的works,^(1,2)

场景二:AMA 上标风格 + 默认值(不设置该字段)

bibliography: command/biblio.bib suppress-bibliography: true csl: command/american-medical-association.csl

输出为:

In numerous recent works^(1,2), statistician Foo and Bar have criticized XXX.

AMA 属于"文中引用(in-text)"风格而非脚注风格,因此默认不移动:上标保持原位置在逗号之前,输出works^(1,2),。对比场景一可见,同样是 AMA 风格,一个开关即可改变上标与标点的相对顺序。

场景三:Chicago full note 脚注风格 +notes-after-punctuation: false

bibliography: command/biblio.bib suppress-bibliography: true csl: command/chicago-fullnote-bibliography.csl notes-after-punctuation: false

输出为:

In numerous recent works[1], statistician Foo and Bar have criticized XXX. [1] John Doe, First Book (Cambridge: Cambridge University Press, 2005); John Doe, "Article," Journal of Generic Studies 6 (2006): 33–34.

关闭该选项后,脚注序号[1]停留在逗号之前。同时注意:因为suppress-bibliography: true只抑制参考文献列表,脚注本身仍然输出在正文之后(plain 格式下显示为编号列表)。item1 与 item2 同属作者 John Doe,芝加哥全注释风格将其合并为同一条脚注,并以分号列出两条文献。

场景四:Chicago full note 脚注风格 + 默认值(脚注风格默认 true)

bibliography: command/biblio.bib suppress-bibliography: true csl: command/chicago-fullnote-bibliography.csl

输出为:

In numerous recent works,[1] statistician Foo and Bar have criticized XXX. [1] John Doe, First Book (Cambridge: Cambridge University Press, 2005); John Doe, "Article," Journal of Generic Studies 6 (2006): 33–34.

这是脚注风格的默认行为[1]被移动到逗号之后,输出works,[1],符合美式排版惯例。对比场景三,同一输入在默认与false之间只有标点与序号的位置互换,其余输出完全一致。

场景五:作者-日期风格 +notes-after-punctuation: true

bibliography: command/biblio.bib suppress-bibliography: true notes-after-punctuation: true

此用例未指定csl,使用 pandoc 默认的作者-日期风格(Chicago author-date 风格)。输出为:

In numerous recent works (Doe 2005, 2006), statistician Foo and Bar have criticized XXX.

即使显式开启notes-after-punctuation: true,括号引文(Doe 2005, 2006)不会移动位置——该选项只作用于脚注序号与上标数字引文。另外注意:item1 与 item2 作者相同(John Doe),作者-日期风格将两条引用压缩为(Doe 2005, 2006)

源码级原理:moveNotes判定与mvPunct移动算法

notes-after-punctuation的处理逻辑集中在 src/Text/Pandoc/Citeproc.hs。在processCitations中,首先读取元数据并决定是否启用移动:

let moveNotes = maybe (styleIsNoteStyle sopts) truish (lookupMeta "notes-after-punctuation" meta)

这段代码(src/Text/Pandoc/Citeproc.hs)揭示了默认值的来源:

  • 若 YAML 中未设置notes-after-punctuation,则取styleIsNoteStyle sopts——即脚注风格(note style)默认移动,非脚注风格默认不移动。这正对应测试场景二(AMA 不移动)与场景四(Chicago full note 移动);
  • 若显式设置,则用truish解析布尔值,显式值覆盖风格默认值,对应场景一、三、五。

关键的移动逻辑在mvPunct函数(src/Text/Pandoc/Citeproc.hs),源码注释直接给出了两条转换规则:

-- 'x [^1],' -> 'x,[^1]' (引文前有空格:空格折叠,序号移到逗号后) -- 'x[^1],' -> 'x,[^1]' (引文紧贴前文:同样把序号移到逗号后)

mvPunct逐 Inline 元素扫描,命中Cite且其末尾元素isNote为真、后续紧跟标点时,若moveNotes为真,则将标点字符串提取出来放到引文之前,并从后续文本中删除该标点。这解释了测试中"逗号被挪到上标/序号前面、同时空格被折叠"的完整行为。

isNote的定义(src/Text/Pandoc/Citeproc.hs)值得特别注意:

-- the following allows citation styles that are "in-text" but use superscript -- references to be treated as if they are "notes" for the purposes of moving -- the citations after trailing punctuation isNote (Superscript _) = True isNote _ = False

即:凡是以上标形式呈现的引文数字(如 AMA、Vancouver 等数字上标风格),即便在风格分类上属于 in-text 风格,也按脚注处理,可以被移动到标点之后。这正是场景一(AMA + true 移动成功)能够成立的实现基础。

此外isPunct(src/Text/Pandoc/Citeproc.hs)排除了破折号:

isPunct c = isPunctuation c && c /= '\x2014' && c /= '\x2013'

即 em-dash(,U+2014)与 en-dash(,U+2013)不算作可穿越的标点,脚注序号不会围绕破折号移动。同一函数中还包含movePunctInsideQuotes逻辑,它与 locale 的punctuation-in-quote设置联动,负责处理引文位于引号内时的标点归位。

官方文档中的定义与使用边界

MANUAL.txt 对该选项给出了权威说明:

notes-after-punctuation: If true (the default for note styles), pandoc will put footnote references or superscripted numerical citations after following punctuation. For example, if the source containsblah blah [@jones99]., the result will look likeblah blah.[^1], with the note moved after the period and the space collapsed. If false, the space will still be collapsed, but the footnote will not be moved after the punctuation. The option may also be used in numerical styles that use superscripts for citation numbers (but for these styles the default is not to move the citation).

关键结论可归纳为:

设置值脚注风格(note style)上标数字风格(如 AMA)作者-日期风格
未设置(默认)移动(默认 true)不移动(默认 false)不移动
true移动移动不移动(括号引文不受影响)
false不移动不移动不移动

另外两点边界需要记住:

  1. 空格折叠始终生效:即使false不移动序号,引文前多余的空格仍会被折叠(works [@jones99].会变为works[^1].而非works [^1].);
  2. 仅作用于脚注与上标:作者-日期风格的括号引文属于句子成分,永远不会被移动,场景五即验证了这一行为。

测试资源与复现方法

7826.md依赖的测试资源均位于 test/command 目录:

  • biblio.bib:包含item1(Book,John Doe,2005,Cambridge University Press)、item2(Article,John Doe,2006,Journal of Generic Studies)与пункт3(InCollection,John Doe & Jenny Roe,2007)三条文献。前两条作者相同,因此在上标风格下合并为^(1,2)、在作者-日期风格下合并为(Doe 2005, 2006)、在全注释风格下合并为同一条脚注;
  • american-medical-association.csl:AMA 数字上标风格,测试场景一、二使用;
  • chicago-fullnote-bibliography.csl:芝加哥全注释脚注风格,测试场景三、四使用。

若想本地复现,可在test/目录下直接执行测试命令,例如:

pandoc -t plain --citeproc --bibliography command/biblio.bib \ --metadata suppress-bibliography=true \ --metadata notes-after-punctuation=true \ --csl command/american-medical-association.csl

然后在 stdin 中输入测试文本(以^D结束)。注意测试文档中 YAML 内路径command/biblio.bib是相对于test/目录的写法;若在仓库根目录运行,应使用test/command/biblio.bib等相对路径。

实战建议

  • 投稿或排版有明确风格要求时:先查阅目标风格对标点位置的规定,再显式设置notes-after-punctuation,不要依赖默认值——同一个开关在 AMA 与 Chicago full note 下默认行为恰好相反;
  • 数字上标风格需要"标点后置"时:务必显式设置notes-after-punctuation: true,因为这类风格的默认值是不移动(见场景一与场景二的对比);
  • 使用-s生成独立文档时:将上述元数据写入 YAML 元数据块(而非命令行参数),便于与bibliographycsl一同纳入版本管理;
  • 排查引文位置异常时:可先关闭suppress-bibliography观察完整输出,再借助 src/Text/Pandoc/Citeproc.hs 中mvPunct的注释规则理解转换方向,避免把"默认不移动"误判为 bug。

小结

notes-after-punctuation是 pandoc citeproc 体系中一个小而精的排版开关:它的默认值由 CSL 风格类型(是否 note style)决定,显式设置可覆盖默认;它只作用于脚注序号与上标数字引文,对括号式作者-日期引文无效;即使关闭移动,空格折叠依然生效。围绕 test/command/7826.md 的五个用例,我们完整还原了该选项在 AMA、Chicago full note 与作者-日期三种风格下的输出差异,并深入到 src/Text/Pandoc/Citeproc.hs 的moveNotes判定与mvPunct算法,从源码与测试两个层面确认了行为依据。掌握这一选项,即可在跨风格写作时精准控制引文标点排布,避免反复手工调整。

【免费下载链接】pandocUniversal markup converter项目地址: https://gitcode.com/gh_mirrors/pa/pandoc

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询