使用 biblatex 源映射编译失败,但如果修改了 bib 文件,编译就会成功

使用 biblatex 源映射编译失败,但如果修改了 bib 文件,编译就会成功

有点复杂的问题:

为了简单起见,我有一个大型 bib 文件,我用 biblatex 源图对其进行修改,以针对不同的论文进行定制。

为了帮助读者找到一些难以找到的论文,我开始通过附录字段添加 OCLC 编号。我制作了一个命令,根据 OCLC 编号自动链接到期刊的 WorldCat 条目。

为了检查错误,我添加了一个命令来检查 OCLC 编号是否有效。如果 OCLC 编号不是正整数,此命令将产生错误。不幸的是,这个额外的代码似乎导致 \printbibliography 行中出现“!缺少 { 插入。”错误,因为有一个带有额外附录的条目。我不知道为什么。我\RequirePosInt{#1}从命令中删除了\OCLC,编译正常。我将更新后的附录放在 bib 文件中,而不是源映射中,编译也正常。

最小工作示例:

\documentclass{article}

% https://texfaq.org/FAQ-isitanum
\def\IsPositive#1{%
  TT\fi%
  \ifcat_\ifnum0<0#1 _\else A\fi%
}

\newcommand*{\RequirePosInt}[1]{%
   \if\IsPositive{#1}%
      \typeout{Is positive integer: #1}%
   \else%
      \PackageError{requireinteger}{Positive integer expected: #1}{}%
   \fi%
}

\usepackage{hyperref}
\newcommand*{\OCLC}[1]{OCLC: \href{https://www.worldcat.org/oclc/#1}{#1}\RequirePosInt{#1}}

\usepackage[style=numeric,backend=biber,natbib=true]{biblatex}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@inproceedings{huh_phenomenological_1991,
  location = {{Tsukuba, Japan}},
  title = {A Phenomenological Model of Diesel Spray Atomization},
  volume = {2},
  booktitle = {Proceedings of the International Conference on Multiphase Flows},
  author = {Huh, K. Y. and Gosman, A. D.},
  editor = {Matsui, G.},
  date = {1991},
  pages = {515--518},
  addendum = {\OCLC{831380048}}
}

@article{huh_diesel_1998,
  title = {Diesel Spray Atomization Model Considering Nozzle Exit Turbulence Conditions},
  volume = {8},
  issn = {1044-5110},
  doi = {10.1615/AtomizSpr.v8.i4.60},
  number = {4},
  journaltitle = {Atomization and Sprays},
  author = {Huh, Kang Y. and Lee, Eunju and Koo, Jaye},
  date = {1998},
  pages = {453--469}
}
\end{filecontents}

\addbibresource{\jobname.bib}

\DeclareSourcemap{
   \maps[datatype=bibtex]{
      \map[overwrite]{
         \step[fieldsource=entrykey, match={huh_phenomenological_1991}, final]
         \step[fieldset=addendum, fieldvalue={\OCLC{831380048} (See the citation for \citet{huh_diesel_1998} for a note about an error in this paper.)}]
      }
   }
}

\begin{document}
\nocite{huh_phenomenological_1991}

\printbibliography

\end{document}

顺便说一句,如果有人知道更好或更干净的方法来完成我打算做的事情,我会感兴趣。

答案1

定义中的宏在\DeclareSourcemap应用之前会先进行扩展。这主要是因为必须先将步骤写入文件,.bcfbiblatex写入文件通常会应用完全扩展。例如,请参见https://github.com/plk/biblatex/issues/740

如果你的源映射中有不可扩展的内容,或者由于其他原因不能扩展的命令,则需要手动保护命令免于扩展。最简单的方法是使用\detokenize\unexpanded\string(如 Ulrike Fischer 所建议的在评论中)。

3.12 及以上版本的文档biblatex在第 186 页发出警告

中使用的宏\step将被展开。不可展开的内容应使用 进行保护\detokenize,正则表达式可以使用专用 \regexp命令进行转义(参见下面的示例)。

\detokenize可以按如下方式使用

\DeclareSourcemap{
   \maps[datatype=bibtex]{
      \map[overwrite]{
         \step[fieldsource=entrykey, match={huh_phenomenological_1991}, final]
         \step[fieldset=addendum, fieldvalue={\detokenize{\OCLC{831380048}} (See the citation for \citet{huh_diesel_1998} for a note about an error in this paper.)}]
      }
   }
}

生产

两个示例条目。使用 OCLC 和 <code>\citet</code>

写入字段时实际上并不重要,但当您尝试匹配字段内容时,您必须记住可能\detokenize会在代码中引入空格。例如

\detokenize{\foo{123}{456} lorem \goo{} ipsum}

生产

\foo {123}{456} lorem \goo {} ipsum

如果您使用 RegExp(及其\regexp转义),这应该不是什么大问题,但需要记住这一点。

但它也可以使\OCLC强大的

\newrobustcmd*{\OCLC}[1]{OCLC: \href{https://www.worldcat.org/oclc/#1}{#1}\RequirePosInt{#1}}

\DeclareSourcemap{
   \maps[datatype=bibtex]{
      \map[overwrite]{
         \step[fieldsource=entrykey, match={huh_phenomenological_1991}, final]
         \step[fieldset=addendum, fieldvalue={\OCLC{831380048} (See the citation for \citet{huh_diesel_1998} for a note about an error in this paper.)}]
      }
   }
}

像这样的已经很强大了,因此首先\citet不需要\string或。\detokenize

我同意gusbrs 的评论OCLC 可能应该被视为eprint或一个新的类似 DOI 的字段(见DOI、MR、Zbl 和 arxiv 的 BibTeX 字段?Biblatex 和 Pubmed/Pubmed Central ID)。

相关内容