将命令列表正确地应用于参数

将命令列表正确地应用于参数

我有一个 clist,里面装满了我想要用作命令的值,并将它们依次\cmda{\cmdb{\cmdc{arg}}}应用于 \apply 函数的参数。我添加了一个示例,但它不起作用。有什么想法可以用正确的\apply函数解决这个问题吗?我将不胜感激,因为我花了很多时间,但仍然没有找到任何可行的解决方案。

\documentclass{article}

\usepackage{xparse}
\usepackage{amsmath,amssymb}
\ExplSyntaxOn
\clist_new:N \g_pkg_cmd_clist {}
\NewDocumentCommand{\addcmd}{ m }
   {
      \clist_put_right:Nn \g_pkg_cmd_clist {#1}
   }
\NewDocumentCommand{\apply}{ m }
   {
     \tl_clear:N \l_tmpa_tl
     \tl_set:Nn \l_tmpa_tl {#1}
     \clist_map_inline:Nn \g_pkg_cmd_clist
     {
          \tl_put_right:Nn \l_tmpa_tl {\csname ##1\endcsname{\l_tmpa_tl}}
     }
     \tl_use:N \l_tmpa_tl
   }
\ExplSyntaxOff

\begin{document}
\addcmd{dot}
\addcmd{vec}
\addcmd{breve}

$\apply{x}$ should be $\breve{\vec{\dot{x}}}$
%After appling all entries should be cleared
\addcmd{breve}
\addcmd{dot}
\addcmd{vec}

$\apply{y}$ should be $\vec{\dot{\breve{y}}}$

\end{document}

也许是为了解释目标:我想创建一个允许类似这样的面向对象符号定义命令的包:

\var<fcn1,fcn2,...>[subscripts or if known as superscripts][superscripts]
\current[battery,max][2] %=I_{bat,max}
\state<v>[i] %state vector \vec{x}_i (with \state=x)
\state<M> %=\mathbf{\uppercase{x}} (with \state=x)  

答案1

要按顺序将各种命令应用于输入,也许最简单的方法是建立一个标记列表,使用适当的扩展控制,以便结果正是所需的:

\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath,amssymb}
\ExplSyntaxOn
\clist_new:N \g_pkg_cmd_clist
\tl_new:N \l_pkg_tmp_tl
\NewDocumentCommand \addcmd { m }
   { \clist_gput_right:Nn \g_pkg_cmd_clist {#1} }
\cs_new:Npn \pkg_cmd:n #1 { }
\NewDocumentCommand \apply { m }
   {
     \tl_set:Nn \l_pkg_tmp_tl {#1}
     \clist_map_inline:Nn \g_pkg_cmd_clist
       {
         \tl_set:Nx \l_pkg_tmp_tl
           { \exp_not:c {##1} { \exp_not:V \l_pkg_tmp_tl } }  
       }
     \clist_gclear:N \g_pkg_cmd_clist
     \tl_use:N \l_pkg_tmp_tl  
   }
\ExplSyntaxOff

\begin{document}
\addcmd{dot}
\addcmd{vec}
\addcmd{breve}

$\apply{x}$

\addcmd{dot}

$\apply{y}$

\end{document}

在这里,我习惯\exp_not:c将 csnames 扩展为控制序列,而无需进一步扩展。 (正如评论中所述,OP 希望在使用后清除应用函数列表\apply:我已在此处添加了它。)

我不清楚为什么该\addcmd命令不简单地将控制序列作为参数,如下所示

\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath,amssymb}
\ExplSyntaxOn
\clist_new:N \g_pkg_cmd_clist
\tl_new:N \l_pkg_tmp_tl
\NewDocumentCommand \addcmd { m }
   { \clist_gput_right:Nn \g_pkg_cmd_clist {#1} }
\cs_new:Npn \pkg_cmd:n #1 { }
\NewDocumentCommand \apply { m }
   {
     \tl_set:Nn \l_pkg_tmp_tl {#1}
     \clist_map_inline:Nn \g_pkg_cmd_clist
       {
         \tl_set:Nx \l_pkg_tmp_tl
           { \exp_not:N ##1 { \exp_not:V \l_pkg_tmp_tl } }  
       }
     \tl_use:N \l_pkg_tmp_tl  
   }
\ExplSyntaxOff

\begin{document}
\addcmd{\dot}
\addcmd{\vec}
\addcmd{\breve}

$\apply{x}$

\end{document}

该问题最初似乎需要在输出中进行简单的映射,如下所示:

你试图建立要应用的函数列表,特别是通过循环将文字添加\l_tmpa_tl\l_tmpa_tl,这让生活变得复杂。相反,尝试

\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath,amssymb}
\ExplSyntaxOn
\clist_new:N \g_pkg_cmd_clist
\NewDocumentCommand \addcmd { m }
   { \clist_gput_right:Nn \g_pkg_cmd_clist {#1} }
\NewDocumentCommand \apply { m }
   { \clist_map_inline:Nn \g_pkg_cmd_clist { \use:c {##1} {#1} } }
\ExplSyntaxOff

\begin{document}
\addcmd{dot}
\addcmd{vec}
\addcmd{breve}

$\apply{x}$

\end{document}

请注意,我在这里使用了 ,\clist_gput_right:Nn因为您已全局声明了您的列表。我还使用了 ,\use:c而不是\csname ... \endcsname,因为后者不是“受支持的”LaTeX3 语法,并且在这里也不需要。

相关内容