10

I'm working on a custom lstlisting environment, in which I use TikZ to add a frame and a title. Because of the widespread curly braces of node I cannot use newenvironment, so I have to resort to NewEnviron.

From the MWE and the picture below it should be clear what I'm trying to accomplish:

\documentclass[a4paper,11pt]{article}

\usepackage{listings}
\lstset{breaklines=true, postbreak={\mbox{$\hookrightarrow\space$}}, language=Mathematica}

\usepackage{tikz}
\usetikzlibrary{shapes,decorations}

\tikzstyle{boxround} = [draw=black, thick, rectangle, rounded corners, inner sep=10pt, inner ysep=20pt]
\tikzstyle{head} =[draw=black, fill=white, thick, rectangle]

\usepackage{environ}

\NewEnviron{code}{%
\bigskip
\noindent\begin{tikzpicture}
\node [boxround] (box){%
\begin{minipage}{.94\textwidth}
\BODY
\end{minipage}};
\node[head, right=10pt] at (box.north west) {\textbf{Code listing}};
\end{tikzpicture}
\bigskip
}

\begin{document}

\begin{code}
How to get some \textsc{Mathematica} code (shown below) in this box...
\end{code}

\footnotesize
\begin{lstlisting}
B11[x_, y_] = Piecewise[{{1, 0 <= x <= 1 && 0 <= y <= 1}}];
Plot3D[B11[x, y], {x, -.5, 1.5}, {y, -.5, 1.5}, PlotRange -> Full]; 
\end{lstlisting}
\normalsize

\end{document}

Which results in

enter image description here

If it weren't for tikzpicture, I would just use lstnewenvironment. But considering the widespread curly braces of node I don't know how I could. Any ideas?

6
  • 2
    Sorry, isn't easier to use mdframed for the purpose? Commented Apr 12, 2013 at 16:36
  • Or have a look at the package tcolorbox with the library listings. Commented Apr 12, 2013 at 16:36
  • @ClaudioFiandrino I'm not familiar with that package, but if it is possible to create an environment with the exact same look as the one in my MWE, then that might be the answer.
    – Ailurus
    Commented Apr 12, 2013 at 16:50
  • Do you want to print the code with the size footnotesize? Commented Apr 12, 2013 at 16:57
  • 1
    Look at "example 5" in mdframed-example-tikz.pdf
    – Ignasi
    Commented Apr 12, 2013 at 17:07

2 Answers 2

10

Here a suggestion with mdframed:

\documentclass{article}

\usepackage{libertine}
\usepackage[T1]{fontenc}
\usepackage{listings}
\lstset{basicstyle=\footnotesize\ttfamily,breaklines=true, postbreak={\mbox{$\hookrightarrow\space$}}, language=Mathematica}

\usepackage[framemethod=TikZ]{mdframed}

\mdfdefinestyle{lstlisting}{%
 innertopmargin=5pt,
 middlelinewidth=1pt,
 outerlinewidth=9pt,outerlinecolor=white,
 innerleftmargin=10pt,
 innerrightmargin=10pt,
 leftmargin=-9pt,rightmargin=-9pt,
 skipabove=\topskip,
 skipbelow=\topskip,
 roundcorner=5pt,
 singleextra={\node[draw, fill=white,anchor=west, xshift=10pt+1pt,font=\bfseries] at (O|-P) {Code Listings};},
 firstextra={\node[draw, fill=white,anchor=west, xshift=10pt+1pt,font=\bfseries] at (O|-P) {Code Listings};}
}

\lstnewenvironment{code}{%
  \mdframed[style=lstlisting]%
}{\endmdframed}

\begin{document}
Text
\begin{code}
B11[x_, y_] = Piecewise[{{1, 0 <= x <= 1 && 0 <= y <= 1}}];
Plot3D[B11[x, y], {x, -.5, 1.5}, {y, -.5, 1.5}, PlotRange -> Full]; 
\end{code}
\end{document}

enter image description here


Update

In the example below you have a new environment named code which has one optional and one mandatory argument. The optional argument is passed to \lstset and the mandatory one is the title.

\documentclass{article}

