Это дополнительный вопрос кКак проверить, является ли запись `country = {}` пустой в пользовательской библиотеке BibLaTeX?
У меня есть собственная библиотека BibLaTeX с записью BiBLaTeX Contribution
, которую я использую для управления всеми своими устными и постерными докладами на конференциях, семинарах и т. д. Благодаря помощи, которую я получил на указанном выше сайте, у меня есть отличная работающая система.
Однако есть некоторые косметические проблемы: у меня есть запись с именем , period
которая включает временной период, например, конференции. Она должна отображаться за заголовком события в скобках (см. пример ниже). В файле .dbx
я объявляю поле записи period
как тип данных даты, и поэтому могу вызвать команду \printperiod
. Пока все хорошо.
В некоторых записях BibLaTeX это поле period
пустое, поэтому period = {}
.
Как я могу узнать с помощью условий «если», «тогда», «иначе», \printperiod
печатается ли текст, например, если period = {}
?
Я пробовал и другие вещи \iffieldundef{period}
, \ifciteindex
но у меня ничего не работает.
Итак, вот первый MWE:
\begin{filecontents}{contribution.dbx}
\DeclareDatamodelEntrytypes{contribution}
\DeclareDatamodelFields[type=field,datatype=literal]{
type,
invited,
title,
event,
eventshort,
eventtype,
league,
url,
place,
city,
country,
year,
note,
timestamp
}
\DeclareDatamodelFields[type=field, datatype=datepart]{
year,
month,
day,
periodyear,
periodmonth,
periodday
}
\DeclareDatamodelFields[type=field, datatype=date, skipout]{
date,
period,
}
\DeclareDatamodelFields[type=list,datatype=name]{
author,
presenter,
}
\DeclareDatamodelEntryfields[contribution]{
type,
invited,
author,
presenter,
title,
event,
eventshort,
eventtype,
league,
url,
place,
city,
country,
date,
period,
year,
note,
timestamp}
\end{filecontents}
\begin{filecontents}{\jobname.bib}
@Contribution{Oral_2016_1,
Type = {Oral},
Invited = {invited},
Author = {Author1, A. and Author2, B. and Author3, C. and Author4, D.},
Presenter = {Author2, B.},
Title = {{Cool stuff about the nano-world}},
Event = {{22$^{\rm nd}$ International Conference on Nanotechnology}},
Eventshort= {{NANO-7}},
Eventtype = {Conference},
League = {International},
URL = {},
Place = {Alto University},
City = {Helsinki},
Country = {Finland},
Date = {2016-05-31},
Period = {2016-05-22/2016-06-02},
Year = {2016},
Note = {},
Timestamp = {}
}
@Contribution{Oral_2016_2,
Type = {Oral},
Invited = {},
Author = {Author1, A. and Author2, B. and Author3, C. and Author4, D.},
Presenter = {Author1, B.},
Title = {{Cool stuff about the nano-world}},
Event = {{22$^{\rm nd}$ International Workshop on NanoPhenomena}},
Eventshort= {{IWNP-8}},
Eventtype = {Workshop},
League = {International},
URL = {},
Place = {University of Nano},
City = {Tokyo},
Country = {Japan},
Date = {2016-03-04},
Period = {},
Year = {2016},
Note = {},
Timestamp = {}
}
\end{filecontents}
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[datamodel=contribution,
style=chem-acs,
dateabbrev=false,
natbib=true,
backend=biber]
{biblatex}
\addbibresource{\jobname.bib}
% My own command, which puts into format and prints the complete contribution.
\DeclareCiteCommand{\citeallstuff}
{\defcounter{maxnames}{99}%
\defcounter{minnames}{99}%
\defcounter{uniquename}{2}%
\boolfalse{citetracker}%
\boolfalse{pagetracker}%
\usebibmacro{prenote}}
{%
\ifciteindex{\indexnames*{labelname}}{}\printnames{labelname}, %
\iffieldundef{title}{}{\textit{\printtext{\printfield{title}}}\space}%
\iffieldundef{event}{}{\printtext{\printfield{event}}}%
\space(\printperiod)\addcomma\space% <============ What must I do there?
\iffieldundef{city}{}{\printtext{\printfield{city}}}%
\iffieldundef{country}{\addcomma\space}{ \printtext{(\printfield{country}})\addcomma\space}%
\printdate% <============ The same here?
\iffieldundef{note}{}{\addcomma\space\printtext{\printfield{note}}}%
\iffieldundef{invited}{}{\addcomma\space{\textbf{\printtext{\printfield{invited}}}}}
}
{\multicitedelim}
{\usebibmacro{postnote}}
\begin{document}
\noindent\citeallstuff{Oral_2016_1}\\\\\\
\citeallstuff{Oral_2016_2}
\printbibliography
\end{document}
Как можно заметить, во второй цитате после названия события стоит (), поскольку поле «период» пустое. period = {}
В этом случае не должно быть двух скобок, вместо них должна быть запятая и пробел.
Спасибо за помощь.
PS: Небольшой дополнительный вопрос: как мне изменить, например, May 31
на May 31$^{\rm st}$
?
решение1
Здесь имеет место сочетание двух проблем.
№ 1 заключается в том, что не следует писать голое форматирование в командах bibmacros или cite, следует использовать \DeclareFieldFormat
и их друзей.
Так что пиши
\DeclareFieldFormat{perioddate}{\mkbibparens{#1}}
а потом позже
\printperioddate
и дата периода будет заключена в скобки. С этим методом вам не нужно проверять, пусто ли поле. Если оно пустое, вы ничего не получите, если оно что-то содержит, вы получите это обратно в правильном формате. Если вам действительно нужно проверить, определена ли дата, стандартный метод — проверить ее часть года
\iffieldundef{periodyear}
{<no date>}
{<date>}
biblatex
выведет дату только в том случае, если в ней указан год, а если в дате указан год, biblatex
выведет по крайней мере этот год.
Однако все это не работает с biblatex
3.7/Biber 2.8, если вы вводите пустые поля «явно», как
perioddate = {}
В этом случае вы получите ответ periodyear = {}
, который всех сбивает с толку, поскольку biblatex
это считается определенным годом.
Это известная ошибка, которая будет устранена в Biber 2.8, см.https://github.com/plk/biblatex/issues/528.
В то же время все, что вы можете сделать, это отказаться от странной привычки писать perioddate = {}
для пустых полей вместо того, чтобы вообще оставлять их вне записи. Если вы по какой-то причине не хотите этого делать, позвольте Биберу сделать это за вас с помощью
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map{
\step[fieldsource=perioddate, match=\regexp{^$}, final]
\step[fieldset=perioddate, null]
}
}
}