0

Consider the following biblatex database:

@misc{calvin,
    author     = {Calvin, Susan},
    title      = {Practical Aspects of Robotics},
    translator = {Olivaw, R. Daneel and Reventlov, R. Giskard},
}
@book{martin,
  author     = {Martin, Andrew},
  title      = {History of Robots},
  translator = {Olivaw, R. Daneel},
}
@book{olivaw,
  author     = {Olivaw, R. Daneel},
  title      = {How to Manipulate Humans and Not Die in the Attempt},
}
@book{olivaw-reventlov,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard},
  title      = {The Three Laws of Robotics},
}
@collection{seldon-olivaw,
  editor     = {Seldon, Hari and Olivaw, R. Daneel},
  title      = {Foundations of Psychohistory},
}

I would like to systematically exclude an specific author from appearing in author-like fields (editor, translator, etc.) when calling \pintbibliography.

I want to have two options for doing this:

First option

The target author is removed from the bibliography with the two-place command \remove: its first argument specifies the name of the author to be excluded, and the second, a comma separated list with the (author-like) fields from which the author will be excluded.

There's a catch, though. All entries with a field where the excluded author has collaborated are printed specifying such collaboration. A MWE would be:

\documentclass{article}
\usepackage{biblatex}

\addbibresource{references.bib}
\remove{Olivaw, R. Daneel}{author, editor, translator}

\begin{document}

\nocite{*}
\printbibliography

\end{document}

This would print:

References

[1] Susan Calvin. Practical Aspects of Robotics. Trans. with R. Giskard Reventlov.

[2] Andrew Martin. History of Robots.

[3] How to Manipulate Humans and Not Die in the Attempt.

[4] With R. Giskard Reventlov. The Three Laws of Robotics.

[5] Ed. with Hari Seldon. Foundations of Psychohistory.

(The bold is not meant to be printed by LaTeX. I'm just using for emphasis.)

Note that the normal output would be:

References

[1] Susan Calvin. Practical Aspects of Robotics. Trans. by R. Daneel Olivaw and R. Giskard Reventlov.

[2] Andrew Martin. History of Robots. Trans. by R. Daneel Olivaw.

[3] R. Daneel Olivaw. How to Manipulate Humans and Not Die in the Attempt.

[4] R. Daneel Olivaw and R. Giskard Reventlov. The Three Laws of Robotics.

[5] Hari Seldon and R. Daneel Olivaw, eds. Foundations of Psychohistory.

Had I passed \remove{Olivaw, R. Daneel}{author} instead of \remove{Olivaw, R. Daneel}{author, editor, translator}, the output would have had to be:

References

[1] Susan Calvin. Practical Aspects of Robotics. Trans. by R. Daneel Olivaw and R. Giskard Reventlov.

[2] Andrew Martin. History of Robots. Trans. by R. Daneel Olivaw.

[3] How to Manipulate Humans and Not Die in the Attempt.

[4] With R. Giskard Reventlov. The Three Laws of Robotics.

[5] Hari Seldon and R. Daneel Olivaw, eds. Foundations of Psychohistory.

Second option

In this case, I want a complete anonymisation of the bibliography, specifying the number of authors/editors/etc. with placeholders. This would be done by the two-place command \remove*: a mandatory argument specifies the (author-like) fields to be anonymised, and an optional one specifies an author to be marked as the applicant.

For example, calling \remove*{author, editor, translator} instead of \remove{Olivaw, R. Daneel}{author, editor, translator} in our MWE, would print:

References

[1] [one author]. Practical Aspects of Robotics. Trans. by [two translators].

[2] [one author]. History of Robots. Trans. by [one translator].

[3] [one author]. How to Manipulate Humans and Not Die in the Attempt.

[4] [two authors]. The Three Laws of Robotics.

[5] [two editors]. Foundations of Psychohistory.

Instead, if we specify an author in the optional argument, as in \remove*[Olivaw, R. Daneel]{author, editor, translator}, the output would have had to be:

References

[1] [one author]. Practical Aspects of Robotics. Trans. by [applicant and one collaborator].

[2] [one author]. History of Robots. Trans. by [applicant].

[3] [applicant]. How to Manipulate Humans and Not Die in the Attempt.

[4] [applicant and one collaborator]. The Three Laws of Robotics.

[5] [applicant and one collaborator], eds. Foundations of Psychohistory.

How to help?

It's quite possible that no single person will provide me with a full answer (which is ok). Some partial answers would be helpful towards constructing a whole solution for this. I'm specially interested in feedback concerning the following points:

  • What method could help me count the number of authors in an author-like field?
  • What method can I use for identifying whether the name of an author is in a certain field or not.
  • How do I print the name of the nth author of a field (like editor) from a specific entry?
  • How do I flexibly print the value of editortype field from a specific entry?

If such feedback is provided, I myself may be able to provide a full answer.

1 Answer 1

2

You may want to have a look at biblatex-publist, which implements something similar to your first option.

There are some differences, though, but that is nothing that couldn't be overcome. For example biblatex-publist always assumes you are a co-author (see martin) and apparently it still prints your name if you are the sole author (see olivaw).

\documentclass{article}
\usepackage[style=publist]{biblatex}

\plauthorname[R. Daneel]{Olivaw}

\begin{filecontents}{\jobname.bib}
@misc{calvin,
  author     = {Calvin, Susan},
  title      = {Practical Aspects of Robotics},
  translator = {Olivaw, R. Daneel and Reventlov, R. Giskard},
}
@book{martin,
  author     = {Martin, Andrew},
  title      = {History of Robots},
  translator = {Olivaw, R. Daneel},
}
@book{olivaw,
  author     = {Olivaw, R. Daneel},
  title      = {How to Manipulate Humans and Not Die in the Attempt},
}
@book{olivaw-reventlov,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard},
  title      = {The Three Laws of Robotics},
}
@collection{seldon-olivaw,
  editor     = {Seldon, Hari and Olivaw, R. Daneel},
  title      = {Foundations of Psychohistory},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

Let's get a bit more theoretic.

The first thing you need for this is a way to robustly detect your name in a list of names. biblatex-publist uses string equality tests to check the name given in \plauthorname against the name currently processed.

If I were to implement something like this I would instead use Biber's built-in name hashes to compare names. The advantage is that we avoid string manipulation and testing, which can get a bit tricky in LaTeX especially if the string contains non-ASCII chars - with the hashes we only need to compare one string containing 0-9A-f. I have written about using hashes in my answer to Highlight an author in bibliography using biblatex allowing bibliography style to format it. The updated first part of that answer contains code to automatically calculate name hashes from within the .tex document (so you don't have to look up the hash yourself).

