[Tex/LaTex] Add keywords to an existing language in listings

keywordslanguageslistings

I've already read extending a language with additional keywords and I have found kind of a solution, but I'm not quite sure if it's the right way and if I won't have problems in the future.

The scenario is like this: I have different pieces of code in ruby, Java and a custom one, in a random order (not all ruby code first, then all Java, etc).

Here is a MWE to illustrate:

\documentclass[11pt]{report}

\usepackage{listings}
\usepackage{framed}
\usepackage{xcolor}

\lstset{ %
  basicstyle=\footnotesize\ttfamily,
  numbers=left,
  numberstyle=\tiny\color{gray}\ttfamily,
  numbersep=5pt,
  backgroundcolor=\color{white},
  showspaces=false,
  showstringspaces=false,
  showtabs=false,
  frame=single,
  rulecolor=\color{black},
  captionpos=b,
  keywordstyle=\color{blue}\bf,
  commentstyle=\color{gray},
  stringstyle=\color{green},
  keywordstyle={[2]\color{red}\bf},
}



\lstdefinelanguage{story}
{morekeywords={Given,When,Then},
    sensitive=false,
    morekeywords={[2]Scenario},
}

\begin{document}
First some ruby code
\lstinputlisting[language=Ruby,caption={Ruby}]{ruby_code.rb}

Now some java code
%\lstset{language=Java}
%\lstset{ morekeywords={[2]@Given,@When,@Then}}
\lstinputlisting[language=Java,caption={Java}]{JavaCode.java}

Now some story code
\lstinputlisting[language=story,caption={Story}]{story_code.story}
\end{document}

I'll put only the java code which is the one troubling and the one I really care:

// JavaCode.java
public class ComportamientoSteps {
    Croupier croupier;

    @Given("una nueva mano")
    public void nuevaMano() {
        croupier = new Croupier();
    }
 
    @When("el croupier tiene $carta1 y $carta2")
    public void elCroupierTiene(int carta1, int carta2) {
        croupier.agregarCarta(new Carta(carta1));
        croupier.agregarCarta(new Carta(carta2));
    }
 
    @Then("$valor deberia plantar")
    public void croupierDeberiaPlantar(String valor) {
        boolean debe_pedir = valor.equals("no"); 
        assertThat(croupier.debePedirOtraCarta(), equalTo(debe_pedir));
    }
}

What I'm trying to do is:

  1. First, define a common style for al pieces of code: size, colors of keywords and [2]keywords, etc. I want this style for every language.
  2. Then define the very simple story language.
  3. Lastly, I input the code via \lstinputlisting[language=whatever]{file}

I want to extend the Java language to interpret @Given, @When and @Then as [2]keywords. In the MWE there is a piece of code commented out, with that piece of code it works (you have to remove the language=Java in the options), but I don't want to do that every time I have to put Java code, I just want to use the lstinputlisting with the language option. Besides, I don't know if setting the language to Java like that won't bring me trouble in future listings.

Best Answer

Listing is powerful tool , more documentation can be found here:The Listings Package.

Instead of setting global settings you should set styles for each individual listings

Flowing code should give you good picture of how to customise listings.

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

\lstdefinestyle{basic}{  
  basicstyle=\footnotesize\ttfamily,
  numbers=left,
  numberstyle=\tiny\color{gray}\ttfamily,
  numbersep=5pt,
  backgroundcolor=\color{white},
  showspaces=false,
  showstringspaces=false,
  showtabs=false,
  frame=single,
  rulecolor=\color{black},
  captionpos=b,
  keywordstyle=\color{blue}\bf,
  commentstyle=\color{gray},
  stringstyle=\color{green},
  keywordstyle={[2]\color{red}\bf},
}


\lstdefinelanguage{custom}
{
morekeywords={public, void},
sensitive=false,
morecomment=[l]{//},
morecomment=[s]{/*}{*/},
morestring=[b]",
}

\begin{document}

 \lstinputlisting[ style=basic, language=Python]{main.java}
 \lstinputlisting[ style=basic, language=Java]{main.java}

 \lstinputlisting[ style=basic, language=custom]{main.java}


\end{document}

Three version of customised listings presented in the code above

they all use same colours for identity of: strings, comments, keywords.

also I showed how to create new language for your need. you can use existed languages for your foundation and add more keywords to it.

enter image description here

[UPDATE]

Here is set of different styles , I personally prefer this one.

\documentclass{article}
\usepackage{graphicx} 
\usepackage{listings}
\usepackage{color}
\usepackage{accsupp}



\definecolor{dkblue}{rgb}{0,0,0.5}
\definecolor{comment}{rgb}{1,0,0}
\definecolor{mauve}{rgb}{.627,.126,.941}
\definecolor{purple}{rgb}{0.5, 0, 0.545098}


\lstdefinestyle{java}{
  belowcaptionskip=1\baselineskip,
  breakatwhitespace=false,        % sets if automatic breaks should only happen at whitespace
  breaklines=true,                % sets automatic line breaking
  xleftmargin=\parindent,
  language=Java,
  tabsize=4, 
  tabsize=4,
  numbers=left,
  showstringspaces=false,
  numberstyle=\tiny\noncopynumber,
  basicstyle=\footnotesize\ttfamily,
  keywordstyle=\bfseries\color[rgb]{.133,.545,.133},
  commentstyle=\itshape\color{blue},
  stringstyle=\color{mauve},
  directivestyle=\bfseries\color{purple},
  frame=single],
  resetmargins=true,
}
    \lstdefinestyle{mathlab}{  
  belowcaptionskip=1\baselineskip,
  breakatwhitespace=false,        % sets if automatic breaks should only happen at whitespace
  breaklines=true,                % sets automatic line breaking
  xleftmargin=\parindent,
  language=C,
  morekeywords={end, elseif},
  comment=[l]\%,                              % comments    
  tabsize=4, 
  numberstyle=\tiny\noncopynumber,
  showstringspaces=false,
  basicstyle=\footnotesize\ttfamily,
  keywordstyle=\color[rgb]{0,0,1},
  commentstyle=\itshape\color[rgb]{.133,.545,.133},
  stringstyle=\color{mauve},
  directivestyle=\bfseries\color{purple},
  framexleftmargin=3mm,
  frame=single,
}


\newcommand{\noncopynumber}[1]{%
\BeginAccSupp{method=escape,ActualText={}}%
#1%
\EndAccSupp{}%
}

\begin{document}

 \lstinputlisting[caption=Matlab style main code: "main.java", style=mathlab]{main.java}

 \lstinputlisting[caption=Matlab style main code: "main.java", style=java]{main.java}


\end{document}

enter image description here