7

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?

7

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
6

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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