# biblatex: Switching languages for *citations* according to the bibentry's “hyphenation” field

Quoting from section 3.1.2.1 of the biblatex manual:

[The babel] option controls which language environment is used if the babel package is loaded and a bibliography entry includes a hyphenation field [...]. Note that biblatex automatically adjusts to the main document language if babel is loaded. In multilingual documents, it will also continually adjust to the current language as far as citations and the default language of the bibliography is concerned. This option is for switching languages on a per-entry basis within the bibliography.

Suppose that, in a text with the main language "ngerman", I cite a bibentry with the hyphenation field "english". By default, the in-text-citation will use the hyphenation pattern for "ngerman". That is, if the citation style uses author names, titles or even full bibliographic data, hyphenation of these items is prone to be wrong. Case in point: The author William A. Fischel (an American) should be hyphenated "Fis-chel", but German hyphenation patterns will result in "Fi-schel".

My current workaround is to include any such author in TeX's hyphenation exception list, but this is clumsy and error-prone for longer texts. (Manually enclosing every citation in an appropriate otherlanguage environment is not an option for the same reasons.) My envisaged solution is to use the "hyphenation" field to automatically switch to the correct language in-text for every citekey. biblatex provides an \AtEveryCitekey hook (to be used only in the preamble), so this should be possible in principle. In the following example, I show that switching languages on a one-time basis is possible using \AtNextCitekey.

\documentclass{article}

\usepackage[english,ngerman]{babel}

\usepackage[style=authoryear,babel=hyphen]{biblatex}

\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@book{Fis85,
hyphenation = {english},
author = {Fischel, William A.},
year = {1985},
title = {The economics of zoning laws: A property rights approach to American land use planning},
location = {Baltimore},
publisher = {Johns Hopkins University Press},
}
\end{filecontents}

\textwidth=290pt

% My current workaround: Include author names in the hyphenation exception list
% \hyphenation{Fis-chel}

% My envisaged solution: At every citekey, switch to the language defined in the bibentry's
%     "hyphenation" field. This doesn't work because babel strips away the escape character "\"
%     from "\thefield{hyphenation}"
% \AtEveryCitekey{\selectlanguage{\thefield{hyphenation}}}

\begin{document}

Dies hier ist ein Blindtext zum Testen von Textausgaben \autocite{Fis85}.