\usepackage{libertine}
\usepackage[T1]{fontenc}
\usepackage{listings}
\lstset{basicstyle=\footnotesize\ttfamily,breaklines=true, postbreak={\mbox{$\hookrightarrow\space$}}, language=Mathematica}

\usepackage[framemethod=TikZ]{mdframed}

\makeatletter
\def\mdf@@codeheading{Code Listings}%new mdframed key:
\define@key{mdf}{title}{%
   \def\mdf@@codeheading{#1}
}

\mdfdefinestyle{lstlisting}{%
 innertopmargin=5pt,
 middlelinewidth=1pt,
 outerlinewidth=9pt,outerlinecolor=white,
 innerleftmargin=10pt,
 innerrightmargin=10pt,
 leftmargin=-9pt,rightmargin=-9pt,
 skipabove=\topskip,
 skipbelow=\topskip,
 roundcorner=5pt,
 singleextra={\node[draw, fill=white,anchor=west, xshift=10pt+1pt,font=\bfseries] at (O|-P) {\csname mdf@@codeheading\endcsname};},
 firstextra={\node[draw, fill=white,anchor=west, xshift=10pt+1pt,font=\bfseries] at (O|-P) {\csname mdf@@codeheading\endcsname};}
}

\lstnewenvironment{code}[2][]{%
  \lstset{#1}%
  \mdframed[style=lstlisting,title={#2}]%
}{\endmdframed}

\begin{document}
Text

\begin{code}{Mathematice Listings}
B11[x_, y_] = Piecewise[{{1, 0 <= x <= 1 && 0 <= y <= 1}}];
Plot3D[B11[x, y], {x, -.5, 1.5}, {y, -.5, 1.5}, PlotRange -> Full]; 
\end{code}

Text

\begin{code}{Code Listings}
B11[x_, y_] = Piecewise[{{1, 0 <= x <= 1 && 0 <= y <= 1}}];
Plot3D[B11[x, y], {x, -.5, 1.5}, {y, -.5, 1.5}, PlotRange -> Full]; 
\end{code}
\end{document}
6
  • Nice! So the singleextra and firstextra just use TikZ code. By the way, why do we need both? For this case it seems kind of redundant.
    – Ailurus
    Commented Apr 12, 2013 at 17:48
  • Hmm, then there must be something wrong with the firstextra command because I don't get a Code Listings label when the code has a page break. Is the (O|-P) part for the node correct?
    – Ailurus
    Commented Apr 12, 2013 at 19:41
  • Oh and one other thing — I'd like to use an argument to set the text of the node. For instance, \begin{code}{\textsc{Matlab} listing}. I'm currently studying the mdframed-TikZ example PDF, the anwer might be in there :).
    – Ailurus
    Commented Apr 12, 2013 at 20:11
  • @Ailurus: Indeed. I will fix it tomorrow. Commented Apr 12, 2013 at 20:27
  • 1
    @Ailurus: I updated my answer. Commented Apr 13, 2013 at 9:10
6

Here a suggestion using tcolorbox

\documentclass{article}
\usepackage{libertine}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage{tcolorbox}
\tcbuselibrary{listings}
\tcbuselibrary{skins}

\newenvironment{code}{%
  \tcblisting{listing only,colback=white,enlarge top by=5.5mm,enhanced,%
     overlay={\node[draw,fill=white,xshift=10pt,right,font=\bfseries] at (frame.north west) {Code Listings};},%
     listing options={basicstyle=\footnotesize\ttfamily,breaklines=true,%
                      postbreak={\mbox{$\hookrightarrow\space$}},language=Mathematica},%
  }%
 }%
 {\endtcblisting}

\begin{document}
\begin{code}
B11[x_, y_] = Piecewise[{{1, 0 <= x <= 1 && 0 <= y <= 1}}];
Plot3D[B11[x, y], {x, -.5, 1.5}, {y, -.5, 1.5}, PlotRange -> Full]; 
\end{code}

\end{document}

enter image description here

1
  • Good alternative, but for now I'll stick with the other solution.
    – Ailurus
    Commented Apr 12, 2013 at 20:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .