It is not always simple to change the order of fields for biblatex
with only a few lines of code. This is due to the structure of biblatex
's bibliography handling. biblatex
has a 'driver' for each entry type that defines which fields are printed in what order. These drivers, however, do not always call \printfield
directly, they often call auxiliary bibmacros that do the printing.
Take the driver for @book
from philosophy-standard.bbx
as example
\DeclareBibliographyDriver{book}{%
\usebibmacro{bibindex}%
\usebibmacro{begentry}%
\usebibmacro{author/editor+others/translator+others}%
\setunit{\labelnamepunct}\newblock
\usebibmacro{maintitle+title}%
\newunit
\printlist{language}%
\newunit\newblock
\usebibmacro{byauthor}%
\newunit\newblock
\usebibmacro{byeditor+others}%
\newunit\newblock
\printfield{edition}%
\newunit
\printfield{volumes}%
\newunit\newblock
\usebibmacro{series+number}%
\newunit\newblock
\printfield{note}%
\newunit\newblock
\usebibmacro{publisher+location+date}%
\newunit
\iffieldundef{maintitle}
{\printfield{volume}%
\printfield{part}}
{}%
\newunit\newblock
\usebibmacro{chapter+pages}%
\newunit
\printfield{pagetotal}%
\newunit\newblock
\iftoggle{bbx:isbn}
{\printfield{isbn}}
{}%
\newunit\newblock
\usebibmacro{doi+eprint+url}%
\newunit\newblock
\usebibmacro{addendum+pubstate}%
\newblock
\usebibmacro{phil:related}%
\newunit\newblock
\usebibmacro{pageref}%
\usebibmacro{finentry}}
You can see that some fields are printed directly (\printfield{edition}
), while many other things are printed by a bibmacro (\usebibmacro{byeditor+others}
).
If you are lucky, there is a reasonably short bibmacro that prints the two fields you want to swap. Then changing the order of the fields is as easy as redefining that bibmacro. If you wanted to change the order of publisher
, location
and date
, for example, you could simply redefine publisher+location+date
and that is that. Often these macros are used by all entry types alike, so that you don't even have to worry about that.
But if you want to swap two fields that are printed by different macros in a particular driver, then you have to essentially re-write that driver. You would copy the driver definition and simply re-arrange the fields. This can be tiresome and causes your preamble to fill up quite quickly with many lines of code, since your average bibdriver is about 40 to 50 lines long. And you will have to modify all affected drivers.
In those situations it can be handier to use the package xpatch
. Using the \xpatchbibdriver
command you can replace certain bits of the definition of a driver. To remove the edition
from the driver for @book
you would say
\xpatchbibdriver{book}
{\printfield{edition}%
\newunit}
{}
{}
{\typeout{failed to remove edition from driver for 'book'}}
you can then add it in where you actually want it
\xpatchbibdriver{book}
{\printlist{language}%
\newunit\newblock}
{\printlist{language}%
\newunit\newblock
\printfield{edition}%
\newunit}
{}
{\typeout{failed to add edition to bibmacro 'book'}}
Structurally similar patches have to be applied to other drivers and bibmacros as well.
For this to work it is crucial that you know the structure of the underlying driver.
In full with all entry types patched
\documentclass[11pt, a4paper]{scrartcl}
% Bibliography preamble
\usepackage[giveninits=true, style=philosophy-modern]{biblatex}
\addbibresource{biblatex-examples.bib}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{auerbach2003,
Author = {Auerbach, Erich},
Publisher = {Princeton University Press},
Title = {Mimesis: the representation of reality in Western literature},
date = {2003},
Editor = {Trask, Willard R.},
editortype = {translator},
Location = {Princeton},
edition = {2}}
\end{filecontents}
\addbibresource{\jobname.bib}
% Some tweaks I've already made
\DeclareFieldFormat{postnote}{#1}% no postnote prefix in "normal" citation commands
\DeclareFieldFormat{multipostnote}{#1}% no postnote prefix in "multicite" commands
\DeclareFieldFormat{pages}{#1}% no prefix for the `pages` field in the bibliography
\DeclareFieldFormat[article]{title}{#1} % Remove quotations from Article title
\setlength{\yeartitle}{5.4em} % Set greater spacing between the year and the title
\setlength{\postnamesep}{2.5ex plus 2pt minus 1pt}
\usepackage{xpatch}
\newcommand*{\removeeditiondriver}[1]{%
\xpatchbibdriver{#1}
{\printfield{edition}%
\newunit}
{}
{}
{\typeout{failed to remove edition from driver for '#1'}}}
\forcsvlist{\removeeditiondriver}{book,collection,manual,jurisdiction}
\newcommand*{\removeeditionbibmacro}[1]{%
\xpatchbibdriver{#1}
{\printfield{edition}%
\newunit}
{}
{}
{\typeout{failed to remove edition from bibmacro '#1'}}}
\forcsvlist{\removeeditionbibmacro}{inbook:full,incollection:full,xrefdata}
\newcommand*{\addeditiondriver}[1]{%
\xpatchbibdriver{#1}
{\printlist{language}%
\newunit\newblock}
{\printlist{language}%
\newunit\newblock
\printfield{edition}%
\newunit}
{}
{\typeout{failed to add edition to driver for '#1'}}}
\forcsvlist{\addeditiondriver}{book,collection,manual,jurisdiction}
\newcommand*{\addeditionbibmacroin}[1]{%
\xpatchbibdriver{#1}
{\usebibmacro{maintitle+booktitle}%
\newunit\newblock}
{\usebibmacro{maintitle+booktitle}%
\newunit\newblock
\printfield{edition}%
\newunit}
{}
{\typeout{failed to add edition to bibmacro '#1'}}}
\forcsvlist{\addeditionbibmacroin}{inbook:full,incollection:full}
\xpretobibmacro{xrefdata}
{\printfield{edition}%
\newunit}
{}
{\typeout{failed to add edition to bibmacro '#1'}}
\begin{document}
Sentence containing citation \parencite{nietzsche:ksa,companion,auerbach2003}.
\printbibliography
\end{document}

edition = {2},
instead ofedition = {2nd ed.},
should give the same output and is preferred.