Cleveref 的 \cpageref 带有一系列标签

Cleveref 的 \cpageref 带有一系列标签

cleveref\cpageref当收到三个或更多跨越多个页面的标签时,似乎会出现问题。发生这种情况时,会\cpageref打印第一个和最后一个标签(参数),而不是它应该打印的页面,并且不会发出任何警告。

这个问题早在两年前就出现在这个网站上(见\cpageref 结果不正确,其中包含跨页面范围的多个(3+)引用使用 cleveref 进行多重引用: \cpageref 压缩是否存在错误,或者我使用方式是否错误?,但都没有得到任何答案)。此外,这个问题也已报告给上游,但至今尚未得到处理(该问题仍影响“版本 0.21.5(预发布版本)”,可从https://www.dr-qubit.org/cleveref.html)。

鉴于此,我也受到了这个问题的影响,并尝试了自己的想法。思考我理解这个问题,并有解决办法。但是,我的 TeX-fu 相当有限(说句客气话),所以我对此不确定。所以,我的问题是向更有经验的用户寻求确认。

以下 MWE 可以重现此问题本身:

\documentclass{article}

\usepackage{cleveref}

\begin{document}

See \cref{tab1,tab2,tab3,tab4} on \cpageref{tab1,tab2,tab3,tab4}.

\clearpage{}

\begin{table}
  \caption{Table 1}
  \label{tab1}
  \begin{tabular}{cc}
    1 & 2 \\
    3 & 4 \\
  \end{tabular}
\end{table}

\begin{table}
  \caption{Table 2}
  \label{tab2}
  \begin{tabular}{cc}
    1 & 2 \\
    3 & 4 \\
  \end{tabular}
\end{table}

\clearpage{}

\begin{table}
  \caption{Table 3}
  \label{tab3}
  \begin{tabular}{cc}
    1 & 2 \\
    3 & 4 \\
  \end{tabular}
\end{table}

\begin{table}
  \caption{Table 4}
  \label{tab4}
  \begin{tabular}{cc}
    1 & 2 \\
    3 & 4 \\
  \end{tabular}
\end{table}

\end{document}

编译时没有错误或警告,并产生:

在此处输入图片描述

现在,我认为问题出在哪里。在 的定义中\@cref,在某一点,cleveref执行以下操作:

      \ifnum\count@consecutive=1\relax%
        \edef\@tempa{{\@beginref}{\@pos}}%
        \csname @set\cref@variant\expandafter\endcsname\@tempa%
      \else%
        \edef\@tempa{{\@beginref}{\@endref}{\@pos}}%
        \csname @set\cref@variant range\expandafter\endcsname\@tempa%
      \fi%

(我这里使用的是当前的 TeXLive,我的cleveref.sty有日期2018/03/27和版本0.21.4,这发生在第 1021 行到 1027 行)。

此时\@cref正在循环遍历一个连续标签子组。\cref@variant是面向用户的宏的名称cleveref,它作为的第一个参数接收\@cref(例如cref,,,等)。因此,这是调用一组名称为或的Cref宏。cpageref\@set<variant>\@set<variant>range

我们确实发现其中大部分在以下位置有明确定义cleveref.sty\@setcref\@setCref以及\@setlabelcref第 1044-1046 行;\@setcrefrange\@setCrefrange以及\@setlabelcrefrange第 1072-1074 行;\@setcpageref\@setCpageref以及\@setlabelcpageref第 1087-1089 行(还有其他的)。

但是,我找不到\@setcpagerefrange\@setCpagerefrange\@setlabelcpagerefrange,我认为这就是缺失的。此外,尽管所有相关问题均未提及\Cpageref\labelcpageref,但这一观察表明它们会以与 相同的方式失败\cpageref。事实上,它们确实会失败。

在上面的 MWE 中提供它们如下:

\makeatletter
\newcommand*{\@setcpagerefrange}[3]{%
  \@@setcpagerefrange{#1}{#2}{cref}{#3}}
\newcommand*{\@setCpagerefrange}[3]{%
  \@@setcpagerefrange{#1}{#2}{Cref}{#3}}
\newcommand*{\@setlabelcpagerefrange}[3]{%
  \@@setcpagerefrange{#1}{#2}{labelcref}{#3}}
\makeatother

(请注意,中的参数顺序\@@setcpagerefrange与其兄弟不同)。

现在将给出我们预期的结果:

在此处输入图片描述

那么,这个诊断和修复正确吗?

答案1

好吧,为了不让这个问题悬而未决,据我所知,问题确实是 OP 中诊断出来的。已尝试联系维护人员并提出建议的修复方案。

\documentclass{article}

\usepackage{cleveref}

\makeatletter
\newcommand*{\@setcpagerefrange}[3]{%
  \@@setcpagerefrange{#1}{#2}{cref}{#3}}
\newcommand*{\@setCpagerefrange}[3]{%
  \@@setcpagerefrange{#1}{#2}{Cref}{#3}}
\newcommand*{\@setlabelcpagerefrange}[3]{%
  \@@setcpagerefrange{#1}{#2}{labelcref}{#3}}
\makeatother

\begin{document}

See \cref{tab1,tab2,tab3,tab4} on \cpageref{tab1,tab2,tab3,tab4}.

\clearpage{}

\begin{table}
  \caption{Table 1}
  \label{tab1}
  \begin{tabular}{cc}
    1 & 2 \\
    3 & 4 \\
  \end{tabular}
\end{table}

\begin{table}
  \caption{Table 2}
  \label{tab2}
  \begin{tabular}{cc}
    1 & 2 \\
    3 & 4 \\
  \end{tabular}
\end{table}

\clearpage{}

\begin{table}
  \caption{Table 3}
  \label{tab3}
  \begin{tabular}{cc}
    1 & 2 \\
    3 & 4 \\
  \end{tabular}
\end{table}

\begin{table}
  \caption{Table 4}
  \label{tab4}
  \begin{tabular}{cc}
    1 & 2 \\
    3 & 4 \\
  \end{tabular}
\end{table}

\end{document}

在此处输入图片描述

相关内容