Сколько раз упоминался тот или иной лейбл и какой из них упоминается чаще всего?

Сколько раз упоминался тот или иной лейбл и какой из них упоминается чаще всего?

Учитывая документ 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. th:1

Поскольку lm:1 и lm:2 упоминаются дважды, то допустимым списком является следующий:

  1. лм:3

  2. лм:1

  3. лм:2

  4. th:1

Мне не нужны все возможные списки, достаточно одного из них.

Редактировать: что, если в процессе создания такого списка мы хотим игнорировать каждую метку, начинающуюся с определенного префикса? Предположим, мы хотим игнорировать каждую метку, начинающуюся с "lm" в предыдущем примере. Тогда желаемый вывод будет следующим:

  1. th: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{}, но только один раз на строку, поэтому и используется предыдущая команда. Последующие команды не требуют пояснений.

Чтобы игнорировать метки, вы можете либо сделать регулярное выражение более конкретным, либо отфильтровать вывод выше.

Связанный контент