6

It seems like there used to be a working solution but I guess it stopped working with updates to biblatex:

https://tex.stackexchange.com/a/46469/36836

Maybe someone is able to update the solution or suggest a new one?

Daniel
  • 1,787

1 Answers1

9

This answer assumes biblatex version >= 3.4.

We will have to change the code so it complies to the new name format (cf. Biblatex 3.3 name formatting). Furthermore I have changed the code to use name hashes instead of relying on string comparison.

The code implements a new option nametracker. If set to context names will be tracked separately for the text and footnotes, if set to global (or true) names will not be tracked separately. Of course that option can only be executed after it is defined. So in the MWE it can not be set at loading-time, it can only be set with \ExecuteBibliographyOptions.

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

\usepackage[style=authoryear, backend=biber]{biblatex} \addbibresource{biblatex-examples.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}} \makeatother

\begin{document} \cite{companion}

\cite{companion}

\cite{knuth:ct:a}

\cite{knuth:ct:b} \end{document}

gives

Michel Goossens, Frank Mittelbach and Alexander Samarin 1994

Goossens, Mittelbach and Samarin 1994

Donald E. Knuth 1984

Knuth 1986

moewe
  • 175,683
  • Unfortunately, the solution does not play well with style=verbose. It always gives the full name not just the first instance in this case. I am not sure where the problem is. – Daniel Jun 14 '16 at 17:01
  • 1
    @Daniel The uniquename feature needs to be turned on: add the option uniquename=true for verbose where it is not turned on by default (unlike for authoryear). Maybe you also need \renewbibmacro*{cite:full}{% \usebibmacro{cite:full:citepages}% \printtext[bibhypertarget]{% \usedriver {\DeclareNameAlias{sortname}{labelname}} {\thefield{entrytype}}}% \usebibmacro{shorthandintro}} (i.e. use labelname instead of default for sortname in the full citations). – moewe Jun 14 '16 at 17:16
  • Thanks a lot. Adding uniquename=true to the biblatex options did the trick. – Daniel Jun 14 '16 at 17:19
  • 1
    @Daniel You will also need the other modification for a few corner cases, though. (Try \cite{knuth:ct:a} and then \cite{knuth:ct:b} only if you also add the second bit of code will you get to see "Knuth ..." in knuth:ct:b, if you don't use it you will see Donald E. Knuth also for knuth:ct:b, but maybe that is what you want.) – moewe Jun 14 '16 at 17:24
  • Thanks for the note. But it seems actually to be even trickier: since I am using citation in footnotes with the first being cited in full I want the full name in the first footnote. But when the name of the author appears before the footnote then with your fix the full name will not be output. – Daniel Jun 14 '16 at 17:38
  • 1
    @Daniel Of course, the code does not track appearances in footnotes and text separately. But you can have that too. Check the edit. – moewe Jun 14 '16 at 17:47
  • Thanks again. Seems to work smoothly. I guess the "instead" in the edit refers only to the first part of the code, right? – Daniel Jun 14 '16 at 17:56
  • @Daniel Correct. The \DeclareNameFormat{labelname} bit is the same for both. – moewe Jun 14 '16 at 17:57
  • Great feature. How can I make it work only for \citeauthor so the label will not be changed? I am thinking of a full name for the first \citeauthor and for the following \citeauthor only e.g. Initial and last name or optional only last name.

    Right now it changes the label and the author’s name, too.

    – lukascbossert Jun 15 '16 at 08:19
  • @LukasCB If you write \DeclareNameFormat{citeauthor} instead of \DeclareNameFormat{labelname} in my code and copy the definition of \DeclareCiteCommand{\citeauthor} from the other answer you should be good to go. If you have any trouble with that let me know (either on your github or via a new question here.) – moewe Jun 15 '16 at 14:27
  • @moewe I guess there is one other case in addition to footnotes: abstracts. I guess you want the full name in the abstract as well as in the main text when it first appears. Is that doable? – Daniel Jun 16 '16 at 07:03
  • @Daniel You can reset the tracker after the abstract with \makeatletter\renewcommand*{\cbx@fseen@names}{}\renewcommand*{\cbx@tseen@names}{}\makeatother. If that is enough for you. – moewe Jun 16 '16 at 13:42
  • @moewe Thanks, it works! I added it in the preamble using etoolbox's \AfterEndEnvironment{abstract}{...}. – Daniel Jun 17 '16 at 08:55