Existe um método simples de anexar rótulos a algumas linhas dentro de um ambiente "Verbatim"?

Existe um método simples de anexar rótulos a algumas linhas dentro de um ambiente "Verbatim"?

Tenho muitos Verbatimambientes em meu documento, que contêm código-fonte com caracteres diferentes, incluindo {, (, [, <. Estou tentando encontrar uma maneira de anexar rótulos a algumas linhas dentro desses ambientes. Isso parece desajeitado, já que tenho que substituir all {por \{e all }por \}tornando o código Java bem menos legível (para mim, o editor do documento):

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

Algo assim seria muito melhor:

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

É de alguma forma possível fancyvrbinterpretar !foocomo \label{foo}? (está tudo bem se um "hack" fancyvrbfor necessário)

Responder1

Você pode definir !como ativo com uma definição adequada: ele procurará caracteres alfanuméricos e os passará como argumento para \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}

Aqui está o que você encontrará no .auxarquivo:

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

Responder2

Você pode usar caracteres de grupo diferentes, não usados ​​no código, por exemplo

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

ou

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

fantasiavrb

Nota: Com PDFLaTeX você não pode usar caracteres UTF8 como valor de commandchars. Mas com um mecanismo UTF8, por exemplo, LuaLaTeX também é 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}

pode ser usado.


Outra alternativa seria usarpacotelistingsem vez de fancyvrb. Neste caso, você precisaria apenasumcaractere de escape, por exemplo:

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

ou mesmo:

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

listagens

ou

\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 com cor

Consulte também a seção 8 do listingsmanual para obter mais dicas e uma alternativa para referenciar números de linha, mesmo se você precisar que todos os caracteres possam ser usados ​​no código.


Se você realmente insiste em usar !as \labeldentro do código, mas somente se ele não for seguido por ", eu recomendaria também delimitar o foocom um 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}

No entanto, usar um caractere que nunca é usado como parte do código seria uma ideia melhor:

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

No entanto, não gosto desta solução porque acho que pode dar errado com muita facilidade. E a cada caso em que uma das duas últimas soluções falha, a complexidade do código aumenta. Por outro lado, mudar o personagem nos listingsexemplos é uma bagatela.

informação relacionada