expl3
には、引数を基本関数に渡す前に、それぞれ1レベル展開と2種類の完全展開を表す引数指定子、引数指定子が含まれます。引数を展開する推奨される方法はo
何f
ですか?x
2回基本関数に渡す前に?
例として、パッケージから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
通常、区切り文字のサイズは、 などのオプションの引数としてマクロに渡されます。*
など。または を、 など\abs[\big]{x}
のキー値インターフェイスとして\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 } ]
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]
トークンリストに追加されます。