我如何强制 lstlisting 扩展参数?

我如何强制 lstlisting 扩展参数?

我正在尝试使用listings带有变量语言的包(它实际上是一个包)。但是,我似乎无法将宏作为键值对的值的一半传递。这是一个简单的例子:

\documentclass{article}

\def\lang{Java}

\usepackage{listings}

\begin{document}

% writes "Java" to document
\lang

% writes with no formatting (as expected)
\begin{lstlisting}
int x = 2; // declare, initialize variable
\end{lstlisting}

% writes with Java formatting (as expected)
\begin{lstlisting}[language=Java] % same effect with language={Java}
int x = 2; // declare, initialize variable
\end{lstlisting}

% fails with Error: language Java undefined
\begin{lstlisting}[language=\lang]
int x = 2; // declare, initialize variable
\end{lstlisting}

\end{document}

实际上,这是一个包的一部分,该包本身包含一个键值系统,因此最佳情况下您应该能够做到这一点,\usepackage[language=Java]{foo}并且以后能够\begin{lstlisting}[language=Java]正确执行。

我也尝试过使用\edef而不是\def,并使用\expandafter(尽管这对我来说似乎是倒退的)。正确的方法是什么?

答案1

您必须扩展该参数。视觉上更好的解决方案基于\edef(与 Heiko 的答案相同):

\documentclass{article}
\def\lang{Java}
\usepackage{listings}
\def\expandparam\begin#1[#2]{\edef\tmp{\noexpand\begin{#1}[#2]}\tmp}
\begin{document}

% writes "Java" to document
\lang

% writes with no formatting (as expected)
\begin{lstlisting}
int x = 2; // declare, initialize variable
\end{lstlisting}

% writes with Java formatting (as expected)
\begin{lstlisting}[language=Java] % same effect with language={Java}
int x = 2; // declare, initialize variable
\end{lstlisting}

% The \expandaparams is used here:
\expandparam
\begin{lstlisting}[language=\lang]
int x = 2; // declare, initialize variable
\end{lstlisting}

\end{document}

答案2

的第一部分\begin{lstlisting}[...可以放入\edef以扩展宏。 的扩展\begin被阻止\noexpand

\documentclass{article}

\def\lang{Java}

\usepackage{listings}

\begin{document}

\edef\next{%
  \noexpand\begin{lstlisting}[language=\lang
}\next]
int x = 2; // declare, initialize variable
\end{lstlisting}

\end{document}

结果

相关内容