有点复杂的问题:
为了简单起见,我有一个大型 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
应用之前会先进行扩展。这主要是因为必须先将步骤写入文件,.bcf
而biblatex
写入文件通常会应用完全扩展。例如,请参见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.)}]
}
}
}
生产
写入字段时实际上并不重要,但当您尝试匹配字段内容时,您必须记住可能\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)。