2
  • Ten years ago, Heiko provided the following solution for storing biblatex outputs (\citefield) for later use in headings (hyperref bookmarks).
\makeatletter
\newcommand*{\StoreCiteField}[3]{%
  \begingroup
    \global\let\StoreCiteField@Result\relax
    \citefield{#2}[StoreCiteField]{#3}%
  \endgroup
  \let#1\StoreCiteField@Result
}
\DeclareFieldFormat{StoreCiteField}{%
  \gdef\StoreCiteField@Result{#1}%
}
\makeatother
  • I tried to adapt the code so that it works with \citeauthor and failed.
  • Any ideas?

This is my (failing) attempt to use the same approach for \citeauthior:

\newcommand*{\StoreAuthor}[2]{%
  \begingroup
    \global\let\StoreAuthor@Result\relax
    \citeauthor{#2}%
  \endgroup
  \let#1\StoreAuthor@Result
}
\DeclareFieldFormat{StoreAuthor}{%
  \gdef\StoreAuthor@Result{#1}%
}

I punch way above my weight class here and just tried to find analogies in Heiko's code and adapted it accordingly. I do not understand the code. Yesterday, the previous regular user cfr commented on a related question (How can I make \citetitle work in a hyperref section bookmark?) because he/she has the same problem. This motivated me to try again.


\documentclass{article}

\usepackage{xcolor} \usepackage{biblatex}

\begin{filecontents}{\jobname.bib} @book{key, title = {Book Title}, year = {2000}, author = {Givenname FamilyName}, } \end{filecontents} \addbibresource{\jobname.bib}

\usepackage{hyperref} \usepackage{bookmark}

% https://tex.stackexchange.com/questions/73678 \makeatletter \newcommand{\StoreCiteField}[3]{% \begingroup \global\let\StoreCiteField@Result\relax \citefield{#2}[StoreCiteField]{#3}% \endgroup \let#1\StoreCiteField@Result } \DeclareFieldFormat{StoreCiteField}{% \gdef\StoreCiteField@Result{#1}% } % \newcommand{\StoreAuthor}[2]{% \begingroup \global\let\StoreAuthor@Result\relax \citeauthor{#2}% \endgroup \let#1\StoreAuthor@Result } \DeclareFieldFormat{StoreAuthor}{% \gdef\StoreAuthor@Result{#1}% } \makeatother

\begin{document}

%% StoreCiteField (Working) % Store Results \StoreCiteField\myTitle{key}{title} % Use Results In Headings \section{Title (Working): \textcolor{red}{\myTitle}} \myTitle

\noindent\rule{\textwidth}{1pt}

% Store Results \StoreCiteField\myYear{key}{year} % Use Results In Headings \section{Year (Working): \textcolor{red}{\myYear}} \myTitle

\noindent\rule{\textwidth}{1pt}

%% StoreAuthor (Nor Working) % Store Results \StoreAuthor\myAuthor{key} % Use Results In Headings \section{Author (Not Working): \textcolor{red}{\myAuthor}} \myAuthor

\end{document}

enter image description here

  • For biblatex, "author" ("editor" and some others) is a "name" rather than a simple "field". Take a look at \citename instead of \citefield. – gusbrs Mar 22 '22 at 01:38
  • @gusbrs Thanks for the comment. Maybe I did not made myself clear: I am using already \citeauthor{#2} in the code for that reason. – Dr. Manuel Kuehner Mar 22 '22 at 04:09
  • 1
    You are starting from the wrong point. The citation commands from biblatex target the printed output. They are one many levels not expandable and it is very hard to unwind them to get something usable in the bookmarks. Start instead from the data, look in the bbl and consider how you would define a \bookmarkciteauthor command if you had easy access to the data stored there. – Ulrike Fischer Mar 22 '22 at 08:13
  • @Dr.ManuelKuehner Well, and why do you think \citeauthor uses the \DeclareFieldFormat{StoreAuthor}? But ultimately the problem really is the one mentioned by Ulrike. I've tried with \citename and \DeclareNameWrapperFormat, but it does not expand... – gusbrs Mar 22 '22 at 09:08
  • @gusbrs Thanks again for your reply. I hope you did not think my reply was not friendly (the opposite is true/intended)! I typed on my phone and just replied quickly :). Thanks for testing. As mentioned in the question, I am not skilled enough for the task. – Dr. Manuel Kuehner Mar 22 '22 at 16:21
  • @UlrikeFischer Thanks for the reply! I hope that someone with better skills than me can try to follow your advice. – Dr. Manuel Kuehner Mar 22 '22 at 16:22
  • 1
    @Dr.ManuelKuehner Not at all! Be at ease! ;-) I just added what I knew. – gusbrs Mar 22 '22 at 16:23
  • 2
    Not sure about the 'previous power user' bit ... or the 'he' .... – cfr Mar 24 '22 at 02:31
  • @cfr Sorry for that :). I have modified the wording accordingly. Let me know if you are still unhappy. – Dr. Manuel Kuehner Mar 24 '22 at 04:12
  • 1
    I just found https://tex.stackexchange.com/q/60552/35864, which very roughly uses the same idea that I used below – moewe Mar 24 '22 at 16:06
  • @moewe Thanks for the follow-up! – Dr. Manuel Kuehner Mar 24 '22 at 17:19

1 Answers1

5

The problem here is that a name list is much more complex than a simple field.

Simple fields are relatively straightforward to handle because in the end, the field contents are stored in a macro which is used pretty directly by biblatex for printing. We "just" need get hold of this macro's expansion. (This can be done in the clever StoreCiteField way shown here or with more naive methods.) Specifically, we'll have something like

  \field{year}{1998}

in the .bbl and want to grab the complete 1998 for what we are trying to do here.

Name lists, however, are much more complex beasts. They are stored in an "abstract" way in the .bbl file

  \name{author}{2}{}{%
    {{hash=484061f383fb3b729627e12ab42c1963}{%
       family={Sigfridsson},
       familyi={S\bibinitperiod},
       given={Emma},
       giveni={E\bibinitperiod}}}%
    {{hash=b7e299b632e5db12681c2decc8ce023f}{%
       family={Ryde},
       familyi={R\bibinitperiod},
       given={Ulf},
       giveni={U\bibinitperiod}}}%
  }

You can't just grab "all" of these contents to get nice output. We need to post-process them heavily so that something useful comes out. This post-processing is usually done by biblatex. But it is done in a manner that is fundamentally unexpandable, which means it's no good to us here.

We essentially have to replicate the whole name formatting code in an expandable manner. For the family name this is done in the StoreName name format below. We add the family name part of the current name to \StoreName@Result in \protected@xappto\StoreName@Result{\namepartfamily}. The remainder of the code takes care of commas, "and", "et al." in an expandable manner (so everything is hard-coded).

\documentclass{article}

\usepackage{xcolor} \usepackage{biblatex} \addbibresource{biblatex-examples.bib}

\usepackage{hyperref} \usepackage{bookmark}

% https://tex.stackexchange.com/questions/73678 \makeatletter \newcommand{\StoreCiteField}[3]{% \begingroup \global\let\StoreCiteField@Result\relax \citefield{#2}[StoreCiteField]{#3}% \endgroup \let#1\StoreCiteField@Result } \DeclareFieldFormat{StoreCiteField}{% \gdef\StoreCiteField@Result{#1}% } % \newcommand{\StoreName}[3]{% \begingroup \global\let\StoreName@Result\relax \blx@indexnamesetup \citename{#2}[StoreName]{#3}% \endgroup \let#1\StoreName@Result } \DeclareNameFormat{StoreName}{% \ifnumgreater{\value{listcount}}{\value{liststart}} {\ifboolexpr{ test {\ifnumless{\value{listcount}}{\value{liststop}}} or test \ifmorenames } {\gappto\StoreName@Result{, }} {\gappto\StoreName@Result{ and }}} {}% \protected@xappto\StoreName@Result{\namepartfamily}% \ifboolexpr{ test {\ifnumequal{\value{listcount}}{\value{liststop}}} and test \ifmorenames } {\gappto\StoreName@Result{et~al.}} {}% } \newcommand*\StoreAuthor[2]{\StoreName{#1}{#2}{author}} \makeatother

\begin{document} \StoreCiteField\myTitle{sigfridsson}{title} \section{Title: \textcolor{red}{\myTitle}} \myTitle

\noindent\rule{\textwidth}{1pt}

\StoreCiteField\myYear{sigfridsson}{year} \section{Year: \textcolor{red}{\myYear}} \myYear

\noindent\rule{\textwidth}{1pt}

\StoreAuthor\myAuthor{sigfridsson} \section{Author: \textcolor{red}{\myAuthor}} \myAuthor

\end{document}

3 Author: Sigfridsson and Ryde
Sigfridsson and Ryde

moewe
  • 175,683