10

I am using the cleveref package and I am very happy with it. However, I encountered one problem I wasn't able to solve. I am probably just not combining the syntax correctly. This is highly connected to the question already asked, here: Crossreference in Ref Range [(1a-1e) to (1a-e)] I am sorry if this is already answered.

The above thread explains how to reference ranges of subequations (or floats) like 1a to e, rather than the default 1a to 1e. I would like to have the same feature for a pair of references combined by an "and", namely: 1a and b rather than the default 1a and 1b.

Here is a MWE:

\documentclass{book}

\usepackage{cleveref}
\usepackage{subfig}
\crefrangelabelformat{figure}{#3#1#4--#5\crefstripprefix{#1}{#2}#6}
\crefmultiformat{figure}{figs.~#2#1#3}{ and~#2#1#3}{, #2#1#3}{ and~#2#1#3}

\begin{document}
\begin{figure}
  \centering
  \subfloat[][]{\rule{2.cm}{2.cm}\label{subfig:1a}}
  \subfloat[][]{\rule{2.cm}{2.cm}\label{subfig:1b}}\\
  \subfloat[][]{\rule{2.cm}{2.cm}\label{subfig:1c}}
  \subfloat[][]{\rule{2.cm}{2.cm}\label{subfig:1d}}\\
  \caption{\label{fig:1}my figures}
\end{figure}

Referencing a range works as wanted and gives figs. 1a-b: \cref{subfig:1a,subfig:1b,subfig:1c,subfig:1d}.\\
But, referencing a pair gives \cref{subfig:1a,subfig:1b}, rather than the desired figs. 1a and b.\\ 

\end{document}

I think combining \crefstripprefix together with \crefmultiformat{figure} (which I use in the MWE to remove the "()") could give me the desired result. But I am not able to get the correct syntax to make this work, since I am pretty unfamiliar with the deep-down latex syntax.

user44532
  • 101

2 Answers2

4

In your definition of \crefmultiformat you want to use \crefrefstripprefix in the second argument using a value from the first argument. This can be achieved as follows:

\crefmultiformat{figure}{figs.~#2#1\xdef\mycreffirstarg{#1}#3}%
 { and~#2{\crefstripprefix{\mycreffirstarg}{#1}}#3}{, #2#1#3}{ and~#2#1#3}

Also you need to define \crefrangelabelformat in a similar way (update following comments).

Sample output

\documentclass{book}

\usepackage{cleveref} \usepackage{subfig}

\crefrangelabelformat{figure}{#3#1\xdef\mycreffirstarg{#1}#4--% #5\crefstripprefix{#1}{#2}#6} \crefmultiformat{figure}{figs.~#2#1\xdef\mycreffirstarg{#1}#3}% { and~#2{\crefstripprefix{\mycreffirstarg}{#1}}#3}% {, #2{\crefstripprefix{\mycreffirstarg}{#1}}#3}% { and~#2{\crefstripprefix{\mycreffirstarg}{#1}}#3} \crefrangemultiformat{figure}{figs.~#3#1#4--#5\crefstripprefix{#1}{#2}#6}% { and~#3#1#4--#5\crefstripprefix{#1}{#2}#6}% {, #3#1#4--#5\crefstripprefix{#1}{#2}#6}% { and~#3#1#4--#5\crefstripprefix{#1}{#2}#6}

\begin{document} \begin{figure} \centering \subfloat[][]{\rule{2.cm}{2.cm}\label{subfig:1a}} \subfloat[][]{\rule{2.cm}{2.cm}\label{subfig:1b}}\ \subfloat[][]{\rule{2.cm}{2.cm}\label{subfig:1c}} \subfloat[][]{\rule{2.cm}{2.cm}\label{subfig:1d}}\ \subfloat[][]{\rule{2.cm}{2.cm}\label{subfig:1e}} \caption{\label{fig:1}my figures} \end{figure}

\tracingmacros=1 Referencing a range works as wanted and gives figs.~1a--d: \cref{subfig:1a,subfig:1b,subfig:1c,subfig:1d}.

Gives figs.~1a--c and e: \cref{subfig:1a,subfig:1b,subfig:1c,subfig:1e}.

Gives figs.~1a, b, d and e: \cref{subfig:1a,subfig:1b,subfig:1d,subfig:1e}.

Also referencing a pair gives \cref{subfig:1a,subfig:1b}, which is then the desired figs.~1a and~b.

\end{document}

Andrew Swann
  • 95,762
  • For me this fails if there is a range: https://tex.stackexchange.com/questions/672267/cleveref-with-subcaption-using-crefmultiformat-and-crefstripprefix – Chachni Jan 19 '23 at 23:12
  • 1
    @Chachni I you code in that question you use \edef instead of \xdef. The latter is needed to make a global assignment. – Andrew Swann Jan 20 '23 at 07:35
  • Ok, thanks. I see the code in my question works with \xdef instead of \edef. But I then don't understand why your code fails when I add another subfloat \subfloat[][]{\rule{2.cm}{2.cm}\label{subfig:1e}}\ and reference to \cref{subfig:1a,subfig:1b,subfig:1c,subfig:1e} – Chachni Jan 20 '23 at 13:16
  • 1
    @Chachni Thanks for pointing out that combination. It turns out that in the abce case, the first part gets past to the range constructor, so this also needs to define the \mycreffirstarg macro. Code updated. – Andrew Swann Jan 20 '23 at 16:40
  • Thanks for the solution @AndrewSwann! – Chachni Jan 20 '23 at 21:14
2

Using the subcaption package instead of subfig will get you most of the way. subcaption provides a \subref command, which gives you only the subfigure index without the figure number.

\documentclass{article}
\usepackage{graphicx}
\usepackage{cleveref}
\usepackage{subcaption}
\begin{document}
\begin{figure}
  \centering
  \begin{subfigure}{0.2\textwidth}
  \includegraphics[width=\linewidth]{example-image-a}
  \caption{Image a}
  \label{subfig:foo}
  \end{subfigure}
  \begin{subfigure}{0.2\textwidth}
  \includegraphics[width=\linewidth]{example-image-b}
  \caption{Image b}
  \label{subfig:bar}
  \end{subfigure}\\
  \begin{subfigure}{0.2\textwidth}
  \includegraphics[width=\linewidth]{example-image-c}
  \caption{Image c}
  \label{subfig:baz}
  \end{subfigure}
  \begin{subfigure}{0.2\textwidth}
  \includegraphics[width=\linewidth]{example-image}
  \caption{Image d}
  \label{subfig:qux}
  \end{subfigure}
  \caption{\label{fig:1}my figures}
\end{figure}
Referencing a range works as wanted and gives figs.~\ref{subfig:foo}--\subref{subfig:bar}. There is also \cref{subfig:foo,subfig:bar,subfig:baz,subfig:qux}.
A pair can be referenced like figs.~\ref{subfig:foo} to \subref{subfig:baz}.
\end{document}

enter image description here

erik
  • 12,673
  • 1
    Of course, this workaround works, but the whole point of using cleveref is to avoid such manual specification of the names and labels. – Hugo Raguet Feb 20 '18 at 22:04
  • Surely hard-coding 1a-b is cheating, at least! Well, the rest undermines the point of cleveref, but this bit undermines the point of using the \label-\ref system to boot. – cfr Feb 21 '18 at 01:07
  • @HugoRaguet Yes, but I simply used the MWE provided by the OP and changed only the commands. I've edited the answer to remove the original hard-coded part as well. – erik Feb 21 '18 at 22:01
  • @erik: By manual specification, I was actually thinking of the "figs.", the "to" and the "\subref" parts. Otherwise, there is no use in using cleveref, as also mentioned by cfr. – Hugo Raguet Feb 22 '18 at 16:10