# How to define package options in a command (for reuse)?

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.

\documentclass{scrartcl}

\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[american]{babel}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{keyval}
\usepackage{filecontents}

% write dummy R file
\begin{filecontents*}{foo.R}
f <- function(x){
t <- exp(-x) # just some dummy example
sqrt(t) # return value
}
\end{filecontents*}

% general listings settings
\lstset{
language=R,
basicstyle=\ttfamily\small,
keywords={if, else, repeat, while, function, for, in, next, break},
otherkeywords={}
}

% define my own listings settings which frequently appear

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

\begin{document}
Show \texttt{foo.R}:
\lstinputlisting[\mylstset]{foo.R}% my listings settings
\end{document}

-
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} –  cgnieder 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} –  cgnieder 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
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) –  cgnieder Nov 21 '12 at 13:45

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:

\expandafter\lstinputlisting\expandafter[\mylstset]{foo.R}


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:

\newcommand\myinputlisting[1][]{\expandafter\lstinputlisting\expandafter[#1]}


Now one can use it as follows:

\myinputlisting[\mylstset,otherkey=...]{foo.R}


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:
\let\origlstinputlisting\lstinputlisting
% renew definition of \lstinputlisting:
\renewcommand\lstinputlisting[1][]{\expandafter\origlstinputlisting\expandafter[#1]}


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: