tcolorbox newtcblisting "! File ended while scanning use of \verbatim@start"

I have the following code snippet:

\documentclass{article}
\usepackage[minted]{tcolorbox}

\newtcblisting{shell}[1][]{listing only, title={Output},
listing engine=minted, minted language=text}

\begin{document}

\begin{shell}
a {"John Marwood Cleese", 123456}
\end{shell}

\begin{shell}
{"John Marwood Cleese", 123456}
\end{shell}

\end{document}

The first shell environment can correct compiled. But the second one issued the error "! File ended while scanning use of \verbatim@start".

Can anyone explain this?

What I want is:

\begin{shell}
{"John Marwood Cleese", 123456}
\end{shell}

How can I get this code work? Thank you very much.

I guess that you're going to use the optional argument in your real-life code, so I won't tell you to remove it.

You can use the xparse library. Just for the sake of experimenting, I use the optional argument to set the language.

\documentclass{article}
\usepackage[minted]{tcolorbox}
\tcbuselibrary{xparse}

\NewTCBListing{shell}{!O{text}}{
listing only,
title={Output},
listing engine=minted,
minted language=#1,
}

\begin{document}

\begin{shell}
a {"John Marwood Cleese", 123456}
\end{shell}

\begin{shell}
{"John Marwood Cleese", 123456}
\end{shell}

\begin{shell}[tex]
a {"John Marwood Cleese", 123456}
\end{shell}

\begin{shell}[tex]
{"John Marwood Cleese", 123456}
\end{shell}

\end{document}

The ! preceding the specification for the optional argument tells LaTeX that if a space (or endline) is found, then no optional argument will be looked for.

Limitation: you can't say \begin{shell} [options]: the optional argument must be attached to }. It doesn't seem a big deal.

The problem with \newtcblisting{shell}[1][]{...} is that the [ will be looked for ignoring spaces (or the endline), so the leading { is already scanned before the changes for verbatim mode are performed.

The following works by removing the optional argument. Without it there is no look-ahead for the [ that will accidentally tokenize the { and freeze its category code to 1 (begin-group). Because of this category code freezing the argument grabbing for a verbatim environment doesn't work (the corresponding \end{shell} is part of a local group and hence hidden from TeX's delimited argument scanner).

\documentclass{article}
\usepackage[minted]{tcolorbox}

\newtcblisting{shell}{listing only, title={Output},
listing engine=minted, minted language=text}

\begin{document}

\begin{shell}
a {"John Marwood Cleese", 123456}
\end{shell}

\begin{shell}
{"John Marwood Cleese", 123456}
\end{shell}

\end{document}

If you absolutely need the optional argument you'll have a few options:

• implement the argument grabbing logic yourself
• patch some internals to get it working
• use something that doesn't hurt if it's tokenized

The following shows the last option, freezing an \empty that'll just expand to nothing in later steps:

\documentclass{article}
\usepackage[minted]{tcolorbox}

\newtcblisting{shell}[1][]{listing only, title={Output},
listing engine=minted, minted language=text}

\begin{document}

\begin{shell}
a {"John Marwood Cleese", 123456}
\end{shell}

\begin{shell}
\empty{"John Marwood Cleese", 123456}
\end{shell}

\end{document}

But this just shows the problematic aspect of this: You'll always have to watch out to use your environment in a way that doesn't hurt. It would be better to use a mandatory argument (or at least the last argument should be a mandatory one).

Both show the following output: