10

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

  • why can't you use \begin{minted}[caption=...,label=...]?? – user2478 May 2 '13 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 – Marco Daniel May 2 '13 at 18:38
  • it is pretty easy to make all options from fancyvrb available for minted. – user2478 May 2 '13 at 18:42
  • @Herbert: Do you mean \fvset? I have no idea? – Marco Daniel May 2 '13 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 '13 at 18:52
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

  • Interesting and a nice trick – Marco Daniel May 2 '13 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

  • Is it possible to put the caption below the listings? – Marco Daniel May 2 '13 at 20:01
  • I like this approach, but it's giving me errors when no optional argument is supplied. – G. Poore May 2 '13 at 20:18
  • @G.Poore This should be fixed now. – egreg May 2 '13 at 20:31

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.