[Tex/LaTex] How to define a new minted environment with optional arguments

environmentsfancyvrbkey-valueminted

I have the following mwe:

% arara: pdflatex: { shell: true }
% arara: pdflatex: { shell: true }
\documentclass{article}
\usepackage{minted}
\usepackage{listings}
\usepackage{caption}
\captionsetup[lstlisting]{font=sf,labelfont=bf,skip=\smallskipamount}
\usepackage{xparse}
\NewDocumentEnvironment {example} { mm  }
{\VerbatimEnvironment
 \captionof{lstlisting}{#2}\ifx\relax#1\relax\else\label{#1}\fi%
\begin{minted}[linenos=true]{latex}}
{\end{minted}}
\NewDocumentEnvironment {xexample} { o o  }
{\VerbatimEnvironment
  \IfNoValueF { #1 }%
    {\captionof{lstlisting}{#1}%
      \IfNoValueF {#2} { \label{#2} }%
   }%
  \begin{minted}[linenos=true]{latex}}%
 {\end{minted}}

\begin{document}

\begin{example}{TheLabel}{The caption}
\usepackage{minted}
\usepackage{caption,floatrow}
\end{example}

%\begin{xexample}[Another caption]
%\usepackage{minted}
%\usepackage{caption,floatrow}
%\end{xexample}

See Example~\ref{TheLabel}

\end{document}

The environment example works like expected. However this environment has two mandatory arguments. I am a friend of optional arguments/keys. With the environment xexample I tried this implementation but it fails.

What's going on here?

Bonus: Is it possible to pass options to minted as well? (of course with an optional argument ;-))

Best Answer

The problem is that when verbatim-style environments take optional arguments, you need to use \obeylines to prevent the body of the environment from being tokenized in the process of checking for arguments.

You should be able to pass options to minted, though if you're primarily working with formatting, passing options directly to \fvset might be easier.

\documentclass{article}
\usepackage{minted}
\usepackage{listings}
\usepackage{caption}
\captionsetup[lstlisting]{font=sf,labelfont=bf,skip=\smallskipamount}
\usepackage{xparse}
\NewDocumentEnvironment {example} { mm  }
{\VerbatimEnvironment
 \captionof{lstlisting}{#2}\ifx\relax#1\relax\else\label{#1}\fi%
\begin{minted}[linenos=true]{latex}}
{\end{minted}}
\NewDocumentEnvironment {xexample} {}
{\VerbatimEnvironment
 \begingroup\obeylines\getargs}%
 {\end{minted}}

\NewDocumentCommand\getargs{ o o }
{\endgroup
  \IfNoValueF { #1 }%
    {\captionof{lstlisting}{#1}%
      \IfNoValueF {#2} { \label{#2} }%
   }%
  \begin{minted}[linenos=true]{latex}}

\begin{document}

\begin{example}{TheLabel}{The caption}
\usepackage{minted}
\usepackage{caption,floatrow}
\end{example}

\begin{xexample}[Another caption]
\usepackage{minted}
\usepackage{caption,floatrow}
\end{xexample}

See Example~\ref{TheLabel}

\end{document}

enter image description here