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 struggle with the following listings styles. I have code of two different languages (R and LaTeX) in my .tex file. As some settings are the same for R listings and LaTeX listings, I define the style "all". It should be respected by any \begin{lstlisting} .. \end{lstlisting}. I therefore use style=all in the lstset definitions for the two languages. Then, there are additional, language specific settings, which should also be respected. However, as you can see, that does not quite work. Although I set the keywords in the R listings to just be if, else, or function, lapply and sapply get a blue color as well. Why? And how can this be solved?

It seems like I would have to repeat all the definitions in the optional argument of the lstlisting environment. But it's tedious to do this every time, that's why I wanted to define styles in the first place. Also, it's not clear to me why a setting like keywords is overwritten since the optional argument of lstlisting does not contain keywords=....

\documentclass{scrartcl}

\usepackage[T1]{fontenc}
\usepackage[american]{babel}
\usepackage{xcolor}
\usepackage{fancyvrb}
\usepackage{listings}

\xdefinecolor{blue}{RGB}{0, 0, 255}
\xdefinecolor{red}{RGB}{255, 0, 0}

% this style should be active for all lstlistings environments
\lstdefinestyle{all}{
  basicstyle=\ttfamily\small,
  frame=lrtb, framerule=1pt, framexleftmargin=1pt,
  showstringspaces=false
}

% this style should be active (additionally to "all") for "input" lstlistings environments
\lstdefinestyle{input}{
  commentstyle=\itshape\color{red},
  keywordstyle=\color{blue}
}

% listings settings for LaTeX in general [this is not respected!]
\lstset{
  language=[LaTeX]TeX,
  style=all,
  keywords={},
  otherkeywords={}
}

% listings settings for R (should hold for all R listings in general)
\lstset{
  language=R,
  style=all,
  literate={<-}{{$\leftarrow$}}2,% this is respected
  keywords={if, else, function},% this is not respected
  otherkeywords={}
}

\begin{document}

\begin{lstlisting}[{language=[LaTeX]TeX}, style=input]
\begin{enumerate}
\item foo % bar
\end{enumerate}
\end{lstlisting}

\begin{lstlisting}[language=R, style=input]
x <- 4
s <- lapply(1:10, function(z) z+x)
k <- sapply(1:10, function(z) z+2*x) # other case
\end{lstlisting}

\end{document}
share|improve this question
    
Just set general rules with lstset and create two language styles, which you may use then together with the input style. –  bloodworks Jan 17 '13 at 16:33

2 Answers 2

up vote 4 down vote accepted

You seem to think that \lstset sets parameters for one specified language, i.e., the language given within \lstset. That is not how it works. Your code first sets the default language for all listings of your document to TeX, then it sets it to R, and so on. Similarly, it sets three default keywords for all listings of your document (if, else, function), but when you typeset your R listing, the keyword list that belongs to R overwrites the default keyword list.

What you actually want is probably best achived with styles, or you define a new language based on R, or a new dialect of R. Let's try with styles:

\documentclass{scrartcl}

\usepackage[T1]{fontenc}
\usepackage[american]{babel}
\usepackage{xcolor}
\usepackage{fancyvrb}
\usepackage{listings}

% this style should be active for all lstlistings environments
\lstdefinestyle{all}{
  basicstyle=\ttfamily\small,
  frame=lrtb, framerule=1pt, framexleftmargin=1pt,
  showstringspaces=false
}

% this style should be active (additionally to "all") for "input" lstlistings environments
\lstdefinestyle{input}{
  commentstyle=\itshape\color{red},
  keywordstyle=\color{blue}
}

\lstdefinestyle{newLaTeXsettings}{
  style=all,
  keywords={},
  otherkeywords={}
}


% listings settings for R (should hold for all R listings in general)
\lstdefinestyle{newRsettings}{
  style=all,
  literate={<-}{{$\leftarrow$}}2,% this is respected
  keywords={if, else, function},% this is not respected
  otherkeywords={}
}

\begin{document}

\begin{lstlisting}[language={[LaTeX]TeX}, style=input, style=newLaTeXsettings]
\begin{enumerate}
\item foo % bar
\end{enumerate}
\end{lstlisting}

\begin{lstlisting}[language=R, style=input, style=newRsettings]
x <- 4
s <- lapply(1:10, function(z) z+x)
k <- sapply(1:10, function(z) z+2*x) # other case
\end{lstlisting}

\end{document}
share|improve this answer
    
Thanks, mafp. Why are the words "begin", "item", and "end" still blue although newLaTeXSettings resets the keywords? –  Marius Hofert Jan 17 '13 at 18:46
    
@MariusHofert The reason is that the TeX dialects don't have keywords, but texcs's (for tex control sequences). Here, even after resetting the keywords, begin, item, and end are still valid texcs. To get rid of them, use texcs={...}, moretexcs={...}, deletetexcs={...}, just as with keywords. –  mafp Jan 17 '13 at 20:03
    
Thanks a lot, that solved it! –  Marius Hofert Jan 17 '13 at 21:00

If you have certain priorities in your style settings you MUST load them in the right order. Cause style=... will just output the list given in \lstdefinestyle so the latter style will rule.

\documentclass{scrartcl}

\usepackage[T1]{fontenc}

\usepackage{xcolor}

\usepackage{listings}


% priority: low
\lstset{
  basicstyle=\ttfamily\small,
  frame=lrtb, framerule=1pt, framexleftmargin=1pt,
  showstringspaces=false
}
% priority: mid
\lstdefinestyle{input}{
  commentstyle=\itshape\color{red},
  keywordstyle=\color{blue}
}
% priority major
\lstdefinestyle{mylatex}{%
  language=[LaTeX]TeX,
 keywordstyle={\color{black}},% just redoing what input would do to us. 
  otherkeywords={}%
}

\lstdefinestyle{myr}{
  language=R,
  literate={<-}{{$\leftarrow$}}2,% this is respected
  keywords={if, else, function},% this is not respected
  otherkeywords={}
}



\begin{document}
%low priority must be loaded befor higher priorities. 
%so that i can be overwritten. 
\begin{lstlisting}[ style=input, style=mylatex, ]
\begin{enumerate}
\item foo % bar
\end{enumerate}
\end{lstlisting}

\begin{lstlisting}[style=input,style=myr, ]
x <- 4
s <- lapply(1:10, function(z) z+x)
k <- sapply(1:10, function(z) z+2*x if)     # other case
\end{lstlisting}

\end{document}

All general rules are set with lstset and in force until a local command (given as style or actual optional argument to the environment ) will overwrite it. So here i created three levels. First to come are the global (low priority) options. You won't feel the need to care about them much. The second level is the input style, which shall be overwritten by the lang style. This style will rule at the end.

share|improve this answer
    
Thanks a lot, bloodworks. I am still wondering why keywords={} instead of keywordstyle={\color{black}} does not work (begin end etc. are still blue). If there are no keywords, there shouldn't be anything blue, right? Hmmm... –  Marius Hofert Jan 17 '13 at 18:57
    
I never took a deeper look into the source of listings since i'm not very fond of catcode hackery. I could imagine, that it's simply to late then to unload the keywordlist. Furthermore it`s known that listings treats tex code a bit different form other (eg R) code. Is painting them simply black not sufficient for you? –  bloodworks Jan 17 '13 at 20:12

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.