检查巨大的 bibtex 数据库以查找系列和编号等

检查巨大的 bibtex 数据库以查找系列和编号等

我有一个大型的 bibtex 条目数据库。作者通常不关心系列和编号信息,但我希望获得完整的信息。我正在寻找一种巧妙的方法来检查数据库中的缺失信息并记录结果。我正在使用 biber/biblatex。我可以声明系列和编号为必填字段,但有些出版商没有系列和/或编号。因此,我希望有一个字段 optnumber,其值可以是“none”,optseries 也可以具有值 none。或者 serieschecked 或 numberchecked,或类似的东西。然后 biber 应该测试是否存在 series 或 optseries/serieschecked,如果不存在,则发出警告。

我已经知道如何使字段成为必填字段,但应该有两个字段之一成为必填字段,这样我就可以看到有人已经检查了正在考虑的项目并添加了系列或没有系列的信息。

\DeclareDatamodelConstraints[book,mvbook,mvcollection,mvreference]{
  \constraint[type=mandatory]{
    \constraintfield{title}
    \constraintfield{series}
    \constraintfield{number}
  }
}

可以这样做吗?谢谢。

答案1

您可以向数据模型添加 XOR 约束,这意味着必须存在其中一个series或。optseries

optseries由于除了数据模型验证之外我们不需要它可以声明它skipout,所以它不会出现在.bbl文件中。

\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}

当使用biber -V生成运行时

[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

我认为我不太喜欢只为了数据模型验证而使用假字段。也许使用空值series不是。然后您只需验证是否series存在,然后过滤掉空值(这可以通过\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

如果您还想验证是否有,number可以series尝试以下方法。它并不像我希望的那样优雅,因为数据模型验证无法在字段值上分支,所以我们必须使用源映射来伪造它

\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

相关内容