Пользовательский стиль номеров для строк, которые \ref'ированы в листинговой среде

Пользовательский стиль номеров для строк, которые \ref'ированы в листинговой среде

Рассмотрим следующий MWE:

\documentclass{article}

\usepackage{tikz}

\usepackage{listings}

\lstset{%
  basicstyle =\ttfamily,
  language = Python,
  keywordstyle = \bfseries,
  commentstyle = \itshape,
  numbers = left,
  numberstyle = \tiny\sffamily,
  escapechar = |,
  gobble = 2,
}

\begin{document}

\begin{lstlisting}
  import numpy as np
  from matplotlib import pyplot as plt

  t = np.linspace(0, 1, 100) |\label{that-line}|
  plt.plot(t, t**2)
  plt.show() |\label{that-other-line}|
\end{lstlisting}

Please see line~\ref{that-line} and line~\ref{that-other-line}.

\end{document}

Текущий выход:

листинг-вывод

Я бы хотел, чтобы номера, соответствующие строкам, которые \ref"редактируются" (строки 4 и 6 в моем MWE), имели определенный стиль (например, набранные внутри квадрата или круга, в идеале произвольный tikzкод). Например:

с-кругами

решение1

Адаптация моего ответа наКак добавить реферальные пронумерованные круговые символы в списки кодов?:

\documentclass{article}

\usepackage{tikz}

\usepackage{listings}

\usepackage{circledsteps}
\pgfkeys{/csteps/outer color=orange}

\lstset{%
  basicstyle =\ttfamily,
  language = Python,
  keywordstyle = \bfseries,
  commentstyle = \itshape,
  numbers = left,
  numberstyle = \tiny\sffamily,
  escapechar = |,
  gobble = 2,
}
\makeatletter
\newcommand*\CircleNext{%
  \lst@AddToHook{OnNewLine}{%
   \def\thelstnumber{\Circled{\arabic{lstnumber}}\hskip-2.1pt}}%
}
\def\circlabel#1{
  \lst@AddToHook{OnNewLine}{%
   \def\thelstnumber{\arabic{lstnumber}}}%
  \label{#1}%
}
\makeatother
\begin{document}

\begin{lstlisting}
  import numpy as np
  from matplotlib import pyplot as plt
  |\CircleNext|
  t = np.linspace(0, 1, 100) |\circlabel{that-line}|
  plt.plot(t, t**2)|\CircleNext|
  plt.show() |\circlabel{that-other-line}|
\end{lstlisting}

Please see line~\ref{that-line} and line~\ref{that-other-line}.

\end{document}

введите описание изображения здесь


Ниже приведен вариант, которому не нужны \CircleNextкоманды. Он работает, записывая дополнительную метку, состоящую из формата listing number-line number. Вместо OnNewLineхука для листингов теперь команда \thelstnumber(которая печатает номер строки для каждой строки) изменена для проверки того, существует ли метка для текущего листинга и текущей строки или нет. Если метка существует, то номер обводится кружком (при следующем запуске).

К сожалению, \thelstnumberтакже записывается в файл .aux как текст метки, который считывается \ref. Чтобы предотвратить появление обведенных цифр в основном тексте, решением является временное переопределение, \thelstnumberчтобы быть просто числом при записи обычного \label.

Остальная часть кода — это бухгалтерский учет для создания и увеличения счетчика объявлений, который используется в новой метке.

Код:

\documentclass{article}
\usepackage{tikz}
\newcounter{lstprefix}
\setcounter{lstprefix}{0}
\usepackage{listings}
\AddToHook{env/lstlisting/before}{\stepcounter{lstprefix}}

\usepackage{circledsteps}
\pgfkeys{/csteps/outer color=orange}

\lstset{%
  basicstyle =\ttfamily,
  language = Python,
  keywordstyle = \bfseries,
  commentstyle = \itshape,
  numbers = left,
  numberstyle = \tiny\sffamily,
  escapechar = |,
  gobble = 2,
}
\makeatletter
\def\thelstnumber{%
\ifcsname r@lst\thelstprefix-\arabic{lstnumber}\endcsname%
\Circled{\arabic{lstnumber}}\hskip-2.1pt%
\else%
\arabic{lstnumber}%
\fi%
}
\def\circlabel#1{
  {\def\thelstnumber{\arabic{lstnumber}}\label{#1}}%
  \label{lst\thelstprefix-\arabic{lstnumber}}%
}
\makeatother
\begin{document}

\begin{lstlisting}
  import numpy as np
  from matplotlib import pyplot as plt
  
  t = np.linspace(0, 1, 100) |\circlabel{that-line}|
  plt.plot(t, t**2)
  plt.show() |\circlabel{that-other-line}|
\end{lstlisting}

Please see line~\ref{that-line} and line~\ref{that-other-line}.

\begin{lstlisting}
  import numpy as np
  from matplotlib import pyplot as plt |\circlabel{import-line}|
  
  t = np.linspace(0, 1, 100)
  plt.plot(t, t**2)
  plt.show()
\end{lstlisting}
See also line \ref{import-line}.
\end{document}

Это создаст следующий .aux-файл:

\relax 
\newlabel{that-line}{{4}{1}}
\newlabel{lst1-4}{{\Circled {4}\hskip -2.1pt}{1}}
\newlabel{that-other-line}{{6}{1}}
\newlabel{lst1-6}{{\Circled {6}\hskip -2.1pt}{1}}
\newlabel{import-line}{{2}{1}}
\newlabel{lst2-2}{{\Circled {2}\hskip -2.1pt}{1}}
\gdef \@abspage@last{1}

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