我想使用一些宏作为 的参数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
应该是外部命令的定义。