# Can I automatically generate abbreviated citations in Tufte documents after the first occurrence?

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:

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},
}

-

\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
}

% We've modified this Tufte-LaTeX macro to call \@tufte@print@margin@citation
\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.

-
Nice! Is this going in officially in the next upadate? –  Yiannis Lazarides Feb 26 '12 at 19:30
@YiannisLazarides: Yeah, it's on my to do list for the upcoming refactoring. (I expect that'll take place in a few months when I start writing my dissertation.) –  godbyk Feb 26 '12 at 21:09
This works like a charm, BTW. Thanks! –  raxacoricofallapatorius Feb 26 '12 at 21:49
@godbyk +1, but why not use biblatex? –  Audrey Feb 27 '12 at 4:14
@Audrey: biblatex is probably the best solution going forward as it provides a lot more flexibility than natbib. Unfortunately, I haven't had time to learn it yet. (When we first wrote the Tufte-LaTeX code, biblatex wasn't ready for regular use, so we settled on natbib.) –  godbyk Feb 27 '12 at 6:37

tufte-handout loads the natbib package. You can make use of that, even cite with (page-) specifications (useful in humanities):

I defined a \citealias in this case, other choices are explained in the reference sheet. First occurrence can be cited like that:

\citepalias[S.148]{Camus10}\cite{Camus10}


The next occurrences are wrapped into a \footnote{}:

\footnote{\citepalias[S.147]{Camus10}}


It produces a solution that's elegant enough for my purposes. I'd like to see Godbyk's solution with the possibility to use cite-specifications. Until then I'd rather have a brittle document.

Example images:

-

The accepted answer didn't actually work for me. I had to slightly modify the first command, \@tufte@print@margin@citation, as follows (please note that i use BibLaTeX so your citation commands might differ, too.

\newcommand{\@tufte@print@margin@citation}[1]{%
% print full citation if bibkey is not in the old bibkeys list
\xifinlist{#1}{\@tufte@old@bibkeys}{% CHANGED
\cite{#1}% print short entry
}{%
\fullcite{#1}% print full entry
% add bibkey to the old bibkeys list
\listxadd{\@tufte@old@bibkeys}{#1}% CHANGED, and moved to avoid duplicates
}%
%\show\@tufte@old@bibkeys%
}


The reason for this was that actually, instead of the bib key, the literal string "\@temp@bibkeyx " was being added to the list \@tufte@old@bibkeys. This was solved by using the command \listxadd, which, according to the etoolbox documentation, expands the element prior to adding it to the list. I discovered this by judicious use of the \show command, if you're wondering.

-
Note that if you use biblatex, there are slightly easier solutions for this problem, because biblatex knows whether a particular citation is the first or not. –  moewe Mar 10 at 15:41
I try to use this solution but did not work in my case. Nothing apears. @moewe: Could you elaborate more your comment, please? –  TeXtnik Mar 11 at 8:31
@zunbeltz Well, biblatex has its own means of telling whether a particular citation is the first one (of a work) (using the \ifciteseen test). There are even standard styles (verbose and friends) that come pretty close to what godbyk seems to have implemented (see e.g. here). Then i's just a matter of using \footcite in your document and you are good to go. (Obviously that only works if you got tufte to work with biblatex, see here: spoiler: you will need a dev version that is not on CTAN). –  moewe Mar 11 at 9:26
@moewe Thanks for the info. I already use biblatex with tufte. I maybe try to use this ifciteseen. –  TeXtnik Mar 12 at 8:13