LaTeX \newenvironment с вложенными фигурными скобками

LaTeX \newenvironment с вложенными фигурными скобками

Я делаю презентацию в бимере и хотел показать команды терминала в окне в стиле терминала. Я создал то, что мне нужно, с помощью tkiz, но теперь у меня возникли некоторые проблемы с определением его как новой среды из-за того, что, как я думаю, препроцессор не совпал со скобками. Вот блок, который я хочу превратить в среду.

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

Вот результат:

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

Но когда я пытаюсь сделать это в новой среде, препроцессор сопоставляет скобку #2 и выдает ошибки. Я пробовал использовать пакетокружающая средавот так:

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

Но я все еще получаю ошибки. Есть ли способ обойти вложенные скобки в этой среде?

А вот и преамбула:

\documentclass{article}

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

\usetikzlibrary{shapes}

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

решение1

Скрытие lstlistingвнутри среды, определенной с помощью , \NewEnvironна самом деле не может работать, поскольку lstlistingсреда должна обрабатывать код таким образом, что она не сможет сделать, если код уже был поглощен \BODY.

Вот рабочая версия (почти, нужно решить проблему с размером):

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

Лучшим стилем LaTeX было бы использование lrbox, но, как оказалось, ему \lstnewenvironmentэто не нравится.

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

Проверьте также tcolorboxупаковку.

решение2

Спасибо egreg за ответ. Основываясь на вашем решении и используя resizebox пакета graphicx, я решил проблему с размером и сделал ширину равной textwidth. Размещаю здесь для тех, кто хочет это использовать. Кроме того, сделать то же самое с tcolorbox должно быть проще, но для этого не требуются никакие пакеты CTAN.

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

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

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