[Tex/LaTex] Crossreference in Ref Range [(1a-1e) to (1a-e)]

cleverefcross-referencing

I am just a beginner in LaTeX, I am facing a problem in Ref Range,

\documentclass{article}
\usepackage{amsmath,amsfonts,amssymb,cleveref}
\begin{document}
\ref{eq1a,eq1b,eq1c,eq1d,eq1e}
\begin{subequations}
  \begin{align}
    1+1=2\label{eq1a}\\
    1-1=0\label{eq1b}\\
    23+23=46\label{eq1c}\\
    d+e=f\label{eq1d}\\
    e+f=g\label{eq1e}
  \end{align}
\end{subequations}
\ref{eq1a,eq1b,eq1c,eq1d,eq1e}
\cref{eq1a,eq1b,eq1c,eq1d,eq1e}
\end{document}

My problem is I want to display the refrange like 1a-e if I use \cref, but I am getting an output like 1a-1e but is it possible to hide the 1 in the refrange (1a-e)

I went through the cleveref style file (Dont know anything about that :)), I found out the command which is replacing the (1a-1e) (cleverref.sty Line Number: 1022)

            \textup{(#3#1#4)}--\textup{(#5#2#6)}}}{}}{}%

In the above mentioned coding from cleverref.sty, I need to delete the Number and retain the 'e' from #2, Please guide me in this problem, thanks in advance

Best Answer

You can do this without hacking any cleveref internals. The beauty of the \cref<x>format commands is that you're really defining the body of a LaTeX macro, not merely a pattern with placeholders to be filled in. This lets you do arbitrarily complex things to the label text before it gets typeset.

To produce equation range references of the form (1a-e) instead of (1a)-(1e), you can redefine the equation range label format with the help of a (new) \crefstripprefix utility macro (see below), like so:

\crefrangelabelformat{equation}{(#3#1#4--#5\crefstripprefix{#1}{#2}#6)}

The \crefstripprefix macro takes two arguments, and outputs the second with the common prefix (if any) removed. Here's an implementation (which can probably be tidied up a bit):

\newcommand\crefstripprefix[2]{%
  \begingroup%
    \edef\@toksa{#1}%
    \edef\@toksb{#2}%
    \def\@accum{}%
    \@crefstripprefix%
    \@result%
  \endgroup}

\def\@crefstripprefix{%
  \let\@iterate\relax%
  \def\accum@flag{0}%
  \let\@tempc\@tempb%
  \cref@poptok{\@toksa}{\@tempa}%
  \cref@poptok{\@toksb}{\@tempb}%
  \ifx\@tempa\@tempb\relax%
    \def\@iterate{\@crefstripprefix}%
    \ifx\@accum\@empty\relax%
      \let\@accum\@tempb%
    \else%
      \ifcat\@tempb\@tempc\relax%
        \ifcat\@tempb a\relax%
          \def\accum@flag{1}%
        \else%
          \expandafter\chardef\expandafter\@tempa%
            \expandafter=\expandafter`\@tempb\relax%
          \ifnum\@tempa>`/\relax%
            \expandafter\ifnum\@tempb<`:\relax%
              \def\accum@flag{1}%
            \fi%
          \fi%
        \fi%
      \fi%
      \def\@tempa{1}%
      \ifx\accum@flag\@tempa%
        \edef\@accum{\@accum\@tempb}%
      \else%
        \let\@accum\@empty%
      \fi%
    \fi%
  \else%
    \ifcat\@tempb\@tempc\relax\else%
      \let\@accum\@empty%
    \fi%
    \edef\@result{\@accum\@tempb\@toksb}%
  \fi%
  \@iterate}

\def\cref@poptok#1#2{%
  \expandafter\expandafter\expandafter\def%
    \expandafter\expandafter\expandafter#2%
    \expandafter\expandafter\expandafter{%
      \expandafter\@cref@firsttok#1\@nil}%
  \expandafter\expandafter\expandafter\def%
    \expandafter\expandafter\expandafter#1%
    \expandafter\expandafter\expandafter{%
      \expandafter\@cref@poptok#1\@nil}}
\def\@cref@firsttok#1#2\@nil{#1}
\def\@cref@poptok#1#2\@nil{#2}

This crefstripprefix utility macro seems like it might be generally useful for producing more sophisticated label formatting, so I may add something like it to the next cleveref release together with this example usage.

A few comments are in order:

  1. The above solution formats \crefrange{eq1}{eq32} as eqs.~(1--32), which is slightly different to Qrrbrbirlbel's solution. This is a deliberate choice. \crefrange is supposed to be a dumb fall-back command, that simply dumps whatever labels you pass it into the appropriate range format. I prefer to keep \crefrange simple and dumb, avoiding too much cleverness. If you want clever reference ranges, pass all the references to \cref and let it sort them out for you. (This is more work, but it's safer since the cross-reference will be correct however you reorder the text in your document.)

  2. Comparing the formatted label text and stripping any common prefix seems to me the "correct" thing to do. A possible alternative would be to compare the c@<counter> values and reset lists, and deduce the appropriate formatting from that (cleveref keeps track of this information anyway). The problem with that approach (apart from being more complex) is that standard LaTeX allows arbitrary reformatting of label counters using the p@<counter> macros, and there's essentially no way to figure out how the label counter part of the cross-reference is being formatted separately from whatever else is being done to it (e.g. adding chapter/section/subsection numbers). Which forces one to guess the appropriate formatting and hope it doesn't change (as in Qrrbrbirlbel's solution). In the end, it's the form of the formatted label text on the page that determines whether or not it's safe to suppress a common prefix. So it's better to compare the final formatted text, rather than the counters.

  3. The above code suppresses common prefixes from all equations, not just subequations. E.g. if your equation numbers include section numbers, and eq1, eq2 and eq3 are all in section 1.2, then \cref{eq1,eq2,eq3} will produce eqs.~(1.2.1--3). This may or may not be what you want. If you only want to do this for subequations, you ought to be able to simply redefine the subequation range format, instead of the equation one ... except that due to the vagaries of amsmath's subequations implementation, there's no separate subequation type in cleveref! The main reason it doesn't exist is there's been no obvious need for it until now. Adding a new subequation type would require some minor hacking of cleveref's amsmath support (which anyway has to support subequations as a special case). If I add the crefstripprefix macro and examples in the next release, I'll probably add a new subequation type at the same time.

  4. I imagine a very similar solution should work with the subfigure references produced by the subfig package, which is something people occasionally ask about.



Borrowing Qrrbrbirlbel's example document, here's a MWE:

\documentclass{article}

\usepackage{amsmath}
\usepackage[colorlinks]{hyperref}
\usepackage{cleveref}


\makeatletter
\newcommand\crefstripprefix[2]{%
  \begingroup%
    \edef\@toksa{#1}%
    \edef\@toksb{#2}%
    \def\@accum{}%
    \@crefstripprefix%
    \@result%
  \endgroup}

\def\@crefstripprefix{%
  \let\@iterate\relax%
  \def\accum@flag{0}%
  \let\@tempc\@tempb%
  \cref@poptok{\@toksa}{\@tempa}%
  \cref@poptok{\@toksb}{\@tempb}%
  \ifx\@tempa\@tempb\relax%
    \def\@iterate{\@crefstripprefix}%
    \ifx\@accum\@empty\relax%
      \let\@accum\@tempb%
    \else%
      \ifcat\@tempb\@tempc\relax%
        \ifcat\@tempb a\relax%
          \def\accum@flag{1}%
        \else%
          \expandafter\chardef\expandafter\@tempa%
            \expandafter=\expandafter`\@tempb\relax%
          \ifnum\@tempa>`/\relax%
            \expandafter\ifnum\@tempb<`:\relax%
              \def\accum@flag{1}%
            \fi%
          \fi%
        \fi%
      \fi%
      \def\@tempa{1}%
      \ifx\accum@flag\@tempa%
        \edef\@accum{\@accum\@tempb}%
      \else%
        \let\@accum\@empty%
      \fi%
    \fi%
  \else%
    \ifcat\@tempb\@tempc\relax\else%
      \let\@accum\@empty%
    \fi%
    \edef\@result{\@accum\@tempb\@toksb}%
  \fi%
  \@iterate}

\def\cref@poptok#1#2{%
  \expandafter\expandafter\expandafter\def%
    \expandafter\expandafter\expandafter#2%
    \expandafter\expandafter\expandafter{%
      \expandafter\@cref@firsttok#1\@nil}%
  \expandafter\expandafter\expandafter\def%
    \expandafter\expandafter\expandafter#1%
    \expandafter\expandafter\expandafter{%
      \expandafter\@cref@poptok#1\@nil}}
\def\@cref@firsttok#1#2\@nil{#1}
\def\@cref@poptok#1#2\@nil{#2}
\makeatother


\crefrangelabelformat{equation}{(#3#1#4--#5\crefstripprefix{#1}{#2}#6)}


\numberwithin{equation}{subsection}
\def\ra{\hfill(\texttt{range})}% only for this example
\textwidth=.6\textwidth        % only for this example

\begin{document}


\section{A section}
\subsection{A subsection}

\Cref{eq1a,eq1b,eq1c,eq1d,eq1e,eq2a,eq2b,eq2c,eq2d,eq2e,eq3a,eq3b,eq3c,eq3d,eq3e}\\
\Cref{eq1,eq2,eq3}\\
\Cref{eq1,eq2}\\
\Cref{eq1,eq3}\\
\Crefrange{eq1a}{eq3d} \ra
\begin{subequations}\label{eq1}
  \begin{align}
    1+1=2    \label{eq1a} \\
    1-1=0    \label{eq1b} \\
    23+23=46 \label{eq1c} \\
    d+e=f    \label{eq1d} \\
    e+f=g    \label{eq1e}
  \end{align}
\end{subequations}

\noindent
\Cref{eq1a,eq1b,eq1c,eq1d,eq1e} \\ 
\Crefrange{eq1a}{eq1e} \ra
\begin{subequations}\label{eq2}
  \begin{align}
    1+1=2    \label{eq2a} \\
    1-1=0    \label{eq2b} \\
    23+23=46 \label{eq2c} \tag{*} \\
    d+e=f    \label{eq2d} \\
    e+f=g    \label{eq2e}
  \end{align}
\end{subequations}

\noindent
\Cref{eq2a,eq2b,eq2c,eq2d,eq2e} \\
\Crefrange{eq2a}{eq2e} \ra
\begin{subequations}\label{eq3}
  \begin{align}
    1+1=2    \label{eq3a} \\
    1-1=0    \label{eq3b} \\
    23+23=46 \label{eq3c} \\
    d+e=f    \label{eq3d} \\
    e+f=g    \label{eq3e} \tag{**}
  \end{align}
\end{subequations}

\noindent
\Cref{eq3a,eq3b,eq3c,eq3d,eq3e}\\
\Crefrange{eq3a}{eq3d} \ra
\end{document}



And here's the corresponding typeset output:

Typeset example document

Related Question