%20%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%20%D0%BF%D1%83%D1%81%D1%82%D1%8B%D0%B5%20%D1%81%D0%BA%D0%BE%D0%B1%D0%BA%D0%B8%2C%20%D0%B5%D1%81%D0%BB%D0%B8%20%D0%B4%D0%B0%D1%82%D0%B0%20%D0%BF%D1%83%D1%81%D1%82%D0%B0.png)
Я хочу использовать pubstate
поле BibLaTeX для публикаций, находящихся «в стадии подготовки», у которых еще нет даты публикации (пустое поле даты), как в этом случае в стиле 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
's \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}