6

I want to change the output format of \citeauthor{} so that full names ("givenname familyname") instead of just family names are displayed. Therefore, I have to define a special format and change \citeauthor so that it uses this format for its output routine.

Like shown in the example in the biblatex manual (section 4.2.3, page 146; biblatex version 3.9), I use \ifblank{\namepartgiven} to check whether the current name has a non-empty field namepartgiven. The logic seems simple enough: If the test succeeds, \namepartgiven\space will be printed just before \namepartfamily; if the field is empty, \namepartfamily should be printed immediately, without any preceding \space. However, I wonder when \ifblank is supposed to trigger.

Consider the following example:

\documentclass{article}

\usepackage[backend=biber,bibstyle=authoryear, citestyle=authoryear-icomp]{biblatex}
\addbibresource{test.bib}

\usepackage{filecontents}
\begin{filecontents*}{test.bib}
@book{test,
  author = {John Doe and Smith},
  title = {How to write an extraordinary book},
  date = {2018}
}%    
\end{filecontents*}

\DeclareNameFormat{citeauthor}{%
%  \iffieldundef{\namepartgiven}{}%
    {\ifblank{\namepartgiven}{}{\namepartgiven\space}}%
  \namepartfamily%
  \ifnumgreater{\value{liststop}}{\value{listcount}}%
    {\ifnumgreater{\value{liststop}-1}{\value{listcount}}%
      {\multinamedelim}%
      {\finalnamedelim}%
    }%
    {\ifmorenames{\usebibmacro{name:andothers}}{}}%
}

\DeclareCiteCommand{\citeauthor}
  {\boolfalse{citetracker}%
   \usebibmacro{prenote}}%
  {\usebibmacro{citeindex}%
   \printnames[citeauthor]{author}}%
  {}
  {\midsentence*}

\begin{document}
\printbibliography

\citeauthor{test}\par\cite{test}
\end{document}

This code works as expected if \namepartgiven is not empty. However, the database contains no given name for the second author (Smith). Apparently, \ifblank doesn't trigger because the field is not present; consequently, it branches off to print the non-existent given name, followed by a space:

Unset field <code>namepartgiven</code> does not trigger <code>\ifblank</code>, so additional space is inserted.

So, how about checking first whether the field namepartgiven is used at all before checking whether it is empty? Just activate the first line after \DeclareNameFormat{citeauthor} and compile the document again! This is what you will see:

Using <code>\iffieldundef{namepartgiven}</code> gives the right result when there are no given names -- however, if the field is set, the given names are not displayed.

Not surprisingly, the erroneous space right before "Smith" has disappeared. But wait, what happened to John Doe? Why has "John" gone as well?

Does anybody know what is happening here? There must be something I haven't understood correctly -- or could this be a bug in biblatex?

