12

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.

  • You can also get this behaviour (with biber) with the entry field: options = {useprefix=false}. This would, in combination with the package option you mention, give van B..., but sort under B. 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 the biblatex manual to get an idea of what considerations are invovled. – jon Oct 2 '13 at 2:42
  • Commenting on the previous comment, you could also automate this if using biber but using \DeclareSourcemap to add that option to entries with names containing a "van" or "von" etc. – PLK Oct 2 '13 at 5:59
  • 1
    @jon: I just tried adding 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 option useprefix=false. Did I get something wrong? – tmalsburg Oct 2 '13 at 7:29
  • @PLK: I considered using \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. – tmalsburg Oct 2 '13 at 7:35
  • You're right. I misunderstood the docs and didn't actually try anything since it would've meant constructing a fake example for myself. \DeclareSourcemap is the better way to go in you need per-document flexibility. (This time I did try it.) – jon Oct 2 '13 at 23:18
5

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 with replace={$2 $3} (To see what happens map all the steps above to addendum instead of sortname). Secondly, is there a way to make sure the sortname is actually in the format specified via \DeclareNameAlias{sortname}{first-last}? – moewe Oct 3 '13 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 the addendum 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). – jon Oct 4 '13 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). – moewe Oct 4 '13 at 19:42
4

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 preserve sortname, 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....) – jon Oct 7 '13 at 16:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.