如何使用可选参数定义一个新的环境?

如何使用可选参数定义一个新的环境?

我有以下想法:

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

环境example按预期工作。但是此环境有两个强制参数。我是可选参数/键的朋友。xexample我尝试使用此环境来实现此目的,但失败了。

这里发生了什么?

奖励:是否也可以传递选项minted?(当然带有可选参数 ;-))

答案1

问题是,当逐字格式的环境采用可选参数时,您需要使用\obeylines来防止环境主体在检查参数的过程中被标记化。

您应该能够将选项传递给minted,但如果您主要进行格式化工作,则直接将选项传递给\fvset可能会更容易。

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

在此处输入图片描述

答案2

我提出了一种具有键值接口的不同语法,使您能够指定比标题和标签更多的内容,例如要传递的选项minted以及语言。

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

在此处输入图片描述

相关内容