宏列表作为另一个宏的参数

宏列表作为另一个宏的参数

我想使用一些宏作为 的参数xparse。我需要它,因为我使用siunitx。这是一个简化的编译代码:

\documentclass[a4paper]{article} 
\usepackage{xparse} 
\usepackage{siunitx} 
 
\ExplSyntaxOn 
 
\NewDocumentCommand{\onemacro}{m}{ 
        Length~is~ \qty{8}{#1}. 
} 
\NewDocumentCommand{\multiplemacro}{m}{ 
 
        \clist_new:N \l_my_clist 
        \clist_set:Nn \l_my_clist {#1} 
 
        first~length: \qty{5}{\clist_item:Nn \l_my_clist {1}} \par 
        second~length: \qty{8}{\clist_item:Nn \l_my_clist {2}} 
 
} 
\ExplSyntaxOff 
 
\begin{document} 
 
\onemacro{\candela} 
 
\multiplemacro{cm,candela} 
 
\end{document} 

当我使用包含多个参数的列表时,只有当参数不是宏时它才有效。一旦我更改为

\multiplemacro{\cm,\candela}

这里我有两个宏作为参数,我得到:

! Undefined control sequence.
\cm ->\ERROR 
             
l.25 \multiplemacro{\cm,\candela}

如何将多个宏作为参数传递给另一个宏。或者:如何将一些字符串转换为宏。例如:如何将字符串转换cm为 siunitx 的宏\cm

答案1

这涉及到如何siunitx检查一个单元是否完全是符号的。我传统上使用扩展,但在某些情况下可能会失败。因此,我将改用双扩展方法。即将发布为 v3.1.1,您可以使用

\prg_set_protected_conditional:Npnn \__siunitx_unit_if_symbolic:n #1 { TF }
  {
    \group_begin:
      \bool_set_true:N \l__siunitx_unit_test_bool
      \protected@edef \l__siunitx_unit_tmp_tl {#1}
      \protected@edef \l__siunitx_unit_tmp_tl { \l__siunitx_unit_tmp_tl }
    \exp_args:NNV \group_end:
    \tl_if_blank:nTF \l__siunitx_unit_tmp_tl
      { \prg_return_true: }
      { \prg_return_false: }
  }

将更新的代码导入旧版本的 v3.1.x 或 v3.0.x siunitx


如果您想知道“为什么不采用试验排版方法”,这种方法无法捕获诸如 之类的输入\second{},这严格来说并不正确,但会产生零宽度输出。它还会妨碍在序言中运行格式化程序:v3 中的设计目标之一是这确实应该可行。

答案2

这是可行的,但 Joseph Wright 或许应该研究一下:

\documentclass[a4paper]{article}
\usepackage{xparse}
\usepackage{siunitx}

\ExplSyntaxOn

\NewDocumentCommand{\onemacro}{m}
 {
  Length~is~ \qty{8}{#1}.
 }

\NewDocumentCommand{\multiplemacro}{m}
 {
  first~length:~ \exp_args:Nnx \qty{5}{\clist_item:nn {#1}{1}} \par
  second~length:~ \exp_args:Nnx \qty{8}{\clist_item:nn {#1}{2}}
 }
\ExplSyntaxOff

\begin{document}

\onemacro{\candela}

\multiplemacro{\cm,\candela}

\end{document}

在此处输入图片描述

请注意,您不需要设置clist;无论如何,\clist_new:N应该是外部命令的定义。

相关内容