¿Existe un método sencillo para adjuntar etiquetas a algunas líneas dentro de un entorno "Verbatim"?

¿Existe un método sencillo para adjuntar etiquetas a algunas líneas dentro de un entorno "Verbatim"?

Tengo muchos Verbatimentornos en mi documento, que contienen código fuente con diferentes caracteres en su interior , incluidos {,,, . Estoy intentando encontrar una manera de adjuntar etiquetas a algunas líneas dentro de estos entornos. Esto parece torpe, ya que tengo que reemplazar all with y all with, lo que hace que el código Java sea mucho menos legible (para mí, el editor del documento):([<{\{}\}

\documentclass{article}
\usepackage{fancyvrb}
\begin{document}
\begin{Verbatim}[commandchars=\\\{\}]
void main() \{
  print("Hello!"); \label{foo}
\}
\end{Verbatim}
\end{document}

Algo como esto sería mucho mejor:

\documentclass{article}
\usepackage{fancyvrb}
\begin{document}
\begin{Verbatim}
void main() {
  print("Hello!"); !foo
}
\end{Verbatim}
\end{document}

¿Es posible de alguna manera hacer que fancyvrbse interprete !foocomo \label{foo}? (Está bien si fancyvrbfuera necesario un "truco")

Respuesta1

Puede configurarlo !para que esté activo con una definición adecuada: buscará caracteres alfanuméricos y los pasará como argumento a \label.

\documentclass{article}
\usepackage{fancyvrb}

\ExplSyntaxOn

\cs_new_protected:Nn \__yegor_verbatim_label:
 {
  \peek_regex_replace_once:nn { [[:alnum:]]* } { \c{label}\cB\{\0\cE\} }
 }
\char_set_active_eq:nN { `! } \__yegor_verbatim_label:

\ExplSyntaxOff

\begin{document}

\begin{Verbatim}[codes={\catcode`\!=\active}]
void main() {
  print("Hello!"); !foo
}
\end{Verbatim}

\end{document}

Esto es lo que encontrará en el .auxarchivo:

\newlabel{foo}{{2}{1}{}{}{}}

Respuesta2

Puede utilizar diferentes caracteres de grupo, que no se utilizan en el código, por ejemplo

\documentclass{article}
\usepackage{fancyvrb}
\begin{document}
\begin{Verbatim}[{commandchars=\\[]}]
void main() {
  print("Hello!"); \label[foo]
}
\end{Verbatim}
\end{document}

o

\documentclass{article}
\usepackage{fancyvrb}
\begin{document}
\begin{Verbatim}[{commandchars=\\$/}]
void main() {
  print("Hello!"); \label$foo/
}
\end{Verbatim}
\end{document}

fantasíavrb

Nota: Con PDFLaTeX no puedes usar caracteres UTF8 como valor de commandchars. Pero con un motor UTF8, por ejemplo, LuaLaTeX también algo como:

% This is a LuaLaTeX example!
\documentclass{article}
\usepackage{fancyvrb}
\begin{document}
\begin{Verbatim}[{commandchars=§«»}]
void main() {
  print("Hello!"); §label«foo»
}
\end{Verbatim}
\end{document}

puede ser usado.


Otra alternativa sería utilizarpaquetelistingsen lugar de fancyvrb. En este caso, sólo necesitaríaunocarácter de escape, por ejemplo:

\documentclass{article}
\usepackage{listings}
\begin{document}
\begin{lstlisting}[escapechar=~]
void main() {
  print("Hello!"); ~\label{foo}~
}
\end{lstlisting}
\end{document}

o incluso:

\documentclass{article}
\usepackage{listings}
\begin{document}
\begin{lstlisting}[escapechar=¡]
void main() {
  print("Hello!"); ¡\label{foo}¡
}
\end{lstlisting}
\end{document}

listados

o

\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\lstset{columns=flexible,basicstyle=\ttfamily,identifierstyle=\color{blue}}
\begin{document}
\begin{lstlisting}[language=Java,escapechar=¡]
void main() {
  print("Hello!"); ¡\label{foo}¡
}
\end{lstlisting}
\end{document}

código java con color

Consulte también la sección 8 del listingsmanual para obtener más sugerencias y una alternativa a los números de línea de referencia, incluso si necesita que todos los caracteres se puedan utilizar en el código.


Si realmente insistes en usarlo !como \labelcódigo interno pero solo si no va seguido de ", recomendaría delimitar también foocon un adicional !:

\documentclass{article}
\usepackage{fancyvrb}
\makeatletter
\let\!!
\begingroup
\catcode`\!=\active
\gdef!{\@ifnextchar"{\!}{\labeltill}}
\gdef\labeltill#1!{\label{#1}}
\endgroup
\makeatother
\begin{document}
\begin{Verbatim}[codes*={\catcode`\!\active}]
void main() {
  print("Hello!"); !foo!
}
\end{Verbatim}
\end{document}

Sin embargo, sería una mejor idea usar un carácter que nunca se use como parte del código:

\documentclass{article}
\usepackage{fancyvrb}
\begingroup
\catcode`\^=\active
\gdef^#1^{\label{#1}}
\endgroup
\begin{document}
\begin{Verbatim}[codes*={\catcode`\^\active}}
void main() {
  print("Hello!"); ^foo^
}
\end{Verbatim}
\end{document}

Sin embargo, no me gusta esta solución porque creo que puede salir mal con demasiada facilidad. Y cada vez que falla una de las dos últimas soluciones, la complejidad del código aumenta. Por el contrario, cambiar el personaje en los listingsejemplos es una nimiedad.

información relacionada