# How can I force lstlisting to expand an argument?

I'm trying to use the listings package with a variable language (it's actually for a package). However, I can't seem to pass a macro as the value half of a key-value pair. Here's a simple example:

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


In reality, this is part of a package that itself includes a key-value system, so optimally you should be able to do \usepackage[language=Java]{foo} and it will later be able to \begin{lstlisting}[language=Java] properly.

I also tried using \edef instead of \def, and using \expandafter (though that seems backwards to me). What's the proper way to do this?

-

You hve to expand the parameter. A visually better solution which is based on \edef (the same as Heiko's answer):

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

-
\def\expandparam\begin#1[#2]{\edef\tmp{\noexpand\begin{#1}[#2]}\tmp}, together with \expandparam before \begin, made my day, thanks! – mmj Sep 26 '15 at 10:39

The first part of \begin{lstlisting}[... can be put into \edef to expand the macros. The expansion of \begin is prevented by \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}


-