是否有一种简单的方法可以在“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}

幻想VRB

注意:使用 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 代码

listings即使您需要所有字符在代码中可用,也请参阅手册的第 8 节以获取更多提示和参考行号的替代方法。


如果你真的坚持在代码中使用!as\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是一件小事。

相关内容