1

I'm using MikTex with biber

\usepackage[backend=biber,natbib=true,style=numeric,sorting=none]{biblatex}

and I want to use a variable for the date value, but it does not provide any output. I set up the biber category and variables as below in file QMSbiblatex.tex

\addtocategory{MILinternal}{ref__MIL_QAM_QualityAssuranceManual}
\newcommand{\RepsSopQualityAssuranceManualNumber}{MIL-QAM-9001}
\newcommand{\RepsSopQualityAssuranceManualTitle}{REPS Quality Assurance Manual - ISO 9001}
\newcommand{\RepsSopQualityAssuranceManualDate}{2017-07-13}

then define the reference in references.bib as

@Electronic{ref__MIL_QAM_QualityAssuranceManual,
  author       = {\RepsSopQualityAssuranceManualNumber},
  organization = {{\RepsCitationOrganization}},
  title        = {{\RepsSopQualityAssuranceManualTitle}},
  date         = {\RepsSopQualityAssuranceManualDate},
}

which does NOT include the date in the reference but

@Electronic{ref__MIL_QAM_QualityAssuranceManual,
  author       = {\RepsSopQualityAssuranceManualNumber},
  organization = {{\RepsCitationOrganization}},
  title        = {{\RepsSopQualityAssuranceManualTitle}},
  date         = {2017-07-13},
}

outputs the reference with the date as expected.

Any thoughts on why using a variable does not work in the DATE field but is fine in the other fields?

2

To understand why this does not work as you hoped we first need to understand how .bib files work. Question mark or bold citation key instead of citation number has a great explanation of the work BibTeX and Biber do. In short (but please also read Paul Stanley's answer, it is great), Biber (and BibTeX, but I'll just say Biber from now on) parse the .bib file and produce output usable for LaTeX. For biblatex the output produced by Biber (the backend) is a structured, LaTeX-readable, predigested and enhanced version of the entry data.

The Biber-digested version of the entry

@book{appleby,
  author    = {Humphrey Appleby},
  title     = {On the Importance of the Civil Service},
  location  = {London},
  publisher = {Routledge},
  date      = {1980-04-06},
}

might look like this

