58

I'm using listings and I want to extend a language with additional keywords for highlightning. I know there is an option morekeywords available, but that only works for a particular lstset declaration and I don't want to have to copy-paste all keywords into all listings. I've tried declaring the keywords as part of a command but that doesn't work (probably because the command is not expanded and I don't know how to fix that).

So is there any way of declaring a new language by copying an existing one and just adding more keywords?

gablin
  • 17,006

5 Answers5

66

It seems that morekeywords also works for extending a language. For instance the Python keyword super isn't in the list of default keywords. In my preamble, I can set it as a keyword by doing:

\lstset{language=Python}
\lstset{
 morekeywords={super}
}

Of course, it would be ideal to contribute those missing keywords to the listings package.

Dominique
  • 1,369
38

You can define the keywords in a separate file and just include it in your preamble. Here is an example of adding for and downto as new keywords:

enter image description here

\documentclass{article}
\usepackage{listings}%
\usepackage{xcolor}

\lstset{%
    backgroundcolor=\color{yellow!20},%
    basicstyle=\small\ttfamily,%
    numbers=left, numberstyle=\tiny, stepnumber=2, numbersep=5pt,%
    }%

% Add your keywords here, and have this in a separate file
% and include it in your preamble
\lstset{emph={%  
    downto, for%
    },emphstyle={\color{red}\bfseries\underbar}%
}%

\begin{document}
\begin{lstlisting}
y = 0
for i = n downto 0
    y = a_i + x * y
\end{lstlisting}
\end{document}
Peter Grill
  • 223,288
  • 1
    I never thought about using a separate \lstset to define the keywords! This solved my problem! – gablin Sep 13 '11 at 06:51
  • 2
    How do I use this to define multiple types of formatting (i.e. make "foo" red and "bar" green)? If I put subsequent \lstset{emph=... commands only the last one seems to take effect and all previous ones are ignored. – PGmath Apr 01 '19 at 07:17
  • @PGmath: I think the way to do that would be to define styles (similar too the other answers) and invoke the desired style. If that does not answer your question, I would suggest you ask a new question and be sure to include a MWE including \documentclass and the appropriate packages that sets up the problem. – Peter Grill Apr 01 '19 at 09:02
  • In my opinion the answers with \lstdefinestyle are way more suitable and elegant to answer the question. – Joysn Dec 03 '22 at 14:11
16

As Dominique said,

\lstset{language=Python}
\lstset{
morekeywords={super}
}

works, but doing so firstly add the Python language to all listing and then adds the keyword to all languages.

To add the keyword only for one language use

\lstdefinestyle{Python}{
morekeywords={super}
}

instead.

  • 1
    This is the best answer for just extending one language's keywords. Thank you! – JeffP Sep 09 '22 at 18:11
  • Agree with @JeffP, best answer because highlights the difference between lstset and lstdefinestyle. – Joysn Dec 03 '22 at 14:12
  • This adds the super keyword to one style, perhaps confusingly named the same as the language Python. See @ASarkar's answer for clarity, where they use lowercase for the style to differentiate it from the language. – Mark Gates Oct 31 '23 at 16:48
10

Adding to Dominique's and Corentin's answer here's my take on this:

\lstdefinestyle{python}{language=Python,
    morekeywords={super},
    ... % more settings for python language
}

\lstdefinestyle{c}{language=C,
    ... % settings for C language
}    

...
\begin{lstlisting}[style = python]
... super
\end{lstlisting}

% changing language
\begin{lstlisting}[style = c]
... 
\end{lstlisting}

% back to python
\begin{lstlisting}[style = python]
... super
\end{lstlisting}

This will add the keyword super to only Python language.

ASarkar
  • 211
4

While the summarization by ASarkar of most other answers is a nice workaround, I want to show how you can actually extend an existing language, like requested by the asker. Given the fact that the HTML language of listing does not highlight HTML 5 elements, let's extend that by some keywords:

\lstdefinelanguage{HTML5}[]{HTML}{
    morekeywords={audio, video, canvas, embed, source}
}

When you add a HTML listing to your document, just use the HTML5 language tag instead of HTML:

\begin{lstlisting}[language=HTML5]
<video src="" controls></video>
\end{lstlisting}