Существует ли простой способ прикрепления меток к некоторым строкам внутри среды «Verbatim»?

Существует ли простой способ прикрепления меток к некоторым строкам внутри среды «Verbatim»?

У меня Verbatimв документе много окружений, содержащих исходный код с различными символами внутри, включая {, (, [, <. Я пытаюсь найти способ прикрепить метки к некоторым строкам внутри этих окружений. Это выглядит неуклюже, так как мне приходится заменять все {на \{и все }на \}, что делает код Java гораздо менее читабельным (для меня, редактора документа):

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

Что-то вроде этого было бы гораздо лучше:

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

Возможно ли как-то сделать так, чтобы fancyvrbинтерпретировалось !fooкак \label{foo}? (ничего страшного, если fancyvrbпонадобится "взлом")

решение1

Вы можете сделать его !активным с помощью подходящего определения: он будет искать буквенно-цифровые символы и передавать их в качестве аргумента \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}

Вот что вы найдете в .auxфайле:

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

решение2

Вы можете использовать различные групповые символы, не используемые в коде, например:

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

или

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

fancyvrb

Примечание: С PDFLaTeX вы не можете использовать символы UTF8 в качестве значения commandchars. Но с движком UTF8, например, LuaLaTeX, также что-то вроде:

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

может быть использован.


Другой альтернативой было бы использованиеупаковкаlistingsвместо fancyvrb. В этом случае вам понадобится толькоодинэкранированный символ, например:

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

или даже:

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

списки

или

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

Код Java с цветом

См. также раздел 8 руководства listingsдля получения дополнительных подсказок и альтернативы ссылкам на номера строк, даже если вам нужно, чтобы все символы можно было использовать в коде.


Если вы действительно настаиваете на использовании !внутреннего \labelкода, но только если за ним не следует ", я бы рекомендовал также отделить его fooдополнительным !:

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

Однако использование символа, который никогда не используется в коде, было бы лучшей идеей:

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

Тем не менее, мне не нравится это решение, потому что я думаю, что оно может слишком легко пойти не так. И с каждым случаем, когда одно из последних двух решений терпит неудачу, сложность кода увеличивается. Напротив, изменение символа в примерах listings— это пустяк.

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