如何获得第二个参考书目? [英] How to get a second bibliography?

查看:44
本文介绍了如何获得第二个参考书目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

rmarkdown PDF 和 HTML 中,我想要两本参考书目——一本用于论文/书籍,另一本用于我在研究中使用的软件.我发现了

以前有没有人做过这个并且可以解释一下怎么做?

解决方案

这并非微不足道,而是可能的.以下使用 pandoc Lua 过滤器和 pandoc 2.1.1 及更高版本中可用的函数.您必须升级到最新版本才能使其正常工作.

通过将其添加到文档的 YAML 部分来使用过滤器:

---输出:bookdown::html_document2:pandoc_args: --lua-filter=multiple-bibliographies.luabibliography_normal: normal-bibliography.bib参考书目_软件:software.bib---

然后添加 div 以标记参考书目应该包含在文档中的位置.

# 参考书目::: {#refs_normal}:::::: {#refs_software}:::

每个 refsX<​​/code> div 应该在标题中有一个匹配的 bibliographyX 条目.

Lua 过滤器

Lua 过滤器允许以编程方式修改文档.我们使用它来单独生成参考部分.对于每个看起来应该包含引用的 div(即,其 ID 为 refsX<​​/code>,X 为空或您的主题名称),我们创建临时虚拟包含所有引文和参考 div 的文档,但其中 bibliography 设置为 bibliographyX 的值.这允许我们为每个主题创建参考书目,同时忽略所有其他主题(以及主要参考书目).

上述步骤并未解析实际文档中的引用,因此我们需要单独执行此操作.将所有 bibliographyX 折叠到 bibliography 元值中并在完整文档上运行 pandoc-citeproc 就足够了.

-- 文件:multiple-bibliographies.lua--- 文档中所有引用的集合本地 all_cites = {}--- 文档元值本地 doc_meta = pandoc.Meta{}---为给定的主题创建参考书目.这作用于其 ID 的所有 div-- 以refs"开头,后面是下划线和字母数字-  人物.本地函数 create_topic_bibliography (div)本地名称 = div.identifier:match('^refs([_%w]*)$')如果没有名字,那么返回零结尾本地 tmp_blocks = {pandoc.Para(all_cites),pandoc.Div({}, pandoc.Attr('refs')),}本地 tmp_meta = pandoc.Meta{bibliography = doc_meta['bibliography' .. name]}本地 tmp_doc = pandoc.Pandoc(tmp_blocks, tmp_meta)本地资源 = pandoc.utils.run_json_filter(tmp_doc, 'pandoc-citeproc')-- 结果的第一个块包含虚拟 para,第二个是 refs Divdiv.content = res.blocks[2].content返回div结尾本地函数 resolve_doc_citations (doc)-- 结合所有参考书目本地元 = doc.meta本地 orig_bib = meta.bibliographymeta.bibliography = pandoc.MetaList{orig_bib}对于名称,值成对(元)做if name:match('^bibliography_') 那么table.insert(meta.bibliography, value)结尾结尾doc = pandoc.utils.run_json_filter(doc, 'pandoc-citeproc')doc.meta.bibliography = orig_bib -- 恢复到原始值返回文档结尾返回 {{引用 = 函数 (c) all_cites[#all_cites + 1] = c 结束,元 = 函数 (m) doc_meta = m 结束,},{Pandoc = resolve_doc_citations,},{Div = create_topic_bibliography,}}

我将过滤器作为官方支持的Lua 过滤器集合的一部分发布.请参阅此处了解更完整、最新的版本,该版本也遵守 cslnocite 设置.

有关 Lua 过滤器的更多信息和详细信息,请参阅 R Markdown 文档.

In rmarkdown PDF and HTML I want two bibliographies—one for papers/books, and one for software I have used in my research. I found this related issue but it doesn't answer my question since it's concerning the combination of two *.bib files into one bibliography.

