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?

  • 2
    Sorry, isn't easier to use mdframed for the purpose? – Claudio Fiandrino Apr 12 '13 at 16:36
  • Or have a look at the package tcolorbox with the library listings. – Marco Daniel Apr 12 '13 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 Apr 12 '13 at 16:50
  • Do you want to print the code with the size footnotesize? – Marco Daniel Apr 12 '13 at 16:57
  • 1
    Look at "example 5" in mdframed-example-tikz.pdf – Ignasi Apr 12 '13 at 17:07
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}
  • 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 Apr 12 '13 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 Apr 12 '13 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 Apr 12 '13 at 20:11
  • @Ailurus: Indeed. I will fix it tomorrow. – Marco Daniel Apr 12 '13 at 20:27
  • 1
    @Ailurus: I updated my answer. – Marco Daniel Apr 13 '13 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

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

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.