如何通过宏创建内联列表

如何通过宏创建内联列表

我想创建一个产生内联列表的宏。我可以轻松使用enumerate*以下代码轻松完成此操作:enumitem,但是当我尝试将其包装在宏中时,我得到:

Extra }, or forgotten \endgroup.
\item ...ctor \relax \fi }\color@endgroup \egroup 
                                                  \enit@outeritem 

代码:

\documentclass{article}
\usepackage[inline]{enumitem}
\usepackage{pgffor}

\newlist{MyHChoices}{enumerate*}{2}
\setlist*[MyHChoices]{label=\Alph*., itemjoin={\hspace*{2.0em}}}

\newcommand*{\InlineList}[1]{%
    \MyHChoices
        \foreach \Choice in {#1} {%
            \item \Choice
        }%
    \endMyHChoices
}%


\begin{document}
\begin{MyHChoices}
    \item One
    \item Two
    \item Three
\end{MyHChoices}

%\InlineList{One, Two, Three}% ???
\end{document}

答案1

Token 注册方法

问题是列表环境不太令人满意,如果\item放在一个组里面, \foreach那么pgffor将主体放在组里面。

以下文件使用令牌寄存器来收集环境主体。\Choice需要扩展一次。

\documentclass{article}
\usepackage[inline]{enumitem}
\usepackage{pgffor}

\newlist{MyHChoices}{enumerate*}{2}
\setlist*[MyHChoices]{label=\Alph*., itemjoin={\hspace*{2.0em}}}

\newtoks\gInlineToks
\newcommand*{\InlineList}[1]{%
    \global\gInlineToks{}%
    \foreach \Choice in {#1} {%
        \global\gInlineToks\expandafter{%
            \the\expandafter\gInlineToks
            \expandafter\item\Choice
        }%
    }%
    \begin{MyHChoices}\the\gInlineToks\end{MyHChoices}%
}%

\begin{document}
\begin{MyHChoices}
    \item One
    \item Two
    \item Three
\end{MyHChoices}

\InlineList{One, Two, Three}
\end{document}

包裹kvsetkeys

另一种方法是pgffor

\documentclass{article}
\usepackage[inline]{enumitem}
\usepackage{kvsetkeys}

\newlist{MyHChoices}{enumerate*}{2}
\setlist*[MyHChoices]{label=\Alph*., itemjoin={\hspace*{2.0em}}}

\makeatletter
\newcommand*{\InlineList}[1]{%
  \begin{MyHChoices}%
    \comma@parse{#1}\InlineListItem
  \end{MyHChoices}%
}
\newcommand*{\InlineListItem}[1]{%
  \item #1%
}
\makeatother


\begin{document}
\begin{MyHChoices}
    \item One
    \item Two
    \item Three
\end{MyHChoices}

\InlineList{One, Two, Three}
\end{document}

答案2

您可以尝试这个,它看起来比 Heiko 的要短:

\documentclass{article}
\usepackage[inline]{enumitem}
\usepackage{xparse}

\newlist{MyHChoices}{enumerate*}{2}
\setlist*[MyHChoices]{label=\Alph*., itemjoin={\hspace*{2.0em}}}

\ExplSyntaxOn
\NewDocumentCommand{\InlineList}{ m }
 {
  \begin{MyHChoices}
  \clist_map_inline:nn { #1 } { \item ##1 }
  \end{MyHChoices}
 }
\ExplSyntaxOff

\begin{document}
\begin{MyHChoices}
    \item One
    \item Two
    \item Three
\end{MyHChoices}

\InlineList{One, Two, Three}     
\end{document}

如果您计划使用除逗号以外的其他分隔符,则通常的“拆分并按顺序存储”策略非常容易遵循:

\ExplSyntaxOn
\NewDocumentCommand{\InlineList}{ O{,} m }
 {
  \begin{MyHChoices}
  \peter_process_hchoices:nn { #1 } { #2 }
  \end{MyHChoices}
 }

\seq_new:N \l__peter_hchoices_seq

\cs_new_protected:Npn \peter_process_hchoices:nn #1 #2
 {
  \seq_set_split:Nnn \l__peter_hchoices_seq { #1 } { #2 }
  \seq_map_inline:Nn \l__peter_hchoices_seq { \item ##1 }
 }
\ExplSyntaxOff

使用此块代替前一个块,您可以输入列表作为

\InlineList{One, Two, Three}

\InlineList[;]{One; Two; Three}

\InlineList[/]{One / Two/ Three}

并得到相同的结果。

相关内容