我的文档中有许多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}
注意:使用 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}
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
是一件小事。