8

I want to put some “C” source code snippets in latex (I am using PDFLaTeX), but I don’t get the result that I want using the “listings” package.

What ideally would like to get is the same result as the source code is visible in Keil uVision IDE.

Here is a sample of what I want to get:

enter image description here

… and this is what I currently have:

enter image description here

The uVision IDE is using “Courier New” font at size 10 in…

  • normal style for the text (black colour)
  • italic style for the comments (green colour)
  • bold style for the keywords (black colour)
  • normal style for the decimal numbers (purple colour)
  • normal style for the brackets (blue colour)

If this proves to be quite tough to achieve, another alternative would be to get an all-black text, but with the C-keywords in bold (e.g. “for”, “if”, “void”, “int”, etc.) and the rest of the text in “Courier New” font at size 10 with no spacing. Also, it will be good to be able to edit the “TAB” size to 3 spaces.

I will really appreciate any help on that.

  • Did you also try the minted package? It uses Pygments which allows user-defined syntax highlighting. Also have a look at the list of syntax highlighting related packages on CTAN. – matth Jan 29 '14 at 18:06
10

The listings package does not have a parser feature to detect decimal numbers. Thus it is very difficult to catch them. Key literate does not help much, because numbers in identifiers must not be colored.

The other requirements are easier:

  • The following example uses the Latin Modern fonts.
  • The colors are taken from the IDE's screenshot in the question.
  • The color for the brackets and other punctuation/operator symbols are set by the literate feature of listings. The list can be extended for other symbols. Exception, if* and / are redefined using literate, then the comment detection breaks.
\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\usepackage[T1]{fontenc}
%\usepackage{tgcursor}
\usepackage{lmodern}

\colorlet{comment}{green!50!black}
\colorlet{cppcomment}{teal}
\colorlet{symb}{blue!50!black}
\colorlet{number}{violet}

\newcommand*{\textcolorsymb}{\textcolor{symb}}

\lstdefinestyle{cpp}{%
  language=C++,
  columns=flexible,
  basewidth=.5em,  
  tabsize=3,
  basicstyle=\ttfamily,
  commentstyle={\itshape\color{comment}\let\textcolorsymb\relax},
  keywordstyle=\bfseries,
  morecomment={[l][\itshape\color{cppcomment}\let\textcolorsymb\relax]//},
  literate=%
    {\{}{\textcolorsymb{\{}}1
    {\}}{\textcolorsymb{\}}}1
    {(}{\textcolorsymb{(}}1
    {)}{\textcolorsymb{)}}1
    {;}{\textcolorsymb{;}}1
    {=}{\textcolorsymb{=}}1
    {<}{\textcolorsymb{<}}1
    {>}{\textcolorsymb{>}}1
    {!}{\textcolorsymb{!}}1
    {\&}{\textcolorsymb{\&}}1 
    {|}{\textcolorsymb{|}}1
    {?}{\textcolorsymb{?}}1
    {:}{\textcolorsymb{:}}1
    {+}{\textcolorsymb{+}}1
    {-}{\textcolorsymb{-}}1
    {,}{\textcolorsymb{,}}1
    {\%}{\textcolorsymb{\%}}1
    {\^}{\textcolorsymb{\textasciicircum}}1
    {~}{\textcolorsymb{\textasciitilde}}1
    %% {/}{\textcolorsymb{/}}1
    %% {*}{\textcolorsymb{*}}1
    % 2 (optionally)
    {==}{\textcolorsymb{==}}2
    {>=}{\textcolorsymb{=>}}2
    {<=}{\textcolorsymb{<=}}2
    {!=}{\textcolorsymb{!=}}2
    {+=}{\textcolorsymb{+=}}2
    {-=}{\textcolorsymb{-=}}2
    {*=}{\textcolorsymb{*=}}2
    {/=}{\textcolorsymb{/=}}2
    {\%=}{\textcolorsymb{\%=}}2
    {\&\&}{\textcolorsymb{\&\&}}2
    {||}{\textcolorsymb{||}}2
    {++}{\textcolorsymb{++}}2
    {--}{\textcolorsymb{--}}2
    {>>}{\textcolorsymb{>\kern0pt>}}2
    {<<}{\textcolorsymb{<\kern0pt<}}2
    {::}{\textcolorsymb{::}}2
    % 3 (optionally)
    {>>=}{\textcolorsymb{>\kern0pt>=}}3
    {<<=}{\textcolorsymb{<\kern0pt<=}}3
    % Remove byte order mark
    {^^ef^^bb^^bf}{}0
}
\lstnewenvironment{cpp}{\lstset{style=cpp}}{}

\begin{document}
\begin{cpp}
long some_function();
int other_function(); 

/* This is a comment ()={}; */
int calling_function()
{
        long test1;
        int test2;

        a == b <= c >= d;
        a & b && c | d || e; 
        a ? b : c;
        a + b++, c - d--;
        a %= b % c >> e << f;
        a *= *c; d /= e;
        a / b ^ c ~ d;
        a <<= b, c >>= d;

        test1 = some_function();

        // this is another comment
        if (test1 > 0)
        {
                test2 = 0;   
        }
        else
        {
                test2 = other_function();
        }
        return test2;
}
\end{cpp}
\end{document}

Result Latin Modern

The result with TeX Gyre Cursor (developed from Ghostscript's Cursor variant): \usepackage{lmodern} is replaced by \usepackage{tgcursor}.

Result TG Cursor

Removal of the byte order mark

Byte order marks in UTF-8 can be removed by a properly configured editor. Or the literate feature can also be used to remove them, see above and here:

literate={^^ef^^bb^^bf{}0}

See Ulrike Fischer's answer to xport's question "How to suppress BOM effect in the output?".

  • Thank you very much, this is great! Two more thing would make it better: i) is it possible to adjust the font size and ii) all the operators as well as all the brackets (apart from the right curly bracket) are displayed in blue while under a comments section. Is it possible to somehow "force" everything that is under a comments section to be displayed in the comments-colour (i.e. green)? – limp Jan 29 '14 at 16:07
  • 1
    @limp: i) You can add a font size command to basicstyle, e.g. basicstyle={\ttfamily\small} or basicstyle={\ttfamily\fontsize{10}{12}\selectfont}. Or it can be placed in the begin part of environment cpp: \lstnewenvironment{cpp}{\lstset{style=cpp}\small}{} – Heiko Oberdiek Jan 29 '14 at 16:22
  • 1
    @limp: ii) Fixed. – Heiko Oberdiek Jan 29 '14 at 16:23
  • There are a couple of problems when I try to define symbols consisting of more than one character in the "literature". Specifically, I get an error when I try to define the &, &&, | and || symbols. Also, in the symbols that I successfully added (==, <=, >= and !=), the space after the double-character symbol is disappeared (so the text following these symbols is “glued” to the symbol. Finally, adding () is also problematic. – limp Jan 29 '14 at 17:19
  • I solved the problem with the dissapearing space after a double-character symbol (defined in literature) by adding keepspaces=true in \lstdefinestyle. – limp Jan 29 '14 at 17:31

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.