我想使用 BibLaTeXpubstate
字段来表示尚未有出版日期(空日期字段)的“准备中”出版物,就像这个 authoryear 样式的:
@Article{Test,
author = {Author, A.},
journaltitle = {A Journal},
title = {A Title},
pubstate = {inpreparation},
}
但是,这会在期刊名称后面留下一个空括号:
\documentclass{article}
\usepackage[backend=biber, style=authoryear]{biblatex}
\addbibresource{Bib2.bib}
\begin{document}
Test \parencite{Test}.
\printbibliography
\end{document}
我怎样才能删除它?
答案1
这里的根本问题是,与其他命令不同,\print(field|list|names|date)
该命令\printtext
事先并不知道它是否会打印某些内容。因此,即使后来发现不需要打印任何内容,它也会始终应用格式参数。这意味着我们最终会得到一对空括号。
解决这个问题的一种方法是在调用之前检查我们是否要打印一些内容\printtext
。
虽然有些biblatex
代码使用\ifthenelse
大多数较新的代码使用etoolbox
。\ifboolexpr
请注意,内部biblatex
没有字段date
,如果您想测试是否存在,date
最好测试year
\renewbibmacro*{issue+date}{%
\ifboolexpr{test {\iffieldundef{issue}} and test {\iffieldundef{year}}}
{}
{\printtext[parens]{%
\printfield{issue}%
\setunit*{\addspace}%
\usebibmacro{date}}%
\newunit}}
也可以看看https://github.com/plk/biblatex/issues/793。
有些人可能会对biblatex-apa
最近实现的一个版本感兴趣\printtext
,它会自动检查是否打印某些内容,如果没有,则抑制格式。请参阅https://github.com/plk/biblatex-apa/pull/99。如果事实证明该命令没有任何负面影响,我们可能会考虑将其移至核心biblatex
,但它需要更多测试(并且实施起来感觉很像作弊)。
\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}
\usepackage[style=authoryear, backend=biber]{biblatex}
\renewbibmacro*{issue+date}{%
\printtexte[parens]{%
\printfield{issue}%
\setunit*{\addspace}%
\usebibmacro{date}}%
\newunit}
% implement \printtexte
\makeatletter
% Optional parens/brackets
% Thanks to egreg from https://tex.stackexchange.com/questions/53068/how-to-check-if-a-macro-value-is-empty-or-will-not-create-text-with-plain-tex-co
% for this test for expanded emptiness so that we can easily opt to not print parens around nothing
% Without this, it is very messy - you have to test all potential fields for defness first and this
% is messy because the fields in the additional info vary betwee entrytypes
\def\foreverunspace{%
\ifnum\lastnodetype=11
\unskip\foreverunspace
\else
\ifnum\lastnodetype=12
\unkern\foreverunspace
\else
\ifnum\lastnodetype=13
\unpenalty\foreverunspace
\fi
\fi
\fi
}
% we need a way to save the state of the punctuation buffer
% cf. \blx@initunit in biblatex.sty for what we need to copy
% this uses the internal implementation of etoolbox toggles
% fingers crossed no one messes with it
\newrobustcmd*{\apablx@savetoggle}[1]{%
\csletcs{apablx@savedtoggle@#1}{etb@tgl@#1}}
\newrobustcmd*{\apablx@restoretoggle}[1]{%
\csletcs{etb@tgl@#1}{apablx@savedtoggle@#1}}
\newrobustcmd*{\apablx@savepunctstate}{%
\apablx@savetoggle{blx@block}%
\apablx@savetoggle{blx@unit}%
\apablx@savetoggle{blx@insert}%
\apablx@savetoggle{blx@lastins}%
\apablx@savetoggle{blx@keepunit}%
\let\apablx@savd@unitpunct\blx@unitpunct
\let\apablx@savd@puncthook\abx@puncthook}
\newrobustcmd*{\apablx@restorepunctstate}{%
\global\apablx@restoretoggle{blx@block}%
\global\apablx@restoretoggle{blx@unit}%
\global\apablx@restoretoggle{blx@insert}%
\global\apablx@restoretoggle{blx@lastins}%
\global\apablx@restoretoggle{blx@keepunit}%
\global\let\blx@unitpunct\apablx@savd@unitpunct
\global\let\abx@puncthook\apablx@savd@puncthook}
% printtext that checks if it would print anything
\newrobustcmd{\printtexte}[2][]{%
\apablx@savepunctstate
\setbox0=\hbox{#2\foreverunspace}%
\apablx@restorepunctstate
\ifdim\wd0=0pt
\else
\ifblank{#1}
{\printtext{#2}}
{\printtext[#1]{#2}}%
\fi}
\makeatother
\begin{filecontents}{\jobname.bib}
@article{test,
author = {Author, A.},
journaltitle = {A Journal},
title = {A Title},
pubstate = {inpreparation},
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\autocite{test}
\printbibliography
\end{document}
答案2
找到了解决方案:
\renewbibmacro*{issue+date}{%
\ifthenelse{\ifentrytype{article}\AND\iffieldundef{date}\AND\iffieldundef{issue}}
{}
{\ifthenelse{\iffieldundef{issue}}
{}
{\printtext[parens]{%
\printfield{issue}%
\setunit*{\addspace}%
\usebibmacro{date}}}}%
\newunit}