expl3 で 2 回展開する場合の推奨される方法は何ですか?

expl3 で 2 回展開する場合の推奨される方法は何ですか?

expl3には、引数を基本関数に渡す前に、それぞれ1レベル展開と2種類の完全展開を表す引数指定子、引数指定子が含まれます。引数を展開する推奨される方法はofですか?x2回基本関数に渡す前に?

例として、パッケージから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
  }

\big通常、区切り文字のサイズは、 などのオプションの引数としてマクロに渡されます。*など。または を、 など\abs[\big]{x}のキー値インターフェイスとして\DeclarePairedDelimiter\abs{\lvert}{\rvert}渡したいです。size = bigsize = auto\myabs[size=big]{x}

上記のコードの問題は、などの選択肢\l__mymodule_size_tlを正しく設定することですbig。拡張する必要があります[ \use:c { \tl_use:N \l_keys_choice_tl } ] 2回これらのトークンを に割り当てる前に\l__mymodule_size_tl

  • 展開を使用しない場合 (つまり、\tl_set:Nn)、 の呼び出しで\abs引数が間違った形式で取得され、ではなく が\l__mymodule_size_tl保持されます。[ \use:c { \tl_use:N \l_keys_choice_tl } ][\big]
  • 1 レベルの展開 (つまり\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]

どうすればいいでしょうか? 1 つのアイデアはo、間にアクロバットを交えて 2 つの拡張を使用することです。

    \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二重拡張のための 型の引数がありました。しかし、それが必要な場所が非常に少なかったため、特にチームがtoksレジスタを一般的に使用しないことに決めたときに、数年前に削除されました。記憶によれば、 には、または同様の形式expl3の構造を使用する必要があった場所が 2 か所あります。\exp_args:NNo \exp_args:No

型引数を保持しなかった理由は2つあります。まず、関数の展開の詳細を知ることに頼ることを可能な限り避けたいからです。これは低レベルの作業には必要ですが、理想的には比較的制限されるべきです。もう1つの理由は、e-TeXが利用できるので、これが必要なことはめったにないということです。覚えておくべき重要な点は、これにより、型コンテキストdでの展開を制御できるということです。x

\tl_set:Nx \l__mymodule_size_tl
  { [ \exp_not:c { \tl_use:N \l_keys_choice_tl } ] }

ここでは必要ありませんが、1つの展開のみが必要な状況については\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]トークンリストに追加されます。

関連情報