1

I would like a (biblatex) bibliography where:

  • The language of the bibliography is always the same, regardless of the language of the entry. I do not want translation or localization of things like: page or volume number, translator or editor data, author's name layout...
  • The title of the entries follow the punctuation spacing rules of the language of the entry. Typically: no space before ? in english, unbreakable space before ? in french.

I've tested various combinations of language and autolang parameters for biblatex, whitout success so far. For example in the MWE below:

  • autolang=other
    • correct punctuation spacing to switch punctuation rules, following the langid of each entry.
    • unwanted localization like: "Trans. by"/"Trad. par", "p."/"pp.", small capital or not for the name of the author...
  • autolang=hyphen
    • correct single language for the bibliography ("Trad. par" in both cases)
    • incorrect typography: the space before ? is missing in french.
\documentclass{article}
\usepackage[english,french]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{filecontents}

\begin{filecontents}{biblio.bib}
@book{compagnon,
  author     = {Compagnon, Antoine},
  translator = {Même, Moi},
  date       = {1998},
  title      = {Titre: aléatoire?},
  pages      = {306-723},
  langid     = {french},
}
@book{glashow,
  author       = {Glashow, Sheldon},
  title        = {Random: title?},
  translator   = {Self, My},
  date         = {1961},
  pages        = {579-588},
  langid       = {english},
}
\end{filecontents}

\usepackage[backend=biber,
    style=verbose-trad2,
    singletitle=true,
    autolang=other,
]{biblatex}  
\addbibresource{biblio.bib}

\begin{document}
\footcite{compagnon}
\footcite{glashow}
\printbibliography
\end{document}

Potential close questions:

  • Adding \foreignlanguage{...} in the title field is often suggested. I can't find again a very didactic post from user moewe explaining that biblatex does not have a per-field language options and presenting distinct strategies.
  • Correct punctuation, but with unwanted localisation at the entry level.
  • Correct hyphenation, but not the punctuation rules.
  • Potential solution in lualatex? Not sure to understand why it should be different.
2

1 Answer 1

2

As discussed in https://github.com/plk/biblatex/issues/757 and Change language on a per field basis, part 2: Fonts, case transformation and sorting this is pretty tricky and would ideally be addressed in the biblatex core. But that needs a lot of groundwork that still is being worked on.

Here is a babel version of the polyglossia-based answer to Change language on a per field basis, part 2: Fonts, case transformation and sorting that should get you a little further.

\documentclass{article}
\usepackage[english,french]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage[backend=biber,
    style=verbose-trad2,
    singletitle=true,
]{biblatex}

\makeatletter
\def\blx@thefakelangenv{otherlanguage}%

\def\blx@beglang@fake{%
  \blx@clearlang
  \begingroup
  \ifdef\abx@field@langid
    {\def\blx@endlang@fake{%
       \end{otherlanguage*}%
       \endgroup}%
     \begin{otherlanguage*}{\abx@field@langid}}
    {}}

\let\blx@endlang@fake\relax

