我想知道是否有可能在 LaTeX 中实现参考书目自动化。
例如,我只会在参考书目中放置 DOI 链接,而 Latex 会获取所有信息(作者、日期、标题等)。
答案1
R
这个答案是通过调用包rcrossref
、及其cr_cn
函数从 DOI 创建参考书目,然后使用knitr
在 LaTeX 中创建参考书目的概念证明。(请注意:knitr
和rcrossref
是R
包和安装R才能继续。
该cr_cn
函数从Crossref 数据库,其中包含期刊和书籍出版商提交给 Crossref 组织的文献计量数据。这种方法的一个限制是并非所有出版商都会将其出版数据提交给 Crossref。因此,如果出版商未提交相关元数据,则传递某些 DOI 可能不会返回元数据。
有多种方法可以R
与LaTeX
使用Sweave
或一起使用来调用代码knitr
。我使用了WinEdt
插件,关系经理。作者谢益辉knitr
在此列出了其他选择:knitr 的编辑. 另一个选择是使用RStudio。
LaTeX 和 R 代码位于 Rnw(R no web)文件中。R 代码块出现在分隔符<<>>=
和之间@
,表示代码块的开始和结束。.Rnw
编译文件时,将调用 R 来首先执行代码R
。这会生成一个.tex
文件,在本例中为.bib
文件。执行R
代码后,可以调用LaTeX
编译器(例如)来生成包含 指定样式的格式化参考书目的文件。PDFLaTeX
.pdf
Biblatex
R 代码只需要创建一个 dois 列表,并循环进行重复调用,以从传递给 Crossref 的 DOI 中检索出版物元数据。每个元数据项都以格式返回,并使用的函数将其bibtex
写入文件。.bib
R
write.table
执行 R 代码后,LaTeX
使用生成的.bib
文件(此处)使用和mybibfile.bib
创建参考书目。biblatex
biber
总结步骤顺序:(1)执行 R 代码生成.bib
文件(2)执行PDFlatex
生成.bcf
文件,(3)执行biber
创建.bbl
文件(4)执行PDFlatex
生成参考书目。自动RManager
执行WinEdt
该序列。
这是代码:
% knitr -> PDFLaTeX in WinEdt 10.2 with RManager plugin
% http://www.winedt.org/config/modes/RManager.html
\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[margin=2.5cm]{geometry}
\usepackage[style=authoryear,backend=biber]{biblatex}
\addbibresource{mybibfile.bib}
% This is the R code chunk
<<Preamble,include=FALSE>>=
# install the R packages, if they are not already installed.
#install.packages("rcrossref",dependencies=True)
#install.packages("patchDVI",dependencies=True)
# load knitr and rcrossref
library(knitr)
library(rcrossref)
# nominate the DOIs of interest
mydois <- c('10.1002/andp.19053221004',
'10.1038/171737a0',
'10.1038/227680a0',
'10.1103/PhysRevB.37.785')
# extract the metadata for each DOI from Crossref and write the bib file
for(i in 1:4) {
x <- cr_cn(dois=mydois[i], format = "bibtex")
write.table(x,file="mybibfile.bib",append=TRUE,row.names=FALSE,col.names=FALSE,fileEncoding="UTF-8")
}
@
% Print the bibliography
\begin{document}
\nocite{*}
\printbibliography
\end{document}
这是LaTeX
输出:
答案2
答案已重新修改,以便可以将任意输入键分配给 DOI 条目。
以下是使用 LuaLaTeX 进行查询的概念证明https://api.crossref.org并将.bib
条目下载到\jobname-doidump.bib
。为了避免对同一条目多次查询数据库,我们会记住临时文件中请求的密钥\jobname.dol
(这意味着不应手动修改这两个文件,而应一起删除,如果 DOI 密钥对发生变化,则应删除这两个文件)。
您可以随时通过 申请 DOI \getdoias{<DOI>}{<entrykey>}
。然后可以照常引用所申请的密钥。
\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}
\usepackage[style=authoryear, backend=biber]{biblatex}
% externalise lua code, so we don't have to escape stuff
\usepackage{filecontents}
\begin{filecontents*}{doidownload.lua}
function download_to_table(url)
local texio = texio
local io = require('io')
local http = require('socket.http')
local ltn12 = require('ltn12')
local requestbody = {}
texio.write_nl('Downloading ' .. url)
texio.write_nl('')
http.request{
url = url,
sink = ltn12.sink.table(requestbody)
}
return requestbody
end
-- this function is not used any more, but might still be of interest
function download_to_file_append(url, file_name)
local io = require('io')
local requestbody = download_to_table(url)
local file_handle = io.open(file_name, 'a')
file_handle:write(table.concat(requestbody))
file_handle:write('\n')
file_handle:write('\n')
io.close(file_handle)
end
function save_doi_as_key_to(doi, key, file_name)
local texio = texio
local string = string
local io = require('io')
local file_handle = io.open(file_name, 'a')
local bibentry_tab = download_to_table('https://api.crossref.org/works/' ..
doi .. '/transform/application/x-bibtex')
local bibentry_str = table.concat(bibentry_tab)
if string.match(bibentry_str, '^%s*@.-{.-,') then
bibentry_str = string.gsub(bibentry_str, '^%s*@(.-){.-,', '@%1{' .. key .. ',', 1)
file_handle:write(bibentry_str)
file_handle:write('\n')
file_handle:write('\n')
else
texio.write_nl('Warning: Failed to obtain valid bib entry for ' .. key)
texio.write_nl('with DOI ' .. doi .. '.')
end
io.close(file_handle)
end
\end{filecontents*}
% load the main lua code
\directlua{dofile('doidownload.lua')}
% machinery to track downloaded entry keys
\newcommand*{\entrylist}{}
\newcommand*{\entrylistadd}[1]{%
\xifinlist{\detokenize{#1}}{\entrylist}
{}
{\listeadd{\entrylist}{\detokenize{#1}}}}
% {<DOI>}{<entrykey>}
% gets an entry by DOI and assigns the supplied entrykey
\newcommand*{\getdoias}[2]{%
\xifinlist{\detokenize{#2}}{\entrylist}
{}
{\directlua{save_doi_as_key_to('\luaescapestring{#1}',
'\luaescapestring{#2}' ,
'\luaescapestring{\jobname-doidump.bib}')}
\listeadd{\entrylist}{\detokenize{#2}}}}
% get known keys from .dol file
\IfFileExists{\jobname.dol}{\input{\jobname.dol}}
% write known keys to .dol file to avoid unnecessary queries to crossref API
\makeatletter
\AtEndDocument{%
\newwrite\dol@out
\immediate\openout\dol@out\jobname.dol\relax
\immediate\write\dol@out{%
\@percentchar\space Do not edit this file\blx@nl
\@percentchar\space You may, however, safely delete this file if you also delete\blx@nl
\@percentchar\space\jobname-doidump.bib}%
\def\do#1{\immediate\write\dol@out{\string\entrylistadd{#1}}}%
\dolistloop\entrylist
\immediate\closeout\dol@out}
\makeatother
% if you change a DOI-key pair you should delete the *.dol7
% and *-doidump.bib file to re-enable a clean download
% load the download .bib file
\addbibresource{\jobname-doidump.bib}
% \getdoias can be used in the preamble or the document
\getdoias{10.1002/(SICI)1096-987X(199803)19:4<377::AID-JCC1>3.0.CO;2-P}{sigfridsson}
\begin{document}
\cite{sigfridsson}
\cite{kastenholz}
\getdoias{10.1063/1.2172593}{kastenholz}
\printbibliography
\end{document}
你可以明白为什么我认为这是个坏主意。我还没有遇到过.bib
不需要手动干预即可下载源代码的在线服务。另请参阅软件生成的书目条目:使用前应检查的常见错误和其他错误
这里,字段url
不必要地重复了 DOI,这一点非常突出。month
两个条目中的字段填写不正确。我忘了展示这一点,但人们可能得到的全大写名称(参见 Ross 的回答)也不太好。
我建议你使用参考文献管理器来创建.bib
文件。其中一些提供了从 DOI 获取条目的方法(当然JabRef 有这样的功能,Zotero 支持,Mendeley 也是如此)。这样做的一大优势在于,您可以在下载条目后对其进行修改(我坚信这在几乎所有情况下都是必要的),而且数据更加持久,您可以在不同的文档中重复使用您的引文。