使用 cleveref 使 refcheck 工作

使用 cleveref 使 refcheck 工作

似乎refcheck无法识别 cleveref 所作的引用:

\documentclass{article}
\usepackage{amsmath}
\usepackage{cleveref}
\usepackage{refcheck}

\begin{document}
\begin{align}
  a & = b \label{eq:a} \\
  c & = d \label{eq:b}
\end{align}

See~\eqref{eq:a}, \cref{eq:b}.

\begin{figure}
  \caption{Figure 1}
  \label{fig:a}
\end{figure}
\begin{figure}
  \caption{Figure 2}
  \label{fig:b}
\end{figure}

See Figure~\ref{fig:a}, \cref{fig:b}.

\end{document}

此处,refcheck标记eq:bfig:b为未引用。

  1. 有没有办法让这两个包一起工作?
  2. 或者,是否有效果更好的替代方案?
  3. 如果对 1) 的回答是肯定的,那么这可以实现吗\crefrange

答案1

refcheck不知道\cref\Cref。我们可以添加一个宏,让包知道其他参考命令:

\documentclass{article}
\usepackage{amsmath}
\usepackage{cleveref}
\usepackage{refcheck}

%%% Infrastructure    
\makeatletter
\newcommand{\refcheckize}[1]{%
  \expandafter\let\csname @@\string#1\endcsname#1%
  \expandafter\DeclareRobustCommand\csname relax\string#1\endcsname[1]{%
    \csname @@\string#1\endcsname{##1}\wrtusdrf{##1}}%
  \expandafter\let\expandafter#1\csname relax\string#1\endcsname
}
\makeatother
%%%

%%% Now we add the reference commands we want refcheck to be aware of
\refcheckize{\cref}
\refcheckize{\Cref}

\begin{document}
\begin{align}
  a & = b \label{eq:a} \\
  c & = d \label{eq:b}
\end{align}

See~\eqref{eq:a}, \cref{eq:b}.

\begin{figure}
  \caption{Figure 1}
  \label{fig:a}
\end{figure}
\begin{figure}
  \caption{Figure 2}
  \label{fig:b}
\end{figure}

See Figure~\ref{fig:a}, \Cref{fig:b}.

\end{document}

在此处输入图片描述

答案2

我遇到了同样的问题,发现扩展 egreg 的答案来处理诸如\crefrange{eq1}{eq2}和之类的额外情况相对简单\cref{eq1,eq2,eq4}

\makeatletter
\newcommand{\refcheckize}[1]{%
  \expandafter\let\csname @@\string#1\endcsname#1%
  \expandafter\DeclareRobustCommand\csname relax\string#1\endcsname[1]{%
    \csname @@\string#1\endcsname{##1}\@for\@temp:=##1\do{\wrtusdrf{\@temp}\wrtusdrf{{\@temp}}}}%
  \expandafter\let\expandafter#1\csname relax\string#1\endcsname
}
\newcommand{\refcheckizetwo}[1]{%
  \expandafter\let\csname @@\string#1\endcsname#1%
  \expandafter\DeclareRobustCommand\csname relax\string#1\endcsname[2]{%
    \csname @@\string#1\endcsname{##1}{##2}\wrtusdrf{##1}\wrtusdrf{{##1}}\wrtusdrf{##2}\wrtusdrf{{##2}}}%
  \expandafter\let\expandafter#1\csname relax\string#1\endcsname
}
\makeatother

\refcheckize{\cref}
\refcheckize{\Cref}
\refcheckizetwo{\crefrange}
\refcheckizetwo{\Crefrange}

最初的解决方案归功于 egreg。

2016年编辑:

我不知道为什么,但这在某个时候对我来说已经停止工作了。我又开始收到很多这样的错误:

Package refcheck Warning: Unused label `{eq:objective}' on input line 30.

无论出于什么原因(可能是软件包之间奇怪的交互),refcheck 都期望有一对额外的花括号。也就是说,它期望\label{eq:objective}与 配对\wrtusdrf{{eq:objective}},但\refcheckize命令只生成\wrtusdrf{eq:objective}

为了解决这个问题,我现在在宏中添加了匹配\wrtusdrf{{...}}\wrtusdrf{...}只要您不单独使用花括号来区分标签(请不要这样做),这就不会产生任何负面影响。

答案3

我最终使用了一个小的 shell 脚本来查找未引用的标签。当然,这有一些缺点,但在我的案例中效果很好(文档有数百页):

# Helper function to find unreferenced labels, since the chkltex tool and the refcheck package do not support cleveref
# Note: this could show false positives sometimes
echo "Checking for unreferenced labels...";
labels=$(grep -Eo '^[\s]*[^%]+.*label{[^}]+}' $_dir_sources/*.tex|sed -Ee "s/^.*{(.*)}/\1/g")
for label in $labels; do
  found=$(grep -E "ref{[^}]*$label" $_dir_sources/*.tex)
  if [[ -z "$found" ]]; then
    echo "Label '$label' not referenced?";
  fi
done

答案4

Alex 的答案一开始对我来说不起作用(sed 发出错误“char 14:{} 的内容无效”)。我不是正则表达式专家,所以我最终重写了查找标签的行。到目前为止,这适用于任何类型的参考:

echo "Checking for unreferenced labels...";
# find all label names
labels=$(grep -oP 'label{[^}]+}' *.tex | sed -e "s/^.*label{//" -e "s/}//")
#echo $labels
# for each label, see if it appears in a ref command (\ref, \cref and others)
for label in $labels; do
   found=$(grep -E "ref{[^}]*$label" *.tex)
if [[ -z "$found" ]]; then
    echo "Label '$label' not referenced";
fi
done

相关内容