\renewrobustcmd*{\blx@imc@printfield}[2][]{%
  \blx@imc@iffieldundef{#2}
    {\blx@nounit}
    {\blx@getformat\blx@theformat{ffd}{#1}{#2}%
     \ifdefvoid\blx@theformat
       {\blx@nounit}
       {\blx@begunit
        \let\blx@theformat@outer\blx@theformat
        \def\blx@theformat##1{\blx@theformat@outer{\blx@beglang@fake ##1\blx@endlang@fake}}%
        \edef\currentfield{#2}%
        \expandafter\expandafter
        \expandafter\blx@theformat
        \expandafter\expandafter
        \expandafter{\csname abx@field@#2\endcsname}%
        \blx@endunit}}}

\long\def\blx@nameparser@i#1#2{%
  \begingroup
  \ifblank{#1}
    {}
    {\setkeys{blx@opt@name}{#1}}%
  \setkeys{blx@opt@namepart}{#2}%
  \blx@beglang@fake\blx@theformat{#2}\blx@endlang@fake
  \endgroup}

\long\def\blx@listparser#1{%
  \ifblank{#1}
    {\blx@listbreak}
    {\ifnum\c@listcount<\c@liststart
     \else
       \blx@beglang@fake\blx@theformat{#1}\blx@endlang@fake
     \fi
     \advance\c@listcount\@ne
     \ifnum\c@listcount>\c@liststop
       \expandafter\blx@listbreak
     \fi
     \blx@listparser}}
\makeatother


\begin{filecontents}{\jobname.bib}
@book{compagnon,
  author     = {Compagnon, Antoine and Someone Else},
  translator = {Même, Moi},
  date       = {1998},
  title      = {Titre: aléatoire?},
  pages      = {306-723},
  langid     = {french},
}
@book{glashow,
  author       = {Glashow, Sheldon and Someone Else},
  title        = {Random: title?},
  translator   = {Self, My},
  date         = {1961},
  pages        = {579-588},
  langid       = {english},
}
\end{filecontents} 
\addbibresource{\jobname.bib}

\begin{document}
\footcite{compagnon}
\footcite{glashow}
\printbibliography
\end{document}

"Compagnon, Antoine et Someone Else. Titre : aléatoire ? Trad. par Moi Même. 1998, 306-723." (with space before colon and question mark)
"Glashow, Sheldon et Someone Else. Random: title? Trad. par My Self. 1961, 579-588." (without space before colon and question mark)


As discussed in the comments, this approach has some shortcomings, because it is not always desirable to have the language switching code applied to the field contents directly.

I cannot offer a good alternative approach, since changing the language after field formats etc. have been applied effects bibstrings (which are supposed to stay the same). What I can offer is an ad-hoc solution that allows you to exempt certain fields from the language switching (you can of course reverse the logic to have language switching only for certain fields if that works better for you).

\documentclass{article}
\usepackage[english,french]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage[backend=biber,
    style=verbose-trad2,
    singletitle=true,
]{biblatex}

\makeatletter
\newcommand*{\mblx@exemptfields}{}
\newrobustcmd*{\ExemptFromLanguageSwitching}{%
  \forcsvlist{\listgadd\mblx@exemptfields}}

\def\blx@thefakelangenv{otherlanguage}%

\def\blx@beglang@fake{%
  \blx@clearlang
  \begingroup
  \ifdef\abx@field@langid
    {\def\blx@endlang@fake{%
       \end{otherlanguage*}%
       \endgroup}%
     \begin{otherlanguage*}{\abx@field@langid}}
    {}}

\let\blx@endlang@fake\relax

\renewrobustcmd*{\blx@imc@printfield}[2][]{%
  \blx@imc@iffieldundef{#2}
    {\blx@nounit}
    {\blx@getformat\blx@theformat{ffd}{#1}{#2}%
     \ifdefvoid\blx@theformat
       {\blx@nounit}
       {\blx@begunit
        \ifinlist{#2}{\mblx@exemptfields}
          {}
          {\let\blx@theformat@outer\blx@theformat
           \def\blx@theformat##1{\blx@theformat@outer{\blx@beglang@fake ##1\blx@endlang@fake}}}%
        \edef\currentfield{#2}%
        \expandafter\expandafter
        \expandafter\blx@theformat
        \expandafter\expandafter
        \expandafter{\csname abx@field@#2\endcsname}%
        \blx@endunit}}}


\catcode`\&=3
\def\blx@printnames#1#2#3#4{%
  \blx@imc@ifnameundef{#4}
    {\blx@nounit}
    {\def\mblx@currentname{#4}%
     \blx@getformat\blx@thewrapperformat{nwd}{#1}{#4}%
     \ifdefvoid\blx@thewrapperformat
       {\blx@nounit}
       {\blx@getformat\blx@theformat{nfd}{#1}{#4}%
        \ifdefvoid\blx@theformat
          {\blx@nounit}
          {\blx@begunit
           \blx@namesetup{#2}{#3}{#4}%
           \blx@thewrapperformat{\expandafter\blx@nameparser\blx@thedata{}&}%
           \blx@endunit}}}}

\def\blx@indexnames#1#2#3#4{%
  \blx@imc@ifnameundef{#4}
    {}
    {\def\mblx@currentname{#4}%
     \blx@getformat\blx@theformat{nid}{#1}{#4}%
     \ifdefvoid\blx@theformat
       {}
       {\begingroup
        \blx@namesetup{#2}{#3}{#4}%
        \blx@indexnamesetup
        \expandafter\blx@nameparser\blx@thedata{}&%
        \endgroup}}}

\long\def\blx@nameparser@i#1#2{%
  \begingroup
  \ifblank{#1}
    {}
    {\setkeys{blx@opt@name}{#1}}%
  \setkeys{blx@opt@namepart}{#2}%
  \expandafter\ifinlist\expandafter{\mblx@currentname}{\mblx@exemptfields}
    {\blx@theformat{#2}}
    {\blx@beglang@fake\blx@theformat{#2}\blx@endlang@fake}%
  \endgroup}


\def\blx@printlist#1#2#3#4{%
  \blx@imc@iflistundef{#4}
    {\blx@nounit}
    {\def\mblx@currentlist{#4}%
     \blx@getformat\blx@thewrapperformat{lwd}{#1}{#4}%
     \ifdefvoid\blx@thewrapperformat
       {\blx@nounit}
       {\blx@getformat\blx@theformat{lfd}{#1}{#4}%
        \ifdefvoid\blx@theformat
          {\blx@nounit}
          {\blx@begunit
           \blx@listsetup{#2}{#3}{#4}%
           \blx@thewrapperformat{\expandafter\blx@listparser\blx@thedata{}&}%
           \blx@endunit}}}}

\def\blx@indexlist#1#2#3#4{%
  \blx@imc@iflistundef{#4}
    {}
    {\def\mblx@currentlist{#4}%
     \blx@getformat\blx@theformat{lid}{#1}{#4}%
     \ifdefvoid\blx@theformat
       {}
       {\begingroup
        \blx@listsetup{#2}{#3}{#4}%
        \expandafter\blx@listparser\blx@thedata{}&%
        \endgroup}}}

\long\def\blx@listparser#1{%
  \ifblank{#1}
    {\blx@listbreak}
    {\ifnum\c@listcount<\c@liststart
     \else
       \expandafter\ifinlist\expandafter{\mblx@currentlist}{\mblx@exemptfields}
         {\blx@theformat{#1}}
         {\blx@beglang@fake\blx@theformat{#1}\blx@endlang@fake}%
     \fi
     \advance\c@listcount\@ne
     \ifnum\c@listcount>\c@liststop
       \expandafter\blx@listbreak
     \fi
     \blx@listparser}}
\makeatother
\catcode`\&=4

\ExemptFromLanguageSwitching{url,doi,eprint,pages}


\begin{filecontents}[force]{\jobname.bib}
@book{compagnon,
  author     = {Compagnon, Antoine and Someone Else},
  translator = {Même, Moi},
  date       = {1998},
  title      = {Titre: aléatoire?},
  pages      = {306-723},
  langid     = {french},
  url        = {https://example.com/~stuff/more.pdf},
}
@book{glashow,
  author       = {Glashow, Sheldon and Someone Else},
  title        = {Random: title?},
  translator   = {Self, My},
  date         = {1961},
  pages        = {579-588},
  langid       = {english},
  url          = {https://example.com/~stuff/more.pdf},
}
\end{filecontents} 
\addbibresource{\jobname.bib}

\begin{document}
\footcite{compagnon}
\footcite{glashow}
\printbibliography
\end{document}
8
  • Some feedbacks: 1. With an url field, I get the following output url : \blx@beglang@fakeugly%20test-url\blx@endlang@fake. 2. The little "p." indicating (in french) a page, pages range or total page number disappears. Is this easily solvable or would the hack become too complex? Thanks again anyhow!
    – letax
    Mar 8, 2022 at 10:24
  • @letax We can exempt fields from language switching (see the edit). But this shows that a general solution in the biblatex core is going to be extremely tricky.
    – moewe
    Mar 8, 2022 at 16:07
  • Wow, I wish I could upvote again! It's always a bit scary as I don't understand the syntax/logic of the code, but so far it seems to work! Now, let's see how the 684 references of the full document behave...
    – letax
    Mar 8, 2022 at 18:25
  • For future readers: the patch was robust enough for my large document. Just make sure that every bib entry has a langid defined.
    – letax
    Mar 9, 2022 at 10:11
  • I stumble on only one incompatibility with your patch (great!): I make an automatic index using (yet) another answer of yours I get a compilation error ! Undefined control sequence. \blx@nameparser@i ...pandafter {\mblx@currentname. I tried to exempt the author field in \ExemptFromLanguageSwitching without success. Should I post a new question or is this too complex too be handled with a patch?
    – letax
    Mar 9, 2022 at 10:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .