# 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?

-
Since you have some responses below that seem to answer your question, please consider marking one of them as ‘Accepted’ by clicking on the tickmark below their vote count (see How do you accept an answer?). This shows which answer helped you most, and it assigns reputation points to the author of the answer (and to you!). It's part of this site's idea to identify good questions and answers through upvotes and acceptance of answers. –  Jubobs Oct 29 '14 at 18:11
@Jubobs Thanks for the reminder! –  WChargin Oct 29 '14 at 20:45

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}

-

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}


-