2

I'm using the listings package to document excerpts from my programs. I have been creating new environments for the various programming languages and wondering whether there was a way to hack the package so that it accepts a variable for the language definition in \lstset.

For example,

\documentclass[11pt]{article}
\usepackage{listings}

\newcommand{\thelanguage}{Python}

\lstnewenvironment{\thelanguage}[1][]{
  \lstset{
    language = \thelanguage,
    #1
  }
}
{}

\begin{document}
\begin{Python}
  This is a test.
\end{Python}
\end{document}

Using the above, latex throws the '!Improper alphabetic constant' error, which I presume is because the listings package is expecting a string rather than a variable. Is there a way round this? Should I be defining it as a macro and expanding it somehow? Still fairly new to latex, so any help would really help my understanding. Thanx.

1 Answer 1

4

Quick tests show that the following modification to the language key-value setting function allows for proper expansion of macros used as languages:

\makeatletter
\lst@Key{language}\relax{\expandafter\lstKV@OptArg\expandafter[\expandafter]\expandafter{#1}%
    {\lst@LAS{language}{lang}{[##1]{##2}}\lst@FindAlias\lstlanguagefiles
         \lsthk@SetLanguage
         {\lst@FindAlias[##1]{##2}%
          \let\lst@language\lst@malias
          \let\lst@dialect\lst@oalias}}}
\makeatother

However, you would also require expansion of the macro passed to \lstnewenvironment. The following MWE shows how this is possible:

enter image description here

\documentclass{article}
\usepackage{listings}% http://ctan.org/pkg/listings
\makeatletter
\lst@Key{language}\relax{\expandafter\lstKV@OptArg\expandafter[\expandafter]\expandafter{#1}%
    {\lst@LAS{language}{lang}{[##1]{##2}}\lst@FindAlias\lstlanguagefiles
         \lsthk@SetLanguage
         {\lst@FindAlias[##1]{##2}%
          \let\lst@language\lst@malias
          \let\lst@dialect\lst@oalias}}}
\makeatother
\newcommand{\thelanguage}{Python}

\expandafter\lstnewenvironment\expandafter{\thelanguage}[1][]{
  \lstset{
    language = \thelanguage,
    #1
  }
}
{}

\begin{document}
\begin{Python}
  This is a test.
\end{Python}
\end{document}

Although it may be considered to manipulate the language and environment using your approach (that is, use \lstnewenvironment and setting language using the same macro), it may seem cumbersome to manage this when working with different language dialects. For example, using

\newcommand{\thelanguage}{[XSC]Pascal}

would require you to use

\begin{[XSC]Pascal}
  %...
\end{[XSC]Pascal}
1
  • Agreed, this method could become cumbersome when using dialects. However, it's a good way to learn more about macros. Method above works. Thanks Werner.
    – James B
    Jan 24, 2013 at 19:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .