[Tex/LaTex] conflict refcheck/subcaption packages for label with underscores

hyperrefincompatibilityrefchecksubcaption

I found a conflict between the hyperref/subcaption/refcheck packages.

I was using figures with subfigures and subcaptions, enabling the hyperref package for cross referencing in the document without any problems so far.

When I included the refcheck package to check for unused bib items and cross references, it causes problems if I cross link a subfigure using the \subref{...} command to a figure label with underscores, eg. \label{fig:A_A_A}, in the caption of the figure environment (see MWE with \subref{fig:A_A_A})

It complaings about missing $ as if it would like to put the underscores in math mode.

Missing $ inserted [...]

Any ideas how to fix this conflict?


EDIT:
If I load the refcheck package before the other two packages, the document compiles fine, but then actually the refcheck package functionality is lost, i.e. no warnings about unused references.


MWE.tex

\documentclass[a4paper,11pt]{report}

\usepackage{hyperref}          %Make hyperlinks available
\usepackage{subcaption}        %Make subfigures available

%commenting out this package restores the working version   
\usepackage{refcheck}          %Warn for unused bibitems

\begin{document}
Figure \ref{fig:A_A} %no problem with the reference here

\begin{figure}[bhpt!]
  \centering
  \begin{subfigure}{0.45\textwidth}
    \rule{3cm}{3cm} %dummy for a grafic
    \caption{A subcaption}
    \label{fig:A_A_A} %problematic label for subfigure with underscores
  \end{subfigure}  
  \caption[A short caption]%
          %caption without the subref works without any problems
          %{A long caption without a subref}
          %caption with subref for the label with underscores causes problem
          {A long caption with a subref with underscores \subref{fig:A_A_A}}
  \label{fig:A_A} %no problem with label for figure with underscores
\end{figure}

\end{document}

Best Answer

The problem is that refcheck isn't really compatible with hyperref, because refcheck doesn't respect hyperref's starred version of the \ref macro (this could be considered a bug with refcheck, and should probably be reported to the package maintainer).

When you do \subref{fig:A_A_A} it expands to something like this:

\hyperref[fig:A_A_A]{%
  \begingroup
    \caption@setoptions{sub}%
    \subcaption@reffmt\p@subref{%
      \ref*{sub@fig:A_A_A}%
    }%
  \endgroup
}

Note the use of \ref* here. It's because hyperref overrides the regular \ref to use \hyperref to produce a hyperlink. hyperref therefore also provides \ref* as an alternative that does the same as \ref, except that it doesn't generate a hyperlink (you can think of \ref{A} as the same as \hyperref[A]{\ref*{A}}). In the case above, the reference text and the link use different reference labels, hence the use of \ref*.

Because refcheck overrides \ref without regards to hyperref's \ref* macro, you basically lose the "capabilities" of the starred version. Hence \ref*{A} will now expand as if you'd written \ref{*}{A}.

In the case of \ref*{sub@fig:A_A_A}, you hence get \ref{*}{sub@fig:A_A_A}, which clearly won't work very well. You'll get a warning

LaTeX Warning: Reference `*' on page 1 undefined on input line XY

and since {sub@fig:A_A_A} is not an argument to the \ref macro, you'll get the normal "underscore error" that you saw.

EDIT

As a quick-fix, you could use something like this in your preamble:

\makeatletter

\AtBeginDocument{%
  \@ifpackageloaded{refcheck}{%
    \@ifundefined{hyperref}{}{%
      \let\T@ref@orig\T@ref
      \def\T@ref#1{\T@ref@orig{#1}\wrtusdrf{#1}}%
      \let\@refstar@orig\@refstar
      \def\@refstar#1{\@refstar@orig{#1}\wrtusdrf{#1}}%
      \DeclareRobustCommand\ref{\@ifstar\@refstar\T@ref}%
    }%
  }{}%
}

\makeatother

This code restores hyperref's definition of \ref, and patches the \T@ref (the non-starred version) and the \@refstar (the starred version) macros that hyperref uses.