Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
    
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 Jun 9 at 18:33

2 Answers 2

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}

Result

share|improve this answer

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}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.