6

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.

1 Answer 1

8

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

3
  • Styles probably are the way to go. However, your answer would be more helpful if you could demonstrate their use on the concrete problem of the OP.
    – Daniel
    May 21, 2013 at 6:01
  • So you're telling me that I should define a complete style for every language? What if I want to change the keyword color later? I should change it in every style? It's not like I have a dozen languages, not even a lot of pieces of code, but still doesn't seem a very LaTeX-way. For instance, when I defined the story-language, it "inherited" the keyword and [2]keyword settings, that was what I wanted to keep it consistent.
    – Nico
    May 21, 2013 at 12:02
  • @Nico, well you probably don't need to add more keywords , take a look at page 12 it shows different languages that supported. If you want different colours then you should identify each style separate, if you only interesting in different keywords then just put different languages instead of style.
    – vveliev
    May 21, 2013 at 17:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .