[Tex/LaTex] bibtex with multiple aliases for the same reference

bibliographiesbibtexciting

Is this something that I can do with bibtex? I have a few different manuscripts with some other collaborators and it would be easier for me if I could make \cite{foo} and \cite{bar} point to the same thing. Of course there are ways to work around this by changing \cite{foo} to \cite{bar} everywhere in the manuscripts, or by duplicating bibtex entries in the .bib file, but I would rather not do these things.

Best Answer

I'm not aware of any possibility to remap keys in a .bib file; if this is true (and I think it is) then this is really a shortcoming.

So my solution is based on doing the remapping in the LaTeX preamble, and as often these days I use the prop datatype of LaTeX3 as that is really useful in such circumstances.

The basic idea is to use a property list that stores the citation keys as keys and the target keys as values. Then whenever a citation command is run we look up the key and if there is a mapping we use the mapping instead. This way the .aux file will end up having only the remapped keys in it and BibTeX will only find those.

\documentclass{article}

\usepackage{expl3}

\ExplSyntaxOn
\prop_new:N \g_cite_map_prop
\tl_new:N \l_citekey_result_tl

\cs_new:Npn \mapcitekey #1#2 {
  \clist_map_inline:nn {#2}
       {  \prop_gput:Nnn  \g_cite_map_prop  {##1} {#1}   }
}

\cs_new:Npn \getcitekey #1 {
   \prop_get:NoN \g_cite_map_prop{#1}  \l_citekey_result_tl
   \quark_if_no_value:NF \l_citekey_result_tl
       {  \tl_set_eq:NN #1  \l_citekey_result_tl  }
}

\cs_new:Npn \showcitekeymaps {\prop_show:N  \g_cite_map_prop }
\ExplSyntaxOff

This gives us \mapcitekey with two arguments: the first is our major key that we want to use with BibTeX and the second is the alternate key that we want to remap. In fact the second argument can also be a comma separated list, e.g.,

\mapcitekey{hello}{world}
\mapcitekey{foo}{bar,baz,foobar}

\showcitekeymaps

This will give us

The property list \g_cite_map_prop contains the pairs (without outer braces):
>  {world}  =>  {hello}
>  {bar}  =>  {foo}
>  {baz}  =>  {foo}
>  {foobar}  =>  {foo}.

Now to look things up we have \getcitekey and what remains to be done is to patch the citation commands to make use of this key. I have done this below for \cite and \nocite from standard LaTeX. If some other citation package such as natbib is used one needs to patch its citation commands. Basically you need to look for the places where the command \citation is being written to the .aux file and the command that is used in the argument to \citation is the one that holds the key needs to be changed.

So here are the patches necessary:

\usepackage{etoolbox}
\makeatletter
\patchcmd{\@citex}{\if@filesw}{\getcitekey\@citeb \if@filesw}%
    {\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}
\patchcmd{\nocite}{\if@filesw}{\getcitekey\@citeb \if@filesw}%
    {\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}
\makeatletter

With those definitions and the remapping above, the input

\cite{foo} \cite{bar} \cite{world} \cite{baz}

will give us the following citations in the aux file:

\citation{foo}
\citation{foo}
\citation{hello}
\citation{foo}

By the way, duplicating BibTeX entries with different keys is not going to work (as suggested in the question). That would result in getting the same reference twice.