
LaTeX 文書が与えられた場合、すべてのラベルのうちどれが最も参照されているか、どれが 2 番目に参照されているかなどを自動的に知る方法を使用したいと思います。わかりやすくするために例を挙げます。次のような文書があるとします。
\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}
この場合、私が見たいリストは次のようになります。
lm:1
文字:3
文字:2
1:1 番目
lm:1 と lm:2 は両方とも 2 回参照されるため、許容される別のリストは次のようになります。
文字:3
lm:1
文字:2
1:1 番目
考えられるすべてのリストは必要ありません。そのうちの 1 つで十分です。
編集: このようなリストを作成する過程で、特定のプレフィックスで始まるすべてのラベルを無視したい場合はどうすればよいでしょうか。前の例で「lm」で始まるすべてのラベルを無視するとします。その場合、望ましい出力は次のようになります。
- 1:1 番目
答え1
方法は次のとおりです:
\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}
答え2
この種のアプリケーションでは、テキストファイルを解析するスクリプト言語を使用する方が簡単だと私はよく思います。以下は、ファイル名がdoc.tex
sed "s:\}:\}\n:g" doc.tex |\
sed -rn "s:.*ref\{(.*)\}.*:\1:p" |\
sort | uniq --count
この出力は
2 lm:1
1 lm:2
2 lm:3
これをパイプでソートすると、sort -r
最初の sed コマンドは } の後に改行を挿入し、次のコマンドは \ref{} パターンに一致しますが、1 行につき 1 回だけなので、前のコマンドが使用されています。後続のコマンドは説明不要です。
ラベルを無視するには、正規表現をより具体的にするか、上記の出力をフィルタリングします。