
Considere el siguiente 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}
La salida actual es:
Me gustaría que los números correspondientes a las líneas escritas \ref
(es decir, las líneas 4 y 6 en mi MWE) tuvieran un estilo específico (por ejemplo, escritos dentro de un cuadrado o un círculo, idealmente tikz
código arbitrario). Por ejemplo:
Respuesta1
Una adaptación de mi respuesta en¿Cómo agregar símbolos de círculos numerados referenciables a listados de códigos?:
\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}
Debajo de una variante que no necesita los \CircleNext
comandos. Funciona escribiendo una etiqueta adicional que consta del formato listing number-line number
. En lugar de un OnNewLine
enlace para listados, ahora el comando \thelstnumber
(que imprime el número de línea para cada línea) se modifica para verificar si la etiqueta para el listado actual y la línea actual existen o no. Si la etiqueta existe, el número se rodea con un círculo (en la siguiente ejecución).
Lamentablemente, \thelstnumber
también se escribe en el archivo .aux como texto de etiqueta que lee \ref
. Para evitar números encerrados en un círculo en el texto principal, una solución es redefinir temporalmente \thelstnumber
para que sea solo el número al escribir el texto normal \label
.
El resto del código es contabilidad para crear e incrementar el contador de listados que se utiliza en la nueva etiqueta.
Código:
\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}
Esto crea el siguiente archivo .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}