在 Latex 中,有多种工具可用于为.bib
从几个较大的文件中提取的引用参考文献创建一个独立的文件.bib
;请参阅这个流行的 tex.stackexchange 问题。
有没有什么办法可以对pandoc
(嗯,pandoc-citeproc
)处理的 markdown 文档执行此操作?
语境:我正在撰写一篇文章(rmarkdown.Rmd
格式),并与云端的协作者共享。我参考了.bib
本地texmf
树中的几个文件。
bibliography:
- "../localtexmf/bibtex/bib/statistics.bib"
- "../localtexmf/bibtex/bib/graphics.bib"
- "../localtexmf/bibtex/bib/Rpackages.bib"
但是我的同事无法访问这些,除非我将它们复制到项目目录(然后必须保留重复的副本)。
LaTeX 解决方案依赖于.aux
处理.tex
文件时生成的文件。但是,pandoc
不会映射[@reference]
到\cite
文件,也不会生成.aux
文件。
有人问过类似的问题这里,但没有得到答复。
更新:可能没有使用 LaTex 或 的直接解决方案pandoc
,但第一步是使用perl
或sed
提取所有引用键、类似文件@key
中的字符串.Rmd
。
答案1
pandoc 的最新版本允许使用简短的 Lua 过滤器来执行此操作:
pandoc --lua-filter extract-bib.lua --to=biblatex paper.Rmd -o paper.bib
paper.Rmd
您的 Markdown 输入在哪里,并且extract-bib.lua
包含
function Pandoc(d)
d.meta.references = pandoc.utils.references(d)
d.meta.bibliography = nil
return d
end
这是最快、最简单、最干净的方法,但需要 pandoc 2.17 或更高版本。
还有 Robert Winkler 的基于 perl 的导出:
mdbibexport.pl 提取 pandoc Markdown 文档的引用参考文献,并为该文档写入 BibTeX 数据库。从 Markdown 文件中提取密钥并将其写入辅助文件,BibTool 将使用该文件在 bibtex (.bib) 数据库中查找参考文献并将其写入新文件。
作为第三种选择,可以将 mdbibexport 中使用的思想与 pandoc Lua 编写器结合起来重新实现。例如,以下内容将把简化的 bib 文件写入bibexport.bib
。将下面的脚本安全保存到文件中bibexport.lua
并正常调用 pandoc,但使用 bibexport.lua 作为目标格式:pandoc --to bibexport.lua …
local citation_ids = {}
function Doc(body, meta, vars)
local citations = {};
for cid, _ in pairs(citation_ids) do
citations[#citations + 1] = cid
end
-- create a dummy .aux file
local aux = '\\bibstyle{alpha}\n' ..
'\\bibdata{' .. meta.bibliography .. '}\n' ..
'\\citation{' .. table.concat(citations, ',') .. '}\n'
local auxfile_name = meta.auxfile or 'bibexport.aux'
local auxfile = io.open(auxfile_name, 'w')
auxfile:write(aux)
auxfile:close()
os.execute('bibexport bibexport.aux')
return 'Output written to bibexport.bib, aux to ' .. auxfile_name
end
function Cite(c, cs)
for i = 1, #cs do citation_ids[cs[i].citationId] = true end
return ''
end
function Str(s) return s end
setmetatable(_G, {__index = function() return function() return "" end end})
即使使用旧版本的 pandoc,它也应该可以工作,但需要将该bibexport
工具作为附加依赖项。
答案2
虽然似乎没有直接的解决方案,但您可以轻松使用 建立工作流程pandoc
。一个可能的解决方案是:
- 使用 pandoc 选项创建一个 tex 文件
--biblatex
。 - 运行
latex
一次 - 跑步
biber --output-format=bibtex file.bcf
当然,这并不是理想的,但如果您使用 makefile/脚本,整个过程就可以轻松实现自动化。
使用 biber,您还可以使用工具模式执行数据源的其他转换,例如解决交叉引用继承。
答案3
根据 Denis 的评论,这完全是有道理的,似乎你应该做一个多步骤的过程,你应该如何做在这篇文章(外部链接)中得到了很好的解释:https://martinandreasandersen.com/guides/a-nerds-guide-to-writing-papers-for-au/
唯一剩下的部分就是你用来创建 .tex 文档的 pandoc 命令。完整的过程如下:
pandoc_command 示例:
pandoc yourpaper.md -o yourpaper.tex --biblatex --bibliography=yourpaper.bib --pdf-engine=pdflatex
因此,在您的命令窗口或脚本中,您将看到类似以下内容:
pandoc_command
latex [yourpaper] # to prepare the document
biber [yourpaper] # to add references
latex [yourpaper] # to collect references
pdflatex [yourpaper] # puts it all together, outputs a pdf
答案4
由于您在 .Rmd 中写入,因此您可以使用以下 R 函数来清理您的 bib 文件:
library(stringr)
clean_bib <- function(input_file, input_bib, output_bib){
lines <- paste(readLines(input_file), collapse = "")
entries <- unique(str_match_all(lines, "@([a-zA-Z0-9]+)[,\\. \\?\\!\\]]")[[1]][, 2])
bib <- paste(readLines(input_bib), collapse = "\n")
bib <- unlist(strsplit(bib, "\n@"))
output <- sapply(entries, grep, bib, value = T)
output <- paste("@", output, sep = "")
writeLines(unlist(output), output_bib)
}
# now call the function
clean_bib(...)
只需在设置块中调用它即可。
该函数的作用是什么?它首先搜索输入文件中的所有引用,即以 @ 开头、包含字母和数字并以逗号、点、问号、感叹号、空格或 ] 结尾的字符串 - 根据您的需要进行调整。
然后它构建一个仅包含这些条目的新 bib 文件。