TeX - LaTeX Asked on April 25, 2021
I have a large database of bibtex items. Often authors do not care for series and number information, but I want to have the complete information. I am looking for a clever way to check the database for missing information and record the result. I am using biber/biblatex. I could declare series and number obligatory fields, but some publishers do not have series and/or number. So, I would like to have a field optnumber, which could have the value "none", and optseries which could also have the value none. Or serieschecked or numberchecked, or something similar. biber should then test whether series or optseries/serieschecked is present and if it is not throw a warning.
I already know how to make the fields obligatory, but there should be one of two fields mandatory, so that I can see that somebody already checked the item under consideration and either added a series or the information that there is no series.
DeclareDatamodelConstraints[book,mvbook,mvcollection,mvreference]{
constraint[type=mandatory]{
constraintfield{title}
constraintfield{series}
constraintfield{number}
}
}
Can this be done? Thanks.
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}
{defNewValue{}}
{}}
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{AnoneZ}, final]
step[fieldset=number, fieldvalue=none]
}
}
}
DeclareFieldInputHandler{series}{%
ifdefstring{NewValue}{none}
{defNewValue{}}
{}}
DeclareFieldInputHandler{number}{%
ifdefstring{NewValue}{none}
{defNewValue{}}
{}}
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
Correct answer by moewe on April 25, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP