expl3
在將參數傳遞給基底函數之前,分別包含用於一級擴展和兩種完全擴展的 、 和 參數說明o
符f
。x
擴展論證的首選方式是什麼兩次在將其傳遞給基底函數之前?
例如,我正在嘗試為使用套件中l3keys
建立的巨集編寫一個鍵值介面。\DeclarePairedDelimiter
mathtools
\tl_new:N \l__mymodule_size_tl
\keys_define:nn { mymodule }
{
size .choices:nn =
{ big , Big , bigg , Bigg }
{
\tl_set:Nn \l__mymodule_size_tl
{ [ \use:c { \tl_use:N \l_keys_choice_tl } ] }
} ,
size / auto .code:n =
\tl_set:Nn \l__mymodule_size_tl {*} ,
size / none .code:n =
\tl_clear:N \l__mymodule_size_tl
}
通常,分隔符號的大小會作為\big
etc. 或 的可選參數傳遞給宏*
,例如\abs[\big]{x}
where \DeclarePairedDelimiter\abs{\lvert}{\rvert}
。我更喜歡size = big
等或size = auto
作為鍵值接口,例如\myabs[size=big]{x}
.
上述程式碼的問題在於正確設定等\l__mymodule_size_tl
選項big
:我需要擴展[ \use:c { \tl_use:N \l_keys_choice_tl } ]
兩次在將這些令牌分配給 之前\l__mymodule_size_tl
。
- 如果我不使用擴展(即
\tl_set:Nn
),則以\abs
錯誤的形式獲取其參數的呼叫\l__mymodule_size_tl
將保持[ \use:c { \tl_use:N \l_keys_choice_tl } ]
,而不是[\big]
。 - 如果我使用一級擴展(即
\tl_set:No
)並[
在擴展完成後添加,\l__mymodule_size_tl
將保留[ \cs:w \tl_use:N \l_keys_choice_tl \cs_end: ]
,而不是[\big]
。 - 如果我使用
f
或x
擴展,\l__mymodule_size_tl
將保存一堆“垃圾”,而不是[\big]
.
我能做些什麼?這裡有一個想法:使用兩個o
擴展,中間進行一些雜技。
\tl_set:No \l__mymodule_size_tl
{ \use:c { \tl_use:N \l_keys_choice_tl } ] }
\exp_args:NNV \tl_set:No \l__mymodule_size_tl
\l__mymodule_size_tl
\tl_put_left:Nn \l__mymodule_size_tl { [ }
在我看來,這相當醜陋。我還能做些什麼更好的事嗎?
答案1
以前有一個d
關於雙重展開的 -type 參數。然而,幾年前它被放棄了,因為需要它的地方很少,特別是當團隊決定toks
一般不使用寄存器時。根據記憶,expl3
有兩個地方我們必須使用\exp_args:NNo \exp_args:No
或類似形式的構造。
我們沒有保留 -type 參數的原因d
有兩個。首先,我們希望盡可能避免依賴了解函數的擴展細節:這是低階工作所必需的,但理想情況下應該相對有限。另一個原因是它很少需要,因為我們有 e-TeX 可用。要記住的關鍵是,這允許我們控制x
-type 上下文中的擴展
\tl_set:Nx \l__mymodule_size_tl
{ [ \exp_not:c { \tl_use:N \l_keys_choice_tl } ] }
雖然這裡不需要,但我們確實記錄了\cs:w
...\cs_end:
對於需要一次擴展的情況,因此您可以
\tl_set:No \l__mymodule_size_tl
{ \exp_after:wN [ \cs:w \tl_use:N \l_keys_choice_tl \cs_end: ] }
雖然我自己不會在這裡使用它。
答案2
我的印像是你想做
\tl_set:Nx \l__mymodule_size_tl
{
[ \exp_not:c { \tl_use:N \l_keys_choice_tl } ]
}
隨著x
擴展被觸發,因此當涉及\exp_not:c
時,參數會像往常一樣完全擴展(它是);那麼生成的令牌將不可擴展,所以如果您有c
\csname...\endcsname
size=big
您將進入[\big]
您的代幣清單。