如何在自定义环境中创建具有可变参数大小的列表?

如何在自定义环境中创建具有可变参数大小的列表?

我有一个自定义环境,我正在将其用作模板的一部分。现在这是模板文件的代码。

%-----------------------------------------------------------
%    customtemplate.cls
%-----------------------------------------------------------

\setlength{\tabcolsep}{0pt}

% New environment for the long list
\newenvironment{twenty}{%
    \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}ll}}{%
    \end{tabular*}
}

\newcommand{\twentyitem}[3]{%
    \parbox[t]{\textwidth}{%
        \textbf{#2}%
        \hfill%
        #1\\%
        #3\vspace{\parsep}%
   }\\
}

.tex文件中,该命令的调用方式如下:

%-----------------------------------------------------------
%    somefile.tex
%-----------------------------------------------------------

\begin{twenty}
    \twentyitem{2013}{This is an example}{lorem ipsum etc\ldots}
\end{twenty}

给出以下输出:

enter image description here

我想要的行为是这样的,我可以根据需要拥有任意多或任意少的参数,但条件是前 3 个参数是必需的。“意味着列表中至少需要有一个项目”

%-----------------------------------------------------------
%    somefile.tex
%-----------------------------------------------------------

\begin{twenty}
    \twentyitem{2013}{This is an example}{lorem ipsum etc\ldots}{as}{many}{as}{possible}
\end{twenty}

enter image description here

我尝试在模板代码中添加一个 itemize,但无法弄清楚如何在至少有 3 个参数的前提下创建可变数量的参数。我尝试的所有方法实际上都无法编译。

任何帮助,将不胜感激。

答案1

我猜测 OP 真正想要什么,但无论如何,我确信,对于他想要的而言,嵌套环境比长参数宏更可取。

\documentclass{article}
\usepackage{enumitem,lipsum}
\newenvironment{twenty}{
  \noindent\hrulefill The Twenty Environment\hrulefill
  \begin{itemize}[itemindent=1em,label={}]}{
  \end{itemize}
  \hrulefill End of The Twenty Environment\hrulefill
}
\newenvironment{twentyitem}[2]{
  \item #2\hfill#1\begin{itemize}}{\end{itemize}}
\begin{document}
\lipsum[1]
\begin{twenty}
\begin{twentyitem}{2013}{This is an example}
\item Blah
\item blah blah
\item lah blah blah
\end{twentyitem}
\begin{twentyitem}{2014}{This is a second example}
\item Blah
\item blah blah
\item lah blah blah
\end{twentyitem}
\end{twenty}
\end{document}

enter image description here

答案2

环境允许有参数,因此你可以有如下内容:

\begin{twenty}{This is an example}{2013}
  lorem ipsum etc\ldots,
  as,
  many,
  as,
  possible
\end{twenty}

产生如下结果:

enter image description here

环境twenty接受两个参数,然后它将逗号分隔列表在环境主体中进入枚举环境(就我个人而言,我只会使用\item命令,这更容易编码,但上面的语法是可能的,并且似乎更接近 OP 的要求)。

完整代码如下:

\documentclass{article}
\usepackage{xparse}
\usepackage{environ}

\ExplSyntaxOn
\seq_new:N \l_tmp_seq
% usage: \begin{twenty}{left header}{right header}  csv of items\end{twenty}
\NewEnviron{twenty}[2]
{\noindent\textbf{#1}\hfill#2% left and right headers
 \begin{itemize}% start the itemize environment
   \seq_set_split:NnV \l_tmp_seq {,} {\BODY}% split the body into \l_tmp_seq
   \item\seq_use:Nn \l_tmp_seq {\item}% write the list
 \end{itemize}
}
\ExplSyntaxOff

\begin{document}

\begin{twenty}{This is an example}{2013}
  lorem ipsum etc\ldots,
  as,
  many,
  as,
  possible
\end{twenty}

\end{document}

一些评论。

  • 环境定义\NewEnviron使用环境包,因为这允许我们获取\BODY环境并将其用作逗号分隔的列表。
  • \docvslist通常情况下,我会使用电子工具箱包来处理列表,但在这种情况下不起作用,大概是因为我们的列表是“段落形状”。相反,我使用expl3/xparse将其分解\BODY成各个组件,然后构建enumerate环境。
  • 我使用逗号作为分隔符,但是您也可以@通过编辑上面的代码来使用,例如,使第 10 行显示为:

    \seq_set_split:NnV \l_tmp_seq {@} {\BODY}
    

编辑

与处理逗号分隔的列表相比,更合理的格式是使用类似语法的标记:

\begin{twenty}{This is an example}{2013}
  - lorem ipsum etc\ldots
  - as
  - many
  - as
  - possible
\end{twenty}

以下是修改后的代码,它还调整了间距:

\documentclass{article}
\usepackage{xparse}
\usepackage{environ}
\usepackage{enumitem}

\ExplSyntaxOn
\seq_new:N \l_tmp_seq
\cs_generate_variant:Nn \regex_split:nnN { nVN }
\NewEnviron{twenty}[2]
{\noindent\textbf{#1}\hfill#2
 \begin{itemize}[nosep]
   \regex_split:nVN {  \B-\B  } { \BODY } \l_tmp_seq
   \seq_pop_left:NN \l_tmp_seq \l_tmpa_tl % pop initial blank
   \item\seq_use:Nn \l_tmp_seq {\item }
 \end{itemize}
}
\ExplSyntaxOff

\begin{document}

\begin{twenty}{This is an example}{2013}
  - lorem ipsum etc\ldots
  - as
  - many
  - as
  - possible
\end{twenty}

\end{document}

有了新的间距,输出现在是:

enter image description here

相关内容