7

In this example I must choose between \cref{sec:bar} and French spacing (o/w disabled using \NoAutoSpace; I presume because sec:bar is read sec\thinspacing:bar. Is there a solution?

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
%\NoAutoSpacing
\usepackage{cleveref}

\begin{document}

\section{Foo}

bonjour: monde; oui? non! «aujourd'hui»

% Voir~\cref{sec:bar}

%(./debug-108.aux)
%! Missing \endcsname inserted.
%<to be read again> 
%                   \unskip 
%l.14 Voir~\cref{sec:bar}
%                        
%? 

\section{Bar}\label{sec:bar}

bonjour: monde; oui? non! « aujourd'hui »

\end{document}

\NoAutospacing

\cref commented out

2
  • 1
    better to avoid active characters in labels. use e.g. sec-bar or whatever instead. Commented 14 hours ago
  • The user guide of the cleveref package is up front in mentioning that active characters mustn’t be used in the arguments of \label and \cref instructions, and that this stricture very much applies to the : character if babel is loaded with french. Commented 11 hours ago

4 Answers 4

4

While \ref “sanitizes” its argument, so properly defined active babel shorthands will work in such argument, \cref doesn't.

You can add the sanitization yourself, but probably the best method is to avoid shorthands (in the case of French, punctuation marks) in labels.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\usepackage{newunicodechar} % for « and »
\usepackage{cleveref}

\newunicodechar{«}{\og\ignorespaces}
\newunicodechar{»}{\fg}

\NewCommandCopy{\originalcref}{\cref}

\ExplSyntaxOn
\cs_set_eq:Nc \__erwann_cref:nn { @cref }
\cs_generate_variant:Nn \__erwann_cref:nn {ne}
\cs_set_protected:cpn { @cref } #1 #2
 {
  \__erwann_cref:ne {#1} { \tl_to_str:n {#2} }
 }
\ExplSyntaxOff

\begin{document}

\section{Foo}

bonjour: monde; oui? non! «aujourd'hui» stop

Voir~\cref{sec:bar}

\section{Bar}\label{sec:bar}

bonjour: monde; oui? non! « aujourd'hui » stop

\end{document}

I also added code for making the guillemets to behave.

output

Explanation: \cref{<label>} does \@cref{cref}{<label>}, so this patch should work also for other related commands. Experiment.

2
  • 1
    this will disable handling of commands in the label name, so \cref{\blub} will no longer work. Commented 10 hours ago
  • @UlrikeFischer A slower routine could be used: process the argument token by token doing one step expansion and forming a string later. But… Commented 8 hours ago
5

cleveref uses \edef in a lots of places where it shouldn't.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}

\usepackage{cleveref}
\usepackage{etoolbox}
\makeatletter
\patchcmd\@cref{\edef}{\protected@edef}{}{\fail}
\patchcmd\@cref{\edef}{\protected@edef}{}{\fail}
\patchcmd\@cref{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@stack@dropempty{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@stack@dropempty{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@processgroupall{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@processgroupall{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@processgroupall{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@stack@sort{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@stack@sort{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@stack@sort{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@processconsecutive{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@processconsecutive{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@processconsecutive{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@processconsecutive{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@processconsecutive{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@processconsecutive{\edef}{\protected@edef}{}{\fail}
\patchcmd\cref@processconsecutive{\edef}{\protected@edef}{}{\fail}
\makeatother
\begin{document}

\section{Foo}

bonjour: monde; oui? non! «aujourd'hui»


 Voir~\cref{sec:bar}

\section{Bar}\label{sec:bar}


bonjour: monde; oui? non! « aujourd'hui »

\end{document}

screenshot of compilation

2
  • The package cleveref hasn't been updated since 2018, are you aware of an alternative [for this task]? ctan.org/pkg/cleveref Commented 6 hours ago
  • I know that it hasn't been updated. Search for my recent answers for cleveref problems. An alternative is zref-clever. Commented 6 hours ago
3

If I'm not mistaken, babel-french doesn't use active characters with lualatex. You should maybe consider using it.

Example, without errors if compiled with lualatex:

\documentclass[french]{article}

\usepackage{babel}
\usepackage{cleveref}

\begin{document}

\section{Foo}

bonjour: monde; oui? non! «aujourd'hui»

Voir~\cref{sec:bar}

\section{Bar}\label{sec:bar}

bonjour: monde; oui? non! « aujourd'hui »

\end{document}

Example

0

Since I was circling around the obvious myself, I think it's worth posting the answer in the comments: "avoid active characters in labels".

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.