如何测试条目书目键是否存在?我有一个接受键的命令,但如果键不存在,则应该回退到将参数作为标签处理。
梅威瑟:
\documentclass{article}
\usepackage{float}
\usepackage[UKenglish]{babel}
\usepackage{csquotes}
\usepackage[style=authoryear,uniquename=init,giveninits]{biblatex}
\DeclareNameAlias{sortname}{family-given}
\begin{filecontents}[overwrite]{\jobname.bib}
@book{bib-key,
author = {John Smith1 and Bob Smith2},
title = {Some Random Thing},
date = {1970}
}
\end{filecontents}
\addbibresource{\jobname.bib}
\newcommand\citecaptioninner[3]{%
{\caption[#3 #2. \protect\fullcite{#1}]{#2 \protect\parencite{#1}}}}%
%{\caption[#3 #2.]{#2}}} % Use this instead if key doesn't exist
\AtBeginEnvironment{figure}{%
\newcommand\citecaption[2]{%
\citecaptioninner{#1}{#2}{\figurename\ \thefigure.}%
\label{fig:#1}}}
\begin{document}
\section{Figures}
\begin{figure}[H]
\citecaption{bib-key}{References bibliography}
\end{figure}
\begin{figure}[H]
\citecaption{just-a-label}{Does not reference bibliography}
\end{figure}
\listoffigures
\end{document}
答案1
这有点棘手,因为在正常设置中(您不会发送 LaTeX 来解析文件本身),LaTeX 只能通过文件间接.bib
了解条目。这也是.bib
.bbl
乌尔丽克·菲舍尔 评论中提到.bbl
。特别是,检查 LaTeX 端是否存在条目的唯一方法是查看该条目是否由 Biber 或 BibTeX写入文件。
biblatex
有一个内部测试来查看文件中是否存在条目.bbl
(\blx@ifdata
),并且很容易使此测试可访问。但该测试依赖于数据.bbl
。
因此,以下内容只能可靠地告诉您.bbl
文件中是否存在条目键,即您的文档是否已请求该条目。实际上,这意味着只能找到明确\cite
d 或\nocite{*}
'd 的条目键(并且只有在成功运行 Biber 后才能找到它们)。
\documentclass{article}
\usepackage[UKenglish]{babel}
\usepackage{csquotes}
\usepackage[style=authoryear,uniquename=init,giveninits]{biblatex}
\DeclareNameAlias{sortname}{family-given}
\makeatletter
\newcommand*{\IsFoundBibkeyTF}{\blx@ifdata}
\makeatother
\addbibresource{biblatex-examples.bib}
\begin{document}
Lorem \autocite{sigfridsson}
% we don't cite the existing nussbaum
% obviouslyfakeentry does not exist in biblatex-examples.bib
\IsFoundBibkeyTF{sigfridsson}{T}{F}
\IsFoundBibkeyTF{nussbaum}{T}{F}
\IsFoundBibkeyTF{obviouslyfakeentry}{T}{F}
\end{document}
如果您将 添加\nocite{*}
到组合中,您还将正确测试nussbaum
未明确引用的 ,但当然\nocite{*}
意味着您将.bib
文件中的所有条目添加到参考书目中,这可能是不可取的。
\documentclass{article}
\usepackage[UKenglish]{babel}
\usepackage{csquotes}
\usepackage[style=authoryear,uniquename=init,giveninits]{biblatex}
\DeclareNameAlias{sortname}{family-given}
\makeatletter
\newcommand*{\IsFoundBibkeyTF}{\blx@ifdata}
\makeatother
\addbibresource{biblatex-examples.bib}
\begin{document}
Lorem \autocite{sigfridsson}
% we don't cite the existing nussbaum
% obviouslyfakeentry does not exist in biblatex-examples.bib
\IsFoundBibkeyTF{sigfridsson}{T}{F}
\IsFoundBibkeyTF{nussbaum}{T}{F}
\IsFoundBibkeyTF{obviouslyfakeentry}{T}{F}
\nocite{*}
\end{document}
可以发布\nocite
只针对要检查的条目键发出一个。然后,这将拾取文档中尚未引用的条目。但它有两个非常重要警告:它会对不存在的键发出警告 - 这大概就是您首先想要避免的。另一方面,如果存在条目,它会将条目添加到参考书目中 - 这可能也不是您想要的。
\documentclass{article}
\usepackage[UKenglish]{babel}
\usepackage{csquotes}
\usepackage[style=authoryear,uniquename=init,giveninits]{biblatex}
\DeclareNameAlias{sortname}{family-given}
\makeatletter
\newcommand*{\IsFoundBibkeyTF}[1]{\nocite{#1}\blx@ifdata{#1}}
\makeatother
\addbibresource{biblatex-examples.bib}
\begin{document}
Lorem \autocite{sigfridsson}
% we don't cite the existing nussbaum
% obviouslyfakeentry does not exist in biblatex-examples.bib
\IsFoundBibkeyTF{sigfridsson}{T}{F}
\IsFoundBibkeyTF{nussbaum}{T}{F}
\IsFoundBibkeyTF{obviouslyfakeentry}{T}{F}
\end{document}
加上警告
Package biblatex Warning: The following entry could not be found
(biblatex) in the database:
(biblatex) obviouslyfakeentry
(biblatex) Please verify the spelling and rerun
(biblatex) LaTeX afterwards.
在里面.log
。
如果您想要一个可以真正判断文件中是否存在输入键的测试.bib
,则需要跳过 Biber。您需要.bib
自己从 LaTeX 解析文件。
这是一个厚颜无耻地从 Enrico Gregorio 的usebib
包,它直接从文件中提取输入字段.bib
。
\documentclass{article}
\usepackage[UKenglish]{babel}
\usepackage{csquotes}
\usepackage[style=authoryear, backend=biber]{biblatex}
\usepackage{etoolbox}
\makeatletter
\newcommand*{\bibentrycheck@labels}{}
\def\bec@reuse@find#1#{%
\lowercase{\def\@tempa{#1}}%
\ifcsname bec@reuse@type@\@tempa\endcsname
\expandafter\@gobble
\else
\begingroup\@makeother\%\makeatother
\expandafter\bec@reuse@extract
\fi}
% special types: ignored
\let\bec@reuse@type@preamble\@empty
\let\bec@reuse@type@string\@empty
% extract key
\def\bec@reuse@extract#1{\bec@reuse@extract@entrykey#1\relax\endgroup}
\def\bec@reuse@extract@entrykey#1,#2\relax{\listgadd{\bibentrycheck@labels}{#1}}
\newcommand{\bibinput}[1]{%
\begingroup
\catcode`\^^M=10
\begingroup\lccode`\~=`\@
\lowercase{\endgroup\let~}\bec@reuse@find
\catcode`\@=\active \input{#1.bib}\endgroup}
\newcommand*{\IsFoundBibkeyTF}[1]{\ifinlist{#1}{\bibentrycheck@labels}}
\makeatother
\begin{filecontents}{\jobname.bib}
@article{sigfridsson,
author = {Sigfridsson, Emma and Ryde, Ulf},
title = {Comparison of methods for deriving atomic charges from the
electrostatic potential and moments},
journaltitle = {Journal of Computational Chemistry},
date = 1998,
volume = 19,
number = 4,
pages = {377-395},
doi = {10.1002/(SICI)1096-987X(199803)19:4<377::AID-JCC1>3.0.CO;2-P},
}
@book{nussbaum,
author = {Nussbaum, Martha},
title = {Aristotle's \mkbibquote{De Motu Animalium}},
date = 1978,
publisher = {Princeton University Press},
location = {Princeton},
}
\end{filecontents}
\addbibresource{\jobname.bib}
\bibinput{\jobname}
\begin{document}
Lorem \autocite{sigfridsson}
% we don't cite the existing nussbaum
% obviouslyfakeentry does not exist in biblatex-examples.bib
\IsFoundBibkeyTF{sigfridsson}{T}{F}
\IsFoundBibkeyTF{nussbaum}{T}{F}
\IsFoundBibkeyTF{obviouslyfakeentry}{T}{F}
\nocite{*}
\end{document}
请注意,这要求您\bibinput{<bib filename without extension>}
再次调用您添加的所有文件\addbibresource
。(似乎可以通过修补程序\addbibresource
自动执行此操作,但这又会带来麻烦。)
如果允许我发表最后评论,我认为编写一个\cite
-related 宏来测试其输入是否可能是输入键并且如果显然不是则表现不同是一种不好的风格。在问题的 MWE 中,似乎\citecaption
用于几件事:它设置一个标签和是(可能)您想要的条目键\cite
。我建议您将这些作业拆分为几个参数(如果您喜欢使用键值接口)。这样从一开始就可以清楚地知道什么是标签以及您引用的条目键是什么。特别是,我觉得调用很奇怪\citecaption
,这很清楚地暗示我引用了某些东西,而参数导致它不尝试引用任何东西。