引言
本文不会讲解一些 \(\LaTeX\) 的 ABC,诸如怎么下载安装,怎么写公式,怎么放图片之类的,这些入门内容 google 都很容易找到。当然也可能会有一些很 tricky 的点,不过本文的重点还是放在 LaTeX 学术写作时的文献引用上,这件事看起来简单,想做的顺心不机械重复,也是很有讲究的。在这个过程中,有一些细节可能很难捋顺,本文就是专门来解决这些痛点。
基本环境
本文的 latex 写作都是基于 APS 提供 revtex4.1 来进行的,这一宏包规定了符合 PR 系列文章的各种格式,使得大部分细节从一开始就是对的。其通过如下的 documentclass 引入。其中 rmp 也可改为 prl 或 prb 之类的,对应了不同期刊的格式。twocolumn 也可以改为 onecolumn 来调整栏数。以下我们很多功能的实现,都是基于这个 documentclass 来讲的。revtex 在主流的 LaTeX 发行版中,都是自带的,基本实现开箱即用。具体的使用细节可以参考其官方文档1,一个更加友好的简化版本2,我建议写物理文章的人都读一读这个文档,即使本来就一直用,也肯定会有新收获,磨刀不误砍柴工。
\documentclass[aps,rmp,twocolumn,reprint]{revtex4-1}
最原始的文献管理
最基本的 latex 中添加参考文献的方式,就是在正文中以 \cite{key}
的方式进行引用,而在文末添加参考文献的具体内容。关于那个 99 的含义可以参考这里。
\begin{thebibliography}{99}
\bibitem{key} Au. Thor, Jou. R. Nal., {\bf volume}, number (year).
\end{thebibliography}
这种方案当然是各种不忍直视。首先,每篇文献的信息,都要自己按照格式手打进 latex。其次由于文末的参考文献需要按照引用顺序,或者是年份,亦或是作者字母顺序排序,那么一旦增删参考文献,都需要重新手动排序。最后,不同的杂志对于文献的格式要求也不同,一旦需要重投,还需要将所有条目的格式改掉,有些还需要增添额外的元信息(比如文章题目),那么你就需要重新再找一遍这些文章,把题目抄下来。所有这些缺点合在一起,对于一个稍微有追求的人,显然是无法接受的。但这样的原始方案也有一个优点,就是方便共享。你可以直接把单个 latex 文件作为文章发送给其他人修改,而不用担心对方的编译问题。下面我就会渐进式的引入一整套解决方案,在避免了无用的手工工作的同时,又不损失共享的优势。
引入 bib
稍微能称得上用过 LaTeX 的人,自然都知道应该用 BibTeX 和 .bib 文件来做文献管理,实现内容和格式的分开(这也是 latex 最重要的精神)。bib 文件中记录的是各个文献的原信息,通过 BibTeX 的编译来将这些内容根据 cite 情况导入 latex 文件。bib 文件格式如下。
@article{key,
author = {Auth. O. R.},
doi = {10.1111/blah-blah},
journal = {Science},
pages = {666},
title = { {Hello World} },
url = {http://www.failtofind.com/nowhere.pdf},
volume = {66},
year = {2018}
}
一个 bib 文件就是由很多这样的文档数据组成的。每一个文献的元数据可以随便添加,因为怎么利用这些元数据生成最后的参考文献内容是 .bst 文件的事情。另一个细节是注意到这里的 title 元数据使用了双括号,事实上很多文献管理软件自动生成的 bib 都有这种特征,其作用是保持题目的大小写状态,阻止 .bst 文件按照某种样式改变引文题目的大小写3。这些 bib 条目当然不需要手写了,大部分期刊网站和 google scholar 都提供这种导出指定文章 bib 信息的功能,这一功能通常叫做 export citation,几乎可以在任何和科研文章有关的网站显眼的地方见到。导出后,数据就长上边的样子,把其统一复制到自己的 bib 文件里就好了,比如 example.bib
。这时在文章正文中还是以 \cite{key}
的方式引用,而正文的最后,只需要一句就好了。
\bibliography{/path/example.bib}
引入文献管理软件
这样做,每篇文章去导出 bib 再复制到本地还是很麻烦。一是每篇文章去导一次本身就很烦。其次,你还需要维护文献的引用 key 是唯一的,不要重复,知道某篇文章 bib 里有了还是没有,这些还是需要大量额外的精力。因此更省力的办法是使用文献管理软件。这种类型的软件现在可以说是多如牛毛,我在这里推荐使用 mendeley,其他软件的情况不太清楚。mendeley 可以自己自动维护一个 bib 文件,因此你只需要在软件里管理文献信息,bib 文件就自动生成好了。mendeley 的一些优势是:多操作系统支持,可以同步文献,可以自动识别 pdf 对应的文献元数据,可以根据一个 DOI 号自动补充完整文献数据,可以自动监视文件夹,可以自定义期刊名称的简写,元数据(尤其是作者和题目)接受 latex 命令,并可以最后在文章引用部分正常显示,可以直接在软件里全文搜索文章,软件内部直接阅读文章,添加关键词,标记和笔记,具有浏览器插件,可以随手添加文章到自己的 mendeley。这里面很多优势都很重要,缺少会使得整个工作流不流畅。考虑到想要引用的文章,大部分都存在本地文件夹里,只要将对应文件夹添加到 mendeley,bib 文件就自动生成好了。万一有元数据不完整的,还可以直接在 doi 号后面的放大镜上点一下,就可以即时获取完整元数据(通过 DOI 获取文献元数据的原理,我恰好也聊过,可以参考这篇我以前的博客)。同时 mendeley 自动分配的 citation key 避免了重复问题,当我们想要引用某篇文章时,只需在 mendeley 中根据作者题目,亦或是自己打的 tag 搜索到,确认一下其 citation key 即可(默认是一作姓+年份的形式)。同时,大部分文献都因为具有网址的元属性,而在最后的文章里带上了链接,这无疑极大提升了阅读体验。mendeley 可以说把维护一个 bib 文件的成本降为了 0,因此我建议 bib 文件不需要按文章,可以整个维护一个大的文献库。因为下面的工作流马上谈到共享方案,会发现 bib 文件变大不影响共享这件事。
共享方案
可能你的很多同事不会或者不喜欢用 bib,把自己的全部文献库的 bib 给出去也不太方便。那么怎么能结合 bib 引用文献的便捷和最初始方案中分享的灵活性呢?答案就在于和 .tex 编译后同处在一个文件夹的 .bbl 文件。事实上,这个文件里的内容,就对应了最原始方案 thebibliography
的部分。在分享之前,我们只需把这个同名 .bbl 文件的全部内容复制到 .tex 文件 替换 \bibliography
那一行即可。此时虽然你并没有手工维护整个参考文献,但原始方案的样子和单文件独立性又回来了。如果连复制一下都嫌麻烦的话,我还准备了脚本,一行命令就完成自动替换,请参考 insert_bbl。
考虑 .bst 文件
上文只提到了参考文献的内容部分,也即 .bib 文件。这节要考虑参考文献的样式控制部分,也即 .bst 文件。事实上,如果使用了 revtex 的 documentclass,也默认使用了 revtex.bst 的参考文献样式,不需要再额外指定。但是,这个官方样式实在是无力吐槽,很多细节和发表版本完全不一样。比如对于已经发表的文章,还会显示出 arxiv 预印版本的信息,如果文献是 book 或者 inproceedings 格式,那么题目爆出界也不换行。因此,想要舒服的使用,还是得准备自己的 bst 文件。一种方案是从零开始,通过命令行以回答问题的方式来作出 bst 文件,对应命令为 latex makebst
。不过一个更好的方案是直接在 revtex.bst 上微调,使得不协调的样式,发现一处魔改一处。下面我的 gist 就提供了一个基于 revtex.bst 的 patch,可以避免上面提到的样式错误。当然 .bst 代码的格式相当难看,可以盲人摸象,边摸索边尝试,其代码的结构可以参考4。使用自己的 bst 文件只需在 tex 文件加上一句 \bibliographystyle{/path/apsrev.bst}
即可。
其他细节
有了软件智能管理的文献内容,和我亲自手调过的文献样式,你以为这就大功告成,最完美的工作流就建立起来了?too young,还有一些小的点,如果不优雅的解决足够你恶心的了。因为 bib 管理生成的文献都是很纯粹的一条一个文献的形式,那么这节恶心的事情,几乎都是关于参考文献的地方,出现别的东西怎么办,此时单纯修改 bib 文件就无能为力了,而且你也不能因为这篇文章的特殊效果来污染了整个文献库的 bib。
需求一:列在参考文献处的脚注。APS 的文章就是这种格式,很多想说的解释也放在参考文献里,装成一个引用(这么做多半是为了避免正文的字数问题)。总不能每个角注都单独建一个 bib 条目。解决:事实上在 revtex 里,就直接当脚注写就行了, main text\footnote{some explanation}
,这样的写法编译出来,就会自动在参考文献中多出一条 some explanation,而且序号也是和参考文献按照引用顺序排下来的,完全符合 APS 的格式要求。
需求二:see supplemental materials for details. 由于 PRL 文章的字数限制,几乎每篇文章都会带有这句话。而这句话按照 APS 的规范,也是得出现在参考文献里边的,不能正文里加个括号了事。简单啊,和需求一一样,加 \footnote
就行了。可是一篇正文,可能有好几处让大家去参考 SM,然而如果只是单纯的利用脚注功能,每一次在参考文献中都会出现一个新的条目,于是一篇文章就会有七八个 see SM 的参考文献条目。解决:事实上,所有的 footnote 都有一个 bib 的自动配给的 key,格式是Note1,1可以替换为其他数字代表是第几个 footnote。那么假设正文第一次引用 supplemental material 时,写法是 main text blah\footnote{see SM for details}
,而这恰好是文章的第一个脚注的话。下一次在写这句话时,要用 main text again \cite{Note1}
。这样两次的引用就会指向同一个项。具体的可以参考5。
需求三:有些时候我们甚至希望在一个 item 里,同时列举两个文章,没错奇奇怪怪的要求就是这么多,这也就是为什么大多数人最后放弃了其他尝试,回归最原始的参考文献解决方案的原因。解决:实际上,利用 revtex 提供的功能,这一问题可以轻松解决,其语法为 \cite{keya,*keyb,*keyc}
, 这样 key abc 对应的三篇文献就会出现在参考文献的同一条目里。
需求四:and reference therein。没错,有时候我们还想在一个引用文献条目的前面或者后面再加上点其他话。这个 revtex 其实也帮我们实现好了,对应的语法是 \cite{*[{See also in }] [{ and reference therein}] key}
,注意中间那两个空格。
需求五:arxiv 文章的引用。这个理论上来讲,revtex 通过 Unpbulished 这个类可以完美支持。但 mendeley 似乎不支持对文献选择这个分类。因此我现在的一个 workaround 是,将 arXiv:2018.66666
整个作为期刊名填在 mendeley 上,这样最后对应的文章中的效果也还行,和正式发表版本的效果比较相似。
小结
至此,和文献引用相关的工作流就算是说的差不多了。最后讲一下,这一部分也不需要强迫症过重,投稿时候期刊格式要求并不严,最后的严格排版也是期刊那边实现,不需要自己操心,因此差不多就行了。有些效果实在折腾不出来也问题不大。文末安利两个和 latex 相关的其它小工具。一个是 git-latexdiff,用 git 来管理 latex 的必备良品;另一个是 tex-decomment.py 是我实现的 latex 去注释的小工具。arxiv 是可以下载到文章的 latex 源码的,上传的时候最好还是先去下注释,免得被别人发现什么不得了的事情。