[Tex/LaTex] biblatex: filter out publications from a specific author in the references dynamically

biblatexsubdividing

I'm using biblatex, and I would like to leave out those entries from the bibliography, where a specific person is an author (it's a PhD thesis and my own publications should come in a separate bibliography).

  • It can be done with using a special keyword in those bib entries, and later filter out that keyword, but I would prefer not to modify the bib entries.
  • I was able to manage it with creating a category (with \DeclareBibliographyCategory), and then manually adding the item in question to them, but an automatic and dynamic solution would be much better.
  • \defbibcheck seems to be exactly the feature I was looking for, but I'm having problems with the substring checking code.

Author names are a name list, and inside the \defbibcheck it can be accessed with \thename{author}. It returns a raw form string with hashes, author first and last names, initials. Now only a substring check is needed.

However

\defbibcheck{ownpublications}{
  % IfSubStr is from xstring package
  \IfSubStr{\thename{author}}{Author1}{
   \skipentry%
  }
}

prints all the references, even those, where Author1 is among the authors.

The substring search and the skipping works, if I use a constant instead of \thename{author}, thus I thought maybe it is an expansion problem. My Tex/Latex knowledge is very limited when it comes to more than the usual formatting commands, but I tried the following (among other random variants with \fullexpand and \expandafter, etc.):

\defbibcheck{ownpublications}{
  \edef\authorstring{\thename{author}}  
  \IfSubStr{\authorstring}{Author1}{
   \skipentry%
  }
}

but the result is the same, none of the entries are skipped.

I tried other various checks which include custom macros returning strings, or macros using other fields from the actual bib entry (like year), so maybe the problem is not with expansion but with \thename.

UPDATE: a full minimal example

\documentclass{article}

\usepackage{xstring}
\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@book{texbook,
    author = {D.E. Knuth},
    title = {The {\TeX}book},
    publisher = {Addison Wesley},
    year = 1986
}

@Book{latexbook,
  author =       "Leslie Lamport",
  title =        "{\LaTeX} - A Document Preparation System - User's Guide and Reference Manual",
  publisher =    {Addison Wesley},  
  year =         "1985"  
}
\end{filecontents}

\usepackage[backend=biber,style=alphabetic]{biblatex}
\addbibresource{\jobname.bib}

\defbibcheck{ownpublications}{
  \edef\authorstring{\thename{author}}  
  \IfSubStr{\authorstring}{Lamport}{%
   \skipentry
  }{}
}

% document body
\begin{document}

Cite something, this should go in the references \cite{texbook}.

Full citation of other, this should appear only here, and not in the references: \fullcite{latexbook}

\printbibliography[check=ownpublications]

\end{document}

Best Answer

Unless you require partial string matching in names, xstring isn't necessary. With backend=biber you can identify matching entries based on the source data (e.g. the bib file) using the source map feature. It supports regular expressions. An example from PLK can be found here.

With any BibTeX implementation as the backend, matching can be done on data in the bbl file via \ifdefstring (from etoolbox) and \indexnames. The latter is a biblatex command that applies an index formatting directive to each item in a name list. Here is an example.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[american]{babel}
\usepackage{csquotes}
\usepackage[backend=bibtex,style=alphabetic,refsection=section]{biblatex}
\bibliography{biblatex-examples}

% Variants of each could be added
\newcommand{\firstinit}{D.~E.}
\newcommand{\firstname}{Donald~E.}
\newcommand{\lastname}{Knuth}

\DeclareBibliographyCategory{byname}

\DeclareIndexNameFormat{byname}{% Test could be refined
  \ifboolexpr{ test {\ifdefstring{\lastname}{#1}}
               and ( test {\ifdefstring{\firstname}{#3}}
                     or test {\ifdefstring{\firstinit}{#4}} ) }
    {\addtocategory{byname}{\thefield{entrykey}}}
    {}}

\AtDataInput{%
  \indexnames[byname]{author}}

\begin{document}
\section{Knuth's books}
\nocite{*}
\printbibliography[type=book,category=byname,heading=none]
\section{Not Knuth's books}
\nocite{*}
\printbibliography[type=book,notcategory=byname,heading=none]
\end{document}

enter image description here

The argument references (#1, #3, etc.) in \DeclareIndexNameFormat correspond to different parts of a name. Further details can be found in the biblatex manual or this post by domwass. The data corresponding to each name element can be found in the bbl file. In the above example, the field author = {Knuth, Donald E.} is parsed as follows.

  \name{author}{1}{}{%
    {{}%
     {Knuth}{K.}%
     {Donald~E.}{D.~E.}%
     {}{}%
     {}{}}%
  }
Related Question