6

I defined several new code environments (using listings' lstnewenvironment); they all share the same attributes except one (the language used). For example:

\documentclass[a4paper,12pt]{book}
\usepackage{listings}
\usepackage[usenames,dvipsnames]{xcolor}
\lstnewenvironment{xml}
{
 \lstset
 {
  literate=
  {é}{{\'e}}1
  {É}{{\'E}}1
  {à}{{\`a}}1 {è}{{\`e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1 {î}{{\^i}}1
  {À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1 {Î}{{\^I}}1,
  language=XML,
  breaklines=true,
  xleftmargin=\parindent,
  showstringspaces=false,
  showspaces=false,
  showtabs=false,
  keepspaces=true,
  tabsize=2,
  captionpos=t,
  numbers=left,
  numbersep=5pt,
  numberstyle=\tiny\color{graycode},
  escapeinside={(*}{*)},
  basicstyle=\footnotesize\ttfamily,
  keywordstyle=\bfseries\color{green!40!black},
  commentstyle=\itshape\color{purple!40!black},
  identifierstyle=\color{blue},
  stringstyle=\color{orange}
 }
}
{}

\begin{document}
  \begin{xml}
   <something> ... </something>
  \end{xml}
\end{document}

I'd like to refactor my code in a way that I keep the common stuff in some sort of macro that dumps as-is (verbatim) whatever stored in the point where it's called. Something like:

\newcommand{\stringlstset}
{
  literate = ...
  breaklines = ...
  ...
}
\lstnewenvironment{xml}
{
 \lstset
 {
  \stringlstset
  language = xml
  ...
 }
}
\lstnewenvironment{prolog}
{
 \lstset
 {
  \stringlstset
  language = prolog
  ...
 }
}

I gather you have to use some low-level gimmick to get this done. I did some googling around but I couldn't come up with a working solution. ConTeXt's buffers, for example, looked promising, but they can't be used here.

There may be something in listings to deal with this, but I'm interested in a general solution here.

  • Welcome to TeX.SE. While code snippets are useful in explanations, it is always best to compose a fully compilable MWE including \documentclass and the appropriate packages that sets up the problem. While solving problems can be fun, setting them up is not. Then, those trying to help can simply cut and paste your MWE and get started on solving the problem. – Peter Grill Oct 18 '14 at 17:55
  • When you call \lstset{\stringlstset,language=prolog,…} if you subtitute the first part with \expandafter\lstset\expandafter{\stringlstset,… it should work. – Manuel Oct 18 '14 at 21:05
6

The second argument of \lstnewenvironment is just arbitrary code to execute before the environment. It can therefore consist of several \lstset commands, and you can put your common customisations in to one command, say \stringlstset, that is a \lstset in its own right. Here is a small example:

\documentclass[a4paper,12pt]{book}

\usepackage{listings}
\usepackage[usenames,dvipsnames]{xcolor}

\newcommand{\stringlstset}{\lstset{
    breaklines=true,
    showspaces=false}}

\lstnewenvironment{xml}
{\lstset{language=XML}\stringlstset}
{}

\begin{document}

\begin{xml}
  <something> Somethig long enough to see a breaking of the line </something>
\end{xml}

\begin{lstlisting}
  <something> Somethig long enough to see a breaking of the line </something>
\end{lstlisting}

\end{document}

producing

Sample output

with line breaks in the xml environment but not in the lstlistng environment.

0

Instead of

\lstnewenvironment{whatever}
{
 \lstset
 {
  \stringlstset,
  language = whatever,
  ...
 }
}

you can

\lstnewenvironment{whatever}
{
 \expandafter\lstset
 \expandafter{
  \stringlstset,
  language = whatever,
  ...
 }
}

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.