3

With the biblatex option uniquename = true (and citetracker = true, maxcitenames = 1), I can with the addition of the code \AtEveryCitekey{\ifciteseen{}{\defcounter{maxnames}{99}}} abbreviate any multi-authored work to Author et al. after its first full citation, cf. the MWE below:

\documentclass{article}
\usepackage[style = authoryear-comp, citetracker = true, maxcitenames = 1, uniquename = true]{biblatex}
\AtEveryCitekey{\ifciteseen{}{\defcounter{maxnames}{99}}} % cite all authors of multi-authored works only once
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@BOOK{lennon1963,
    AUTHOR = "John Lennon and Paul McCartney",
    TITLE = "She loves you",
    YEAR = "1963"}
@BOOK{lennon2004,
    AUTHOR = "Sean Lennon",
    TITLE = "My father was John Lennon",
    YEAR = "2004"}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\noindent\cite{lennon1963}\\
\cite{lennon1963}\\
\cite{lennon2004}
\end{document}

enter image description here

But when changing uniquename = true to uniquename = false, this doesn't work:

enter image description here

Question: How can I retain the functionality of \AtEveryCitekey{\ifciteseen{}{\defcounter{maxnames}{99}}} also with the biblatex option uniquename = false?


EDIT Carlo's answer below works, but now I'm curious how one can constrain this so that the Author 1, Author 2, and Author 3 abbreviation to Author 1 et al. only kicks in when there are three or more authors of a work. In the MWE below, Lennon and McCartney 1963 should remain as such in its second citation, whereas Lennon, McCartney, Harrison, and Starkey 1970 should abbreviate to Lennon et al. 1970 in its second citation.

\documentclass{article}
\usepackage[style = authoryear-comp, citetracker = true, maxcitenames = 99, mincitenames = 2, uniquename = false]{biblatex}
\AtEveryCitekey{\ifciteseen{\defcounter{maxnames}{1}}{}} % cite all authors of multi-authored works only once
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@BOOK{lennon1963,
    AUTHOR = "John Lennon and Paul McCartney",
    TITLE = "She loves you",
    YEAR = "1963"}
@BOOK{lennon1970,
    AUTHOR = "John Lennon and Paul McCartney and George Harrison and Richard Starkey",
    TITLE = "We're breaking up now",
    YEAR = "1970"}
@BOOK{lennon2004,
    AUTHOR = "Sean Lennon",
    TITLE = "My father was John Lennon",
    YEAR = "2004"}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\noindent\cite{lennon1963}\\
\cite{lennon1963}\\
\cite{lennon1970}\\
\cite{lennon1970}\\
\cite{lennon2004}
\end{document}

enter image description here


EDIT to EDIT

Carlo's answer below works perfectly. I've simplified the code a bit, though, and tweaked it a bit so that at least I will understand it when looking at it later :):

\AtEveryCitekey% for every citation
    {%
        \ifnumgreater{\value{labelname}}{2}% if there are >2 authors
            {%
                \ifciteseen% and if citation has been seen before
                    {\setcounter{maxnames}{1}}% then cite only one author
                    {\setcounter{maxnames}{\value{labelname}}}% otherwise cite all authors
            }
            {\setcounter{maxnames}{\value{labelname}}}% otherwise cite ≤2 authors
    }
Sverre
  • 20,729

1 Answers1

1

"Change the logic". maxcitenames = 99 in the biblatex options and \defcounter{maxnames}{1} in the True of ifciteseen.

MWE

\documentclass{article}
\usepackage[style = authoryear-comp, citetracker = true, maxcitenames = 99, uniquename = false]{biblatex}
\AtEveryCitekey{%
    \ifciteseen
    {\defcounter{maxnames}{1}}
    {}} % cite all authors of multi-authored works only once
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@BOOK{lennon1963,
    AUTHOR = "John Lennon and Paul McCartney",
    TITLE = "She loves you",
    YEAR = "1963"}
@BOOK{lennon2004,
    AUTHOR = "Sean Lennon",
    TITLE = "My father was John Lennon",
    YEAR = "2004"}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\noindent\cite{lennon1963}\\
\cite{lennon1963}\\
\cite{lennon2004}
\end{document}

