Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to define a listing style in order to have fortran source codes which look like vim style colors.

For example, I would like to give a specific color to end program or end module or double precision ect ...

It is easy for keywords without blank character but I do not know how to do for keyword such as those above.

As you can see in the example below, the color of program is the good one but the color of end program is not the good one.

\documentclass{article}

\usepackage{xcolor}
\definecolor{keycolor}{RGB}{172, 42, 42}
\definecolor{vimvert}{RGB}{46, 139, 87}

\usepackage{listings}

% global parameters
\lstdefinestyle{global}{
  basicstyle=\ttfamily\scriptsize\color{black!90},%
  stringstyle=\itshape\color{magenta},%
  showstringspaces=false,%
  keywordstyle=\bfseries\color{keycolor},%
  commentstyle=\color{gray}\slshape,%
}

% fortran style
\lstdefinestyle{fortranstyle}{
  language=Fortran,%
  style=global,%
  emph=[1]{implicit none, integer, real, double precision, character, len, parameter, structure, common},%
  emphstyle=[1]\bfseries\color{vimvert},%
  emph=[2]{program,end program, module, end module, subroutine, end subroutine, function, end function},%
  emphstyle=[2]\color{violet}\bfseries\slshape,%
  emph=[3]{call, true, false},%
  emphstyle=[3]\color{teal}\slshape%
}

\begin{document}

\begin{lstlisting}[style=fortranstyle]
program calcPi

  implicit none

  integer            :: i, nbreDansCercle
  integer, parameter :: npts = 1000000000
  double precision   :: x, y, r, pi

  nbreDansCercle = 0
  do i = 1, npts, 1
      call random_number(x)
      call random_number(y)
      x = 2.d0 * x - 1.d0
      y = 2.d0 * y - 1.d0
      r = x**2 + y**2

      if (r < 1.d0) then
          nbreDansCercle = nbreDansCercle + 1
      end if
  end do

  pi = 4.d0 * dble(nbreDansCercle) / dble(npts)
  write(*,"('pi = ', F20.17)") pi

end program calcPi
\end{lstlisting}

\end{document}

enter image description here

share|improve this question

marked as duplicate by Jubobs, Jesse, Werner, Claudio Fiandrino, Peter Jansson Jan 16 at 7:24

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

add comment

1 Answer

One solution would be the use of the moredelim key (see package manual section 3.3 "Delimters")

I defined two more delimeters:

  • moredelim=[is][emphstyle]{|>}{<|} for implicit none and double precision that also don't get highlighted as you might want to define.
  • moredelim=[is][emphstyle2]{|<}{>|} for end program and end module

There is one drawback: This has to be done manually or via Search-and-Replace and Regex but still, you can't simply copypaste code from your source or include it with \lstinputlisting.

Code

\documentclass{article}

\usepackage{xcolor}
\definecolor{keycolor}{RGB}{172, 42, 42}
\definecolor{vimvert}{RGB}{46, 139, 87}

\usepackage{listings}

% global parameters
\lstdefinestyle{global}{
  basicstyle=\ttfamily\scriptsize\color{black!90},%
  stringstyle=\itshape\color{magenta},%
  showstringspaces=false,%
  keywordstyle=\bfseries\color{keycolor},%
  commentstyle=\color{gray}\slshape,%
}

% fortran style
\lstdefinestyle{fortranstyle}{
  language=Fortran,%
  style=global,%
  emph={[1]integer, real, character, len, parameter, structure, common},%
  emphstyle=[1]\bfseries\color{vimvert},%
  emph={[2]program, module, subroutine, function},%
  emphstyle=[2]\color{violet}\bfseries\slshape,%
  emph={[3]call, true, false},%
  emphstyle=[3]\color{teal}\slshape,%
  moredelim=[is][emphstyle]{|>}{<|},%
  moredelim=[is][emphstyle2]{|<}{>|}%
}


\begin{document}
\begin{lstlisting}[style=fortranstyle]
program calcPi

  |>implicit none<|

  integer            :: i, nbreDansCercle
  integer, parameter :: npts = 1000000000
  |>double precision<|   :: x, y, r, pi

  nbreDansCercle = 0
  do i = 1, npts, 1
  end do

  pi = 4.d0 * dble(nbreDansCercle) / dble(npts)
  write(*,"('pi = ', F20.17)") pi

|<end program>| calcPi
\end{lstlisting}
\end{document}

Output

Output of code

PS: You could also use moredelim=[s][emphstyle]{implicit}{none} (note the missing i) but this works only if you use implicit with a following none. The same applies to double precision and most importantly end program.
It would fail when it encounters an end do because end is still a delimiter which does not find a program and it will all be set in emphstyle.

share|improve this answer
    
I think that your last solution in the post scriptum is the best one and the simplest one ! Thanks –  Ger Sep 18 '12 at 7:03
    
Actually, moredelim=[s][emphstyle]{implicit}{none} does not work. If I did that, all the text after implicit none is green. –  Ger Sep 20 '12 at 8:27
add comment

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