为什么我的列表出现了两次

为什么我的列表出现了两次

为什么下面的代码会导致我的列表出现奇怪的但不完全重复的情况?

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\ExplSyntaxOn
\clist_new:N \l_ae_number_clist
\cs_new:Npn \_ae_selection:nn #1#2 
  {
    \clist_map_inline:Nn {#2} { \clist_gput_right:Nn \l_ae_number_clist { $##1$ } }
    \clist_use:Nn \l_ae_number_clist { \hspace*{#1} }
  }
\NewDocumentCommand{\aeQMakeSelection}{ O{1em}m }
  {
    \_ae_selection:nn {#1}{#2}
  }
\ExplSyntaxOff
\begin{document}

\aeQMakeSelection{-2,3,4,-5}

\end{document}

此外,我不明白如何在不做任何全球的定义当我的列表应该只是本地的时。

答案1

应该是\clist_map_inline:nn,而不是\clist_map_inline:Nn;前者需要一个明确的 clist 作为参数,后者需要一个 clist 变量。

但是,还有其他弱点:\l_ae_number_clist每次调用时 clist 变量都会增加\aeQMakeSelection,这似乎并不是我们所希望的(并且您正在对局部变量进行全局分配)。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \l_ae_number_clist
\cs_new:Npn \ae_selection:nn #1 #2
 {
  \group_begin:
  \clist_map_inline:nn {#2} { \clist_put_right:Nn \l_ae_number_clist { $##1$ } }
  \clist_use:Nn \l_ae_number_clist { \hspace*{#1} }
  \group_end:
  }
\NewDocumentCommand{\aeQMakeSelection}{ O{1em}m }
 {
  \ae_selection:nn {#1}{#2}
 }
\ExplSyntaxOff
\begin{document}

\aeQMakeSelection{-2,3,4,-5}

\end{document}

该函数\ae_selection:nn不应该是私有的,因为它处于外部编程级别,由xparse宏使用,但这是一个风格决定。

这是使用比 clist 更有效的序列的不同方法。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_ae_selection_seq
\seq_new:N \l_ae_output_seq

\cs_new:Npn \ae_selection:nn #1 #2
 {
  \group_begin:
  \seq_set_split:Nnn \l_ae_selection_seq { , } { #2 }
  \seq_set_map:NNn \l_ae_output_seq \l_ae_selection_seq { \exp_not:n { $##1$ } }
  \seq_use:Nn \l_ae_output_seq { \hspace*{#1} }
  \group_end:
  }
\NewDocumentCommand{\aeQMakeSelection}{ O{1em}m }
 {
  \ae_selection:nn {#1}{#2}
 }
\ExplSyntaxOff
\begin{document}

\aeQMakeSelection{-2,3,4,-5}

\end{document}

让我们看看哪里出了问题;\clist_map_inline:Nn定义为

\clist_map_inline:Nn:
\protected\long macro:#1#2->\clist_if_empty:NF #1{...}

然后我们需要看看\clist_if_empty:NF

\clist_if_empty:NF:
\long macro:#1->\if_meaning:w #1\c_empty_tl \prg_return_true: \else: \prg_return_false: \fi: \c_zero {}

现在,\if_meaning:w只是\ifx,所以你的电话\aeQMakeSelection{-2,3,4,-5}会转化为

\_ae_selection:nn {1em}{-2,3,4,-5}

最终变成

\clist_if_empty:NF -2,3,4,-5{...}

所以我们得到了

\if_meaning:w -\c_empty_tl \prg_return_true: \else: \prg_return_false: \fi: \c_zero {} ...

-与之相比\c_empty_tl,条件遵循错误分支,导致\prg_return_false:一切都变得非常错误。

尽管参数被指定为N,但这并不意味着如果下一个标记为,TeX 就会犹豫{:TeX 遵循其规则并将整体-2,3,4,-5作为其参数。

相关内容