%20%E7%95%B6%E6%97%A5%E6%9C%9F%E7%82%BA%E7%A9%BA%E6%99%82%E6%94%BE%E7%BD%AE%E7%A9%BA%E6%8B%AC%E8%99%9F.png)
我想將 BibLaTeXpubstate
字段用於尚未發布日期的“準備中”出版物(空日期字段),就像作者年份風格的:
@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
's \ifboolexpr
。請注意,內部 forbiblatex
沒有字段date
,如果您想測試 a 是否存在,date
最好測試 foryear
\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}