Tuesday, March 23, 2010

Nicely formatted listings in LaTeX with adjusted fonts

I'm using the listings package in order to get nicely formatted listings in latex. Since many people are used to the fonts and syntax highlighting of their IDE, I tried to emulate the layout and colors of code as it is formatted in Eclipse. Thanks to XeTeX, I'm able to simply change the font in listing as well. I use two fonts for listing paragraphs and inline:

\newfontfamily\listingsfontinline[Scale=0.8]{Courier New} 
This enables bold fonts in typewriter, another way of solving this problem is to use LuxiMono, but I haven't tried that one. Then I define the colors Eclipse uses, comments are defined a little bit darker:

\definecolor{sh_comment}{rgb}{0.12, 0.38, 0.18 } %adjusted, in Eclipse: {0.25, 0.42, 0.30 } = #3F6A4D
\definecolor{sh_keyword}{rgb}{0.37, 0.08, 0.25}  % #5F1441
\definecolor{sh_string}{rgb}{0.06, 0.10, 0.98} % #101AF9
Sometimes I need math text in listings, e.g. when writing pseudo code. Since I scaled the fonts down, the normal math fonts (displaystyle) are a little bit too large. One possible solution of resizing the math fonts would be to use \DeclareMathSizes, however I do not want to change the font for the whole document. The listings package provides two properties "escapebegin" and "escapeend", which are inserted before and after escaping to latex or math. However, simply using escapebegin={\ \scriptstyle} would cause errors when escaping not to math but to normal latex mode. In order to solve that problem, I define a custom command:

\def\lstsmallmath{\leavevmode\ifmmode \scriptstyle \else  \fi}
\def\lstsmallmathend{\leavevmode\ifmmode  \else  \fi}
Now I'm ready to define the overall style for listings:

\lstset {
 basicstyle= \listingsfont,
 keywordstyle = \color{sh_keyword}\bfseries,
 xleftmargin=0.7cm, xrightmargin=0.5cm,
 escapebegin={\lstsmallmath}, escapeend={\lstsmallmathend}
Comments are printed italic for black-white prints. In order to simplify the use of \lstinline, I define some commands for my favorite languages, e.g.,

\newcommand{\lstJava}[1]{\lstinline[language=Java,breaklines=true,basicstyle= \listingsfontinline]$#1$}


\begin{lstlisting}[language=Java, caption={Just a test}, label={lst:Test}]
package de.jevopi;

 * This is my class
public class Test {

 public void foo(String s) {
  System.out.println("Hello " + s);

will produce the following output (on the left). On the right, you can see the Eclipse version of the very same code snippet. (Click to enlarge images)


madmuffin said...

Thanks! Very helpful for my computer science homework.

Kelvin Hu said...

Thanks very much, very helpful post.

Danny said...

Very useful - thank you very much!