![为什么 \iffieldequalstr 不起作用?](https://linux22.com/image/416551/%E4%B8%BA%E4%BB%80%E4%B9%88%20%5Ciffieldequalstr%20%E4%B8%8D%E8%B5%B7%E4%BD%9C%E7%94%A8%EF%BC%9F.png)
我无法让\iffieldequalstr
Biblatex 中的条件测试工作。下面是一个例子,我打算删除除特定作者的注释之外的所有注释(我的 Zotero 数据库中有一些自动下载的无关注释,我通常不想显示,但对于一位作者,我确实需要一条注释) - 但该作者的注释也被删除了:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[backend=biber,bibstyle=authoryear,citestyle=authoryear-icomp,url=true,isbn=false,doi=false]{biblatex}
\usepackage{filecontents}
\begin{filecontents}{bibfile.bib}
@book{smith_2010,
location = {London},
title = {An Interesting Book},
publisher = {Big Publishing Company},
author = {Smith, John},
date = {2010-01-01},
note = {Note I do want included}
}
@book{evans_2011,
location = {New York},
title = {Another Interesting Book},
publisher = {Small Publishing Company},
author = {Evans, Joe},
date = {2011-01-01},
note = {Note I don't want included}
}
\end{filecontents}
\addbibresource{bibfile.bib}
\AtEveryBibitem{
\iffieldequalstr{author}{Smith, John}
{}
{\clearfield{note}}}
\begin{document}
\textcite{smith_2010}
\textcite{evans_2011}
\printbibliography
\end{document}
作为输出,我得到了包含的两条注释,尽管目的是删除附在 Evans 上的注释。我哪里做错了?
答案1
\iffieldequalstr
仅适用于文字字段,但是author
一个名称列表,其内部结构复杂,不能轻易与简单字符串进行比较。
我认为比较名称的最佳方法是通过名称哈希。另请参阅我的答案到使用 biblatex 将特定作者设为粗体。名称哈希可能有点难以处理(参见使用 biblatex 突出显示参考书目中的作者,并允许使用参考书目样式对其进行格式化),因此链接的答案使用更复杂的方法从 Biber 中自动提取相关的名称哈希。
有了链接答案中的定义,我们现在可以将名称与进行比较\xifinlist{\thefield{hash}}{\nhblx@notehashes}
。现在我们需要一种方法来可靠地检测条目中是否存在名称。一种非常巧妙的方法在奥黛丽的回答 biblatex:动态过滤参考文献中特定作者的出版物:我们滥用名称索引来循环遍历所有名称项。
综合起来,我们得到
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[backend=biber,
style=authoryear-icomp,
doi=false, url=true, isbn=false,
]{biblatex}
\makeatletter
\def\nhblx@bibfile@name{\jobname -nhblx.bib}
\newwrite\nhblx@bibfile
\immediate\openout\nhblx@bibfile=\nhblx@bibfile@name
\immediate\write\nhblx@bibfile{%
@comment{Auto-generated file}\blx@nl}
\newcounter{nhblx@name}
\setcounter{nhblx@name}{0}
\newcommand*{\nhblx@writenametobib}[1]{%
\stepcounter{nhblx@name}%
\edef\nhblx@tmp@nocite{%
\noexpand\AfterPreamble{%
\noexpand\setbox0\noexpand\vbox{%
\noexpand\nhblx@getmethehash{nhblx@name@\the\value{nhblx@name}}}}%
}%
\nhblx@tmp@nocite
\immediate\write\nhblx@bibfile{%
@misc{nhblx@name@\the\value{nhblx@name}, author = {\unexpanded{#1}}, %
options = {dataonly=true},}%
}%
}
\AtEndDocument{%
\closeout\nhblx@bibfile}
\addbibresource{\nhblx@bibfile@name}
\newcommand*{\nhblx@notehashes}{}
\DeclareNameFormat{nhblx@hashextract}{%
\xifinlist{\thefield{hash}}{\nhblx@notehashes}
{}
{\listxadd{\nhblx@notehashes}{\thefield{fullhash}}}}
\DeclareCiteCommand{\nhblx@getmethehash}
{}
{\printnames[nhblx@hashextract][1-999]{author}}
{}
{}
\newcommand*{\addnotenames}{\forcsvlist\nhblx@writenametobib}
\newcommand*{\resetnotenames}{\def\nhblx@notehashes{}}
\newtoggle{notename}
\DeclareIndexNameFormat{notename}{%
\xifinlist{\thefield{hash}}{\nhblx@notehashes}
{\global\toggletrue{notename}}
{}}
\AtEveryBibitem{%
\togglefalse{notename}%
\indexnames[notename]{labelname}%
\iftoggle{notename}
{}
{\clearfield{note}}}
\makeatother
\addnotenames{John Smith}
\begin{filecontents}{\jobname.bib}
@book{smith_2010,
location = {London},
title = {An Interesting Book},
publisher = {Big Publishing Company},
author = {Smith, John},
date = {2010-01-01},
note = {Note I want included},
}
@book{evans_2011,
location = {New York},
title = {Another Interesting Book},
publisher = {Small Publishing Company},
author = {Evans, Joe},
date = {2011-01-01},
note = {Note I don't want included},
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\textcite{smith_2010}
\textcite{evans_2011}
\printbibliography
\end{document}
鉴于我们在评论中关于该目的的讨论note
,这样的事情可能会更方便。
在这里,您不需要在note
文件中给出作者的注释.bib
,而是直接在文档中给出特定作者的注释。注释会自动添加到参考书目中的作者姓名后面。
不过,识别姓名的基本思路与上述相同。我们仍然使用姓名哈希。但这次我们还将注释与可以轻松打印的相关哈希关联起来。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[backend=biber,
style=authoryear-icomp,
doi=false, url=true, isbn=false,
]{biblatex}
\makeatletter
\def\nhblx@bibfile@name{\jobname -nhblx.bib}
\newwrite\nhblx@bibfile
\immediate\openout\nhblx@bibfile=\nhblx@bibfile@name
\immediate\write\nhblx@bibfile{%
@comment{Auto-generated file}\blx@nl}
\newcounter{nhblx@name}
\setcounter{nhblx@name}{0}
\newcommand*{\nhblx@writenameandnotetobib}[2]{%
\stepcounter{nhblx@name}%
\edef\nhblx@tmp@nocite{%
\noexpand\AfterPreamble{%
\noexpand\setbox0\noexpand\vbox{%
\noexpand\nhblx@hashnoteextract{nhblx@name@\the\value{nhblx@name}}}}%
}%
\nhblx@tmp@nocite
\immediate\write\nhblx@bibfile{%
@misc{nhblx@name@\the\value{nhblx@name},\blx@nl
\space\space author = {\unexpanded{#2}},\blx@nl
\space\space note = {\unexpanded{#1}},\blx@nl
\space\space options = {dataonly=true},\blx@nl
}%
}%
}
\AtEndDocument{%
\closeout\nhblx@bibfile}
\addbibresource{\nhblx@bibfile@name}
\newcommand*{\nhblx@notehashes}{}
\DeclareNameFormat{nhblx@hashnoteextract}{%
\global\csletcs{hashnotemap@\thefield{hash}}{abx@field@note}}
\DeclareCiteCommand{\nhblx@hashnoteextract}
{}
{\printnames[nhblx@hashnoteextract][1-999]{author}}
{}
{}
\newcommand*{\addnotenames}[2]{\forcsvlist{\nhblx@writenameandnotetobib{#2}}{#1}}
\makeatother
\newrobustcmd*{\mknotename}[1]{%
\ifcsundef{hashnotemap@\thefield{hash}}
{#1}
{#1 (\csuse{hashnotemap@\thefield{hash}})}%
}
\DeclareNameWrapperFormat{notenames}{%
\renewcommand*{\mkbibcompletename}{\mknotename}%
#1}
\DeclareNameWrapperAlias{sortname}{notenames}
\addnotenames{John Smith}{A note for John Smith}
\begin{filecontents}{\jobname.bib}
@book{smith_2010,
location = {London},
title = {An Interesting Book},
publisher = {Big Publishing Company},
author = {Smith, John},
date = {2010-01-01},
}
@book{evans_2011,
location = {New York},
title = {Another Interesting Book},
publisher = {Small Publishing Company},
author = {Evans, Joe},
date = {2011-01-01},
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\textcite{smith_2010}
\textcite{evans_2011}
\printbibliography
\end{document}
该想法的一个不太自动化的版本使用直接在文件中给出的文字字段注释.bib
,并且可以附加到名称列表中的特定项目。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[backend=biber,
style=authoryear-icomp,
doi=false, url=true, isbn=false,
]{biblatex}
\newrobustcmd*{\mknotename}[1]{%
\hasitemannotation
{#1 (\getitemannotation)}
{#1}%
}
\DeclareNameWrapperFormat{notenames}{%
\renewcommand*{\mkbibcompletename}{\mknotename}%
#1}
\DeclareNameWrapperAlias{sortname}{notenames}
\begin{filecontents}{\jobname.bib}
@book{smith_2010,
location = {London},
title = {An Interesting Book},
publisher = {Big Publishing Company},
author = {Smith, John},
author+an = {1="Some note"},
date = {2010-01-01},
}
@book{evans_2011,
location = {New York},
title = {Another Interesting Book},
publisher = {Small Publishing Company},
author = {Evans, Joe},
date = {2011-01-01},
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\textcite{smith_2010}
\textcite{evans_2011}
\printbibliography
\end{document}