Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to export the page numbers of all the inner references of my document. How can one achieve this? Equivalently, how can we export the section/chapter number of all the inner references?

For external references of the bibliography (I use bibtex), using the \backref command creates a .brf file which contains this information.


Edit: By inner references, I mean references to a label defined by \label and referred by \ref. Consider for instance, the minimal example:

\documentclass{article}
\begin{document}

\section{One}
Here\label{here}

\newpage
\section{Two}

\newpage
\section{Three}
Here is \ref{here}.
\end{document}

I would like to retrieve that there is an inner reference from page 3 (Section 3) to page 1 (Section 1).

share|improve this question
1  
This information is stored in the .aux file, together with some other stuff, but it's all there. –  Werner Mar 21 '13 at 14:04
    
I see \newlabel commands that creates the end-points of the inner references, but not the starting points of the references I made. –  wwjoze Mar 21 '13 at 14:10
    
What do you mean with "export the page numbers"? May you please add some more information? –  egreg Mar 21 '13 at 14:41
    
not sure i understand this exactly. is what you want the chapter/section location where every \ref or \eqref appears? –  barbara beeton Mar 21 '13 at 14:42
    
@egreg: I added an example. –  wwjoze Mar 21 '13 at 14:50
show 2 more comments

1 Answer

up vote 5 down vote accepted

This is not a complete solution as it is not clear to me how you want to actually use the gathered information, but it should give you some starting pointers how to obtain it.

\documentclass{article}

\makeatletter
\def\ref#1{\expandafter\@setref\csname r@#1\endcsname\@firstoftwo{#1}%
% addition
   \protected@write\@auxout{}%
         {\string\usedlabel{#1}{\thepage}}}
\def\pageref#1{\expandafter\@setref\csname r@#1\endcsname
                                   \@secondoftwo{#1}%
% addition
      \protected@write\@auxout{}%
         {\string\usedpagelabel{#1}{\thepage}}}

\def\usedlabel#1#2{\typeout{ref #1 on page #2}}
\def\usedpagelabel#1#2{\typeout{pageref #1 on page #2}}
\makeatother

\begin{document}

\section{A}\label{A}

text\label{B} see section~\ref{A}

\newpage

text referencing page~\pageref{B} in section~\ref{A}

\end{document}

In essense this changes \ref and \pageref to make a note in the .aux file looking like this:

\usedlabel{A}{1}
\usedpagelabel{B}{2}

I defined those commands to do a typeout, but anything is possible. Notice that the aux file is read in twice, once at the beginning and once at the end, so further work is necessary. Also not that in this simple approach it doesn't work with any packages that modify \ref in some way.

As a result of the above you get:

ref A on page 1
pageref B on page 2
ref A on page 2

on the screen and in the log.

Update

I forgot to mention that patching \ref of course only works as long as one isn't using some package that modifies this command as well. So one example where this breaks is the hyperref package, that for good reasons provides its own (and completely different) implementation of \ref, so that the above modification is simply never used.

Looking quickly into hyperref code, the most likely candidate for hooking into seems to be \T@ref but I didn't do an exhaustive check, this may not be the best approach (and it probably doesn't work with all options that hyperref offers). Anyway, for me it worked:

\usepackage{hyperref}

\makeatletter
\AtBeginDocument{%
  \def\T@ref#1{%
     \protected@write\@auxout{}{\string\usedlabel{#1}{\thepage}}%
      \Hy@safe@activestrue
      \expandafter\@setref\csname r@#1\endcsname\@firstoffive{#1}%
      \Hy@safe@activesfalse
    }%
    \def\T@pageref#1{%
      \protected@write\@auxout{}{\string\usedpagelabel{#1}{\thepage}}
      \Hy@safe@activestrue
      \expandafter\@setref\csname r@#1\endcsname\@secondoffive{#1}%
      \Hy@safe@activesfalse
    }%
}
share|improve this answer
    
Thanks, you found the way to write exactly the information to the .aux file. –  wwjoze Mar 21 '13 at 16:55
    
@wwjoze having written some of it an being involved with it for 20+ year kind of helps :-) –  Frank Mittelbach Mar 21 '13 at 17:26
    
This does not seem to work when I load the hyperref package. Do you know why? –  wwjoze Mar 21 '13 at 21:54
    
@wwjoze yes, forgot to mention that redefinitions of commands of course only work as long as not something else is trying to do the same. This is why I said this is not a complete solution only some pointers how to work up a solution. Updated the answer to show one way to make it work with hyperref –  Frank Mittelbach Mar 22 '13 at 8:11
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.