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 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.

share|improve this question

1 Answer 1

up vote 4 down vote accepted

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}
share|improve this answer
    
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 '13 at 19:52

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.