0

I'm at the end of writing a text, and I'm not very lucky about the way I had to handle author names so far. I'm using the solution from Citing author's full name in biblatex the first time it appears and cite authornames with \citeauthor{key}.

Well, this can become hard to read in the source code, if you always have to deal with keys, especially if you have more entries with the same author. So I'm looking for a way to make author citing more convenient.

Look at the following MWE:

\documentclass{article}
\usepackage[style=verbose-ibid]{biblatex}
\usepackage{filecontents}

\begin{filecontents*}{mybib.bib}
@book{kpv,
    author={Immanuel Kant},
    title={Kritik der praktischen Vernunft}
}
@book{krv,
    author={Immanuel Kant},
    title={Kritik der reinen Vernunft}
}   
@book{sz,
    author={Martin Heidegger},
    title={Sein und Zeit}
}
@book{sg,
    author={Martin Heidegger},
    title={Der Satz vom Grund}
}
\end{filecontents*}

\addbibresource{mybib.bib}


\makeatletter
\newcommand*{\cbx@seennames}{}
\newrobustcmd*{\cbx@nameseen}[1]{%
  \listxadd{\cbx@seennames}{\detokenize{#1}}}
\newrobustcmd*{\cbx@ifnameseen}[1]{%
  \xifinlist{\detokenize{#1}}{\cbx@seennames}}

\DeclareNameFormat{citeauthor}{%
  \cbx@ifnameseen{#1#3#5#7}
    {\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}}%
     \fi}%
    {\usebibmacro{name:first-last}{#1}{#3}{#5}{#7}%
     \cbx@nameseen{#1#3#5#7}}%
  \usebibmacro{name:andothers}}
\DeclareCiteCommand{\citeauthor}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\indexnames{labelname}%
   \printnames[citeauthor]{labelname}}
  {\multicitedelim}
  {\usebibmacro{postnote}}
\makeatother

\begin{document}
\noindent{}\citeauthor{sz} has shown that\ldots, but \citeauthor{kpv} presumes that\ldots.

However, \citeauthor{krv} lived in the 18. century, \citeauthor{sg} in the 20.

\nocite{*}

\printbibliography
\end{document}


Idea 1: Let LaTeX automatically generate commands like \kant and \heidegger out of the .bib-file. I don't know if this is possible, but that would be my absolute favourite.

Idea 2: Let biblatex automatically generate dummy entries (i.e. @book) for every author. So, in my example below it had to generate the entries @book{kant,authorname={Immanuel Kant}} and @book{heidegger,authorname={Martin Heidegger}} and I can at least use \citeauthor{kant}.

This all could become more difficult, if you have more authors for one record: \heideggeretal

5
  • 1
    Why even use the cite command if you do not actually cite the work?
    – lvcivs
    Commented May 20, 2014 at 9:10
  • It's just a short MWE, I also cite titles in the text and have fullcites in footnotes etc.
    – musicman
    Commented May 20, 2014 at 9:13
  • 1
    Maybe you could approach this from a more semantic point of view: When you use \citeauthor{work}, you refer to the author of work. Now if you don't want to refer to a particular person as the author of a work, you should type the name of that person out or use another command. You can have a list of people in biblatex, but you will have to create it manually - a automatic creation might have big problems to decide on what names to use for the commands (b/c of name ambiguities etc.).
    – moewe
    Commented Apr 5, 2015 at 12:00
  • Is there any news here?
    – Johannes_B
    Commented May 9, 2016 at 8:32
  • Any news here? What did you end up doing?
    – moewe
    Commented Nov 15, 2017 at 16:47

1 Answer 1

1

You may be interested in the nameauth package for consistent formatting of names.

Here is something to get you started. You can ignore the first bit, it's just a copy of my answer to First citation with first name that improves slightly on Citing author's full name in biblatex the first time it appears and makes it compatible with biblatex >= 3.3.

The second bit of code starting at \DeclareCiteCommand{\specialciteauthor} creates a macro \<Lastname> for each name encountered and associates it with an internal version of \citeauthor{<some entry key authored by name>}.

\documentclass{article}
\usepackage[style=verbose-ibid]{biblatex}
\usepackage{filecontents}

\begin{filecontents*}{\jobname.bib}
@book{kpv,
    author={Immanuel Kant},
    title={Kritik der praktischen Vernunft}
}
@book{krv,
    author={Immanuel Kant},
    title={Kritik der reinen Vernunft}
}   
@book{sz,
    author={Martin Heidegger},
    title={Sein und Zeit}
}
@book{sg,
    author={Martin Heidegger},
    title={Der Satz vom Grund}
}
@book{apphack,
    author={Humprey Appleby and James Hacker},
    title={On the Importance of the Civil Service}
}
\end{filecontents*}

\addbibresource{\jobname.bib}


\makeatletter
\newrobustcmd*{\cbx@nametracker@global}[1]{%
  \xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}
    {}
    {\listcsxadd{cbx@bseen@names@\the\c@refsection}{#1}}}

\newrobustcmd*{\cbx@nametracker@context}[1]{%
  \iftoggle{blx@footnote}
    {\xifinlistcs{#1}{cbx@fseen@names@\the\c@refsection}
       {}
       {\listcsxadd{cbx@fseen@names@\the\c@refsection}{#1}}}
    {\xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}
       {}
       {\listcsxadd{cbx@bseen@names@\the\c@refsection}{#1}}}}

\newrobustcmd*{\cbx@ifnameseen@global}[1]{%
  \xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}}

\newrobustcmd*{\cbx@ifnameseen@context}[1]{%
  \iftoggle{blx@footnote}%
    {\xifinlistcs{#1}{cbx@fseen@names@\the\c@refsection}}%
    {\xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}}}

\DeclareBibliographyOption[string]{nametracker}[true]{%
  \ifcsdef{blx@opt@nametracker@#1}
    {\csuse{blx@opt@nametracker@#1}}
    {\blx@err@invopt{nametracker=#1}{}}}

\def\blx@opt@nametracker@global{%
  \let\cbx@ifnameseen\cbx@ifnameseen@global
  \let\cbx@nametracker\cbx@nametracker@global}

\let\blx@opt@nametracker@true\blx@opt@nametracker@global

\def\blx@opt@nametracker@false{%
  \protected\long\def\cbx@ifnameseen##1##2##3{##3}%
  \let\cbx@nametracker\relax}

\def\blx@opt@nametracker@context{%
  \let\cbx@ifnameseen\cbx@ifnameseen@context
  \let\cbx@nametracker\cbx@nametracker@context}

\appto\blx@secinit{%
  \ifcsundef{cbx@bseen@names@\the\c@refsection}
    {\global\cslet{cbx@bseen@names@\the\c@refsection}\@empty}
    {}%
  \ifcsundef{cbx@fseen@names@\the\c@refsection}
    {\global\cslet{cbx@fseen@names@\the\c@refsection}\@empty}
    {}}

\InitializeCitationStyle{%
  \global\cslet{cbx@bseen@names@\the\c@refsection}\@empty
  \global\cslet{cbx@fseen@names@\the\c@refsection}\@empty}

\ExecuteBibliographyOptions{nametracker=context}

\DeclareNameFormat{labelname}{%
  \cbx@ifnameseen{\thefield{hash}}
    {\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}
    {\usebibmacro{name:given-family}
       {\namepartfamily}
       {\namepartgiven}
       {\namepartprefix}
       {\namepartsuffix}%
     \cbx@nametracker{\thefield{hash}}}%
    \usebibmacro{name:andothers}}

\DeclareCiteCommand{\specialciteauthor}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}}
  {\renewbibmacro*{name:andothers}{}%
   \printnames[labelname][\thefield{postnote}-\thefield{postnote}]{author}}
  {}
  {}

\DeclareIndexNameFormat{createauthorcommands}{%
  \ifcsundef{nbx@\thefield{hash}}
    {\global\cslet{nbx@\thefield{hash}}\@empty
     \csxdef{\namepartfamily}{%
       \noexpand\specialciteauthor[\the\value{listcount}]
       {\thefield{entrykey}}}%
     \typeout{created author command '\namepartfamily' for
       \namepartfamily\space to point to author
       \the\value{listcount} of \thefield{entrykey}.}
     }
    {}}%

\AtDataInput{\indexnames[createauthorcommands][1-999]{author}}

\makeatother


\begin{document}
\Kant{} and \Appleby{} and \Hacker{}

\citeauthor{sz} has shown that\ldots, but \citeauthor{kpv} presumes that\ldots.

However, \citeauthor{krv} lived in the 18. century, \citeauthor{sg} in the 20.

\nocite{*}

\printbibliography
\end{document}

The approach is not ideal and has a few drawbacks

  1. If there are two people with the same last name, the commands are overwritten. Maybe one can use the uniquename feature to avoid this.
  2. Names with non-ASCII chars can cause problems because the name is used as a \csname. This could be solved by sanitising the name (ideally with Biber's sourcemapping -> strip non-ASCII chars and maybe even lowercase).
  3. The macros \<Lastname> are only available after a Biber run. So in the example \Kant will produce an undefined control sequence error. The compilation must not be aborted (because then Biber can not be run), tell TeX to plough on regardless, then run Biber and things should work in the next run. This could be solved by using a different interface like \mmname{Kant} where \mmname can always be defined.

The following approach solves 3. and uses uniquename to prevent name clashes as explained in 1.

\documentclass{article}
\usepackage[style=verbose-ibid, uniquename, maxnames=999]{biblatex}
\usepackage{filecontents}

\begin{filecontents*}{\jobname.bib}
@book{kpv,
    author={Immanuel Kant},
    title={Kritik der praktischen Vernunft}
}
@book{krv,
    author={Immanuel Kant},
    title={Kritik der reinen Vernunft}
}   
@book{sz,
    author={Martin Heidegger},
    title={Sein und Zeit}
}
@book{sg,
    author={Martin Heidegger},
    title={Der Satz vom Grund}
}
@book{apphack,
    author={Humprey Appleby and James Hacker},
    title={On the Importance of the Civil Service}
}
@book{elk,
    author={Emma Elk and Anne Belk},
    title={Brontos!}
}
@book{elk2,
    author={Anne Elk and Anna Belk},
    title={Brontos!}
}
\end{filecontents*}

\addbibresource{\jobname.bib}


\makeatletter
\newrobustcmd*{\cbx@nametracker@global}[1]{%
  \xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}
    {}
    {\listcsxadd{cbx@bseen@names@\the\c@refsection}{#1}}}

\newrobustcmd*{\cbx@nametracker@context}[1]{%
  \iftoggle{blx@footnote}
    {\xifinlistcs{#1}{cbx@fseen@names@\the\c@refsection}
       {}
       {\listcsxadd{cbx@fseen@names@\the\c@refsection}{#1}}}
    {\xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}
       {}
       {\listcsxadd{cbx@bseen@names@\the\c@refsection}{#1}}}}

\newrobustcmd*{\cbx@ifnameseen@global}[1]{%
  \xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}}

\newrobustcmd*{\cbx@ifnameseen@context}[1]{%
  \iftoggle{blx@footnote}%
    {\xifinlistcs{#1}{cbx@fseen@names@\the\c@refsection}}%
    {\xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}}}

\DeclareBibliographyOption[string]{nametracker}[true]{%
  \ifcsdef{blx@opt@nametracker@#1}
    {\csuse{blx@opt@nametracker@#1}}
    {\blx@err@invopt{nametracker=#1}{}}}

\def\blx@opt@nametracker@global{%
  \let\cbx@ifnameseen\cbx@ifnameseen@global
  \let\cbx@nametracker\cbx@nametracker@global}

\let\blx@opt@nametracker@true\blx@opt@nametracker@global

\def\blx@opt@nametracker@false{%
  \protected\long\def\cbx@ifnameseen##1##2##3{##3}%
  \let\cbx@nametracker\relax}

\def\blx@opt@nametracker@context{%
  \let\cbx@ifnameseen\cbx@ifnameseen@context
  \let\cbx@nametracker\cbx@nametracker@context}

\appto\blx@secinit{%
  \ifcsundef{cbx@bseen@names@\the\c@refsection}
    {\global\cslet{cbx@bseen@names@\the\c@refsection}\@empty}
    {}%
  \ifcsundef{cbx@fseen@names@\the\c@refsection}
    {\global\cslet{cbx@fseen@names@\the\c@refsection}\@empty}
    {}}

\InitializeCitationStyle{%
  \global\cslet{cbx@bseen@names@\the\c@refsection}\@empty
  \global\cslet{cbx@fseen@names@\the\c@refsection}\@empty}

\ExecuteBibliographyOptions{nametracker=context}

\DeclareNameFormat{labelname}{%
  \cbx@ifnameseen{\thefield{hash}}
    {\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}
    {\usebibmacro{name:given-family}
       {\namepartfamily}
       {\namepartgiven}
       {\namepartprefix}
       {\namepartsuffix}%
     \cbx@nametracker{\thefield{hash}}}%
    \usebibmacro{name:andothers}}

\DeclareCiteCommand{\specialciteauthor}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}}
  {\renewbibmacro*{name:andothers}{}%
   \printnames[labelname][\thefield{postnote}-\thefield{postnote}]{author}}
  {}
  {}

\DeclareIndexNameFormat{createauthorcommands}{%
  \ifcsundef{nbx@\thefield{hash}}
    {\global\cslet{nbx@\thefield{hash}}\@empty
     \typeout{\the\value{uniquename}}%
     \ifcase\value{uniquename}
       \def\nbx@macroname{\namepartfamily}%
      \or
       \def\nbx@macroname{\namepartfamily\namepartgiveni}%
     \or
       \def\nbx@macroname{\namepartfamily\namepartgiven}%
     \fi
     \csxdef{nbx@\nbx@macroname}{%
       \noexpand\specialciteauthor[\the\value{listcount}]
       {\thefield{entrykey}}}%
     \typeout{created author command '\nbx@macroname'
       to point to author \the\value{listcount} of
       \thefield{entrykey}.}}
    {}}%

\AtDataInput{\indexnames[createauthorcommands][1-999]{author}}

\newcommand*{\mmname}[1]{%
  \ifcsundef{nbx@#1}
    {\textbf{#1}%
     \@latex@warning{Name #1 not found.\MessageBreak
       Either you need to re-run Biber and then LaTeX,\MessageBreak
       or the name is misspelled.}}
    {\csuse{nbx@#1}}}
\makeatother


\begin{document}
\mmname{Kant} and \mmname{Appleby} and \mmname{Hacker}

\citeauthor{sz} has shown that\ldots, but \citeauthor{kpv} presumes that\ldots.

However, \citeauthor{krv} lived in the 18. century, \citeauthor{sg} in the 20.

\nocite{*}

\printbibliography
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .