pandoc,markdown:根据引用的参考文献创建自包含的.bib 文件

pandoc,markdown:根据引用的参考文献创建自包含的.bib 文件

在 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,但第一步是使用perlsed提取所有引用键、类似文件@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。一个可能的解决方案是:

  1. 使用 pandoc 选项创建一个 tex 文件--biblatex
  2. 运行latex一次
  3. 跑步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 文件。

相关内容