I'm used to place my bibliography with <div id="refs"></div> as explained here. Possibly a second one can be placed similarly with <div id="refs_2"></div>, but I couldn't figure out how to do it since this "refs" seems not to be defined anywhere.

I usually define the software in the YAML header like this

nocite: |
    @xie_knitr:_2018, @allaire_rmarkdown:_2018, @rstudio_team_rstudio:_2016, 
    @r_development_core_team_r:_2018

so I don't have to constantly copy-paste it into the *.bib-file every time (which works well with one bibliography). Ideally this nocite:-list would appear as a new bibliography titled "Software" below the other, but I also would be happy with a two *.bib-file solution.

The expected output would be something like this:

Has anybody done this before and could explain how to do this?

解决方案

This isn't entirely trivial, but possible. The following uses pandoc Lua filters and a function available in pandoc 2.1.1 and later. You'll have to upgrade to a recent version to make it work.

Using the filter works by adding this to your document's YAML section:

---
output:
  bookdown::html_document2:
    pandoc_args: --lua-filter=multiple-bibliographies.lua
bibliography_normal: normal-bibliography.bib
bibliography_software: software.bib
---

Then add divs to mark where the bibliographies are supposed to be included in the document.

# Bibliography

::: {#refs_normal}
:::

::: {#refs_software}
:::

Each refsX div should have a matching bibliographyX entry in the header.

The Lua Filter

Lua filters allow to modify the document programmatically. We use this to generate the reference section separately. For each div that looks like it is supposed to contain references (i.e., whose ID is refsX, with X being empty or the name of your topic), we create temporary dummy documents which contain all citations and the reference div, but where bibliography is set to the value of bibliographyX. This allows us to create the bibliography for each topic while ignoring all other topics (as well as the main bibliography).

The aforementioned step doesn't resolve the citations in the actual document, so we need to do this separately. It is enough to fold all bibliographyX into the bibliography meta value and the run pandoc-citeproc on the full document.

-- file: multiple-bibliographies.lua

--- collection of all cites in the document
local all_cites = {}
--- document meta value
local doc_meta = pandoc.Meta{}

--- Create a bibliography for a given topic. This acts on all divs whose ID
-- starts with "refs", followed by nothings but underscores and alphanumeric
-- characters.
local function create_topic_bibliography (div)
  local name = div.identifier:match('^refs([_%w]*)$')
  if not name then
    return nil
  end
  local tmp_blocks = {
    pandoc.Para(all_cites),
    pandoc.Div({}, pandoc.Attr('refs')),
  }
  local tmp_meta = pandoc.Meta{bibliography = doc_meta['bibliography' .. name]}
  local tmp_doc = pandoc.Pandoc(tmp_blocks, tmp_meta)
  local res = pandoc.utils.run_json_filter(tmp_doc, 'pandoc-citeproc')
  -- first block of the result contains the dummy para, second is the refs Div
  div.content = res.blocks[2].content
  return div
end

local function resolve_doc_citations (doc)
  -- combine all bibliographies
  local meta = doc.meta
  local orig_bib = meta.bibliography
  meta.bibliography = pandoc.MetaList{orig_bib}
  for name, value in pairs(meta) do
    if name:match('^bibliography_') then
      table.insert(meta.bibliography, value)
    end
  end
  doc = pandoc.utils.run_json_filter(doc, 'pandoc-citeproc')
  doc.meta.bibliography = orig_bib -- restore to original value
  return doc
end

return {
  {
    Cite = function (c) all_cites[#all_cites + 1] = c end,
    Meta = function (m) doc_meta = m end,
  },
  {Pandoc = resolve_doc_citations,},
  {Div = create_topic_bibliography,}
}

I published the filter as part of the officially supported Lua filters collection. See there for a more complete, up-to-date version which also respects csl and nocite settings.

For more info and details on Lua filters, see the R Markdown docs.

这篇关于如何获得第二个参考书目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