Then you need a way to check if your name is in the name list and count the number of names in the list without your name. This can be done with a cute little trick I learned from Audrey in biblatex: filter out publications from a specific author in the references dynamically. This is also how biblatex-publist counts the names (https://github.com/jspitz/biblatex-publist/blob/57595995240ad5163ad3fd128b4e5155b311fa3d/publist.bbx#L437-L466).

Those two seem like the most important issues, but then you also need to get the small things out of the way. For example you need to make sure that the list delimiters (commas and "and") work out correctly.

The following should be a fairly comprehensive implementation of the "first option".

\documentclass{article}
\usepackage[style=numeric]{biblatex}

\makeatletter
% name hash extraction
\def\nhblx@bibfile@name{\jobname -removenames.bib}
\newwrite\nhblx@bibfile
\immediate\openout\nhblx@bibfile=\nhblx@bibfile@name
\newcounter{nhblx@name}
\setcounter{nhblx@name}{0}
\newcommand*{\nhblx@writenametobib}[1]{%
  \stepcounter{nhblx@name}%
  \edef\nhblx@tmp@nocite{%
    \noexpand\AfterPreamble{%
      \noexpand\setbox0\noexpand\vbox{%
        \noexpand\nhblx@getmethehash{nhblx@name@\the\value{nhblx@name}}}}%
  }%
  \nhblx@tmp@nocite
  \immediate\write\nhblx@bibfile{%
    @misc{nhblx@name@\the\value{nhblx@name}, author = {\unexpanded{#1}}, %
          options = {dataonly=true},}%
  }%
}

\AtEndDocument{%
  \closeout\nhblx@bibfile}

\addbibresource{\nhblx@bibfile@name}

\newcommand*{\nhblx@hashlist}{}
\DeclareNameWrapperFormat{nhblx@hashextract}{#1}
\DeclareNameFormat{nhblx@hashextract}{%
  \xifinlist{\thefield{hash}}{\nhblx@hashlist}
    {}
    {\listxadd{\nhblx@hashlist}{\thefield{fullhash}}}}

\DeclareCiteCommand{\nhblx@getmethehash}
  {}
  {\printnames[nhblx@hashextract][1-999]{author}}
  {}
  {}

\newcommand*{\addtonamelist}{\nhblx@writenametobib}
\newcommand*{\resetnamelist}{\let\nhblx@hashlist\@empty}

\newcommand*{\ifremovename}{%
  \ifdefvoid\nhblx@hashlist
    {\@secondoftwo}
    {\xifinlist{\thefield{hash}}{\nhblx@hashlist}}}

\newcommand*{\ifremovenamepresent}{%
  \ifnumgreater{\value{removed}}{0}}

\newcounter{removed}
\newcounter{unremoved}
\DeclareIndexNameFormat{count:removed}{%
  \ifremovename
    {\stepcounter{removed}}
    {}}

\newbibmacro*{count:removed}[1]{%
  \setcounter{removed}{0}%
  \indexnames[count:removed]{#1}%
  \global\defcounter{unremoved}{\value{#1}-\value{removed}}}
\makeatother

\NewBibliographyString{with,edited,translated}
\DefineBibliographyStrings{english}{
  with       = {with},
  edited     = {ed\adddot},
  translated = {trans\adddot},
}


\DeclareNameWrapperFormat{family-given:remove}{%
  \defcounter{listtotal}{\value{listtotal}-\value{removed}}%
  \defcounter{liststop}{\value{liststop}-\value{removed}}%
  #1%
}

\DeclareNameFormat{family-given:remove}{%
  \ifremovename
    {\addtocounter{listcount}{-1}}
    {\ifgiveninits
       {\usebibmacro{name:given-family}
         {\namepartfamily}
         {\namepartgiveni}
         {\namepartprefix}
         {\namepartsuffix}}
       {\usebibmacro{name:given-family}
         {\namepartfamily}
         {\namepartgiven}
         {\namepartprefix}
         {\namepartsuffix}}}%
  \usebibmacro{name:andothers}}


\renewbibmacro*{author}{%
  \ifboolexpr{
    test \ifuseauthor
    and
    not test {\ifnameundef{author}}
  }
    {\usebibmacro{count:removed}{author}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{author}}
          {\printnames{author}%
           \iffieldundef{authortype}
             {}
             {\setunit{\printdelim{authortypedelim}}%
              \usebibmacro{authorstrg}}}}
       {}}
    {}}

\renewbibmacro*{editor}{%
  \ifboolexpr{
    test \ifuseeditor
    and
    not test {\ifnameundef{editor}}
  }
    {\usebibmacro{count:removed}{editor}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{edited}
           \setunit{\addspace}
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{editor}}
          {\printnames{editor}%
           \setunit{\printdelim{editortypedelim}}%
           \usebibmacro{editorstrg}}%
        \clearname{editor}}
       {}}
    {}}

\renewbibmacro*{editor+others}{%
  \ifboolexpr{
    test \ifuseeditor
    and
    not test {\ifnameundef{editor}}
  }
    {\usebibmacro{count:removed}{editor}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{edited}
           \setunit{\addspace}
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{editor}}
          {\printnames{editor}%
           \setunit{\printdelim{editortypedelim}}%
           \usebibmacro{editor+othersstrg}}%
        \clearname{editor}}
       {}}
    {}}

\renewbibmacro*{translator}{%
  \ifboolexpr{
    test \ifusetranslator
    and
    not test {\ifnameundef{translator}}
  }
    {\usebibmacro{count:removed}{translator}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{translated}
           \setunit{\addspace}
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{translator}}
          {\printnames{editor}%
           \setunit{\printdelim{translatortypedelim}}%
           \usebibmacro{translatorstrg}}}%
        \clearname{translator}}
    {}}

