7

I defined an entry set and use the \clearfield command to get rid of the month in entries. It works with the normal entries, but in the entry set the months are still displayed. How can I remove the month field for entries in an entry set?

MWE:

\documentclass[10pt]{article}

\usepackage[hyperref,backend=biber, maxnames=2,style=nature,%
articletitle=false,
isbn=false]{biblatex}
\AtEveryBibitem{\clearfield{month}} 
\addbibresource{\jobname.bib}
\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@article{key1,
author = {Author, A.},
year = {2001},
month = {3},
title = {Title},
publisher = {Publisher},
}
@article{key2,
author = {Author, B.},
year = {2002},
month = {2},
title = {Title},
publisher = {Publisher},
}
@article{key3,
author = {Author, C.},
year = {2003},
month = {1},
title = {Title},
publisher = {Publisher},
}

\end{filecontents}

\begin{document}

\defbibentryset{set1}{key1,key2}
\cite{set1}
\cite{key3}

\printbibliography

\end{document}
  • Please consider accepting gusbrs' answer instead of mine. As explained in my answer his approach is preferable. I just added my answer to explain and give a bit of context. – moewe Apr 5 '18 at 9:20
  • @moewe Hm, if you think so. I just liked that you actually explained what was going on there. :) – fifaltra Apr 5 '18 at 10:34
6

You can use a sourcemap instead:

\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map{
      \step[fieldset=month,null]
    }
  }
}

In full:

\documentclass[10pt]{article}

\usepackage[hyperref,backend=biber,maxnames=2,style=nature,articletitle=false,
isbn=false]{biblatex}
\usepackage{hyperref}
\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@article{key1,
author = {Author, A.},
year = {2001},
month = {3},
title = {Title},
publisher = {Publisher},
}
@article{key2,
author = {Author, B.},
year = {2002},
month = {2},
title = {Title},
publisher = {Publisher},
}
@article{key3,
author = {Author, C.},
year = {2003},
month = {1},
title = {Title},
publisher = {Publisher},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map{
      \step[fieldset=month,null]
    }
  }
}

\begin{document}

\defbibentryset{set1}{key1,key2}
\cite{set1}
\cite{key3}

\printbibliography

\end{document}

enter image description here

5

gusbrs has already given the preferable answer, so let me explain what causes this behaviour and offer an alternative (but inferior) solution. The source mapping solution is preferable because it removes the field information before it even gets to biblatex, while with \clearfield the field is read and processed by Biber and only suppressed when printing at the very last moment. This can lead to differences in output if the cleared field is relevant for sorting, uniqueness, label... field resolution or other advanced features. If a source map is used, the field is effectively removed before any of the mentioned functions kick in, but if you use \clearfield these functions all honour and act upon the presence of the field. The month field may be used for sorting, in that case it is crucial it be removed by Biber so that the document does not seemingly sort entries from the same year randomly. Another example is urldate that may be used as a fallback for labeldate if other dates are not present, if you want to suppress urldate it should not sneak back into your bibliography by virtue of being the source of labeldate, this can only be prevented by deleting the field in a source map.

Have a look at the following example. As you can see by presence of the red X, \AtEveryBibitem is executed once at the very beginning of each item in the bibliography, at that point the entry key marked in grey is in scope and being worked on. In particular the red X is not repeated for all members of a set.

You'll see that for the set the entry in scope is set1, so if \clearfield{month} is issued there, that only deletes the (already non-existent) month field of the meta-entry set1, not its elements.

The sets are processesed with the special driver @set and the command \entryset. \entryset typesets the set members in a loop by calling their respective drivers. We can add \clearfield{month} to the pre-code of \entryset to delete the month for the set members. The pre-code is executed once for each set member (see the yellow Y below) in the correct scope (cf. the blue entrykey after the yellow Y).

A similar effect can be observed with related entries: while \AtEveryBibitem is executed for the main entry all related entries are not affected.

\documentclass[10pt]{article}
\usepackage{xcolor}
\usepackage[backend=biber, maxnames=2,style=nature, articletitle=false, isbn=false]{biblatex}

\AtEveryBibitem{%
  \textcolor{red}{X}%                     only for demonstration
  \textcolor{gray}{\thefield{entrykey}}%  only for demonstration
  \clearfield{month}}

\DeclareBibliographyDriver{set}{%
  \entryset
    {\clearfield{month}%
     \textcolor{yellow}{Y}%                 for illustrative purposes only
     \textcolor{gray}{\thefield{entrykey}}% for illustrative purposes only
     \ifbool{bbx:subentry}
       {\printfield[bibentrysetcount]{entrysetcount}%
        \printunit*{\addnbspace}}
       {}}
    {}%
  \newunit\newblock
  \usebibmacro{setpageref}%
  \finentry}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@article{key1,
  author = {Author, A.},
  year = {2001},
  month = {3},
  title = {Title},
  publisher = {Publisher},
}
@article{key2,
  author = {Author, B.},
  year = {2002},
  month = {2},
  title = {Title},
  publisher = {Publisher},
}
@article{key3,
  author = {Author, C.},
  year = {2003},
  month = {1},
  title = {Title},
  publisher = {Publisher},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\defbibentryset{set1}{key1,key2}
\cite{set1}
\cite{key3}

\printbibliography
\end{document}

enter image description here

  • Thorough, as usual! (+1) – gusbrs Apr 5 '18 at 12:34

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.