[Tex/LaTex] Combining multiple listings styles in a single \lstdefinestyle command

listingssyntax highlighting

Here is my code:

\documentclass{article}
\usepackage{listings}
\usepackage{textcomp}
\usepackage{xcolor}
\lstdefinestyle{style1}{
    basicstyle=\ttfamily,
    columns=fullflexible,
    keepspaces=true,
    upquote=true,
}
\lstdefinestyle{style2}{
    showstringspaces=false,
    commentstyle=\color{olive},
    keywordstyle=\color{blue},
    identifierstyle=\color{violet},
    stringstyle=\color{purple},
}
\lstdefinestyle{style3}{
    language=c,
    directivestyle=\color{teal},
}
\lstdefinestyle{combined}{
    style=style1,
    style=style2,
    style=style3,
}
\lstnewenvironment{code}{
    \lstset{
        style=combined,
    }
}{}
\begin{document}
\begin{code}
/* hello, world program */
#include <stdio.h>

int main()
{
    printf("hello, world\n");
    return 0;
}
\end{code}
\end{document}

This has the expected output:

enter image description here

I am worried about this code:

\lstdefinestyle{combined}{
    style=style1,
    style=style2,
    style=style3,
}

Is it legal to use the style attribute three times in the same \lstdefinestyle command. It works but is it legal? I could not find any mention of it in http://texdoc.net/texmf-dist/doc/latex/listings/listings.pdf. Is there a good reference for this usage?

Best Answer

Well, in the documentation of listings you can find in chapter 3:

part of documentation

There you can find (see red arrows in image): Moreover it is possible to activate other styles.

For me that means you can call several styles, but there is of course a logical limitation: What should happen, if you call in both styles for example different languages?

See the following mwe:

\documentclass{article}

\usepackage{listings}
\usepackage{textcomp}
\usepackage{xcolor}

\lstdefinestyle{test1}{%
    basicstyle=\ttfamily,
    columns=fullflexible,
    keepspaces=true,
    upquote=true,
    language=c, % <=====================================================
    commentstyle=\color{olive},
}

\lstdefinestyle{test2}{%
    showstringspaces=false,
    keywordstyle=\color{blue},
    identifierstyle=\color{violet},
    stringstyle=\color{purple},
    language=TeX, % <===================================================
}

\lstdefinestyle{combined}{%
    style=test1,
    style=test2
}

\lstnewenvironment{code}{%
    \lstset{%
        style=combined,
    }
}{}


\begin{document}

First style:
\begin{lstlisting}[style=test1]
/* hello, world program */
#include <stdio.h>

int main()
{
    printf("hello, world\n");
    return 0;
}
\end{lstlisting}

Second style:
\begin{lstlisting}[style=test2]
\usepackage{listings}
\usepackage{textcomp}
\usepackage{xcolor}

\lstdefinestyle{test1}{%
    basicstyle=\ttfamily,
    columns=fullflexible,
    keepspaces=true,
    upquote=true,
    language=c,
    commentstyle=\color{olive},
}
\end{lstlisting}


All styles combined:

\begin{code}
/* hello, world program */
#include <stdio.h>

int main()
{
    printf("hello, world\n");
    return 0;
}
\end{code}
\end{document}

and its result:

resulting pdf

As you can see the latest call of definition wins: language=TeX overwrites the first set language=c.

So to be sure you get the result you want I suggest to create special styles for your different listings. Then you have the best control over your used styles and that it uses only proper definitions ...