是否有一種簡單的方法可以將標籤附加到“Verbatim”環境中的某些行?

是否有一種簡單的方法可以將標籤附加到“Verbatim”環境中的某些行?

Verbatim我的文件中有很多環境,其中包含內部帶有不同字元的源代碼,包括{, (, [, <。我正在嘗試找到一種將標籤附加到這些環境中的某些線路的方法。這看起來很笨拙,因為我必須將 all 替換{\{和 all }with ,\}從而使 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程式碼

另請參閱手冊第 8 節listings以取得更多提示和參考行號的替代方法,即使您需要所有字元在程式碼中都可用。


如果您真的堅持使用!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範例中的字元是小事一樁。

相關內容