TransWikia.com

Isolate a specific author from a bibliography entry with multiple authors

TeX - LaTeX Asked on April 26, 2021

Suppose I have the following entry in my references.bib file

@incollection{sampleref,
  author      = "Author 1 and Author 2",
  title       = "Sample Title",
  booktitle   = "A sample book title",
  publisher   = "Custom Monographs",
  year        = 2020,
  pages       = "1-10",
  chapter     = 1,
}

In addition, I have the following minimal code.

documentclass[11pt,letterpaper,openany,oneside]{book}
usepackage[square,sort,comma,numbers]{natbib}

begin{document}

It was citeauthor{sampleref} % would like to isolate author 2
in cite{sampleref} who came up with Theorem X.

nocite{*}
bibliographystyle{plainnat} % to use natbib
bibliography{references}

end{document}

I’m using natbib and I would like to specifically refer to Author 2.
If I use citeauthor{sampleref}, I get Author 1 and Author 2 appear in the body.

Is it possible to use citeauthor or some other technique to isolate for one specific author in a .bib entry that has multiple authors?

One Answer

natbib does not really have the list of authors of your citation available in machine-readable form in citations. So a command that lets you typeset a particular author of your citation is a bit tricky to implement.

So I suggest you just type the name manually. If you want to be able to link it, the following should help you

documentclass{article}
usepackage{natbib}
usepackage{hyperref}

