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 have lots of C++ sources with LaTeX formulas in the comments. Ideal for using the listings packages to pretty print the source. However, most of the formulas break either, the background or the frame lines when the formula is "tall" (e.g. contains an integral or a sum) as seen in the following working example and preview. The question is: how can I force listing not to break the frame on tall lines produced by tall math equations?

\documentclass{article}
\usepackage[]{listings}
\usepackage{xcolor}
 \lstset{
        backgroundcolor=\color[gray]{0.9},
        frame=single,
        mathescape=true,
}
\lstset{language=C++}
\begin{document}

\begin{lstlisting}
for(i = 0; i < 10; i++)
{
// gratuitious equation $\mathcal{D}_3(x) = \frac{x^n}{n} \int_{0_0}^{x^2} \frac{t^n}{e^t-1}dt$ 
*p++ = i;
House h = new house();
int romms = h.getRooms():
}
\end{lstlisting}

\end{document}

enter image description here

Note: If this is an intrinsic limitation of listings packages, then the real question could be how can equations be force to use the normal vertical space as much as possible in math mode. For example to force integrals and sums to be even shorter than inline math model.

I am also aware of this other question: listings with background color and mathescape broken, but that only solved for a particular math symbol.

share|improve this question

1 Answer 1

up vote 5 down vote accepted

You have at least two options to correct for this behaviour.

  1. If your mathematical equations (contained within the escaping $...$) is fairly simple and usually only contains a one line, and perhaps even does not have any other code above/below it, then you can \smash the escaped content:

    \documentclass{article}
    \usepackage{listings}% http://ctan.org/pkg/listings
    \usepackage{xcolor}% http://ctan.org/pkg/xcolor
    \begin{document}
    \lstset{%
      backgroundcolor=\color[gray]{0.9},%
      frame=single,%
      mathescape=true,%
    }
    \lstset{language=C++}%
    
    \begin{lstlisting}
    for(i = 0; i < 10; i++)
    {
    // gratuitious equation $\smash{\mathcal{D}_3(x) = \frac{x^n}{n} \int_{0_0}^{x^2} \frac{t^n}{e^t-1}dt}$ 
    *p++ = i;
    House h = new house();
    int romms = h.getRooms():
    }
    \end{lstlisting}
    
    \end{document}
    

    enter image description here

    However, as you can see, even from this small example, the bottom part of the equation is overwritten with the background colour. This is because the algorithm is typeset sequentially, overwriting anything with a depth below the baseline. So this option is very restrictive, and typically only works if your mathematical expression does not drop below the baseline. Pretty restrictive...

  2. You can use a different environment to draw the frame and background. The mdframed package does an excellent job of this:

    \documentclass{article}
    \usepackage{listings}% http://ctan.org/pkg/listings
    \usepackage{xcolor}% http://ctan.org/pkg/listings
    \usepackage[framemethod=TikZ]{mdframed}% http://ctan.org/pkg/mdframed
    \begin{document}
    \lstset{%
    %  backgroundcolor=\color[gray]{0.9},
    %  frame=single,
      mathescape=true,
    }
    \lstset{language=C++}%
    
    \begin{mdframed}[backgroundcolor=black!15,outerlinewidth=0.25pt,outerlinecolor=black,%
      innerleftmargin=5pt,innerrightmargin=5pt,innertopmargin=0pt,innerbottommargin=0pt]
    \begin{lstlisting}
    for(i = 0; i < 10; i++)
    {
    // gratuitious equation $\mathcal{D}_3(x) = \frac{x^n}{n} \int_{0_0}^{x^2} \frac{t^n}{e^t-1}dt$ 
    *p++ = i;
    House h = new house();
    int romms = h.getRooms():
    }
    \end{lstlisting}
    \end{mdframed}
    
    \end{document}
    

    enter image description here

    In the above example, mdframed uses tikz to draw the frame. It is possible to automate this process of using mdframed in conjunction with listings. For this, the etoolbox package provides hooked to add code before the beginning and after the end of an environment (lstlisting in this case). For this, the macros \BeforeBeginEnvironment and \AfterEndEnvironment is helpful. It is crucial to add code in this manner, since lstlisting modified catcodes for formatting:

    \documentclass{article}
    \usepackage{listings}% http://ctan.org/pkg/listings
    \usepackage{xcolor}% http://ctan.org/pkg/listings
    \usepackage[framemethod=TikZ]{mdframed}% http://ctan.org/pkg/mdframed
    \usepackage{etoolbox}{% http://ctan.org/pkg/etoolbox
    
    \mdfdefinestyle{listingstyle}{%
      backgroundcolor=black!15,outerlinewidth=0.25pt,outerlinecolor=black,%
      innerleftmargin=5pt,innerrightmargin=5pt,innertopmargin=0pt,innerbottommargin=0pt%
    }
    
    \begin{document}
    
    \lstset{mathescape=true,language=C++}%
    
    \BeforeBeginEnvironment{lstlisting}{\begin{mdframed}[style=listingstyle]}
    \AfterEndEnvironment{lstlisting}{\end{mdframed}}
    
    \begin{lstlisting}
    for(i = 0; i < 10; i++)
    {
    // gratuitious equation $\mathcal{D}_3(x) = \frac{x^n}{n} \int_{0_0}^{x^2} \frac{t^n}{e^t-1}dt$ 
    *p++ = i;
    House h = new house();
    int romms = h.getRooms():
    }
    \end{lstlisting}
    
    \end{document}
    

In the above modification, a new mdframed style listingstyle is defined and used as style=listingstyle in the option argument to the mdframed environment. The output is similar to the previous example.

share|improve this answer
    
thanks, two decent workarounds for sure. And it is good to know about the smash command. for the smash alternative: can the problem be alleviated by defining the background color as a transparency level? (is that possible at all?). For the mdframed based solution: probably perfect solution (at the cost of adding more dependecies --not present in TeXLive 2009-- and another level of environment), also can listing package be directly be told to use mdframed for framing? –  alfC Oct 5 '11 at 6:47
    
I would think the mdframed solution is best. I've updated my solution to accommodate an automated approach (it additionally requires the etoolbox package). –  Werner Oct 5 '11 at 7:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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