Try the following code, it largely relies on your pseudo code above.
We use a \savebox
to evaluate the length. We just need to set \setlength{\availablewidth}{\linewidth}
.
We define a new bibmacro
varwidthname
. We need some new name formats for that
\DeclareNameFormat{first-last-full}{%
\usebibmacro{name:first-last}{#1}{#3}{#5}{#7}}
\DeclareNameFormat{first-last-inits}{%
\usebibmacro{name:first-last}{#1}{#4}{#5}{#7}}
\DeclareNameFormat{first-last-inits-etal}{%
\usebibmacro{name:first-last}{#1}{#4}{#5}{#7}%
\usebibmacro{name:andothers}}
\newlength{\availablewidth}
\setlength{\availablewidth}{\linewidth}
%\setlength{\availablewidth}{50mm}
\newcounter{templabelnamea}
\newcounter{templabelnameb}
\newcommand*{\thisnamedelim}{\multinamedelim}
\newif\ifprintouthappened
\printouthappenedfalse
\newsavebox\mybox
\makeatletter
\newbibmacro*{varwidthname}{%
\printouthappenedfalse
\sbox{\mybox}{\printnames[first-last-full][-\c@labelname]{labelname}}% this is the full name list
\ifdim\wd\mybox>\availablewidth% if the full list is to long, start shortening it
\sbox{\mybox}{\printnames[first-last-inits][-\c@labelname]{labelname}}% all initials
\ifdim\wd\mybox<\availablewidth
\setcounter{templabelnamea}{\c@labelname}%
\setcounter{templabelnameb}{\c@labelname}%
\addtocounter{templabelnameb}{-1}%
\loop\ifnum\value{templabelnamea}>1%
\ifnum\value{templabelnamea}=\c@labelname
\renewcommand{\thisnamedelim}{\finalnamedelim}%
\else
\renewcommand{\thisnamedelim}{\multinamedelim}%
\fi
\sbox{\mybox}{\printnames[first-last-full][1-\value{templabelnameb}]{labelname}\thisnamedelim\printnames[first-last-inits][\value{templabelnamea}-\c@labelname]{labelname}}%
\ifnum\wd\mybox<\availablewidth
\printnames[first-last-full][1-\value{templabelnameb}]{labelname}\thisnamedelim\printnames[first-last-inits][\value{templabelnamea}-\c@labelname]{labelname}%
\printouthappenedtrue
\let\iterate\relax
\fi
\addtocounter{templabelnamea}{-1}%
\addtocounter{templabelnameb}{-1}%
\repeat
\ifprintouthappened
\else
\printnames[first-last-inits][-\c@labelname]{labelname}%
\printouthappenedtrue
\fi
\else
\sbox{\mybox}{\printnames[first-last-inits][-\c@labelname]{labelname}}%
\setcounter{templabelnamea}{\c@labelname}%
\loop\ifnum\value{templabelnamea}>0
\sbox{\mybox}{\printnames[first-last-inits-etal][-\value{templabelnamea}]{labelname}}%
\ifnum\wd\mybox<\availablewidth
\printnames[first-last-inits-etal][-\value{templabelnamea}]{labelname}%
\printouthappenedtrue
\let\iterate\relax
\fi
\addtocounter{templabelnamea}{-1}%
\repeat
\fi
\else% full list is fine
\printnames[first-last-full][-\c@labelname]{labelname}%
\printouthappenedtrue
\fi
\ifprintouthappened
\else
\printnames[first-last-inits-etal][1-1]{labelname}%
\fi}
\makeatother
This command will not print anything if the available width is too small to fit anything in.
The command will always choose the shortest possible form (one author with initials and "et al." if applicable) if the space is too small to fit anything in.
We can the define a new cite command: \varwidthciteauthor
.
\DeclareCiteCommand{\varwidthciteauthor}
{\usebibmacro{prenote}}
{\usebibmacro{citeindex}%
\usebibmacro{varwidthname}}
{\multicitedelim}
{\usebibmacro{postnote}}
MWE
\documentclass[a4paper]{article}
\usepackage[maxnames=999]{biblatex}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
@book{foo1, Author={Agnes Ursula Thor and Charles-Oliver Author and William Riter and Claire Ontributor and Sandra Uperv-Isor and Gina Raphics}, Year={2014}, Title={A very interesting book}, Subtitle={With subtitle}, Publisher={SUP Press}, Location={Someplace / Otherplace}}
@book{foo2, Author={Agnes Ursula Thor and Charles-Oliver Author and William Riter and Claire Ontributor and Sandra Uperv-Isor}, Year={2014}, Title={A very interesting book}, Subtitle={With subtitle}, Publisher={SUP Press}, Location={Someplace / Otherplace}}
@book{foo3, Author={Agnes Ursula Thor and Charles-Oliver Author and William Riter and Claire Ontributor}, Year={2014}, Title={A very interesting book}, Subtitle={With subtitle}, Publisher={SUP Press}, Location={Someplace / Otherplace}}
@book{foo4, Author={Agnes Ursula Thor and Charles-Oliver Author and William Riter}, Year={2014}, Title={A very interesting book}, Subtitle={With subtitle}, Publisher={SUP Press}, Location={Someplace / Otherplace}}
@book{foo5, Author={Agnes Ursula Thor and Charles-Oliver Author}, Year={2014}, Title={A very interesting book}, Subtitle={With subtitle}, Publisher={SUP Press}, Location={Someplace / Otherplace}}
@book{foo6, Author={Agnes Ursula Thor}, Year={2014}, Title={A very interesting book}, Subtitle={With subtitle}, Publisher={SUP Press}, Location={Someplace / Otherplace}}
\end{filecontents*}
\addbibresource{\jobname.bib}
\DeclareCiteCommand{\varwidthciteauthor}
{\usebibmacro{prenote}}
{\usebibmacro{citeindex}%
\usebibmacro{varwidthname}}
{\multicitedelim}
{\usebibmacro{postnote}}
\DeclareNameFormat{first-last-full}{%
\usebibmacro{name:first-last}{#1}{#3}{#5}{#7}}
\DeclareNameFormat{first-last-inits}{%
\usebibmacro{name:first-last}{#1}{#4}{#5}{#7}}
\DeclareNameFormat{first-last-inits-etal}{%
\usebibmacro{name:first-last}{#1}{#4}{#5}{#7}%
\usebibmacro{name:andothers}}
\newlength{\availablewidth}
\setlength{\availablewidth}{\linewidth}
%\setlength{\availablewidth}{50mm}
\newcounter{templabelnamea}
\newcounter{templabelnameb}
\newcommand*{\thisnamedelim}{\multinamedelim}
\newif\ifprintouthappened
\printouthappenedfalse
\newsavebox\mybox
\makeatletter
\newbibmacro*{varwidthname}{%
\printouthappenedfalse
\sbox{\mybox}{\printnames[first-last-full][-\c@labelname]{labelname}}% this is the full name list
\ifdim\wd\mybox>\availablewidth% if the full list is to long, start shortening it
\sbox{\mybox}{\printnames[first-last-inits][-\c@labelname]{labelname}}% all initials
\ifdim\wd\mybox<\availablewidth
\setcounter{templabelnamea}{\c@labelname}%
\setcounter{templabelnameb}{\c@labelname}%
\addtocounter{templabelnameb}{-1}%
\loop\ifnum\value{templabelnamea}>1%
\ifnum\value{templabelnamea}=\c@labelname
\renewcommand{\thisnamedelim}{\finalnamedelim}%
\else
\renewcommand{\thisnamedelim}{\multinamedelim}%
\fi
\sbox{\mybox}{\printnames[first-last-full][1-\value{templabelnameb}]{labelname}\thisnamedelim\printnames[first-last-inits][\value{templabelnamea}-\c@labelname]{labelname}}%
\ifnum\wd\mybox<\availablewidth
\printnames[first-last-full][1-\value{templabelnameb}]{labelname}\thisnamedelim\printnames[first-last-inits][\value{templabelnamea}-\c@labelname]{labelname}%
\printouthappenedtrue
\let\iterate\relax
\fi
\addtocounter{templabelnamea}{-1}%
\addtocounter{templabelnameb}{-1}%
\repeat
\ifprintouthappened
\else
\printnames[first-last-inits][-\c@labelname]{labelname}%
\printouthappenedtrue
\fi
\else
\sbox{\mybox}{\printnames[first-last-inits][-\c@labelname]{labelname}}%
\setcounter{templabelnamea}{\c@labelname}%
\loop\ifnum\value{templabelnamea}>0
\sbox{\mybox}{\printnames[first-last-inits-etal][-\value{templabelnamea}]{labelname}}%
\ifnum\wd\mybox<\availablewidth
\printnames[first-last-inits-etal][-\value{templabelnamea}]{labelname}%
\printouthappenedtrue
\let\iterate\relax
\fi
\addtocounter{templabelnamea}{-1}%
\repeat
\fi
\else% full list is fine
\printnames[first-last-full][-\c@labelname]{labelname}%
\printouthappenedtrue
\fi
\ifprintouthappened
\else
\printnames[first-last-inits-etal][1-1]{labelname}%
\fi}
\makeatother
\begin{document}
\noindent\varwidthciteauthor{foo1}
\noindent\varwidthciteauthor{foo2}
\noindent\varwidthciteauthor{foo3}
\noindent\varwidthciteauthor{foo4}
\noindent\varwidthciteauthor{foo5}
\noindent\varwidthciteauthor{foo6}
\end{document}
Note that you really should not use this kind of citation command in an actual document, for one the proper length to test against will be harder to establish than just \linewidth
. And - this is the more important point - it will look very very inconsistent (at times you print 4 names, then again only 2, sometimes only initials, sometimes full names, at times even some kind of hybrid in between), style guides normally despise inconsistencies - especially inconsistencies of such proportion - for a good reason.