Ich muss ein Skript schreiben, elisp
das mich warnt, wenn ein Float vor der Seite erscheint, auf der dieser Float zum ersten Mal referenziert wird. Aus der .aux
Datei kann ich das Label, die Nummer und die Seitenzahl des Floats extrahieren. Aber ich muss die genaue Seite ermitteln, auf der jeder \ref
Befehl platziert ist. Ich habe Folgendes versucht:
\AtBeginDocument{\hypersetup{pageanchor=false}
\let\oldref\ref
\renewcommand{\ref}[1]{{\oldref{#1}\typeout{RefsPagesInLog --> {#1} \thepage}}}
So wird beispielsweise \ref{fig:2}
in den .tex
Dateien Folgendes gedruckt:
RefsPagesInLog --> {fig:2} 29
in der Protokolldatei. Es funktioniert fast, schlägt aber manchmal fehl. In sehr wenigen Fällen druckt es eine falsche Seitenzahl in die Protokolldatei, sodass mein Skript fehlschlägt.
Gibt es einen Trick, um das gleiche Ziel zu erreichen?
Die Daten, die ich brauche, sind das Etikett, \ref
auf das verwiesen wird, und die „genaue“ Seite, auf der die Verweise erscheinen.
Antwort1
Dies wird schreiben
\ref@page{<key>}{<page>}
in der .aux
Datei für jeden \ref{<key>}
im Dokument gefundenen Befehl.
Im Beispielfall erhalten Sie
\ref@page{somefigure}{4}
die von Ihrem externen Skript gelesen werden können.
\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}
Antwort2
Dieses kennzeichnet (!) die Verwendung von \ref
mit dem Label refusage:\therefusage
und extrahiert die Seite, bei der dies vorkommt \getpagerefnumber
(im Paket enthalten refcount
, aber trotzdem von geladen hyperref
!)
- Denken Sie daran, zweimal zu kompilieren, um die Querverweise richtig zu machen!
- Manipulieren Sie den Zähler nicht
refusage
!
\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}