Get the "exact" page of a \ref command in .log or .aux files

This will write

\ref@page{<key>}{<page>}

in the .aux file for each \ref{<key>} command found in the document.

In the example case, you get

\ref@page{somefigure}{4}

which can be read by your external script.

\documentclass{article}

\usepackage{blindtext}

\usepackage{etoolbox}    
\usepackage{hyperref}

\makeatletter
\AtBeginDocument{%
  \renewcommand{\NR@setref}[1]{%
    \ref@page@write{#1}%
    \begingroup\@safe@activestrue\expandafter\endgroup
    \expandafter\NR@@setref\csname r@#1\endcsname
  }%
}
\newcommand{\ref@page@write}[1]{%
  \protected@write\@auxout{}{\string\ref@page{#1}{\thepage}}%
}
\newcommand{\ref@page}[2]{}
\makeatother

\begin{document}

\blindtext[10]

\clearpage

\ref{somefigure}

\section{First section}\label{firstsec}

\blindtext[50]


\begin{figure}
  \caption{Some figure}\label{somefigure}
\end{figure}

\blindtext[50]

\section{Second section}\label{secondsec}

\end{document}

This labels (!) the usage of \ref with the label refusage:\therefusage and extracts the page where this occurs with \getpagerefnumber (contained in refcount package, but loaded by hyperref anyway!)

  • Remember to compile twice to get the cross-references correct!
  • Do not manipulate the refusage counter!

\documentclass{article}

\usepackage{etoolbox}    
\usepackage{hyperref}

\newcounter{refusage}

\AtBeginDocument{\hypersetup{pageanchor=false}
\let\oldref\ref
\renewcommand{\ref}[1]{{\refstepcounter{refusage}\label{refusage:\therefusage}\oldref{#1}\typeout{RefsPagesInLog --> {#1} \getpagerefnumber{refusage:\therefusage}}}}
\robustify\ref
}

\usepackage{blindtext}

\begin{document}

\blindtext[10]

\clearpage

\ref{somefigure}

\section{First section}\label{firstsec}

\blindtext[50]


\begin{figure}
  \caption{Some figure}\label{somefigure}
\end{figure}

\blindtext[50]


\section{Second section}\label{secondsec}




\end{document}