# maxcitenames to be a variable

I need to submit my work. The publisher has the following requirements. To use the author-year method of citing.

For works with 2 authors, include both authors for all citations; for works with 3 to 5 authors, include all authors on the first citation, and use the first author's name with "et al." on subsequent citations: for works with 6 or more authors, use the first author's name with "et al." on all citations.

In my document

I have the following set up.

\usepackage[style=authoryear-comp, giveninits, hyperref=auto, uniquename=mininit, maxbibnames=99, maxcitenames=5, url=false, doi=false,  backend=biber,sortcites,  sorting=nyt]{biblatex}
\DeclareNameAlias{author}{last-first}
\DefineBibliographyStrings{english}{
}


I realize maxcitenames=5 should be something like

\if first encounter then greater than 2 and less than 6 then 5 but if not first encounter then 1 but if only 2 then always 2 and so on

I also need pages to be formatted as (pp. 3-4) unless this is the last field in the bibliography then keep it like it is

I struggle with the if statements and do not understand the syntax structure

I don't have the rep to create tags pagination, maxcitenames, and if. These may have been relevant to this question.

• The rules you quote sound like APA style. biblatex-apa (which can be loaded with style=apa) implements APA style as closely as possible with biblatex, maybe you want to try that. – moewe May 18 at 12:20
• But just to answer the question in the title: The value of (min|max)(bib|cite)?names can only be an integer. It is not possible to introduce conditionals at that point. Conditionals can be introduced later down the line, but then one might have to take care of a few things manually. For the "pp." issue I strongly suggest you open a new question (tex.meta.stackexchange.com/q/7425/35864) ideally with a full example document that shows what you are doing (because I don't quite get what you are after). – moewe May 18 at 12:30

The values of the (min|max)(bib|cite)?names options can only be integers greater or equal to one, they can not contain conditionals and you can not conditionally set the option (you could set the corresponding counter manually though, the option does not do more than that either, but it passes the value on to the backend where it might become relevant for uniqueness and label calculations) from within the document (which is when you know whether you are at a first or subsequent citation). You will have to implement the behaviour without help of those options.

One natural way to do that can be found in apa.cbx, ll. 98-177

% Can't do this with the built-in printnames format as APA requires truncation
% and disambiguation only after first cite
% We either use uniquelist or minnames for truncation. If uniquelist isn't
% defined, we fall back on minnames
%
% \printnames does different things depending on whether the format you are
% calling is the default for the name field or is a custom format:
%
% max/minnames truncation is done before calling the format so we have
% to do \printnames[format][-\value{listtotal}]{field} to ensure we get
% all of the names in the list to work on here
%
% Explicit "and others" is dealt with in labelname:doname via a custom name:andothers

\DeclareNameFormat{labelname}{%
% First set the truncation point
\ifthenelse{\value{uniquelist}>1}
{\numdef\cbx@min{\value{uniquelist}}}
{\numdef\cbx@min{\value{minnames}}}%
% Always print the first name and the second if there are only two since
% "et al" must always be plural
\ifboolexpr{test {\ifnumcomp{\value{listcount}}{=}{1}}
or test {\ifnumcomp{\value{listtotal}}{=}{2}}}
{\usebibmacro{labelname:doname}%
{\namepartfamily}%
{\namepartfamilyi}%
{\namepartgiven}%
{\namepartgiveni}%
{\namepartprefix}%
{\namepartprefixi}%
{\namepartsuffix}%
{\namepartsuffixi}}
% We are looking at name >=3
% If the list is 6 or more names or we have seen citation before, potential truncation
{\ifboolexpr{test {\ifnumcomp{\value{listtotal}}{>}{5}}
or test {\ifciteseen}}
% Less than the truncation point, print normally
{\ifnumcomp{\value{listcount}}{<}{\cbx@min + 1}
{\usebibmacro{labelname:doname}%
{\namepartfamily}%
{\namepartfamilyi}%
{\namepartgiven}%
{\namepartgiveni}%
{\namepartprefix}%
{\namepartprefixi}%
{\namepartsuffix}%
{\namepartsuffixi}}
{}%
% At potential truncation point ...
\ifnumcomp{\value{listcount}}{=}{\cbx@min + 1}
% but enforce plurality of et al - only truncate here if there is at
% least one more element after the current potential truncation point
% so that "et al" covers at least two elements.
{\ifnumcomp{\value{listcount}}{<}{\value{listtotal}}
{\printdelim{andothersdelim}\bibstring{andothers}}
{\usebibmacro{labelname:doname}%
{\namepartfamily}%
{\namepartfamilyi}%
{\namepartgiven}%
{\namepartgiveni}%
{\namepartprefix}%
{\namepartprefixi}%
{\namepartsuffix}%
{\namepartsuffixi}}}
{}%
% After truncation point, do not print name
\ifnumcomp{\value{listcount}}{>}{\cbx@min + 1}
{\relax}%
{}}%
% We are looking at name >=3
% Name list is < 6 names or we haven't seen this citation before, print normally
{\usebibmacro{labelname:doname}%
{\namepartfamily}%
{\namepartfamilyi}%
{\namepartgiven}%
{\namepartgiveni}%
{\namepartprefix}%
{\namepartprefixi}%
{\namepartsuffix}%
{\namepartsuffixi}}}}


Essentially, the style makes sure to always call \printnames{labelname} as \printnames[labelname][-\value{listtotal}]{labelname} to always get all names regardless of any maxnames truncations. The name format then goes through the different cases and only prints a name in the list in the cases you want to see it. It also takes the uniquelist feature into account and makes sure that et al. refers to more than one author, so it is a little more complex than one might expect at first.

A simpler version that ignores any of these subtleties and works with authoryear-comp would be the following. The modifications of the cite and textcite bibmacros compared to the default consists only in exchanging \printnames{labelname} with \printnames[labelname][-\value{listtotal}]{labelname}. The macro labelname:indiv holds the original definition of the labelname name format without the code for et al..

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[style=authoryear-comp,
maxcitenames=2, mincitenames=1, maxbibnames=999,
citetracker, backend=biber]{biblatex}

\DeclareNameFormat{labelname}{%
\ifboolexpr{test {\ifnumcomp{\value{listcount}}{=}{1}}
or test {\ifnumcomp{\value{listtotal}}{=}{2}}}
{\usebibmacro{labelname:indiv}}
{\ifboolexpr{test {\ifnumcomp{\value{listtotal}}{>}{5}}
or test {\ifciteseen}}
{\ifnumcomp{\value{listcount}}{=}{2}
{\printdelim{andothersdelim}\bibstring{andothers}}
{}}
{\usebibmacro{labelname:indiv}}}}

\newbibmacro{labelname:indiv}{%
\ifcase\value{uniquename}%
\usebibmacro{name:family}
{\namepartfamily}
{\namepartgiven}
{\namepartprefix}
{\namepartsuffix}%
\or
\ifuseprefix
{\usebibmacro{name:given-family}
{\namepartfamily}
{\namepartgiveni}
{\namepartprefix}
{\namepartsuffixi}}
{\usebibmacro{name:given-family}
{\namepartfamily}
{\namepartgiveni}
{\namepartprefixi}
{\namepartsuffixi}}%
\or
\usebibmacro{name:given-family}
{\namepartfamily}
{\namepartgiven}
{\namepartprefix}
{\namepartsuffix}%
\fi
}

\makeatletter
\renewbibmacro*{cite}{%
\iffieldundef{shorthand}
{\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
{\usebibmacro{cite:label}%
\setunit{\printdelim{nonameyeardelim}}%
\usebibmacro{cite:reinit}}
{\iffieldequals{namehash}{\cbx@lasthash}
{\ifthenelse{\iffieldequals{labelyear}{\cbx@lastyear}\AND
$$\value{multicitecount}=0\OR\iffieldundef{postnote}$$}
{\setunit{\compcitedelim}%
\savefield{labelyear}{\cbx@lastyear}}}
{\printnames[labelname][-\value{listtotal}]{labelname}%
\setunit{\printdelim{nameyeardelim}}%
\savefield{namehash}{\cbx@lasthash}%
\savefield{labelyear}{\cbx@lastyear}}}}
{\usebibmacro{cite:shorthand}%
\usebibmacro{cite:reinit}}%
\setunit{\multicitedelim}}

\renewbibmacro*{textcite}{%
\iffieldequals{namehash}{\cbx@lasthash}
{\iffieldundef{shorthand}
{\ifthenelse{\iffieldequals{labelyear}{\cbx@lastyear}\AND
$$\value{multicitecount}=0\OR\iffieldundef{postnote}$$}
{\setunit{\compcitedelim}%
\savefield{labelyear}{\cbx@lastyear}}}
{\setunit{\compcitedelim}%
\usebibmacro{cite:shorthand}%
\global\undef\cbx@lastyear}}
{\ifnameundef{labelname}
{\iffieldundef{shorthand}
{\usebibmacro{cite:label}%
\setunit{%
\global\booltrue{cbx:parens}%
\printdelim{nonameyeardelim}\bibopenparen}%
\ifnumequal{\value{citecount}}{1}
{\usebibmacro{prenote}}
{}%
{\usebibmacro{cite:shorthand}}}
{\printnames[labelname][-\value{listtotal}]{labelname}%
\setunit{%
\global\booltrue{cbx:parens}%
\printdelim{nameyeardelim}\bibopenparen}%
\ifnumequal{\value{citecount}}{1}
{\usebibmacro{prenote}}
{}%
\iffieldundef{shorthand}
{\iffieldundef{labelyear}
{\usebibmacro{cite:label}}
\savefield{labelyear}{\cbx@lastyear}}
{\usebibmacro{cite:shorthand}%
\global\undef\cbx@lastyear}}%
\stepcounter{textcitecount}%
\savefield{namehash}{\cbx@lasthash}}%
\setunit{%
\ifbool{cbx:parens}
{\bibcloseparen\global\boolfalse{cbx:parens}}
{}%
\textcitedelim}}
\makeatother

\begin{document}
\cite{sigfridsson,aksin,companion,herrmann}

\cite{sigfridsson,aksin,companion,herrmann}
\printbibliography
\end{document}


Your description of the desired output, however, matches exactly the APA rules and the rest of your set-up also makes me suspect that you want something that is very close if not exactly APA style. So maybe you'd be better off using

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[style=apa, backend=biber]{biblatex}


One caveat: biblatex-apa implements APA style as closely as possible with biblatex (and probably even with LaTeX overall, the other LaTeX implementation of APA style is the BibTeX-based apacite), that means it is quite complex and not as easily customised as the standard styles. So if you don't need APA style, you can use biblatex-apa as a basis, but depending on your desiderata it might be more tricky than in the standard styles to implement the modifications you need.