Here is one approach which gives exactly the result you want. Put this in your biber.conf
:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<sourcemap>
<maps datatype="bibtex" map_overwrite="1">
<map maptype="field">
<map_pair map_source="AUTHOR"/>
<also_set map_field="SHORTAUTHOR" map_origfieldval="1"/>
<also_set map_field="SORTNAME" map_origfieldval="1"/>
</map>
<map maptype="field">
<map_pair map_source="SHORTAUTHOR" map_match="Doe,\s*J(?:\.|ohn)(?:[ -]*)(?:P\.|Paul)*" map_replace="Doe, John Paul"/>
<map_pair map_source="SORTNAME" map_match="Doe,\s*J(?:\.|ohn)(?:[ -]*)(?:P\.|Paul)*" map_replace="Doe, John Paul"/>
</map>
</maps>
</sourcemap>
</config>
This follows the new Biber 0.9.8 semantics for the maps - the maps are processed sequentially, each depending on the results of the previous. Within a map, you can also use multiple items but items within a map which change things should not rely on the results of other other changes within the map element. Use map elements to do the sequencing. So, this first copies AUTHOR to both SHORTAUTHOR and SORTNAME and then, after that, edits these two fields to regularise some specific names. Biber DEV PDF doc will be updated soon.
It's a rather hairy regular expression but they are incredibly useful for faking semantic equivalence. This essentially renders the Does into the canonical "Doe, John Paul" format so that Biber knows that they are the same person. It's probably possible to design a regular expression to make this not so name specific but that will depend in the idiosyncracies of the name formats. For example, you could remove all "-' characters in names and also, since you are using firstinits
, force all names to initials only.
EDIT: There will be a simpler syntax in Biber 0.9.8 like this:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<sourcemap>
<maps datatype="bibtex" map_overwrite="1">
<map>
<map_step map_field_source="AUTHOR" map_match="Doe," map_final="1"/>
<map_step map_field_set="SHORTAUTHOR" map_origfieldval="1"/>
<map_step map_field_set="SORTNAME" map_origfieldval="1"/>
<map_step map_field_source="SHORTAUTHOR" map_match="Doe,\s*J(?:\.|ohn)(?:[ -]*)(?:P\.|Paul)*" map_replace="Doe, John Paul"/>
<map_step map_field_source="SORTNAME" map_match="Doe,\s*J(?:\.|ohn)(?:[ -]*)(?:P\.|Paul)*" map_replace="Doe, John Paul"/>
</map>
</maps>
</sourcemap>
</config>
As biblatex
does not distinguish multiple first names, we need to split this list ourselves:
\makeatletter
\def\@empty{}
\def\first#1{\expandafter\@first#1 \@nil}
\def\@first#1 #2\@nil{#1\addspace%
\if\relax\detokenize{#2}\relax\else\@initials#2\@nil\fi}
\def\initials#1{\expandafter\@initials#1 \@nil}
\def\@initials#1 #2\@nil{%
\initial{#1}%
\def\NextName{#2}%
\ifx\@empty\NextName\relax%
\else\@initials#2\@nil\fi}
\def\initial#1{\expandafter\@initial#1\@nil}
\def\@initial#1#2\@nil{#1.\addspace}
\makeatother
Now calling \first{John Arthur Kyle}
yields "John A. K.".
The trick used is that the macro \first
passes its argument to \@first
which in turn delimits its arguments by spaces, i.e. #1
is "John" and #2
is "Arthur Kyle". This gets sent to \@initials
which goes through the list of names (in case there are more or less than two) and calls \initial
with each name. \initial
in turn calls \@initial
which throws away all but the first letter and adds a dot and a space.
Now we can use this in \DeclareNameFormat
:
\def\bibnamedelima{ }%
\def\bibnamedelimb{ }%
\DeclareNameFormat{author}{%
\ifblank{#5}{}{#5\addspace}% prefix if applicable
#1% last name
\edef\firstname{#3}%
\ifblank{#3}{}{\addcomma\addspace\expandafter\first{\firstname}}%
\ifthenelse{\value{listcount}<\value{liststop}}%
{\addslash}{}%
}
Note that for author = {Doe, John Arthur Kyle}
in the bib
file, #3
actually consists of John\bibnamedelimb Arthur\bibnamedelima Kyle
, so we need to eliminate these for the \first
macro to work.
EDIT: a "proper" NameFormat
should include deliminators for multiple names, thus we check if we are in the middle of a list of names and if so print a slash.
Additionally, the authoryear
style uses labelname
to display the author name in citations, so that format should be changed to keep the formatting of the citation in line with that of the bibliography entry:
\DeclareNameFormat{labelname}{%
\ifblank{#5}{}{#5\addspace}% prefix if applicable
#1% last name
\edef\firstname{#3}%
\ifblank{#3}{}{\addcomma\addspace\expandafter\first{\firstname}}%
\ifthenelse{\value{listcount}<\value{liststop}}%
{\addslash}{}%
}
To summarize: This code
\documentclass{scrartcl}
\usepackage[backend=biber,style=authoryear]{biblatex}
\bibliography{bibliography}
\usepackage[T1]{fontenc}
\def\bibnamedelima{ }%
\def\bibnamedelimb{ }%
\DeclareNameFormat{author}{%
\ifblank{#5}{}{#5\addspace}% prefix if applicable
#1% last name
\edef\firstname{#3}%
\ifblank{#3}{}{\addcomma\addspace\expandafter\first{\firstname}}%
\ifthenelse{\value{listcount}<\value{liststop}}%
{\addslash}{}%
}
\DeclareNameFormat{labelname}{%
\ifblank{#5}{}{#5\addspace}% prefix if applicable
#1% last name
\edef\firstname{#3}%
\ifblank{#3}{}{\addcomma\addspace\expandafter\first{\firstname}}%
\ifthenelse{\value{listcount}<\value{liststop}}%
{\addslash}{}%
}
\makeatletter
\def\@empty{}
\def\first#1{\expandafter\@first#1 \@nil}
\def\@first#1 #2\@nil{#1\addspace%
\if\relax\detokenize{#2}\relax\else\@initials#2\@nil\fi}
\def\initials#1{\expandafter\@initials#1 \@nil}
\def\@initials#1 #2\@nil{%
\initial{#1}%
\def\NextName{#2}%
\ifx\@empty\NextName\relax%
\else\@initials#2\@nil\fi}
\def\initial#1{\expandafter\@initial#1\@nil}
\def\@initial#1#2\@nil{#1.\addspace}
\makeatother
\begin{document}
\cite[123]{Doe}\par
\cite[124]{Doe2}\par
\cite[125]{vD}
\printbibliography
\end{document}
together with this bib
file:
@book{Doe,
title = {The secret life of John Doe},
author = {Doe, John Arthur Kyle and Jane Emma Dane and Someone Else},
year = {2013}
}
@book{Doe2,
title = {The secret life of John Doe 2},
author = {Doe, John},
year = {2013}
}
@book{vD,
title = {The secret life of John von Doe},
author = {John Arthur Kyle von Doe},
year = {2013}
}
produces this output:
EDIT: For more details on splitting strings, see e.g. the answers to this question; for information on macros using "strange" argument delimiters, see e.g. this thread.
Best Answer
EDIT: Since
biblatex
v2.2, one may simply issue\renewcommand*{\revsdnamepunct}{}
in the document preamble.ORIGINAL ANSWER: Redefine the bibmacro
name:last-first
.