expl3 展開兩次的首選方式是?

expl3 展開兩次的首選方式是?

expl3在將參數傳遞給基底函數之前,分別包含用於一級擴展和兩種完全擴展的 、 和 參數說明ofx擴展論證的首選方式是什麼兩次在將其傳遞給基底函數之前?

例如,我正在嘗試為使用套件中l3keys建立的巨集編寫一個鍵值介面。\DeclarePairedDelimitermathtools

\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
  }

通常,分隔符號的大小會作為\bigetc. 或 的可選參數傳遞給宏*,例如\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]
  • 如果我使用fx擴展,\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]您的代幣清單。

相關內容