\renewbibmacro*{translator+others}{%
  \ifboolexpr{
    test \ifusetranslator
    and
    not test {\ifnameundef{translator}}
  }
    {\usebibmacro{count:removed}{translator}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{translated}
           \setunit{\addspace}
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{translator}}
          {\printnames{editor}%
           \setunit{\printdelim{translatortypedelim}}%
           \usebibmacro{translator+othersstrg}}}%
        \clearname{translator}}
    {}}

\renewbibmacro*{bytranslator}{%
  \ifnameundef{translator}
    {}
    {\usebibmacro{count:removed}{translator}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{translated}%
           \setunit{\addspace}%
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{translator}}
          {\bibstring{bytranslator}%
           \setunit{\addspace}%
           \printnames[bytranslator]{translator}}}
       {}}}

\renewbibmacro*{bytranslator+others}{%
  \ifnameundef{translator}
    {}
    {\usebibmacro{count:removed}{translator}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{translated}%
           \setunit{\addspace}%
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{translator}}
          {\usebibmacro{bytranslator+othersstrg}%
           \setunit{\addspace}%
           \printnames[bytranslator]{translator}}%
        \clearname{translator}%
        \newunit}
       {}}%
  \usebibmacro{withothers}}

\addtonamelist{Olivaw, R. Daneel}

