Consider a document whose author is "van Beethoven, Ludwig". I'd like to cite it as "van Beethoven" in the text and list it as "van Beethoven" in the references. This could be achieved with useprefix=true
. However, I'd like to list the entry not under "v" but under "B" in the references. In Germany, this is often considered to be the proper way to treat names with von and van prefixes. I understand that I can get this behavior by adding a sortkey field to the relevant BibTeX entries, but an automatic solution would of course be preferable.
2 Answers
I'm not a regexp person, really, so I suspect many people could improve on this. But there are two different approaches: a more 'manual' one, which is easier (for me) to fine-tune the final sorting scheme; and a fancier one that may cause havoc if you have many van
and von
entries with names otherwise identical to other people. (The worst case scenario would be to have a Ludwig Beethoven
, Ludwig van Beethoven
, and Ludwig von Beethoven
--- not sure if it would ever get that bad, but there you have it.) So:
Manual fine-tuning:
\documentclass[12pt]{article}
\usepackage[T1]{fontenc}
\usepackage[backend=biber,useprefix=true,style=authortitle]{biblatex}
\addbibresource{\jobname.bib}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
@article{aaa,
author = {Adams, Ludwig},
title = {Title},
journal = {Sort this one under Adams},
date = 1998,
}
@article{ccc,
author = {Curtius, Ludwig},
title = {Title},
journal = {Sort this one under Curtius},
date = 1998,
}
@article{sss,
author = {Smith, Ludwig},
title = {Title},
journal = {Sort this one under Smith},
date = 1998,
}
@article{www,
author = {Williams, Ludwig},
title = {Title},
journal = {Sort this one under Williams},
date = 1998,
}
@article{van,
author = {van Beethoven, Ludwig},
title = {Title},
journal = {Sort this one under Beethoven},
date = 1998,
}
@article{von,
author = {von Beethoven, Ludwig},
title = {Another Title},
journal = {Sort this one under Beethoven},
date = 1999,
}
@article{nosort,
author = {van~Beethoven, Ludwig},
title = {Another Title},
journal = {Don't Sort this One via DeclareSourceMap, thanks to the Tilde},
date = 2001
}
@article{override,
author = {van Beethoven, Ludwig},
title = {Title},
journal = {Sortname is: ZZZ -- Will be Overwritten!},
date = 2000,
sortname = {ZZZ},
}
@article{beethoven,
author = {Beethoven, Ludwig},
title = {Title},
journal = {Sort this one under Beethoven but
before the von/van entries (to pinpoint final sort)},
date = 1998,
}
@article{beZthoven,
author = {Bezthoven, Ludwig},
title = {Title},
journal = {Sort this one under BeZthoven (to pinpoint final sort)},
date = 1998,
}
\end{filecontents*}
\DeclareSourcemap{%
\maps[datatype=bibtex]{
\map[overwrite=true]{
\perdatasource{\jobname.bib}
\step[fieldsource=author, final]
\step[fieldset=sortname, origfieldval]
\step[fieldsource=sortname,
match=\regexp{van\s(Beethoven,)\s(Ludwig)*},
replace={BeethovenY, Ludwig}]
\step[fieldsource=sortname,
match=\regexp{von\s(Beethoven,)\s(Ludwig)*},
replace={BeethovenZ, Ludwig}]
}% The disadvantage is clear: you need to add manual sorting
}% rules for each individual. But the advantage is that it is
}% easier to control the final sorting scheme
\begin{document}
\nocite{*}
\printbibliography
\end{document}
Trying to be clever with REGEXP:
\documentclass[12pt]{article}
\usepackage[T1]{fontenc}
\usepackage[backend=biber,useprefix=true,style=authortitle]{biblatex}
\addbibresource{\jobname.bib}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
% well, just use the same entries as above
\end{filecontents}
\DeclareSourcemap{%
\maps[datatype=bibtex]{
\map[overwrite=true]{
\perdatasource{\jobname.bib}
\step[fieldsource=author, final]
\step[fieldset=sortname, origfieldval]
\step[fieldsource=sortname,
match=\regexp{(v.n)\s(\w+,)\s(\w+)*},
replace={$2}]
}% the problem: 'von' will be sorted before 'van' IFF the title
}% of the 'von' entry is alphabetically prior to the title of
}% the 'van' entry. Worse(?): a regular 'Beethoven, Ludwig' will
% also be sorted among the 'van's and 'von's based solely on their
% titles.
\begin{document}
\nocite{*}
\printbibliography
\end{document}
-
Awesome! Two things though, I believe
replace={$2}
drops parts of the name (the (last) first name), replace it withreplace={$2 $3}
(To see what happens map all the steps above toaddendum
instead ofsortname
). Secondly, is there a way to make sure thesortname
is actually in the format specified via\DeclareNameAlias{sortname}{first-last}
?– moeweOct 3, 2013 at 18:55 -
@moewe -- Oh, good catch! The
{$2}
was from an experiment and I didn't correct back to{$2 $3}
. And I really like theaddendum
trick -- that would've saved me some time, had I thought of it myself. But I'm not sure what your question is asking. If I add\step[fieldset=addendum, origfieldval] \step[fieldsource=addendum,match=\regexp{(v.n)\s(\w+,)\s(\w+)*}, replace={$3 $2}]
after the last\step
given above, I get 'Ludwig Beethoven' in the addendum fields for 'van/von' entries (and not in the other enties). But you obviously are hoping for something else (and probably trickier).– jonOct 4, 2013 at 16:46 -
Never mind the second part of my comment above, it is certainly not clear what I was asking; I got slightly tangled up in the whole name formatting (I expected the output I had diverted to the
addendum
field to be parsed by the name parser, which it obviously is not).– moeweOct 4, 2013 at 19:42
This is an attempt to expand on jon's great answer to allow for slightly more flexibility.
The standard sorting schemes defined in biblatex.def
all contain (at some point) the lines
\sort{
\field{sortname}
\field{author}
\field{editor}
\field{translator}
\field{sorttitle}
\field{title}
}
So there seems to be some hierarchy as to what name field is called upon when it comes to sorting. The order seems to be sortname
>
author
>
editor
>
translator
.
If we want to fully automate stripping von
/van
from sorting we will have to deal with all those fields.
To deal with these subtleties it seems to be not too bad an idea to define a new name field which we can use for internal sorting. (There might be more efficient ways to do this, but this one seems quite natural and is somewhat comprehensible - and it was the only one I could think of).
We define the new name list tempsortname
.
This can be done very easily via the following two lines (put them into biblatex-dm.cfg
or any other file that can cope with data model commands).
\DeclareDatamodelFields[type=list, datatype=name]{tempsortname}
\DeclareDatamodelEntryfields{tempsortname}
We will now successively copy the name fields in the hierarchy above from low to high (translator
<
editor
<
author
) to our tempsortname
field.
If any field is empty, it will not be copied over. After this mapping step, tempsortname
will hold the "highest" non-empty field in the hierarchy - this is, not entirely coincidentally, the exact same field biber will use to sort the entry.
Then, we strip von
/van
from tempsortname
via regex. (The pattern matches the string van
or von
, iff it appears at the start of the field [as in van Beethoven, Ludwig
] or is preceded by at least one whitespace [as in Johann Wolfgang von Goethe
] and is succeeded by at least one whitespace.) The original fields will not be changed, but tempsortname
will lose the prefix.
Finally tempsortname
is copied over to sortname
, if sortname
is not already specified. So in this set-up sortname
always trumps our tempsortname
field; considering tempsortname
is actually author
, editor
or translator
(minus the prefix) this is exactly what the standard sorting would do.
\DeclareSourcemap{%
\maps[datatype=bibtex]{
\map[overwrite=true]{
\step[fieldsource=translator]
\step[fieldset=tempsortname, origfieldval]
\step[fieldsource=editor]
\step[fieldset=tempsortname, origfieldval]
\step[fieldsource=author]
\step[fieldset=tempsortname, origfieldval]
}
\map[overwrite=true]{
\step[fieldsource=tempsortname, match=\regexp{(^|\s+)\Kv[a|o]n\s+}, replace={$1}]
}
\map[overwrite=false]{
\step[fieldsource=tempsortname]
\step[fieldset=sortname, origfieldval]
}
}
}
It should be noted that in this solution Ludwig Beethoven
, Ludwig van Beethoven
and Ludwig von Beethoven
will be sorted as though they are the same person, the prefix will completely be ignored.
This might lead to (very likely undesirable) situations like this
Van Beethoven, Ludwig. Title A. 2000.
Beethoven, Ludwig. Title B. 2000.
Van Beethoven, Ludwig. Title C. 2000.
An MWE
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[backend=biber,useprefix=true,style=authortitle]{biblatex}
\addbibresource{\jobname.bib}
\usepackage{filecontents}
\begin{filecontents*}{biblatex-dm.cfg}
\DeclareDatamodelFields[type=list,datatype=name]{tempsortname}
\DeclareDatamodelEntryfields{tempsortname}
\end{filecontents*}
\begin{filecontents*}{\jobname.bib}
@InCollection{brandt,
author = {von Brandt, Ahasver and Erich Hoffmann},
editor = {Ferdinand Seibt},
title = {Die nordischen L{\"a}nder von der Mitte des 11.~Jahrhunderts
bis 1448},
date = 1987,
booktitle = {Europa im Hoch- und Sp{\"a}tmittelalter},
series = {Handbuch der europ{\"a}ischen Geschichte},
number = 2,
publisher = {Klett-Cotta},
location = {Stuttgart},
pages = {884-917},
hyphenation = {german},
}
@Book{vangennep,
author = {van Gennep, Arnold},
title = {Les rites de passage},
date = 1909,
publisher = {Nourry},
location = {Paris},
hyphenation = {french},
}
@article{aaa,
author = {Adams, Ludwig},
title = {Title},
journal = {Sort this one under Adams},
date = 1998,
}
@article{ccc,
author = {Curtius, Ludwig},
title = {Title},
journal = {Sort this one under Curtius},
date = 1998,
}
@article{hhhh,
author = {Hoffmann, Bernd},
title = {Title},
journal = {Sort this one under Hoffmann},
date = 1998,
}
@article{sss,
author = {Smith, Ludwig},
title = {Title},
journal = {Sort this one under Smith},
date = 1998,
}
@article{www,
author = {Williams, Ludwig},
title = {Title},
journal = {Sort this one under Williams},
date = 1998,
}
@article{van,
author = {van Beethoven, Ludwig},
title = {Title},
journal = {Sort this one under Beethoven},
date = 1998,
}
@book{vonn,
author = {Johann Wolfgang von Goethe},
editor = {von Beethoven, Ludwig},
subtitle = {Another Title},
title = {Sort this one under Goethe},
date = 1999,
}
@collection{von,
editor = {von Beethoven, Ludwig},
subtitle = {Another Title},
title = {Sort this one under Beethoven},
date = 1999,
}
@article{nosort,
author = {van~Beethoven, Ludwig},
title = {Another Title},
journal = {Don't Sort this One via DeclareSourceMap, thanks to the Tilde},
date = 2001
}
@article{override,
author = {van Beethoven, Ludwig},
title = {Title},
journal = {Sortname is: ZZZ -- Will be Overwritten!},
date = 2000,
sortname = {ZZZ},
}
@book{beeta,
author = {van Beethoven, Ludwig},
title = {Title A},
date = 2000,
}
@book{beetb,
author = {Beethoven, Ludwig},
title = {Title B},
date = 2000,
}
@book{beetc,
author = {van Beethoven, Ludwig},
title = {Title C},
date = 2000,
}
@book{beetd,
author = {van Beethoven, Ludwig},
title = {Title D},
date = 2000,
}
@article{beethoven,
author = {Beethoven, Ludwig},
title = {Title},
journal = {Sort this one under Beethoven but
before the von/van entries (to pinpoint final sort)},
date = 1998,
}
@article{beZthoven,
author = {Bezthoven, Ludwig},
title = {Title},
journal = {Sort this one under BeZthoven (to pinpoint final sort)},
date = 1998,
}
@article{mevon,
author = {Mevon, Peter},
title = {Title},
journal = {Mr Mevon -- just to see that he does not get matched},
date = 1998,
}
@article{vontong,
author = {Vontong, Jane},
title = {Title},
journal = {Mrs Vontong -- just to see that she does not get matched},
date = 1998,
}
@book{somebook,
author = {Arnold von Uthor},
editor = {Edward von Ditor},
translator = {Ted von Ranslator},
title = {Title},
date = 1998,
}
@book{somebooktr,
translator = {Ted von Ranslator},
title = {Title},
date = 1998,
}
@book{uz,
author = {James Uzambara},
title = {Sort under Uzambara},
date = 2000,
}
\end{filecontents*}
\DeclareSourcemap{%
\maps[datatype=bibtex]{
\map[overwrite=true]{
\step[fieldsource=translator]
\step[fieldset=tempsortname, origfieldval]
\step[fieldsource=editor]
\step[fieldset=tempsortname, origfieldval]
\step[fieldsource=author]
\step[fieldset=tempsortname, origfieldval]
}
\map[overwrite=true]{
\step[fieldsource=tempsortname, match=\regexp{(^|\s+)\Kv[a|o]n\s+}, replace={$1}]
}
\map[overwrite=false]{
\step[fieldsource=tempsortname]
\step[fieldset=sortname, origfieldval]
}
}
}
\begin{document}
\nocite{*}
\printbibliography
\end{document}
-
Nice! I've made a note of this in case I ever need it myself. The
tempsortname
is a clever way to preservesortname
, which I actually do use in my.bib
file. (The problem with edge cases is that programming an 'automatic' solution is often ridiculously difficult to effect one or two small changes....)– jonOct 7, 2013 at 16:42
biber
) with the entry field:options = {useprefix=false}
. This would, in combination with the package option you mention, givevan B...
, but sort underB
. Providing a generic sorting solution that is not language-dependent is very complex: think of the differences between 'von', 'de la', and 'Jr'. Take a look at§ 4.5.5
in thebiblatex
manual to get an idea of what considerations are invovled.biber
but using\DeclareSourcemap
to add that option to entries with names containing a "van" or "von" etc.option = {useprefix}
to the entries that have a prefix name. The result is that the name is cited and listed without the prefix. Basically, I get the same result as when I set the package optionuseprefix=false
. Did I get something wrong?\DeclareSourcemap
to add a sortkey field. That's more flexible than editing the .bib file because I can define the sort order on a per-document basis. However, I thought that the cleanest way to handle this would perhaps be in the sorting logic, i.e., by defining a new sorting scheme.\DeclareSourcemap
is the better way to go in you need per-document flexibility. (This time I did try it.)