# LaTeX \newenvironment with nested braces

I'm making a beamer presentation and I wanted to show terminal commands in a terminal-styled box. I've created what I want using tkiz but now I have some trouble defining it as a new environment due to what I think is the preprocessor mismatching braces. Here is the block I want to turn into an environment.

% Define box and box title style
\tikzstyle{terminal} = [draw=white, text=white, font=courier, fill=black, very thick,
rectangle, inner sep=10pt, inner ysep=20pt]
\tikzstyle{terminalTitle} =[fill=black, text=white, draw=white]

\begin{tikzpicture}
\node [terminal] (box){      % 1: this
\begin{minipage}{0.90\textwidth}
\begin{lstlisting}
$python -c " print 'x'*80 + '\x01' " | ./test1 Enter password: You win!$
\end{lstlisting}
\end{minipage}
};                           % 2: matches this
\node[terminalTitle, rounded corners, right=10pt] at (box.north west) {\texttt{tty1: /bin/bash}};
\end{tikzpicture}


Here is the result:

But when I try to make it into a new environment, the pre-processor matches brace #2 and throws errors. I tried using the package environ like so:

\NewEnviron{terminal}{
\tikzstyle{terminal} = [draw=white, text=white, font=courier, fill=black, very thick,
rectangle, inner sep=10pt, inner ysep=20pt]
\tikzstyle{terminalTitle} =[fill=black, text=white, font=\ttfamily, draw=white]

\begin{tikzpicture}
\node [terminal] (box){%
\begin{minipage}{0.90\textwidth}
\begin{lstlisting}
\BODY
\end{lstlisting}
\end{minipage}
};
\node[terminalTitle, rounded corners, right=10pt] at (box.north west) {tty: /bin/bash}};
\end{tikzpicture}%
}


But I still get errors. Is there a way to escape the nested braces in this environ?

Also here is the preamble:

\documentclass{article}

\usepackage{tikz}
\usepackage{listings}
\usepackage{lipsum}
\usepackage{courier}
\usepackage{environ}

\usetikzlibrary{shapes}

\lstset{basicstyle=\ttfamily,breaklines=true}

-
You shouldn't bury lstlisting in an environment defined with \NewEnviron; and there's no need of environ either. – egreg Dec 27 '13 at 15:48

Hiding lstlisting inside an environment defined with \NewEnviron can't really work, because the lstlisting environment needs to massage the code in a way that it can't do if the code has already been absorbed in \BODY.

Here's a working version (almost, you need to solve the size problem):

\documentclass{article}

\usepackage{tikz}
\usepackage{listings}

\usetikzlibrary{shapes}

\lstset{basicstyle=\ttfamily,breaklines=true}
\newsavebox\terminalbox
\lstnewenvironment{terminal}[1][]
{\lstset{#1}\setbox\terminalbox=\vbox\bgroup\hsize=0.7\textwidth}
{\egroup
\tikzstyle{terminal} = [
draw=white, text=white, font=courier, fill=black, very thick,
rectangle, inner sep=10pt, inner ysep=20pt
]
\tikzstyle{terminalTitle} = [
fill=black, text=white, font=\ttfamily, draw=white
]
\begin{tikzpicture}
\node [terminal] (box){\usebox{\terminalbox}};
\node[terminalTitle, rounded corners, right=10pt] at (box.north west) {tty: /bin/bash};
\end{tikzpicture}
}

\begin{document}

\begin{terminal}
$python -c " print 'x'*80 + '\x01' " | ./test1 Enter password: You win!$
\end{terminal}

\end{document}


A better LaTeX style would use lrbox, but it turns out that \lstnewenvironment doesn't like it.

Check also the tcolorbox package.

-
Also, is there a way to make the current lstset style not affect the terminal environment? – rausted Dec 31 '13 at 3:05
@rausted You have to issue another style choice. – egreg Dec 31 '13 at 9:51

Thanks egreg for your answer. Based on your solution and using resizebox of the graphicx package, I solved the size issue and made the width equal to textwidth. Posting here for whoever wants to use this. Also, doing the same with tcolorbox should be easier but this doesn't require any CTAN packages.

\usepackage{graphicx}
\usepackage{listings}
\usepackage{color}
\usepackage{courier}
\usepackage{tikz}

\usetikzlibrary{shapes}

\lstset{basicstyle=\ttfamily\footnotesize,breaklines=true}
\newsavebox\terminalbox
\lstnewenvironment{terminal}[1][]
{\lstset{#1}\setbox\terminalbox=\vbox\bgroup\hsize=0.8\textwidth}
{\egroup
\tikzstyle{terminal} = [
draw=white, text=white, font=courier, fill=black, very thick,
rectangle, inner sep=2pt, inner ysep=8pt
]
\tikzstyle{terminalTitle} = [
fill=black, text=white, font=\ttfamily, draw=white
]
\noindent\resizebox{\textwidth}{!}{ % This line fits the box to textwidth
\begin{tikzpicture}
\node [terminal] (box){\usebox{\terminalbox}};
\node[terminalTitle, rounded corners, right=10pt] at (box.north west) {tty: /bin/bash};
\end{tikzpicture}}
}

\begin{document}
\begin{terminal}
$python -c " print 'x'*80 + '\x01' " | ./test1 Enter password: You win!$
\end{terminal}
\end{document}


-