4

I am trying to add a field to biblatex entries in the texfile. I am currently not able to apply a rule to one entry then apply it other rules to other entries.

I defined a command to add a field. Something is wrong with it but I don't know what it is:

\newcommand{\addnotetoentry}[2]{%
  \DeclareSourcemap{%
  \maps[datatype=bibtex]{%
    \map[overwrite]{%
      \step[fieldsource=entrykey,match=\regexp{^#1$},final]%
      \step[fieldset=note,fieldvalue={#2}]%
    }%
  }%
}%
}

Which is used like this:

\addnotetoentry{a}{one note --- hello my friend}
\addnotetoentry{b}{another note}

MWE:

\documentclass[12pt,letterpaper]{article}
\usepackage[backend=biber,style=alphabetic-verb,doi=false,eprint=false]{biblatex}
\usepackage{filecontents}

\begin{filecontents}{jobname.bib}
@ARTICLE{a,
   author = {Doe, J.},
   title = {The Title},
   journal = {The Journal},
}
@ARTICLE{b,
   author = {Smith, J.},
   title = {The New Title},
   journal = {The Same Journal},
}
\end{filecontents}
\addbibresource{jobname.bib}

\newcommand{\addnotetoentry}[2]{%
  \DeclareSourcemap{%
  \maps[datatype=bibtex]{%
    \map[overwrite]{%
      \step[fieldsource=entrykey,match=\regexp{^#1$},final]%
      \step[fieldset=note,fieldvalue={#2}]%
    }%
  }%
}%
}
\addnotetoentry{a}{one note}
\addnotetoentry{b}{another note}
\AtEveryBibitem{\printfield{note}\clearfield{note}\item}

\begin{document}

\nocite{*}
\printbibliography
\end{document}

I get in the ouput's references only one note (the last one that I defined):

buggy output

8
  • I currently cannot find the reference in the documentation, but I am pretty sure one can only use one \DeclareSourcemap per document (only the last one will be executed), one can use an unlimited (I think) number of \maps in a \DeclareSourcemap though.
    – moewe
    Apr 10, 2014 at 15:02
  • What exactly do you want to do? It is probably not the best idea to change bibliography data on the fly in a document. If you have to change anything, change the .bib file.
    – moewe
    Apr 10, 2014 at 15:11
  • I don't want to modify my bib file to add notes. Since the bib file is dynamically generated remotely.
    – pastjean
    Apr 10, 2014 at 15:25
  • I feared you'd have a good reason to do that... I think we will have to look for a different solution. \DeclareSourcemap in this form does not look like your best bet...
    – moewe
    Apr 10, 2014 at 15:29
  • declaring multiple map into one source map works (just tried), so i'm searching for a way to add maps using a command (to make it easier) , I'll look into the implementation of DeclareSourcemap
    – pastjean
    Apr 10, 2014 at 15:32

2 Answers 2

4

The problem with Biber's \DeclareSourcemap is that it may only be used once in a document (only the last instance will be executed, all the other calls will be ignored)*, as such it is quite hard to implement a macro using \DeclareSourcemap.

If you just want to add a comment to some bibliography entries, we can go down a different route.

\newcommand*{\writecomment}[2]{\csdef{localcomment#1}{#2}}

We define \writecomment to define a macro localcomment<entrykey> (<entrykey> as given in #1) that takes the value #2.

That macro localcomment<entrykey> can then be used as \csuse{localcomment<entrykey>}, like so

Before every element:

\AtEveryBibitem{\csuse{localcomment\thefield{entrykey}}\item}

Or after every element:

\renewbibmacro*{finentry}{%
  \finentry
  \ifcsdef{localcomment\thefield{entrykey}}
    {\\\csuse{localcomment\thefield{entrykey}}}
    {}%
}

\csuse will not do anything if its argument is not a valid command sequence; that means, if the macro was not created via \writecomment this will result in no output at all.

Another plus side of this solution is that we do not have to fiddle with the note field and do not override existing notes.

Usage of \writecomment is straightforward: \writecomment{<entrykey>}{<note>}

\writecomment{a}{first comment}
\writecomment{b}{second comment}

MWE

\documentclass{article}
\usepackage[backend=biber,style=alphabetic-verb,doi=false,eprint=false]{biblatex}
\begin{filecontents}{jobname.bib}
@ARTICLE{a,
   author = {Doe, J.},
   title = {The Title},
   journal = {The Journal},
}
@ARTICLE{b,
   author = {Smith, J.},
   title = {The New Title},
   journal = {The Same Journal},
}
@ARTICLE{c,
   author = {Miller, J.},
   title = {The New Title},
   journal = {Won't Get A Comment},
}
\end{filecontents}
\addbibresource{jobname.bib}

\newcommand*{\writecomment}[2]{\csdef{localcomment#1}{#2}}
\AtEveryBibitem{\csuse{localcomment\thefield{entrykey}}\item}

\writecomment{a}{first comment}
\writecomment{b}{second comment}

\begin{document}
  \nocite{*}
  \printbibliography
\end{document}

enter image description here

* I cannot find any piece of documentation that backs this claim up, but I'm quite confident it is correct.

1
  • 1
    @pastjean I noticed you have included your use case in my answer, I have slightly modified the solution to use \renewbibmacro*{finentry}{\finentry \ifcsdef{localcomment\thefield{entrykey}} {\\\csuse{localcomment\thefield{entrykey}}}{}} instead. That seems more apt than redefining the \finentrypunct, plus it will check if there is any comment and if that is not the case, no line break will be inserted.
    – moewe
    Apr 11, 2014 at 16:55
2

So apparently you cannot add multiple \DeclareSourcemap to a latex file since only the last one it taken into account.


One Solution can be to declare only one source map and modify the entries manually

\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map[overwrite]{
      \step[fieldsource=entrykey,match=\regexp{^a$},final]
      \step[fieldset=note,fieldvalue={one note}]
    }
    \map[overwrite]{
      \step[fieldsource=entrykey,match=\regexp{^b$},final]
      \step[fieldset=note,fieldvalue={another note}]
    }
  }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .