为什么 \seq_put_right:Nx 和 \textsc 不能很好地协同工作?

为什么 \seq_put_right:Nx 和 \textsc 不能很好地协同工作?

(这个问题在某种程度上与这个答案

我想创建一个具有任意数量(以逗号分隔)参数的文档命令,每个参数都是一个逗号列表,其中的项目必须进行处理。

以下 MCE:

\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand\signature{m}
 {
  \__mymodule_process_list:n {#1}
 }
\seq_new:N \l__mymodule_items_seq
\cs_new_protected:Npn \__mymodule_process_list:n #1
{
  \seq_clear:N \l__mymodule_items_seq
  \seq_set_from_clist:Nn \l_tmpa_seq {#1}
  \seq_map_inline:Nn \l_tmpa_seq {
    \seq_set_from_clist:Nn \l_tmpb_seq {##1}
    \seq_get_right:NN \l_tmpb_seq \l_tmpa_tl
    \seq_get_left:NN \l_tmpb_seq \l_tmpb_tl
    \seq_put_right:Nx \l__mymodule_items_seq {
    % \seq_put_right:NV \l__mymodule_items_seq {
      \l_tmpa_tl
      \c_space_tl \l_tmpb_tl
      % \c_space_tl \textsc{\l_tmpb_tl}
    }
  }
  \seq_use:Nn \l__mymodule_items_seq { ~ \& ~ }
}
\ExplSyntaxOff

\begin{document}
\signature{
  {Last1, First1}
}

\signature{
  {Last1, First1},
  {Last2, First2}
}

\signature{
  {Last1, First1},
  {Last2, First2},
  {Last3, First3}
}
\end{document}

效果很好,也就是说结果是:

First1 Last1
First1 Last1 & First2 Last2
First1 Last1 & First2 Last2 & First3 Last3

但是,如果我\c_space_tl \l_tmpb_tl用替换\c_space_tl \textsc{\l_tmpb_tl}以便将姓氏变为小写,LaTeX 会抱怨:

! Missing control sequence inserted.
 <inserted text>
\inaccessible ```

在这种情况下,如果我\seq_put_right:Nx用例如替换\seq_put_right:NV,编译会顺利进行,但结果不是预期的结果(每行的姓氏相同):

First1 Lᴀꜱᴛ1
First1 Lᴀꜱᴛ2 & First2 Lᴀꜱᴛ2 
First1 Lᴀꜱᴛ3 & First2 Lᴀꜱᴛ3 & First3 Lᴀꜱᴛ3

使用\seq_put_right:Nx和 ,而不是\textsc{\l_tmpb_tl}{\scshape \l_tmpb_tl}它可以按预期工作,但为什么不使用 呢\textsc{\l_tmpb_tl}

答案1

\textsc您需要使用 来防止(或任何其他不应扩展的宏)的扩展\exp_not:N,因此

\seq_put_right:Nx \l__mymodule_items_seq
  { \c_space_tl \exp_not:N \textsc { \l_tmpb_tl } }
%               ^^^^^^^^^^

你对NV变体的使用是错误的。V-type 应该采用单变量作为参数,因此这是正确的:

\seq_put_right:NV \l__mymodule_items_seq \l_tmpb_tl

这是一个有点奇怪的语法(但不一定是错误的):

\seq_put_right:NV \l__mymodule_items_seq { \l_tmpb_tl }

这完全不对

\seq_put_right:NV \l__mymodule_items_seq { \l_tmpa_tl \l_tmpb_tl }

\scshape有效(在 之后\begin{document}),因为它是用 定义的\protected。如果你执行\ShowCommand\scshape,你会看到\scshape=\protected macro:->[...],所以它不会在 中扩展(由中的扩展\edef使用)。x\seq_put_right:Nx

\textsc另一方面,是一个robust宏(\ShowCommand\textsc):

> \textsc=robust macro:
->\protect \textsc  .

> \textsc =\long macro:
#1->[...]

所以它会在内部破裂\edef(它需要\protected@edef不爆炸)。

答案2

您可以使用\exp_not:N \textsc,但名称中的标记也可能会引发问题。我建议使用\text_expand:n可能包含危险标记的文本输入部分进行包装。

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand\signature{m}
 {
  \__mymodule_process_list:n {#1}
 }

\seq_new:N \l__mymodule_items_seq

\cs_new_protected:Npn \__mymodule_process_list:n #1
 {
  \seq_clear:N \l__mymodule_items_seq
  \seq_set_from_clist:Nn \l_tmpa_seq {#1}
  \seq_map_inline:Nn \l_tmpa_seq
   {
    \seq_set_from_clist:Nn \l_tmpb_seq {##1}
    \seq_get_right:NN \l_tmpb_seq \l_tmpa_tl
    \seq_get_left:NN \l_tmpb_seq \l_tmpb_tl
    \seq_put_right:Nx \l__mymodule_items_seq
     {
      \text_expand:n { \l_tmpa_tl \c_space_tl \textsc { \l_tmpb_tl } }
     }
   }
  \seq_use:Nn \l__mymodule_items_seq { ~ \& ~ }
 }
\ExplSyntaxOff

\begin{document}
\signature{
  {Last1, First1}
}

\signature{
  {Last1, First1},
  {Last2, First2}
}

\signature{
  {Last1, First1},
  {Last2, First2},
  {La\'st3, F\'irst3}
}
\end{document}

在此处输入图片描述

相关内容