enter image description here

EDIT Answer to the edit question.##

I found two ways and goint to post both.

The first

This is not the best form, initially I didn't find another. In this way it is not used \AtEveryCitekey. It is used listtotal that is a counter of total number in the list (author, editors... or labelname). The counter listtotal is only allowed in list formatting directives and does not hold a meaningful value when used anywhere else.

In the \patchlabelnameformat if the value of listtotal is greater that two and it is the first citation set the liststop (maximun number of item list to print) in the \value{listtotal}. If not is the first citation, the listtop is set to 1. On the other hand, if the value of listtotal is less that two the listtop is set at \value{listtotal}.

MWE:

\documentclass{article}
\usepackage[style = authoryear-comp, citetracker = true,maxnames=2, minnames=2,uniquename=false]{biblatex}

\def\fgt{\setcounter{liststop}{\value{listtotal}}} %first and greater than two \def\nfgt{\setcounter{liststop}{1}} %non first and greater than two

\def\flt{\setcounter{liststop}{\value{listtotal}}} %first and lower than two

\def\patchlabelnameformat{% \ifnumgreater{\value{listtotal}}{2} {\ifciteseen {\nfgt} {\fgt}} {\flt}}

\DeclareNameFormat{labelname}{% \patchlabelnameformat \ifcase\value{uniquename}% \usebibmacro{name:last}{#1}{#3}{#5}{#7}% \or \ifuseprefix {\usebibmacro{name:first-last}{#1}{#4}{#5}{#8}} {\usebibmacro{name:first-last}{#1}{#4}{#6}{#8}}% \or \usebibmacro{name:first-last}{#1}{#3}{#5}{#7}% \fi \usebibmacro{name:andothers}}

\usepackage{filecontents} \begin{filecontents}{\jobname.bib} @BOOK{lennon1963, AUTHOR = "John Lennon and Paul McCartney", TITLE = "She loves you", YEAR = "1963"} @BOOK{lennon1970, AUTHOR = "John Lennon and Paul McCartney and George Harrison and Richard Starkey", TITLE = "We're breaking up now", YEAR = "1970"} @BOOK{lennon2004, AUTHOR = "Sean Lennon", TITLE = "My father was John Lennon", YEAR = "2004"} \end{filecontents} \addbibresource{\jobname.bib} \begin{document} \noindent\cite{lennon1963}\ \cite{lennon1963}\ \cite{lennon1970}\ \cite{lennon1970}\ \cite{lennon2004} \end{document}

The Second

The best form. It is used \AtEveryCitekey. The logic is the same to the first way, but it is not possible used listtotal and listtop because \AtEveryCitekey is not list formatting directive. Then, in this way is used the counter labelname and is set the maxnames. It is necessary to use uniquelist=false in the biblatex options.

MWE:

\documentclass{article}
\usepackage[style = authoryear-comp, citetracker = true,uniquename=false,uniquelist=false]{biblatex}

\AtEveryCitekey{\maxminformat} % cite all authors of

\def\fgt{\setcounter{maxnames}{\value{labelname}}} %first and greater than two \def\nfgt{\setcounter{minnames}{1}\setcounter{maxnames}{1}} %non first and greater than two

\def\flt{\setcounter{maxnames}{\value{labelname}}} %first and lower than two

\def\maxminformat{% \ifnumgreater{\value{labelname}}{2} {\ifciteseen {\nfgt} {\fgt}} {\flt}}

\usepackage{filecontents} \begin{filecontents}{\jobname.bib} @BOOK{lennon1963, AUTHOR = "John Lennon and Paul McCartney", TITLE = "She loves you", YEAR = "1963"} @BOOK{lennon1970, AUTHOR = "John Lennon and Paul McCartney and George Harrison and Richard Starkey", TITLE = "We're breaking up now", YEAR = "1970"} @BOOK{lennon2004, AUTHOR = "Sean Lennon", TITLE = "My father was John Lennon", YEAR = "2004"} \end{filecontents} \addbibresource{\jobname.bib} \begin{document} \noindent\cite{lennon1963}\ \cite{lennon1963}\ \cite{lennon1970}\ \cite{lennon1970}\ \cite{lennon2004} \end{document}

enter image description here