Andreas
  • 955
  • \ifblank{\namepartgiven} never returns true. – egreg Mar 06 '18 at 10:48
  • 1
    You probably need \ifdefvoid instead of \ifblank. The example in the docs need tweaking. I'll have a look later, but maybe there is a simpler solution altogether. – moewe Mar 06 '18 at 10:53
  • What is the {\midsentence*} for? The standard is \DeclareCiteCommand{\citeauthor} {\boolfalse{citetracker}% \boolfalse{pagetracker}% \usebibmacro{prenote}} {\ifciteindex {\indexnames{labelname}} {}% \printnames{labelname}} {\multicitedelim} {\usebibmacro{postnote}} so I assume you want \DeclareCiteCommand{\citeauthor} {\boolfalse{citetracker}% \boolfalse{pagetracker}% \usebibmacro{prenote}} {\ifciteindex {\indexnames[citeauthor]{labelname}} {}% \printnames{labelname}} {\multicitedelim} {\usebibmacro{postnote}} – moewe Mar 06 '18 at 11:13
  • (modulo line breaks and zero-width chars, of course). – moewe Mar 06 '18 at 11:13
  • @moewe (Sorry for the delay -- real life interfered!) Regarding the \midsentence*: I have one peculiar entry in my database where the name corresponds to \namepartgiven \namepartfamilyi; the author used his family name's initial as a pseudonym. \citeauthor will end with \adddot for this author, so I thought it would make sense to indicate that this is no end-of-sentence mark. If I understand you correctly, \midsentence will only be honored in the bibliography, not in such citations, and should be removed as redundant? – Andreas Mar 06 '18 at 12:24
  • @moewe Regarding the wrong example code in the manual: Should I file a bug, or are you perchance the maintainer of biblatex? :-) – Andreas Mar 06 '18 at 12:28
  • @Andreas I'm part of the 'team'. As I said in my answer, the manual has already been fixed: https://github.com/plk/biblatex/commit/7f470c138fcb9e2312969d90f3bcc5e6e1841b9c – moewe Mar 06 '18 at 12:31
  • Mhhh. I would need to see the exact example, but normally \adddot is already an abbreviation dot and not a sentence-ending full stop, so \midsentence should not be needed, I would have thought. – moewe Mar 06 '18 at 12:36
  • @moewe Sorry, I must have missed this part. Thanks for the prompt fix! – Andreas Mar 06 '18 at 12:37

2 Answers2

5

The standard styles use \ifdefvoid instead of \ifblank. The \ifblank in the docs is a remnant of the old name format scheme (see Biblatex 3.3 name formatting) when the names parts were not passed down as macros, but as arguments. The documentation was fixed in version 3.12 (commit 7f470c1).

The answer to what you want to do is even easier

\DeclareNameAlias{citeauthor}{given-family}

enter image description here

moewe
  • 175,683
  • OK, the issue with \ifblank{} not expanding its arguments is resolved. Now, I have a further question: Why do the given names disappear if I enclose the \ifdefvoid in an \iffieldundef test? I know that this test is not necessary because ifdefvoid triggers on control sequences that are undefined, expand to \relax, or expand to an empty string -- so this is a purely academic question. – Andreas Mar 06 '18 at 12:52
  • @Andreas \namepartgiven is not a field as such and so \iffieldundef{\namepartgiven} is always true (i.e. the 'field' is undefined). The only proper way to test \namepart...s is \ifdefvoid. – moewe Mar 06 '18 at 12:55
4

\ifblank does no expansion on its argument, so \ifblank{\namepartgive} never returns true.

Expand \namepartgiven before \ifblank acts:

\DeclareNameFormat{citeauthor}{%
  \expandafter\ifblank\expandafter{\namepartgiven}{}{\namepartgiven\space}%
  \namepartfamily 
  \ifnumgreater{\value{liststop}}{\value{listcount}}%
    {\ifnumgreater{\value{liststop}-1}{\value{listcount}}%
      {\multinamedelim}%
      {\finalnamedelim}%
    }%
    {\ifmorenames{\usebibmacro{name:andothers}}{}}%
}

enter image description here

If you're afraid that the argument to \ifblank needs more than one expansion step to deliver the final result, you can define

\newcommand{\ifblankx}[1]{%
  \expandafter\ifblank\expandafter{\romannumeral-`Q#1}%
}

and use \ifblankx{\namepartgiven}{<true>}{<false>}. On the other hand, if you're confident that \namepartgiven just needs one expansion step, you can use

\ifdefvoid{\namepartgiven}{<true>}{<false>}
egreg
  • 1,121,712
  • 2
    The standard styles use \ifdefvoid. – moewe Mar 06 '18 at 10:56
  • That works perfectly, thank you! I never thought of checking the etoolbox manual for the definition of \ifblank because I assumed the official example would be correct. :-) – Andreas Mar 06 '18 at 11:12
  • AFAIK the set up is such that we can always expect the \namepart... macros to need exactly one expansion step. – moewe Mar 06 '18 at 11:42