[Tex/LaTex] automatically generate abbreviated citations in Tufte documents after the first occurrence

citingnatbibtufte

In documents using Tufte document classes (tuft-handout or tuft-book) \cite is replaced by a footnote (which appears as a sidenote) corresponding to the full bibliography entry for the cited work. This is fine for the first occurrence, but (generally) not what I want for subsequent occurrences of the same work.

Is there a way to automatically generate abbreviated citations after the first, using \cite alone?

For example, I'd like something like this:

Rendered MWE

But in order to get that I need to manually use something like

\footnote{\citealp{...}}

for citations after the first:

\documentclass[]{tufte-handout}

\begin{document}

This is the first occurrence of a citation,\cite{Deutsch:2002} which works as expected. I would also ideally like to be able to cite the same paper again, and have it appear automatically in some abbreviated form but instead I have to do this manually with a footnote and ERT\footnote{\citealp{Deutsch:2002}}. Is there a way to ensure that citations automatically appear in this "abbreviated" form after the first occurrence in Tufte documents? 

\bibliographystyle{unsrtnat}
\bibliography{References}

\end{document}

This not is not only brittle within the document (if the first citation is moved after one of these hand-coded ones) but destroys portability across classes (since the subsequent citations are all explicitly implemented as footnotes).


References.bib:

@article{Deutsch:2002,
author = {Deutsch, D},
title = {{The structure of the multiverse}},
journal = {Proceedings: Mathematical, Physical and Engineering Sciences},
year = {2002},
volume = {458},
number = {2028},
pages = {2911--2923},
}

Best Answer

Add the following code to the preamble of your document:

\usepackage{etoolbox}% provides some support for comma-separated lists

\makeatletter
% We'll keep track of the old/seen bibkeys here.
\def\@tufte@old@bibkeys{}

% This macro prints the full citation if it's the first time it's been used
% and a shorter citation if it's been used before.
\newcommand{\@tufte@print@margin@citation}[1]{%
  % print full citation if bibkey is not in the old bibkeys list
  \ifinlist{#1}{\@tufte@old@bibkeys}{%
    \citealp{#1}% print short entry
  }{%
    \bibentry{#1}% print full entry
  }%
  % add bibkey to the old bibkeys list
  \listgadd{\@tufte@old@bibkeys}{#1}%
}

% We've modified this Tufte-LaTeX macro to call \@tufte@print@margin@citation
% instead of \bibentry.
\renewcommand{\@tufte@normal@cite}[2][0pt]{%
  % Snag the last bibentry in the list for later comparison
  \let\@temp@last@bibkey\@empty%
  \@for\@temp@bibkey:=#2\do{\let\@temp@last@bibkey\@temp@bibkey}%
  \sidenote[][#1]{%
    % Loop through all the bibentries, separating them with semicolons and spaces
    \normalsize\normalfont\@tufte@citation@font%
    \setcounter{@tufte@num@bibkeys}{0}%
    \@for\@temp@bibkeyx:=#2\do{%
      \ifthenelse{\equal{\@temp@last@bibkey}{\@temp@bibkeyx}}{%
        \ifthenelse{\equal{\value{@tufte@num@bibkeys}}{0}}{}{and\ }%
        \@tufte@trim@spaces\@temp@bibkeyx% trim spaces around bibkey
        \@tufte@print@margin@citation{\@temp@bibkeyx}%
      }{%
        \@tufte@trim@spaces\@temp@bibkeyx% trim spaces around bibkey
        \@tufte@print@margin@citation{\@temp@bibkeyx};\space
      }%
      \stepcounter{@tufte@num@bibkeys}%
    }%
  }%
}


% Calling this macro will reset the list of remembered citations. This is
% useful if you want to revert to full citations at the beginning of each
% chapter.
\newcommand{\resetcitations}{%
  \gdef\@tufte@old@bibkeys{}%
}
\makeatother

It keeps a list of known/old/seen bibkeys. Each time you call \cite{key}, it will add those bibkeys to the list. When it prints the reference in the margin, it will check the list of known keys. If we've seen the key before, we'll call \citealp{key}. If we haven't seen the key before, we'll call the usual \bibentry{key}.

I've thrown in a \resetcitations macro (for free!) that will cause LaTeX to forget all the bibkeys it's seen before. This can be used, for instance, at the beginning of each chapter so that you'll see the full reference for the first citation of each chapter.

Note that this macro isn't particularly efficient. It doesn't sort the list of known bibkeys and checking the list is a linear-time process, so it will take longer the more \cites you have.