12

I am typesetting something that has a lot of Java code listings. Because the Java code has a lot of annotations, and that they are important to the reader, I'd like to have them highlighted, like other keywords such as class, public, etc.

I want the output to be in black and white.

I tried using minted, but the bw output does not highlight the annotations.

How can I arm-twist listings to highlight the annotations?

P.S. Here is the lstset that I am using:

\lstset{
  basicstyle=\footnotesize\tt,        % the size of the fonts that are used for the code
  breakatwhitespace=false,         % sets if automatic breaks should only happen at whitespace
  breaklines=true,                 % sets automatic line breaking
  captionpos=b,                    % sets the caption-position to bottom
  extendedchars=true,              % lets you use non-ASCII characters; for 8-bits encodings only, does not work with UTF-8
  frame=single,                    % adds a frame around the code
  language=Java,                 % the language of the code
  keywordstyle=\bf,
  showspaces=false,                % show spaces everywhere adding particular underscores; it overrides 'showstringspaces'
  showstringspaces=false,          % underline spaces within strings only
  showtabs=false,                  % show tabs within strings adding particular underscores
  tabsize=2                       % sets default tabsize to 2 spaces
}
  • you should first search for your answer. use morekeywords={public, void} .Take a look at this link – vveliev May 21 '13 at 23:20
  • 2
    What vvelieve said is partially true. The point is public and void are not annotations; @Override is an annotation. What you should do is to add @Override as a key world (with the @). If you are using classical java annotations this is feasible solution. However if you have many user-defined annotations a better solution is to tell listings to declare every word that comes after @ as a key word. This is maybe achievable by using moredelim option. You can have an idea how to do so by reading listings documentation. – Pouya May 22 '13 at 10:12
  • I am looking at moredelim, but it looks like I need to know both the starting and ending characters. Annotations are not required to be ended with anything specific, which I guess would be a mine field for the listings package. – malaverdiere May 22 '13 at 14:58
16

First, some thoughts on minted: this great package relies on Pygments and AFAIK most of the available styles does support Java annotations. Sadly, as you pointed out, the bw style doesn't highlight annotations.

One possibility is to create an extended version of this style (in order words, create a new style with bw as base) and then include the instruction that sets the formatting for annotations (I just took a quick look at some styles, but failed to determine which instruction is used by Pygments to refer to an annotation).

If you want to try listings instead, I'd go with Pouya's suggestion on using custom delimiters. The reason is that, in my humble opinion, since annotations are syntactic metadata, they cannot be treated as keywords or comments, hence a different style to represent them would be a wiser choice.

I know you are using a black and white theme, but I decided to create a colored output just for us to see which style is being applied to each identifier. The concept would be the same, just replace color occurrences by the font series you want.

In my code, I'd create two delimiters:

moredelim=[il][\textcolor{pgrey}]{$$},
moredelim=[is][\textcolor{pgrey}]{\%\%}{\%\%}

The first, $$, is applied to the whole line and it can be used for annotations that are in lines of their own (think of a single line comment here). The second one, %% ... %%, behaves like a multiline comment, which encloses everything that is inside these delimiters, and it's useful for annotations that are applied inline to methods or fields.

A sample code is as follows (the Java example here is a courtesy of Project Lombok):

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage{inconsolata}

\usepackage{color}

\definecolor{pblue}{rgb}{0.13,0.13,1}
\definecolor{pgreen}{rgb}{0,0.5,0}
\definecolor{pred}{rgb}{0.9,0,0}
\definecolor{pgrey}{rgb}{0.46,0.45,0.48}

\usepackage{listings}
\lstset{language=Java,
  showspaces=false,
  showtabs=false,
  breaklines=true,
  showstringspaces=false,
  breakatwhitespace=true,
  commentstyle=\color{pgreen},
  keywordstyle=\color{pblue},
  stringstyle=\color{pred},
  basicstyle=\ttfamily,
  moredelim=[il][\textcolor{pgrey}]{$$},
  moredelim=[is][\textcolor{pgrey}]{\%\%}{\%\%}
}

\begin{document}

\begin{lstlisting}
/**
 * This is a doc comment.
 */
package com.ociweb.jnb.lombok;

import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;

$$@Data
$$@EqualsAndHashCode(exclude={"address","city","state","zip"})
public class Person {
    enum Gender { Male, Female }

    // another comment

    %%@NonNull%% private String firstName;
    %%@NonNull%% private String lastName;
    %%@NonNull%% private final Gender gender;
    %%@NonNull%% private final Date dateOfBirth;

    private String ssn;
    private String address;
    private String city;
    private String state;
    private String zip;
}
\end{lstlisting}

\end{document}

The output:

Output

Hope it helps. :)

  • 1
    After the line moredelim=[il][\textcolor{pgrey}]{$$}, the whole code is green in TexStudio. Shouldn't you put moredelim=[il][\textcolor{pgrey}]{\$\$}, ? – Sweidán Omár Jun 1 '17 at 17:27
1

You can do it by getting listings to treat annotations like it does comments. Add this to your lstset:

morecomment=[s][\color{gray}]{@}{\ }

In brief: s-type comments have two delimiters, cannot be nested, and are defined as: morecomment=[s][(optional) <style>]{<startDelimiter>}{<endDelimiter>}

So the annotations style given above treats any string starting with @ and ending with a space as a comment, which is typeset in gray.

1

You can use the option keywordsprefix as defined in the docs on page 44, e.g.

keywordsprefix={@},

to highlight all Java annotations (all words starting with @). There are currently a few caveats/bugs though:

keywordsprefix=<prefix>

All identifers starting with the prefix will be printed as first order
keywords.

Bugs: Currently there are several limitations. (1) The prefix is always
case sensitive. (2) Only one prefix can be defined at a time. (3) If used 
‘standalone’ outside a language definition, the key might work only after 
selecting a nonempty language (and switching back to the empty language 
if necessary). (4) The key does not respect the value of classoffset and
has no optional class number argument.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.