% The following code line shows that my envisaged solution (see above) would work if
%     "\thefield{hyphenation}" would be expanded to (in this case) "english"
%     (Note: "\AtNextCitekey" is the "one-time" variant of  "\AtEveryCitekey"
\AtNextCitekey{\selectlanguage{english}}

Dies hier ist ein Blindtext zum Testen von Textausgaben \autocite{Fis85}.

Dies hier ist ein Blindtext zum Testen von Textausgaben \autocite{Fis85}.

\printbibliography

\end{document}


So why doesn't my envisaged solution work? Trying

\AtEveryCitekey{\selectlanguage{\thefield{hyphenation}}}


results in the the following error message:

Package babel Error: You haven't defined the language thefield{hyphenation}

That is, instead of expanding \thefield{hyphenation} to "english" (as I naively assumed), babel strips away away the escape character \ from \thefield{hyphenation} and then complains about an unknown language. (According to section 7 of the babel manual, this stripping away is done for reasons of compatibility with the german package (which uses the syntax \selectlanguage{\german}.)

Sifting through biblatex.sty, I found the following code snippet that patches internal babel commands. It may well reveal what needs to be done to properly expand \thefield{hyphenation} to "english" in my above example -- but to be honest, I have no clue what this code snippet does exactly.

\def\blx@mkbabel{%
\patchcmd\bbl@set@language
{\select@language}
{\blx@langsetup\languagename\select@language}%
{\ifdef\blx@thelangenv
{\def\blx@beglang{%
\blx@clearlang
\begingroup
\blx@imc@iffieldundef{hyphenation}
{}
{\blx@hook@initlang
\def\blx@endlang{%
\blx@hook@endlang
\csname end\blx@thelangenv\endcsname
\endgroup}%
\csname\blx@thelangenv\expandafter\endcsname
\expandafter{\abx@field@hyphenation}}}}
{}%
\blx@langsetup\bbl@main@language}
{\blx@err@patch{'babel' package}%
\blx@mknobabel}}


Long story, short question: How can I make my envisaged solution work, i.e. automatically switch languages for citations according to the bibentry's "hyphenation" field?

-
Interesting question. Might be reasonable to ask for an extension of any solution to csquotes' integrated interface (see section 5 of the manual). –  N.N. Jun 20 '11 at 20:20

I think this works:

\makeatletter
\AtEveryCitekey{%
\blx@langsetup\abx@field@hyphenation%
\blx@hyphenreset%
}
\makeatother


In \abx@field@hyphenation is hyphenation value. Probably it needs some testing, if it is set.

edit:

Some time ago, I was looking at biblatex language switching because of problem with my citation style[1]. I didn't understand this code at all, so I ended with ugly hack[2].

But when I looked yesterday on biblatex's patch of babel you posted, I have found line

\blx@langsetup\languagename\select@language


Function \blx@langsetup uses edef to define \blx@languagename, which is used by macro \blx@hyphenreset to load hyphenation patterns, and then loads localization strings for given language. So in fact, instead of

\blx@langsetup\abx@field@hyphenation%


it is possible to use just

\edef\blx@languagename{\abx@field@hyphenation}%


Then there is problem with French language. When used as the main document language, instead of

... (Fis-
el 1985)...


there is

...(FISCHEL
1985)...


I think there is issue only with French, I tried Czech, Russian and Spanish and they worked correctly.

With babel, we can solve this issue with

\select@language\abx@field@hyphenation%


but, polyglossia in xelatex has same issue and this trick is there not working, I don't know how to fix that.

Anyway, if you don't need French with polyglossia, this is the current solution

\makeatletter
\AtEveryCitekey{%
\ifcsdef{abx@field@hyphenation}{%
\edef\blx@languagename{\abx@field@hyphenation}%
\select@language\abx@field@hyphenation%
\blx@hyphenreset%
}{}%
}
\makeatother

-
Looks good -- I will do some further testing. Could you elaborate a bit how you came up with your code snippet? –  lockstep Jun 20 '11 at 21:09
@michal.h21: If I replace ngerman with french in my example and then add your code snippet, "Fischel" isn't hyphenated at all in the first and third paragraph. However, if I then add \select@language\abx@field@hyphenation to your code, things work as expected. It seems that one has also explicitely to switch to the new language to cancel the side effects of (e.g.) french. If you can confirm this modified solution, please edit your answer. –  lockstep Jun 20 '11 at 21:56
I will try to write some details tommorow –  michal.h21 Jun 20 '11 at 22:36
@lockstep I have edited my answer –  michal.h21 Jun 21 '11 at 9:22
@michal.h21: Please add the missing \makeatother in your second code snippet. –  lockstep Jun 21 '11 at 14:40

michal.h21's latest solution also works for the French language (at least if one doesn't use polyglossia), but its drawback is that it will also switch languages for terms like "ibidem", "sequens" and "sequentes". So I've adapted michal.h21's code to only switch hyphenation patterns:

\makeatletter
\AtEveryCitekey{%
\ifcsdef{abx@field@hyphenation}{%
\edef\blx@languagename{\abx@field@hyphenation}%
\blx@hyphenreset
}{%
}%
}
\makeatother


A possible workaround for the French language is to use michal.h21's latest solution, but additionally to redefine the localization keys for "ibidem" & friends for every language used in a particular document so that they match the keys of the main document language.

-

Thanks to @oleg prompting me, I have implemented this in the biblatex 2.8a development version available on SF. See the PDF doc for the language option. Basically, just set language=auto to turn on language switching for both bib entries and citations.

-

This is a solution sensitive to the babel option of biblatex. It wraps every citation in the \blx@thelangenv environment, which depends on this option. This should also work with polyglossia.

\gpreto\blx@hook@citekey{%
\ifdef\abx@field@hyphenation
{\ifdef\blx@thelangenv
{\edef\blx@temp@langenv{\noexpand\csname\blx@thelangenv\endcsname%
{\abx@field@hyphenation}}%
\blx@temp@langenv}
{}}%
{}}
\apptocmd{\blx@citeprint}{%
\ifdef\abx@field@hyphenation
{\ifdef\blx@thelangenv
{\csname end\blx@thelangenv\endcsname}
{}}%
{}%
}{}{\blx@err@patch{citeprint command}}%


UPDATE: This doesn't work with biblatex 2.8 and polyglossia. Instead the following patch can be used (BUT: see this answer by @PLK, biblatex is going to support the feature natively)

\patchcmd{\blx@citeprint}{\begingroup}{\begingroup\blx@beglang}
{}{\blx@err@patch{citeprint command}}
\patchcmd{\blx@citeprint}{\endgroup}{\blx@endlang\endgroup}
{}{\blx@err@patch{citeprint command}}

-
Did you try the 2.8a version with polyglossia? –  PLK Nov 21 '13 at 10:57
I did some tests, everything is fine. Thanks for implementing this :) –  Oleg Domanov Nov 23 '13 at 8:49