You can add an XOR constraint to the datamodel, which means that exactly one of series
or optseries
needs to be present.
Since we don't need optseries
except for datamodel validation we can declare it skipout
, so it does not appear in the .bbl
file.
\documentclass{article}
\begin{filecontents}{seriescheck.dbx}
\DeclareDatamodelFields[type=field, datatype=literal, skipout]{optseries}
\DeclareDatamodelEntryfields[
book,mvbook,inbook,
collection,mvcollection,incollection
]{optseries}
\DeclareDatamodelConstraints[
book,mvbook,inbook,
collection,mvcollection,incollection]
{
\constraint[type=mandatory]{
\constraintfieldsxor{
\constraintfield{series}
\constraintfield{optseries}
}
}
}
\end{filecontents}
\usepackage[
backend=biber,
datamodel=seriescheck,
]{biblatex}
\begin{filecontents}{\jobname.bib}
@book{nussbaum,
author = {Nussbaum, Martha},
title = {Aristotle's \mkbibquote{De Motu Animalium}},
date = 1978,
publisher = {Princeton University Press},
location = {Princeton},
optseries = {none},
}
@book{worman,
author = {Worman, Nancy},
title = {The Cast of Character},
date = 2002,
publisher = {University of Texas Press},
location = {Austin},
}
@collection{omeara,
editor = {O'Meara, Dominic J.},
title = {Studies in {Aristotle}},
date = 1981,
series = {Studies in Philosophy and the History of Philosophy},
number = 9,
publisher = {The Catholic University of America Press},
location = {Washington, D.C.},
pages = {161-191},
}
@book{aristotle:poetics,
author = {Aristotle},
title = {Poetics},
date = 1968,
editor = {Lucas, D. W.},
series = {Clarendon {Aristotle}},
publisher = {Clarendon Press},
location = {Oxford},
optseries = {none},
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\nocite{*}
\printbibliography
\end{document}
When run with biber -V
generates
[437] Biber.pm:1641> INFO - Datamodel validation starting
[438] Utils.pm:395> WARN - Datamodel: Entry 'worman' (Namenddfdfdsflos-21.bib): Missing mandatory field - one of 'series, optseries' must be defined
[443] Utils.pm:395> WARN - Datamodel: Entry 'aristotle:poetics' (Namenddfdfdsflos-21.bib): Mandatory fields - only one of 'series, optseries' must be defined - ignoring field 'optseries'
[443] Biber.pm:1690> INFO - Datamodel validation complete
I don't think I am a big fan of a fake field just for data model verification. Maybe it would be more suitable to use a null value for series
instead. Then you would only need to verify if series
is present and later filter out the null value (this can be done via \DeclareFieldInputHandler
).
\documentclass{article}
\begin{filecontents}{seriescheck.dbx}
\DeclareDatamodelFields[type=field, datatype=literal, skipout]{optseries}
\DeclareDatamodelEntryfields[
book,mvbook,inbook,
collection,mvcollection,incollection
]{optseries}
\DeclareDatamodelConstraints[
book,mvbook,inbook,
collection,mvcollection,incollection]
{
\constraint[type=mandatory]{
\constraintfield{series}
}
}
\end{filecontents}
\usepackage[
backend=biber,
datamodel=seriescheck,
]{biblatex}
\DeclareFieldInputHandler{series}{%
\ifdefstring{\NewValue}{none}
{\def\NewValue{}}
{}}
\begin{filecontents}{\jobname.bib}
@book{nussbaum,
author = {Nussbaum, Martha},
title = {Aristotle's \mkbibquote{De Motu Animalium}},
date = 1978,
publisher = {Princeton University Press},
location = {Princeton},
series = {none},
}
@book{worman,
author = {Worman, Nancy},
title = {The Cast of Character},
date = 2002,
publisher = {University of Texas Press},
location = {Austin},
}
@collection{omeara,
editor = {O'Meara, Dominic J.},
title = {Studies in {Aristotle}},
date = 1981,
series = {Studies in Philosophy and the History of Philosophy},
number = 9,
publisher = {The Catholic University of America Press},
location = {Washington, D.C.},
pages = {161-191},
}
@book{aristotle:poetics,
author = {Aristotle},
title = {Poetics},
date = 1968,
editor = {Lucas, D. W.},
series = {Clarendon {Aristotle}},
publisher = {Clarendon Press},
location = {Oxford},
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\nocite{*}
\printbibliography
\end{document}
[442] Biber.pm:1641> INFO - Datamodel validation starting
[443] Utils.pm:395> WARN - Datamodel: Entry 'worman' (Namenddfdfdsflos-21.bib): Missing mandatory field 'series'
[444] Biber.pm:1690> INFO - Datamodel validation complete
If you also want to verify whether you have a number
for your series
you can try the following. It isn't quite as elegant as I would have liked it to be because the data model verification cannot branch on field values, so we have to fake that with a source map
\documentclass{article}
\begin{filecontents}{seriescheck.dbx}
\DeclareDatamodelFields[type=field, datatype=literal, skipout]{optseries}
\DeclareDatamodelEntryfields[
book,mvbook,inbook,
collection,mvcollection,incollection
]{optseries}
\DeclareDatamodelConstraints[
book,mvbook,inbook,
collection,mvcollection,incollection]
{
\constraint[type=mandatory]{
\constraintfield{series}
}
\constraint[type=conditional]{
\antecedent[quantifier=all]{
\constraintfield{series}
}
\consequent[quantifier=all]{
\constraintfield{number}
}
}
}
\end{filecontents}
\usepackage[
backend=biber,
datamodel=seriescheck,
]{biblatex}
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map{
\step[fieldsource=series, match=\regexp{\Anone\Z}, final]
\step[fieldset=number, fieldvalue=none]
}
}
}
\DeclareFieldInputHandler{series}{%
\ifdefstring{\NewValue}{none}
{\def\NewValue{}}
{}}
\DeclareFieldInputHandler{number}{%
\ifdefstring{\NewValue}{none}
{\def\NewValue{}}
{}}
\begin{filecontents}{\jobname.bib}
@book{nussbaum,
author = {Nussbaum, Martha},
title = {Aristotle's \mkbibquote{De Motu Animalium}},
date = 1978,
publisher = {Princeton University Press},
location = {Princeton},
series = {none},
}
@book{worman,
author = {Worman, Nancy},
title = {The Cast of Character},
date = 2002,
publisher = {University of Texas Press},
location = {Austin},
}
@collection{omeara,
editor = {O'Meara, Dominic J.},
title = {Studies in {Aristotle}},
date = 1981,
series = {Studies in Philosophy and the History of Philosophy},
number = 9,
publisher = {The Catholic University of America Press},
location = {Washington, D.C.},
pages = {161-191},
}
@book{aristotle:poetics,
author = {Aristotle},
title = {Poetics},
date = 1968,
editor = {Lucas, D. W.},
series = {Clarendon {Aristotle}},
publisher = {Clarendon Press},
location = {Oxford},
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\nocite{*}
\printbibliography
\end{document}
[396] Biber.pm:1641> INFO - Datamodel validation starting
[396] Utils.pm:395> WARN - Datamodel: Entry 'worman' (Namenddfdfdsflos-21.bib): Missing mandatory field 'series'
[398] Utils.pm:395> WARN - Datamodel: Entry 'aristotle:poetics' (Namenddfdfdsflos-21.bib): Constraint violation - all of fields (number) must exist when all of fields (series) exist
[401] Biber.pm:1690> INFO - Datamodel validation complete