11

I think this MWE says it all. \cite can ignore spaces in its argument, while \cref cannot. I wonder if \cref could be improved that way.

\documentclass{article}
\usepackage{cleveref}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
    @misc{1, author="One Author", year=2000}
    @misc{2, author="Another Writer", year=2010}
\end{filecontents}
\begin{document}
    We can use \cite{1,2} AND \cite{1, 2}!

    Yet, we can use \cref{1,2}, but not \cref{1, 2}!

    \section{Section 1}
    \label{1}

    \section{Section 2}
    \label{2}

    \bibliographystyle{apalike}
    \bibliography{\jobname}

\end{document}

Why is this important? Because some text editors, TeXstudio being one of them, have trouble implementing line wraps at commas without a subsequent space.

12

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}

Result

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}

Result

\zap@space is defined in the LaTeX kernel and is used to normalize options list for classes and packages, for example.

  • 1
    This answer has one drawback: \cref{1,2,3,,4} (sections 1-3 and 4) shall behave differently from \cref{1,2,3,4} (sections 1-4). This behavior is documented in cleveref, yet lost with this solution. – bers Nov 22 '16 at 20:54
  • 1
    @bers See updated answer. – Heiko Oberdiek Nov 22 '16 at 21:01
  • Thanks. Your second example does not even need \usepackage{kvsetkeys}. – bers Nov 25 '16 at 4:19
6

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.

enter image description here

4

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.

enter image description here

\documentclass{article}
\usepackage{cleveref}

\usepackage{luacode}
\begin{luacode}
function nospace ( t ) -- remove all whitespace from string "t"
  return ( string.gsub ( t, "%s", "" ) )
end
function crefnospace ( s ) 
  return ( string.gsub ( s , "\\.-[cC]ref%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}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.