I need some options of the listings package several times in my document. I am thus wondering if one can define (and later change) these options once somewhere in the preamble via a command/macro, for example, and use the command/macro later on if required? I tried the keyval package, but wasn't successful.



% write dummy R file
f <- function(x){
  t <- exp(-x) # just some dummy example
  sqrt(t) # return value

% general listings settings
  keywords={if, else, repeat, while, function, for, in, next, break},

% define my own listings settings which frequently appear
\newcommand{\mylstset}{\setkeys{keywordstyle=\color{blue}, commentstyle=\itshape\color{red}}}

% specific listing environment
\xdefinecolor{blue}{RGB}{58, 95, 205}%
\xdefinecolor{red}{RGB}{178, 34, 34}%
  \lstset{\mylstset}% my listings settings
  #1% content

Show \texttt{foo.R}:
\lstinputlisting[\mylstset]{foo.R}% my listings settings
  • It should work if you define the command without the \setkeys (\newcommand{\mylstset}{keywordstyle=\color{blue}, commentstyle=\itshape\color{red}}) and expand them first \expandafter\lstinputlisting\expandafter[\mylstset]{foo.R} – clemens Nov 21 '12 at 11:23
  • Thanks. Is there a solution which does not require the wrap-around of \lstinputlisting with \expandafter? Ideally, the call of \lstinputlisting should not be changed (by having to add \expandafter commands) – Marius Hofert Nov 21 '12 at 12:10
  • Yes, it should be possible to define a wrapper for \lstinputlisting that does the expansion for you. Try \newcommand\myinputlisting[1][]{\expandafter\lstinputlisting\expandafter[#1]} and then use \myinputlisting[\mylstset]{foo.R} – clemens Nov 21 '12 at 12:19
  • Thanks a lot. I tried to use your suggestion with \renewcommand\lstinputlisting..., but LaTeX hangs during compilation. Do you know why? Again, I would like to not change the actual call of \lstinputlisting since I don't want to change the code which is already working (it's a bit complicated to explain but basically a compatibility issue of several people working together). – Marius Hofert Nov 21 '12 at 13:24
  • 1
    You cannot redefine \lstinputlistingusing itself in the definition (that causes an infinite loop). You can try \let\myinputlisting\lstinputlisting \renewcommand\lstinputlisting[1][]{\expandafter\myinputlisting\expandafter[#1]} (that might or might not work. I cannot test until tonight) – clemens Nov 21 '12 at 13:45

Summarizing my comments in an answer:

First thing is to define the custom setting without \setkeys as a simple list of key/value pairs:

\newcommand*\mylstset{keywordstyle=\color{blue}, commentstyle=\itshape\color{red}}

Now, the main problem is, that this macro needs to be expanded once before fed to \lstinputlisting:


As this is tedious (and is not too good a style in the document body, anyway) when one has to do it more often it might be convenient to define a wrapper for this:


Now one can use it as follows:


It should be noted, that \mylstset must be the first entry in the key/value list otherwise it won't be expanded first.

Since the requirement is not to use a custom command but the original syntax one needs to redefine \lstinputlisting. For this its definition needs to be saved first and can then be used in the redefinition:

% save original definition of \lstinputlisting:
% renew definition of \lstinputlisting:

This works but it should be noted that this kind of redefinition can fail with commands that have optional arguments. A safer way is to use \LetLtxMacro (from the letltxmacro package) instead of \let.

All in all there is a better way, imho: define a custom style and use it via the style option:

% preamble:
\lstdefinestyle{mystyle}{keywordstyle=\color{blue}, commentstyle=\itshape\color{red}}
% document

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.