0

Somewhat complex problem:

For simplicity I have a single large bib file that I modify with biblatex source maps to customize for different papers.

To help readers find some harder to locate papers, I started adding OCLC numbers through the addendum field. I made a command to automatically link to the WorldCat entry for the journal given the OCLC number.

For error checking, I added a command to check that the OCLC number is valid. This command will produce an error if the OCLC number is not a positive integer. Unfortunately it appears that this extra code causes a "! Missing { inserted." error on the \printbibliography line for one entry with an extra addendum. I have no idea why. I remove the \RequirePosInt{#1} from the \OCLC command and this compiles fine. I put the updated addendum in the bib file rather than source map and this compiles fine too.

Minimum working example:

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

As a side note if anyone knows a better or cleaner way to do what I intend to do, I'm interested.

  • 3
    your command is already expanded when the driver file (the bcf) is written. Use e.g. \step[fieldset=addendum, fieldvalue={\string\OCLC{831380048}... – Ulrike Fischer Dec 18 '18 at 18:26
  • 2
    Regarding the side note: I think what you are trying to do with OCLC looks very much a job for the eprint facilities provided by biblatex. – gusbrs Dec 18 '18 at 18:29
2

Macros in \DeclareSourcemap definitions are expanded before they are applied. That is mainly because the steps have to be written to the .bcf file by biblatex and writing to a file usually applies full expansion. See for example https://github.com/plk/biblatex/issues/740.

If you have unexpandable stuff in your sourcemaps or commands that must not be expanded for other reasons, you need to protect your commands from expansion manually. The easiest way is with \detokenize, \unexpanded or \string (as suggested by Ulrike Fischer in the comments).

The documentation of biblatex 3.12 and above warns on p. 186

Macros used in \step are expanded. Unexpandable contents should be protected with \detokenize, regular expressions can be escaped using the dedicated \regexp command (see the examples below).

\detokenize could be used as follows here

\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.)}]
      }
   }
}

to produce

Two example entries. With OCLC and <code>\citet</code>

It does not really matter when you write to a field, but when you try to match field contents you have to keep in mind that \detokenize may introduce spaces into your code. For example

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

produces

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

This should not be that much of a problem if you are using RegExp (and its \regexp escape), but it is something to keep in mind.

But it would also work to make \OCLC robust

\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.)}]
      }
   }
}

like \citet which is already robust and therefore did not need a \string or \detokenize in the first place.

I agree with gusbrs' comment that OCLCs should probably be dealt with as eprint or a new DOI-like field (see BibTeX fields for DOI, MR, Zbl and arxiv?, Biblatex and Pubmed/Pubmed Central IDs).

| improve this answer | |
  • Thanks, this was very informative! The comment you quote does not seem to be in the biblatex 3.11 documentation, so I'll see about upgrading. The code you provide works in 3.11. I treat the OCLC number as an alternative to an ISSN or ISBN, so I think treating it as a DOI-like field would make more sense than eprint. Ultimately either works, though. – Ben Trettel Dec 18 '18 at 23:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.