\entry{appleby}{book}{}
  \name{author}{1}{}{%
    {{uniquename=0,uniquepart=base,hash=dd90e644e3018ab2c6a7ffa2a58522d0}{%
       family={Appleby},
       familyi={A\bibinitperiod},
       given={Humphrey},
       giveni={H\bibinitperiod},
       givenun=0}}%
  }
  \list{location}{1}{%
    {London}%
  }
  \list{publisher}{1}{%
    {Routledge}%
  }
  \strng{namehash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \strng{fullhash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \strng{bibnamehash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \strng{authorbibnamehash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \strng{authornamehash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \strng{authorfullhash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \field{sortinit}{A}
  \field{sortinithash}{d77c7cdd82ff690d4c3ef13216f92f0b}
  \field{extradatescope}{labelyear}
  \field{labeldatesource}{}
  \field{labelnamesource}{author}
  \field{labeltitlesource}{title}
  \field{day}{6}
  \field{month}{4}
  \field{title}{On the Importance of the Civil Service}
  \field{year}{1980}
  \field{dateera}{ce}
\endentry

Note that some fields have been processed by Biber. In particular the name Humphrey Appleby has been split into its two components and Biber has produced a name hash. Appleby, Humphrey in the .bib entry would have produced exactly the same result. Similarly, the date = {1980-04-06}, has been parsed and decomposed into its date parts (\field{year}{1980}, \field{month}{4}, \field{day}{6}, ...).

It is important to note that Biber and BibTeX are not LaTeX, they do not understand or resolve LaTeX macros.

title     = {\foo},

would just come out as

  \field{title}{\foo}

(Biber actually knows about some LaTeX macros, namely some that resolve to Unicode characters, but that does not help us here.)

The macros are just passed through and are only used (expanded) when the data is used in the document. In particular that means that the

date         = {\RepsSopQualityAssuranceManualDate},

in your .bib file can not be resolved and parsed by Biber, since the information

\newcommand{\RepsSopQualityAssuranceManualDate}{2017-07-13}

is only available in the .tex document and can not be accessed by Biber. So Biber just sees \RepsSopQualityAssuranceManualDate which is not a valid date and discards it with a complaint in the .blg file.

WARN - Entry 'ref__MIL_QAM_QualityAssuranceManual' (test.bib):
       Invalid format '\RepsSopQualityAssuranceManualDate' of date field 'date' - ignoring

A similar thing would happen to name fields. If we had written

author    = {\appleby},

in the .bib and defined

\newcommand*{\appleby}{Humphrey Appleby}

in the .tex file, we would have ended up with

  \name{author}{1}{}{%
    {{uniquename=0,uniquepart=base,hash=0213062b7acb78617f5861ef3be11354}{%
       family={\appleby},
       familyi={y\bibinitperiod}}}%
  }

in the .bbl. This shows that Biber did not parse the name as consisting of the family name "Appleby" and given name "Humphrey". Instead it consists of only the family part \appleby (which expands to "Humphrey Appleby"). All features that rely on biblatex knowing the given and family name part will not work as expected, the "Humphrey Appleby" will be treated as an atomic unit. In author-year citations for example we would get "Humphrey Appley 1980" and not "Appleby 1980".

This shows that you can't use TeX macros/variables to fill fields in your .bib entries, that have to be parsed by Biber.


So what can you do?

That very much depends on your use case.

The first question is probably whether you need an entry like this at all. It seems a little odd that bibliographic data of a work you cite would change in a way that requires you to modify the data on the fly from within the document.

A second attempt could be to invert the flow of information. Depending on what use case you have in mind, it might be enough to just type the data once in the .bib file and retrieve certain bits with \citetle{ref__MIL_QAM_QualityAssuranceManual}, \citeauthor{ref__MIL_QAM_QualityAssuranceManual}, \citedate{ref__MIL_QAM_QualityAssuranceManual}, or maybe even \citefield{ref__MIL_QAM_QualityAssuranceManual}{title}, \citelist{ref__MIL_QAM_QualityAssuranceManual}{organization}, ... etc. The \cite... commands are not expandable, though, so if you need the data in an expandable fashion, you need to take a slightly different approach (it should still be possible, if you are interested, you should probably ask a new question, though, this answer is long enough already).

If you need to create an entry with data on the fly from the document, you can always just use filecontents.

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[backend=biber,natbib=true,style=numeric,sorting=none]{biblatex}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{appleby,
  author    = {Humphrey Appleby},
  title     = {On the Importance of the Civil Service},
  location  = {London},
  publisher = {Routledge},
  date      = {1980-04-06},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\begin{document}
\cite{appleby}
\printbibliography
\end{document}

.bib files know @strings that can be used to store repeated or possibly changing info. @strings can even be taken from a different .bib file, so you could do something like

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[backend=biber,natbib=true,style=numeric,sorting=none]{biblatex}

\usepackage{filecontents}
\begin{filecontents}{\jobname-entry.bib}
@book{appleby,
  author    = {Humphrey Appleby},
  title     = {On the Importance of the Civil Service},
  location  = {London},
  publisher = {Routledge},
  date      = mydate,
}
\end{filecontents}
\begin{filecontents}{\jobname-strings.bib}
@string{mydate = {1980-06-05}}
\end{filecontents}

\addbibresource{\jobname-strings.bib}
\addbibresource{\jobname-entry.bib}


\begin{document}
\cite{appleby}
\printbibliography
\end{document}

You could also manipulate field data with a sourcemap. Due to the way sourcemaps work, macros will be expanded in the \replace step, so you could even use a macro here.

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[backend=biber,natbib=true,style=numeric,sorting=none]{biblatex}

\newcommand*{\applebydate}{1980-07-08}
\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map{
      \step[fieldsource=date,
            match=\regexp{\A\\applebydate\Z},
            replace=\applebydate]
    }
  }
}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{appleby,
  author    = {Humphrey Appleby},
  title     = {On the Importance of the Civil Service},
  location  = {London},
  publisher = {Routledge},
  date      = {\applebydate},
}
\end{filecontents}

\addbibresource{\jobname.bib}


\begin{document}
\cite{appleby}
\printbibliography
\end{document}
  • Thank you very, very much for the very detailed description of why what I was trying to do won't work! – Lewis Collier Jun 14 at 20:36
  • \addtocategory{MILinternal}{ref__MIL_QAM_QualityAssuranceManual} \newcommand{\RepsSopQualityAssuranceManualNumber}{MIL-QAM-9001-B} \newcommand{\RepsSopQualityAssuranceManualTitle}{REPS Quality Assurance Manual - ISO 9001} \newcommand{\RepsSopQualityAssuranceManualReleaseDate}{12 April 2019} \newcommand{\citeRepsQualityAssuranceManual}{\RepsSopQualityAssuranceManualNumber, \RepsSopQualityAssuranceManualTitle~\cite{ref__MIL_QAM_QualityAssuranceManual}} – Lewis Collier Jun 14 at 20:42
  • @Electronic{ref__MIL_QAM_QualityAssuranceManual, author = {\RepsSopQualityAssuranceManualNumber}, organization = {{\RepsCitationOrganization}}, title = {{\RepsSopQualityAssuranceManualTitle}}, addendum = {\RepsSopQualityAssuranceManualReleaseDate}, } – Lewis Collier Jun 14 at 20:43
  • I was trying to do the above to keep all the details of each volatile QMS document (continuous improvement, you know) in one file and the reference.bib file out of sight and out of mind. The above allows me to change the xxxNumber to account for revision level and the ReleaseDate to account for revision date without having to edit two files. Thanks again for the very detailed explanation! – Lewis Collier Jun 14 at 20:46

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.