Can \cref Be Made To Ignore Spaces?
Answer :
Normalization with removal of spaces before and after label names and removing of empty entries.
The following example uses the comma parser of package kvsetkeys
for parsing the label name list of the referencing commands of package cleveref
. The internal \@cref
with the list in its second argument is redefined for this:
\documentclass{article} \usepackage{cleveref} \usepackage{kvsetkeys} \makeatletter \let\org@@cref\@cref \renewcommand*{\@cref}[2]{% \begingroup \toks@={}% \comma@parse{#2}\add@cref@item \edef\process@me{\endgroup \noexpand\org@@cref{#1}{\the\toks@}% }\process@me } \newcommand*{\add@cref@item}[1]{% \expandafter\ifx\expandafter\\\the\toks@\\% \toks@{#1}% \else \toks@\expandafter{\the\toks@,#1}% \fi } \makeatother \begin{document} \noindent We can use \cref{1,2}, and now \cref{1, 2},\\ and even with a leading or trailing comma: \Cref{ , 1 , 2 ,}. \section{Section 1} \label{1} \section{Section 2} \label{2} \end{document}
Removal of open spaces and retaining commas
Solution that zaps all open spaces. If a label contains spaces, the label must be put in curly braces.:
\documentclass{article} \usepackage{cleveref} \usepackage{kvsetkeys} \makeatletter \let\org@@cref\@cref \renewcommand*{\@cref}[2]{% \edef\process@me{% \noexpand\org@@cref{#1}{\zap@space#2 \@empty}% }\process@me } \makeatother \begin{document} \noindent We can use \cref{1,2}, and now \cref{1, 2}. \section{Section 1} \label{1} \section{Section 2} \label{2} \end{document}
\zap@space
is defined in the LaTeX kernel and is used to normalize options list for classes and packages, for example.
Almost self-explaining code:
\begin{filecontents}{\jobname.bib} @misc{1, author="One Author", year=2000} @misc{2, author="Another Writer", year=2010} \end{filecontents} \documentclass{article} \usepackage{xparse} \usepackage{cleveref} \ExplSyntaxOn \cs_set_eq:Nc \bers_cref:nn { @cref } \cs_generate_variant:Nn \bers_cref:nn { nx } \cs_set_protected:cpn { @cref } #1 #2 { \seq_set_split:Nnn \l_bers_cref_seq { , } { #2 } \bers_cref:nx { #1 } { \seq_use:Nn \l_bers_cref_seq { , } } } \seq_new:N \l_bers_cref_seq \ExplSyntaxOff \begin{document} We can use \cite{1,2} AND \cite{1, 2}! Yet, we can use \cref{1 space,2}, but also \cref{1 space, 2}! Also \cref{1 space,2 , 3,, 4} Also \Cref{1 space, 2, 3 , , 4} \section{Section 1} \label{1 space} \section{Section 2} \label{2} \section{Section 3} \label{3} \section{Section 4} \label{4} \bibliographystyle{apalike} \bibliography{\jobname} \end{document}
I redefine the internal command \@cref
to first split its second argument at commas, which removes leading and trailing spaces, but preserves inner ones. The original \@cref
is saved in \bers_cref:nn
, and then \@cref
is redefined to use \bers_cref:nx
, a variant that fully expands its second argument where we do \seq_use:Nn
with a comma between entries.
Note that also \Cref
is modified automatically. Empty entries are honored.
Here's a LuaLaTeX-based solution. It allows whitespace (spaces, tab characters, line breaks) in the arguments of \cref
, \Cref
, and \labelcref
. Note that the approach pursued in this solution doesn't modify the cleveref
macros in any way.
\documentclass{article} \usepackage{cleveref} \usepackage{luacode}
\begin{luacode} function nospace ( t ) -- remove all whitespace characters from string "t" return ( t:gsub ( "%s", "" ) ) end function crefnospace ( s ) return ( s:gsub ( "\\.-[cC]ref%s-%b{}" , nospace ) ) end
\end{luacode} \AtBeginDocument{\directlua{luatexbase.add_to_callback ( "process_input_buffer", crefnospace, "crefnospace" )}} \begin{document} We may use \cref{a,b}, \Cref{a, b}, \cref{a ,b}, and \Cref{{ a }, b }. ``\labelcref{ b , {a }}'' works too. \section{Section 1}\label{a} \section{Section 2}\label{b} \end{document}
Comments
Post a Comment