[Tex/LaTex] rectangle around code in lstlisting (deal with multiple pages)

framedlistings

I've been trying to get this working, but have hit an issue.

I was using TikZ to draw rectangles around blocks of code – so without splitting up my lstlisting I could add start-end and it would draw a rounded rectangle around that block. I've included my simple code.

BIG problem is, it won't work across multiple pages – so for longer code listings that go across pages, it fails 🙁

I've tried frames and different version, but always failing.

\documentclass[11pt]{article}
\usepackage{listingsutf8}
\usepackage{tikz}

\usetikzlibrary{decorations.text}

\newcommand\myboxs[1]%
{
    \tikz[remember picture,overlay]\node (mk1) {};
}

\newcommand\myboxe[1]%
{
    \tikz[remember picture,overlay]\node (mk2) {};

    \begin{tikzpicture}[remember picture,overlay]
    \draw[red,ultra thick,rounded corners] ([shift={(-10pt,2ex)}] mk1) rectangle ([shift={(\textwidth,-0.65ex)}] mk2);
    \end{tikzpicture}
}



\begin{document}


    \begin{lstlisting}[language=c,escapeinside={(*@}{@*)}]
    #include <stdio.h>

    #include <iostream>

    int test()
    {
    std::cout << "Hello World!";
    }

    (*@ \myboxs{}; @*)
    int main (void)
    {
        int value1, value2, sum;//declaring
        value1 = 50;//assign values
        value2 = 25;
        sum = value1 + value2;//sum them
        //output

        printf ("%d (*@  @*)+%d \n");


        while (true)
        {
            printf(..)
        }
    (*@ \myboxe{}; @*)


    int etc()
    {
    std::cout << "Hello World!";
    }

    int another()
    {
    std::cout << "Hello World!";
    }


    \end{lstlisting}

\end{document}

Best Answer

It can be done with the framed package together with tcolorbox. tcolorbox alone will not close the rounded rectangles at a page break, as far as I know.

\documentclass[a4paper, 12pt, twoside]{book}

\usepackage{sourcecodepro}
\usepackage{listingsutf8}

\usepackage{framed}
\usepackage{tcolorbox}
\newenvironment{roundedframe}{%
  \def\FrameCommand{\tcbox[arc=5mm,colframe=red]}%
  \MakeFramed {\advance\hsize-\width \FrameRestore}}%
 {\endMakeFramed}

\lstnewenvironment{clisting}
    {\lstset{language=c,escapeinside={(*@}{@*)}}}
    {}

\lstnewenvironment{boxedlisting}
    {\lstset{language=c,escapeinside={(*@}{@*)}}}
    {}

\usepackage{etoolbox}
\BeforeBeginEnvironment{boxedlisting}{\begin{roundedframe}}
\AfterEndEnvironment{boxedlisting}{\end{roundedframe}}

\usepackage{lipsum}
\begin{document}
\lipsum[1-2] % to force a page break

\begin{clisting}
 #include <stdio.h>

 #include <iostream>

 int test()
 {
 std::cout << "Hello World!";
 }
\end{clisting}
\begin{boxedlisting}
 int main (void)
 {
     int value1, value2, sum;//declaring
     value1 = 50;//assign values
     value2 = 25;
     sum = value1 + value2;//sum them
     //output

     printf ("%d (*@  @*)+%d \n");


     while (true)
     {
         printf(..)
     }
 }
\end{boxedlisting}
\begin{clisting}

 int etc()
 {
 std::cout << "Hello World!";
 }

 int another()
 {
 std::cout << "Hello World!";
 }

\end{clisting}
\end{document}

enter image description here