Объединение `tikzpicture` и `lstlisting`

Объединение `tikzpicture` и `lstlisting`

Я работаю над пользовательской lstlistingсредой, в которой я использую TikZ для добавления рамки и заголовка. Из-за широко распространенных фигурных скобок я nodeне могу использовать newenvironment, поэтому мне приходится прибегать к NewEnviron.

Из MWE и рисунка ниже должно быть ясно, чего я пытаюсь добиться:

\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}

Что приводит к

введите описание изображения здесь

Если бы не tikzpicture, я бы просто использовал lstnewenvironment. Но учитывая распространенность фигурных скобок , nodeя не знаю, как я мог бы. Есть идеи?

решение1

Вот предложение с 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}

введите описание изображения здесь


Обновлять

В примере ниже у вас есть новая среда с именем, codeкоторая имеет один необязательный и один обязательный аргумент. Необязательный аргумент передается \lstset, а обязательным является заголовок.

\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}

решение2

Вот предложение с использованием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}

введите описание изображения здесь

Связанный контент