为什么 biber 在作者字段中使用宏会导致段错误?

为什么 biber 在作者字段中使用宏会导致段错误?

在我 5 分钟前更新我的 TexLive2018 (Win7-64bit, Texstudio) 之前,以下代码编译正常:

\documentclass[12pt]{article}

\usepackage{filecontents}

\begin{filecontents}{bib.bib}
@book{authorA20,
    author = {Author, A.},
    translator = {Translator, A.},
    title = {These and that},
    subtitle = {Nothing special},
    volume = 1,
    location = {Here and there},
    publisher = {Who knows},
    year = {2020},
    isbn = {978-0-000-00000-2},
}
@book{buthorB22,
    author = {\authorSn, \authorGivenname},
    shorthand = {\volTwoShorthand},
    translator = {\volTwoTranslator},
    title = {\volTwoTitle},
    subtitle = {\volTwoSubtitle},
    volume = {\volTwoNumber},
    location = {\volTwoLocation},
    publisher = {\volTwoPublisher},
    year = {\volTwoYear},
    isbn = {\volTwoIsbn},
}
\end{filecontents}

\usepackage{xstring} %<- provides StrLeft/-Right (s. below)
\newcommand{\authorSn}{Buthor}
\newcommand{\authorGivenname}{B.}
\newcommand{\volTwoTranslator}{Translator, B.}
\newcommand{\volTwoTitle}{These and that}
\newcommand{\volTwoSubtitle}{Nothing special}
\newcommand{\volTwoNumber}{2}
\newcommand{\volTwoLocation}{Here and there}
\newcommand{\volTwoPublisher}{Who knows}
\newcommand{\volTwoYear}{2022}
\newcommand{\volTwoShorthand}{\StrLeft{\authorSn}{3}%
    \StrRight{\volTwoYear}{2}}

\newcommand{\volTwoIsbn}{978-1-111-11111-1}

\usepackage[style=alphabetic]{biblatex}
\addbibresource{bib.bib}

\begin{document}

Wow \cite{authorA20}!

Crazy \cite{buthorB22}!

\printbibliography

\end{document}

更新后,biber 2.12 可重现段错误。我不知道之前用过哪个版本的 biber(上次更新是在今年夏天)。

有问题的字段似乎是author = {\authorSn, \authorGivenname}。如果我使用硬编码值替换此字段,例如author = {Bauthor, B.}编译成功,但会出现明显的(在我看来无害的)警告。

也运行biber --tool --validate-datamodel bib.bibSEGV。

答案1

有趣的是,在我的计算机上,我可以在大约 70% 的运行中重现段错误(我没有收到任何错误报告,Biber 只是死机并且没有写入),而其他 30% 的运行可以正常编译( :.bbl中的数据略有奇怪)。.bblfamily={\volTwoTranslator}, familyi={r\bibinitperiod}

您可以并且应该向以下机构报告此问题https://github.com/plk/biber/issues(Stackexchange 不是错误跟踪器),但可能 Biber 中没有很好的方法来解决这个问题。Biber 依赖于 Perl 模块文本::BibTeX,它将其工作委托给 C 库btparse。从该模块捕获错误(尤其是段错误)有时会有些困难。

在这种情况下,解析名称的代码(尤其是处理名称首字母的代码)似乎无法处理仅由宏组成的名称。请记住,Biber 不了解 LaTeX,这意味着它不会扩展/解包宏定义(除非在非常特殊的硬编码情况下)。同时,Biber 需要访问字段的正确字符串值才能完成其工作:只有当 Biber 真正了解宏的扩展而不仅仅是其名称时,才能按预期执行排序。而且——这就是这里的问题——只有知道其字符串值时才能从名称生成首字母。

我能想到两种解决方法。

  1. 正如所提到的古斯布斯 在评论中\relax,在字段中使用author\relax可以用作btparse名称中 BibTeX/ 的标记,以告诉它以不同的方式解析名称的当前位。

    author = {\relax\authorSn, \relax\authorGivenname},
    

    编译为

    family={\relax\authorSn},
    familyi={\\bibinitperiod},
    given={\relax\authorGivenname},
    giveni={\\bibinitperiod}}}%
    

    这仍然是错误的,但至少没有让比伯死去。

    BibTeX 将名称中以控制序列开头的组视为一个字符,这意味着 将{\'E}cole被缩写为{\'E}而不是{\'}{E}或其他名称。在 BibTeX 中,这允许巧妙地将{\relax Th}omas“Th.”作为名称首字母(这在 Biber 中不再有效)。

  2. 您可以通过自行提供扩展名称格式来关闭首字母的计算。

    author = {family={\authorSn}, given={\authorGivenname},
              family-i={\authorSn}, given-i={\authorGivenname}},
    

    编译为

    family={\authorSn},
    familyi={\authorSn\bibinitperiod},
    given={\authorGivenname},
    giveni={\authorGivenname\bibinitperiod}}}%
    

    虽然不是很好,但总比没有好。

    当然你可以给真实的如果您事先自己确定了首字母,则必须明确地使用首字母。

相关内容