[Tex/LaTex] How to make a custom \crefformat dependent on language chosen with babel

babelcleverefcross-referencing

For my custom class I use the package and define new custom reference styles:

\crefformat{figure}{Meine tolle Abbildung ~#2#1#3}

Is there a way to make this command consider the language chosen with ? Like:

\crefformat[ngerman]{figure}{meine tolle Abbildung ~#2#1#3}
\crefformat[english]{figure}{my fancy figure ~#2#1#3}

So I get the correct output for what I've chosen loading :

\usepackage[english]{babel}

The manual states, that it is no problem with something like:

\crefformat{equation}{#2\cref@equation@name~(#1)#3}

But I can't see how to apply that to my case.


Edit:

I found a cumbersome solution by myself, but I'd prefer one which wouldn't require to load all languages with babel (though I don't know if it's necessarily a bad thing, I'd just guess its overkill).


MWE:

\documentclass{article}

\usepackage[demo]{graphicx}
\usepackage[english]{babel}
\usepackage{hyperref}
\usepackage{cleveref}

\crefformat{figure}{Abb.~#2#1#3}

\begin{document}
    \cref{fig:one}

    \begin{figure}[h]
        \includegraphics[width=\textwidth]{example-image-a}
        \caption{I am a figure\label{fig:one}}
    \end{figure}

\end{document}

Best Answer

As it says in the cleveref manual, you need to hook your \crefformat commands into babel's language-switching mechanism. This is explained in detail in the babel documentation, but basically you need to add your \crefformat definitions to the appropriate \extras<language> macro.

Cleveref provides a convenience macro \cref@addlanguagedefs to accomplish this (which has the advantage of also working for the polyglossia package). Adding the following to your preamble will do the trick:

\makeatletter
\cref@addlanguagedefs{english}{%
  \crefformat{figure}{my fancy figure~#2#1#3}}
\cref@addlanguagedefs{ngerman}{%
  \crefformat{figure}{meine tolle Abbildung~#2#1#3}}
\makeatother

There's one more wrinkle. This hooks the format changes into babel's language-switching, but it doesn't actually set the formats until you switch language. (Arguably cleveref should do this for you - maybe I'll fix this in a future version.) Perhaps the easiest way to set the initial formats is to add a \selectlanguage{ngerman} command at the very beginning of your document.

Also, you should carefully read the instructions in the cleveref manual about where to pass language options. Basically, you should be passing language options to \documentclass, not to \usepackage{babel} as in your MWE. Otherwise cleveref won't do what you want.

(Off topic: I'm not sure why you're putting a space before the ~ in your \crefformat definitions. ~ inserts a non-breaking space, so you almost certainly don't want the additional space character before it. I've fixed this in the \crefformat definitions given above.)

Here's a full MWE demonstrating all of the above:

\documentclass[english,ngerman]{article}

\usepackage[demo]{graphicx}
\usepackage{babel}
\usepackage{hyperref}
\usepackage{cleveref}

\makeatletter
\cref@addlanguagedefs{english}{%
  \crefformat{figure}{my fancy figure~#2#1#3}}
\cref@addlanguagedefs{ngerman}{%
  \crefformat{figure}{meine tolle Abbildung~#2#1#3}}
\makeatother

\begin{document}
\selectlanguage{ngerman}
    \cref{fig:one}

    \begin{figure}[h]
        \includegraphics[width=\textwidth]{example-image-a}
        \caption{I am a figure\label{fig:one}}
    \end{figure}

\selectlanguage{english}
\cref{fig:one}

\selectlanguage{ngerman}
\cref{fig:one}

\end{document}

Note that, since you're only changing the name used for figures, you could also accomplish everything you want using the higher-level \crefname command instead of \crefformat. This has the advantage of automatically defining all the other variants - plurals, reference ranges, etc. - which would otherwise need to be added manually to the above MWE in any real document:

\documentclass[english,ngerman]{article}

\usepackage[demo]{graphicx}
\usepackage{babel}
\usepackage{hyperref}
\usepackage{cleveref}

\makeatletter
\cref@addlanguagedefs{english}{%
  \crefname{figure}{my fancy figure}{my fancy figures}}
\cref@addlanguagedefs{ngerman}{%
  \crefname{figure}{meine tolle Abbildung}{meine tolle Abbildungen}}
\makeatother


\begin{document}
\selectlanguage{ngerman}
\cref{fig:one}

\begin{figure}[h]
  \includegraphics[width=\textwidth]{example-image-a}
  \caption{I am a figure\label{fig:one}}
\end{figure}

\selectlanguage{english}
\cref{fig:one}

\selectlanguage{ngerman}
\cref{fig:one}

\end{document}

Maybe there's a case for adding an optional language argument to \crefname, \crefformat etc. when babel or polyglossia is loaded, to simplify this a little in multilingual documents. On the other hand, language switching in cleveref works "out of the box" as long as you're happy with the default formats and names. Going beyond this and customising the default language strings seems to require very similar solutions in other packages (e.g. varioref). And the above mechanism is explained in the babel documentation. There's a strong case for making cleveref work the same way as other packages.