라벨은 몇 번이나 참조되었으며 가장 많이 참조된 라벨은 무엇입니까?

라벨은 몇 번이나 참조되었으며 가장 많이 참조된 라벨은 무엇입니까?

LaTeX 문서가 주어지면 자동 방법을 사용하여 모든 레이블 중 어느 레이블이 가장 많이 참조되는지, 어느 레이블이 두 번째로 가장 많이 참조되는지 등을 알고 싶습니다. 명확하게 설명하기 위해 예를 들어 보겠습니다. 다음 문서가 있다고 가정해 보겠습니다.

\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}

이 경우 보고 싶은 목록은 다음과 같습니다.

  1. 작품:1

  2. 작품:3

  3. 작품:2

  4. 일:1

lm:1과 lm:2는 모두 두 번 참조되므로 허용되는 또 다른 목록은 다음과 같습니다.

  1. 작품:3

  2. 작품:1

  3. 작품:2

  4. 일: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

이런 종류의 응용 프로그램에서는 텍스트 파일을 구문 분석하는 스크립팅 언어를 사용하는 것이 더 쉽다는 것을 종종 알게 됩니다. 다음은 파일 이름이 지정된 Unix 도구의 예입니다.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{} 패턴과 일치하지만 한 줄에 한 번만 일치하므로 이전 명령이 사용되는 이유입니다. 후속 명령은 설명이 필요하지 않습니다.

라벨을 무시하려면 정규식을 더 구체적으로 만들거나 위의 출력을 필터링하면 됩니다.

관련 정보