Using R: 使用 Zotero 为 Rmarkdown 插入参考文献

如何在 blogdown 中处理参考文献?

什么是 blogdown?

其入门手册标题 blogdown: Creating Websites with R Markdown 是对 blogdown 最恰当最简洁的解释。实际上笔者自己的博客正是使用 blogdown 构建。

什么是参考文献?

证明我说的话不是乱讲的底气(误

为什么要处理参考文献

首先需要确定的是,手动添加参考文献是不在本文的讨论范围内的,毕竟 Copy & Paste 似乎只需要管理好剪切板(Clipboard)就已经完成了绝大多数工作,且这就是纯文本的处理。然而,在我个人看来手动粘贴参考文献最终会发展参考灾难,不是这一次出错就是下一次出错,而且改参考文献格式的痛苦谁试谁知道。

常见的参考文献管理工具大致有 EndNote、Mendeley、Zotero 管理库。得益于师兄师姐的流行,基于中科院大用户版的EndNote大概是国内普及程度最高的参考文献管理工具之一(此处没有文献支持,就显得很没底气)。然而考虑到支持正版人人有责,且EndNote在macOS诡异的UX以及通用型不强的样式管理又及对手稿的污染性插入,所有笔者个人选择了 Zotero 作为参考文献管理工具。Why not Mendeley?不知为何,这软件总是处理不好 Who et, al 2021 这种句内引用,所以放弃。不过这并不是说软件有问题,大概率是笔者没有搞清楚而已。

不过参考文献管理工具的选择并非本文的核心内容,我们需要的是将参考文献导出为 bib (Bibliography) 而已。

One More Step upon R Markdown

在讨论 blogdown 插入参考文献之前,我们先说回 R Markdown 插入参考文献,毕竟 blogdown 也只是 R Markdown 更进一步的应用。根据 2.1 in bookdown 的阐述,R Markdown 通过 knitrknitr::knit 渲染为 Markdown 文件,随后 Markdown 通过 Pandoc 渲染为目标格式。而对于参考文献样样式的处理就是发生在 Pandoc 的转换过程中。根据 R Markdown 参考手册,可以使用手工插入 Bibliography 文件中文献标记的方法半手工的插入参考文献。

A diagram illustrating how an R Markdown document is converted to the final output document

然而这种方法虽然可以杜绝参考文献引用错误且能方便的修改格式——只要引入自定义好的 csl (Citation Style) 文件即可。然而手动插入参考文献本身效率也是比较低下的,相较于 Zotero 在 Microsoft Word 中的 Zotero Citation Addon 也没有那么优雅。更要命的是 Zotero 只有在将文献导出为 bib 文件的时候才会为其生成一个 Citation Keys,这就意味着需要再打开 bib 文件,定位到文献位置,查找 Citation Keys 才能在 R Markdown 中引用。

Add Citations in MS Word

不好用就改造它,Better BibTeX for Zoterorbbt 登场!

把参考文献优雅引入 R Markdown 分三步

Step1,设置 Citation Key

首先解决 Citation Keys 获取繁琐的问题。使用 Better BibTeX for Zotero (下称 BBT)可以增强 Zotero 对 bib 文件的支持能力。首先 BBT 在文献倒入 Zotero 数据库的同时就会为其生成一个唯一的 Citation Keys。

Citation Keys generated by BBT (retrieved from https://guides.library.iit.edu/c.php?g=720120&p=6296986)

对于大多数用户来说,BBT 默认的设置以及 Citation Key 生成模式已经足够使用了。不过对于多个数据库或者多设备同步的用户来说 patternA 和 pattern_b 等不同格式的混用也是非常的令人困扰。根据 BBT 官方设置指南,可以按照作者姓名及其各种变体、日期、备注信息、页码、期刊、关键字、标题以及几乎 Zotero 参考条目中的任何信息的任何格式用作 Citation Key 的格式,据日可自定义字段参考Generating citekeys for your references

以我在 Zotero 中使用的格式例如 jiangContaminationShortchainChlorinated2018 为例,如何进行这样的设置呢?

首先在 Zotero 的 Preference 中找到 Better BibTeX 选项卡,随后在 Citation keys 页面中的 Citation key kormat 设置样式,例如: [auth:lower][shorttitle3_3][year]

其中 auth:lower 代表将第一作者英文名小写,shorttitle3_3 代表选取文献标题的前三个字符,year 则代表文献出版年份。

BBT Preference

当论文生成 Citation Key 并已经在 RMarkdown 中引用之后,大概没人希望 Citation Key 会再次发生变化。为了避免在之后刷新数据库或者其他操作导致 Citation Key 变化,选中参考文献,通常笔者会选中 Zotero 库中的所有文献,点击右键 Better BibTe - Pin BibTex Key 就可以锁定 Citation Key。

Pin BibTex Key

这样后续的操作,例如修改作者名字和论文名(Typo 是敌人),将不会改变 Citation Key,也就不会导致参考文献引用的失败。

Step 2,导出 Bibliography 参考文献 —— 可跳过

这里还是以 Zotero 为例,选中需要使用的 Library,将其导出为 bib 文件即可。

不过这还不是最优雅的使用方法,每次都要手动导出,也是很累的!怎么办?后面继续看!

Export Bib

Step 3,一键插入参考文献

首先在 RMarkdown 中 YAML Header 部分引入 Step 2 导出的 bib 文件,例如:

---
title: 'R for Everything: 时间序列预测—— ARIMA、灰色模型 GM(1,1)、神经网络与混合预测(上)'
author: Han Chen
date: '2021-04-26'

## A bib file which is generated by Zotero
bibliography: references.bib
---

随后在 RStudio 中安装 rbbt:

remotes::install_github("paleolimbot/rbbt")

随后在 RStudio 的 Addins 中应该可以看到 rbbt 相关的按钮。

rbbt button

点击 Insert Zotero Citation 按钮就会弹出 Zotero 文献的选择弹窗,选取后可自动插入 RMakdown 中。

rbbt addon

不过点击 Addin 也是挺麻烦的,不如给这个功能设置快捷键。在 RStudio 最顶端的 Tools 菜单中,选择 Modify Keyboard Shortcuts,在弹出页面中搜索 Insert Zotero Citation 便可给该功能设置快捷方式,这里我们设置成 CMD/Ctrl + M 插入(毕竟是 Mendeley 的老用户……

RStudio Shortcuts

上面这些操作看起来还不错是吧?不过,每次添加新的文献到 Zotoer 并将其引用到文章中依然要在 Zotero 中导出才好,这完全不像是现代化的操作模式。

rbbt 根据引用文献,自动从 Zotero 生成 bib 文件的功能。

其方法如下:

rbbt::bbt_update_bib(path_rmd = "manuscript.Rmd", path_bib = "references.bib", translator = "bibtex"s)

上述命令会检查 manuscript.Rmd 文件中的所有 LaTeX 引文标记,并按照 bibtex 的格式,输出为 references.bib 文件(在 YAML Header 部分定义)。这一操作,在 Addins 中也有定义:Update bibliography for current document

对于普通的 Rmarkdown 文件,上面的全套操作基本能满足插入引文的需求。然而,对于 blogdown 渲染文章来说,上述的操作有一个小问题:knitr 对于 blogdown 的渲染几乎是一键式操作,所以在执行之前,还需要手动 Update bibliography for current document,这还是不够自动化!

通过 knitr 渲染 Blogdown

想要解决这个问题,方法也很简单,只要在第一个引文标记出现之前,自动化的运行 rbbt::bbt_update_bib 就可以自动化生成最新的参考文献目录。

具体来说,通常 Rmd 文件在 YAML Header 之后会跟

{r include=FALSE}
knitr::opts_knit$set(tidy = TRUE,
                     cache = TRUE)

这样一段代码,其实是对 knitr 进行初始化的设置,同样的道理,我们可以在 knitr 对正文开始渲染之前也插入一段代码,更新并生成 bibliography 文件:

# Collect cited reference from current RMarkdown file into references.bib file
rbbt::bbt_write_bib("references.bib",
                    rbbt::bbt_detect_citations("index.zh-hans.Rmd"), 
                    overwrite = TRUE)

注意,默认设置下 knitr 对文件渲染过程中,文件所在目录即为 word directory,因此如无特殊需求, index.zh-hans.Rmdreferences.bib 均无需添加路径。

这段代码可以添加到最开始的 knitr 初始化代码块中,也可以自行添加新的代码块,通过将代码块设置为 include = FALSE 即可将代码块从最终文档中隐藏。

至此,使用 Zotero 自动化处理 Rmarkdown 中参考文献的方法就完成了。

上篇文章 R for Everything: 时间序列预测—— ARIMA、灰色模型 GM(1,1)、神经网络与混合预测(上),便是使用此方法插入文献。


欢迎通过邮箱微博, Twitter以及知乎与我联系。也欢迎关注我的博客。如果能对我的 Github 感兴趣,就再欢迎不过啦!