\begin{filecontents}{\jobname.bib}
@misc{calvin,
  author     = {Calvin, Susan},
  title      = {Practical Aspects of Robotics},
  translator = {Olivaw, R. Daneel and Reventlov, R. Giskard},
}
@book{martin,
  author     = {Martin, Andrew},
  title      = {History of Robots},
  translator = {Olivaw, R. Daneel},
}
@book{olivaw,
  author     = {Olivaw, R. Daneel},
  title      = {How to Manipulate Humans and Not Die in the Attempt},
}
@book{olivaw-reventlov,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard},
  title      = {The Three Laws of Robotics},
}
@collection{seldon-olivaw,
  editor     = {Seldon, Hari and Olivaw, R. Daneel},
  title      = {Foundations of Psychohistory},
}
@book{olivaw-reventlov-another,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard and Anne Other},
  title      = {ORA},
}
@collection{seldon-another-olivaw,
  editor     = {Seldon, Hari and Anne Other and Olivaw, R. Daneel},
  title      = {SAO},
}
@collection{seldon-olivaw-another,
  editor     = {Seldon, Hari and Olivaw, R. Daneel and Anne Other},
  title      = {SOA},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

Susan Calvin. Practical Aspects of Robotics. Trans. with R. Giskard Reventlov.

There is no simple option to enable or disable this for the different name lists (author, editor, translator), but you can simply comment out the relevant bibmacro redefinitions in case you don't want the replacement to happen in some of the name lists.


The first bit of the second option is actually much, much easier. The number of names in the author list is available in the counter author.

A very simple solution would be to just redefine the name wrapper format to just print the number of \currentnames. Then we just need to make sure to suppress the "eds." etc. that would be printed by other macros.

\documentclass{article}
\usepackage[style=numeric]{biblatex}

\DeclareNameWrapperFormat{default}{%
  \mkbibbrackets{%
    \arabic{\currentname}~%
    \ifnumgreater{\value{\currentname}}{1}
      {\ifbibstring{\currentname s}
         {\bibstring{\currentname s}}
         {\currentname s}}
      {\ifbibstring{\currentname}
         {\bibstring{\currentname}}
         {\currentname}}}}

\renewbibmacro*{authorstrg}{}
\renewbibmacro*{editorstrg}{}
\renewbibmacro*{editor+othersstrg}{}
\renewbibmacro*{translatorstrg}{}
\renewbibmacro*{translator+othersstrg}{}

\begin{filecontents}{\jobname.bib}
@misc{calvin,
  author     = {Calvin, Susan},
  title      = {Practical Aspects of Robotics},
  translator = {Olivaw, R. Daneel and Reventlov, R. Giskard},
}
@book{martin,
  author     = {Martin, Andrew},
  title      = {History of Robots},
  translator = {Olivaw, R. Daneel},
}
@book{olivaw,
  author     = {Olivaw, R. Daneel},
  title      = {How to Manipulate Humans and Not Die in the Attempt},
}
@book{olivaw-reventlov,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard},
  title      = {The Three Laws of Robotics},
}
@collection{seldon-olivaw,
  editor     = {Seldon, Hari and Olivaw, R. Daneel},
  title      = {Foundations of Psychohistory},
}
@book{olivaw-reventlov-another,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard and Anne Other},
  title      = {ORA},
}
@collection{seldon-another-olivaw,
  editor     = {Seldon, Hari and Anne Other and Olivaw, R. Daneel},
  title      = {SAO},
}
@collection{seldon-olivaw-another,
  editor     = {Seldon, Hari and Olivaw, R. Daneel and Anne Other},
  title      = {SOA},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

[1 author]. Practical Aspects of Robotics. Trans. by [2 translators].

This answer is quite long already and it should be possible to piece together a solution for the remaining use case from the two suggestions presented here. So for now I'll leave it at that and will suggest that the remainder of the question is an exercise for the reader (I've always wanted to do that). In case there are any difficulties with that I suggest to ask a new question.

You must log in to answer this question.

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