makeatletter
newcommand*{linktocite}[2]{%
  hyper@natlinkstart{#1}#2hyper@natlinkend}
makeatother

begin{filecontents}{jobname.bib}
@book{appleby,
  author    = {Humphrey Appleby and James Hacker and Annie Hacker and Bernard Wolley},
  title     = {On the Importance of the Civil Service},
  year      = {1980},
  publisher = {Pub & Co.},
}
end{filecontents}

begin{document}
cite{appleby}

linktocite{appleby}{Annie Hacker}

bibliographystyle{plainnat}
bibliography{jobname}
end{document}

Annie Hacker. linked


Just for fun here is a biblatex implementation of a citespecificauthor command that lets you pick the specific author you want to cite. The implementation is a bit longer than I initially thought, but that is mainly to make the input a little more intuitive. We are abusing the postnote argument to pass the author number and so we need a few tricks to get things right.

documentclass[british]{article}
usepackage[T1]{fontenc}
usepackage[utf8]{inputenc}
usepackage{babel}
usepackage{csquotes}

usepackage[style=authoryear, maxbibnames=999, backend=biber]{biblatex}
usepackage{hyperref}

DeclareNameFormat{labelname:noetal}{%
  ifcasevalue{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}

makeatletter
protecteddefnmu@ifinstr#1#2{%
  defnmu@ifinstr@i##1#2##2nmu@end{%
    notblank{##2}}%
  nmu@ifinstr@i#1#2nmu@end}

newcommand*{printspecificlabelname@n}[1]{%
  nmu@ifinstr{#1}{-}
    {printnames[labelname:noetal][#1]{labelname}}
    {printnames[labelname:noetal][#1-#1]{labelname}}}

newcommand*{printspecificlabelname@x}[1]{%
  begingroup
  edefx{endgroupprintspecificlabelname@n{#1}}%
  x}

DeclareCiteCommand{citespecificauthor}
  {boolfalse{citetracker}%
   boolfalse{pagetracker}}
  {printtext[bibhyperref]{%
     iffieldundef{postnote}
       {printnames{labelname}}
       {printspecificlabelname@x{thefield{postnote}}}}}
  {multicitedelim}
  {}
makeatother

begin{filecontents}{jobname.bib}
@book{appleby,
  author    = {Humphrey Appleby and James Hacker and Annie Hacker and Bernard Wolley},
  title     = {On the Importance of the Civil Service},
  year      = {1980},
  publisher = {Pub & Co.},
}
end{filecontents}
addbibresource{jobname.bib}
addbibresource{biblatex-examples.bib}


begin{document}
cite{sigfridsson,appleby}

citespecificauthor[3]{appleby}

citespecificauthor[1-2]{appleby}

citespecificauthor{appleby}

printbibliography
end{document}

If you tweak your .bst style to produce a machine-readable list of names for each entry, you can implement something similar with natbib.

The key is to use plainnat-namelist.bst from https://gist.github.com/moewew/80f83c4c93a9f0cdf4fada246b454fe2 instead of plainnat.bst. The diff to plainnat.bst is

--- plainnat.bst    2010-09-14 11:10:56.000000000 +0200
+++ plainnat-namelist.bst   2020-08-01 14:26:49.739944200 +0200
@@ -1,3 +1,11 @@
+%%%% plainnat-namelist.bst
+%%%% A version of plainnat that extracts the author names in
+%%%% machine-readable format for further use on the LaTeX side.
+%%%% The new macro is make.list.names and friends.
+%%%% 2020-08-01 MW
+%%%% for https://tex.stackexchange.com/q/556932/35864
+%%%%
+%%%% original copyrght header follows
 %% File: `plainnat.bst'
 %% A modification of `plain.bst' for use with natbib package 
 %%
@@ -373,6 +381,65 @@
   if$
 }
 
+FUNCTION {format.list.names}
+{'s :=
+  #1 'nameptr :=
+  s num.names$ 'numnames :=
+  numnames 'namesleft :=
+    { namesleft #0 > }
+    { "namelistitem{"
+      cite$ *
+      "}{" *
+      nameptr int.to.str$ *
+      "}{" *
+      s nameptr "{vv~}{ll}" format.name$ *
+      "}" *
+      write$
+      newline$
+      nameptr #1 + 'nameptr :=
+      namesleft #1 - 'namesleft :=
+    }
+  while$
+}
+
+FUNCTION {author.editor.list}
+{ author empty$
+    { editor empty$
+        { "" }
+        { editor format.list.names }
+      if$
+    }
+    { author format.list.names }
+  if$
+}
+
+FUNCTION {author.list}
+{ author empty$
+    { "" }
+    { author format.list.names }
+  if$
+}
+
+FUNCTION {editor.list}
+{ editor empty$
+    { "" }
+    { editor format.list.names }
+  if$
+}
+
+FUNCTION {make.list.names}
+{ type$ "book" =
+  type$ "inbook" =
+  or
+    'author.editor.list
+    { type$ "proceedings" =
+        'editor.list
+        'author.list
+      if$
+    }
+  if$
+}
+
 FUNCTION {output.bibitem}
 { newline$
   "bibitem[" write$
@@ -385,6 +452,8 @@
   cite$ write$
   "}" write$
   newline$
+  make.list.names
+  newline$
   ""
   before.all 'output.state :=
 }
@@ -1420,6 +1489,8 @@
   write$ newline$
   "  providecommand{doi}{doi: begingroup urlstyle{rm}Url}fi"
   write$ newline$
+  "  providecommand{namelistitem}[3]{}"
+  write$ newline$
 }
 
 EXECUTE {begin.bib}

Then it is just a matter of using that data.

documentclass{article}
usepackage{natbib}
usepackage{hyperref}

usepackage{etoolbox}

makeatletter
newcommand*{namelistitem}[3]{%
  immediatewrite@auxout{stringnamelistitemaux{#1}{#2}{#3}}}

newcommand*{namelistitemaux}[3]{%
  csgdef{nmu@namelist@#1@#2}{#3}}

newcommand*{citespecificauthor}[2]{%
  hyper@natlinkstart{#1}%
  ifcsundef{nmu@namelist@#1@#2}
    {textbf{??}}
    {csuse{nmu@namelist@#1@#2}}%
  hyper@natlinkend}
makeatother

begin{filecontents}{jobname.bib}
@book{appleby,
  author    = {Humphrey Appleby and James Hacker and Annie Hacker and Bernard Wolley},
  title     = {On the Importance of the Civil Service},
  year      = {1980},
  publisher = {Pub & Co.},
}
end{filecontents}

begin{document}
cite{appleby}

citespecificauthor{appleby}{2}

bibliographystyle{plainnat-namelist}
bibliography{jobname}
end{document}

Correct answer by moewe on April 26, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP