
Dado un documento LaTeX, me gustaría usar un método automático para saber cuál de todas las etiquetas es la más referenciada, cuál es la segunda más referenciada y así sucesivamente. Te daré un ejemplo para que quede claro. Supongamos que tenemos este documento:
\documentclass{article}
\usepackage{amsthm}
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}{Lemma}
\begin{document}
\begin{lemma}
\label{lm:1} Content of the first lemma.
\end{lemma}
Using lemma~\ref{lm:1} we have the following:
\begin{lemma}
\label{lm:2} Content of the second lemma.
\end{lemma}
Another consequence of lemma~\ref{lm:3} is the following:
\begin{lemma}
\label{lm:3} Content of the third lemma.
\end{lemma}
Finally, combining lemmas~\ref{lm:1},~\ref{lm:2},~\ref{lm:3} we have the following:
\begin{theorem}
\label{th:1}
\end{theorem}
\end{document}
En este caso, la lista que me gustaría ver es la siguiente:
película: 1
película:3
película: 2
es:1
Dado que se hace referencia a lm:1 y lm:2 dos veces, otra lista aceptable es la siguiente:
película:3
película: 1
película: 2
es:1
No necesito todas las listas posibles, una de ellas es suficiente.
Editar: ¿qué pasa si, en el proceso de hacer dicha lista, queremos ignorar todas las etiquetas que comienzan con un prefijo específico? Supongamos que queremos ignorar todas las etiquetas que comienzan con "lm" en el ejemplo anterior. Entonces el resultado deseado sería el siguiente:
- es:1
Respuesta1
Aquí hay una manera:
\documentclass{article}
\usepackage{amsthm}
\usepackage{pgffor}
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}{Lemma}
\let\oldref\ref
\let\oldlabel\label
\newcounter{labls}
\makeatletter
\def\ref#1{%
\@ifundefined{refrs@#1}{\xdef\temp{1}\expandafter\expandafter\expandafter\global\expandafter\let\csname refrs@#1\endcsname\temp}{%
\xdef\temp{\expandafter\expandafter\expandafter\number\expandafter\numexpr\csname refrs@#1\endcsname+1\relax}\expandafter\expandafter\expandafter\global\expandafter\let\csname refrs@#1\endcsname\temp\oldref{#1}}%
}
\def\label#1{%
\@ifundefined{labls@#1}
{\stepcounter{labls}}%
{Error:Already Defined Label: #1}
\@ifundefined{refrs@#1}{\xdef\temp{0}\expandafter\expandafter\expandafter\global\expandafter\let\csname refrs@#1\endcsname\temp}{\relax}%
\xdef\temp{#1}%
\expandafter\expandafter\expandafter\global\expandafter\let\csname LabelName\arabic{labls}\endcsname\temp\oldlabel{#1}%
}
\makeatother
\newcommand\reflist[1][]{%
\foreach\i in {1,...,\value{labls}}{%
\expandafter\expandafter\expandafter\global\expandafter\let\csname printed\i\endcsname\undefined%
}%
\foreach\k in {1,...,\value{labls}}{%
\xdef\maxRefs{-1}%
\xdef\printLabelNum{\k}%
\xdef\printLabelName{\csname LabelName\k\endcsname}%
\foreach \l in {1,...,\value{labls}}{%
\xdef\CurLabel{\csname LabelName\l\endcsname}%
\xdef\CurNum{\l}%
\xdef\CurRefs{\csname refrs@\CurLabel\endcsname}%
\ifnum\CurRefs > \maxRefs
\ifcsname printed\l\endcsname
\relax
\else
\xdef\maxRefs{\CurRefs}%
\xdef\printNum{\l}%
\fi
\fi
}%
{\bfseries \k)\csname LabelName\printNum\endcsname\xdef\t{#1}\ifx\t\empty\relax\else:~\maxRefs\fi\ifnum\k<\value{labls}\\\fi}%
\expandafter\expandafter\expandafter\global\expandafter\let\csname printed\printNum\endcsname\maxRefs%
}%
}
\begin{document}
\begin{lemma}
\label{lm:1} Content of the first lemma.
\end{lemma}
Using lemma~\ref{lm:1} we have the following:
\begin{lemma}
\label{lm:2} Content of the second lemma.
\end{lemma}
Another consequence of lemma~\ref{lm:3} is the following:
\begin{lemma}
\label{lm:3} Content of the third lemma.
\end{lemma}
Finally, combining lemmas~\ref{lm:1},~\ref{lm:2},~\ref{lm:3} we have the following:
\begin{theorem}
\label{th:1}
\end{theorem}
\noindent\reflist\vspace{1cm}
%You may add a non empty optional argument to print the appearances
\noindent\reflist[ ]
\end{document}
Respuesta2
Para este tipo de aplicaciones, a menudo me resulta más fácil utilizar un lenguaje de programación que analice el archivo de texto. Aquí hay un ejemplo con herramientas Unix, donde su archivo se llamadoc.tex
sed "s:\}:\}\n:g" doc.tex |\
sed -rn "s:.*ref\{(.*)\}.*:\1:p" |\
sort | uniq --count
Esto produce
2 lm:1
1 lm:2
2 lm:3
Que luego puedes ordenar conectándolo asort -r
El primer comando sed inserta una nueva línea después de }, el siguiente comando coincide con el patrón \ref{}, pero solo una vez por línea, por eso se usa el comando anterior. Los comandos siguientes se explican por sí mismos.
Para ignorar las etiquetas, puede hacer que la expresión regular sea más específica o filtrar la salida anterior.