11

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 ;-))

5
  • why can't you use \begin{minted}[caption=...,label=...]??
    – user2478
    May 2, 2013 at 18:31
  • @Herbert: minted doesn't provide the options caption nor label. egreg found a nice way: chat.stackexchange.com/transcript/message/9247614#9247614 May 2, 2013 at 18:38
  • it is pretty easy to make all options from fancyvrb available for minted.
    – user2478
    May 2, 2013 at 18:42
  • @Herbert: Do you mean \fvset? I have no idea? May 2, 2013 at 18:44
  • the keys from fancyvrb are imported by minted with \minted@define@extra{...} Replace ... with label and it is known. But I suppose that fancyvrb did not know the caption option.
    – user2478
    May 2, 2013 at 18:52

2 Answers 2

10

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

1
  • Interesting and a nice trick May 2, 2013 at 19:21
7

I propose a different syntax with a key-value interface that enables you to specify much more than the caption and the label, for instance options to be passed to minted and also the language.

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

\ExplSyntaxOn
\keys_define:nn {xexample}
 {
  caption  .tl_set:N = \l_mdxex_caption_tl,
  label    .tl_set:N = \l_mdxex_label_tl,
  minted   .tl_set:N = \l_mdxex_minted_tl,
  language .tl_set:N = \l_mdxex_language_tl
 }

\NewDocumentEnvironment {xexample} { O {} }
 {
  \keys_set:nn { xexample }
   {
    language=latex,
    #1
   }
  \tl_set:Nx \l__mdxex_temp_tl
   {
    \exp_not:N \VerbatimEnvironment
    \tl_if_empty:NTF \l_mdxex_caption_tl
     {
      \scan_stop:
     }
     {
      \exp_not:N \captionof { lstlisting }{ \exp_not:V \l_mdxex_caption_tl }
      \tl_if_empty:NF \l_mdxex_label_tl
       { \exp_not:N \label { \l_mdxex_label_tl } }
     }
    \exp_not:n { \begin{minted} } [ \l_mdxex_minted_tl ] { \l_mdxex_language_tl }
   }
  \l__mdxex_temp_tl
 }
 {\end{minted}}
\ExplSyntaxOff

\begin{document}

\begin{xexample}[caption=The caption,label=TheLabel,language=bash]
ls -l /usr/local/texlive/2012/texmf-dist
\end{xexample}

\begin{xexample}[caption=Another caption,label=foo,
  minted={linenos=true}]
\usepackage{minted}
\usepackage{caption,floatrow}
\end{xexample}

See example~\ref{TheLabel} and example~\ref{foo}

\end{document}

enter image description here

4
  • Is it possible to put the caption below the listings? May 2, 2013 at 20:01
  • I like this approach, but it's giving me errors when no optional argument is supplied.
    – G. Poore
    May 2, 2013 at 20:18
  • @G.Poore This should be fixed now.
    – egreg
    May 2, 2013 at 20:31
  • @egreg Still throws an error for me if no optional arguments are provided: FancyVerb Error: Extraneous input '\usepackage {minted}' between \begin{xexample}[<key=value>] and line end . \FV@Error ... {FancyVerb Error: \space \space #1 }
    – steve
    Aug 26, 2020 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.