LaTeX3 関数のインターフェース

LaTeX3 関数のインターフェース

最近、プレーン TeX でマクロを記述して、ユーザー指定のリストの要素を変更する方法について質問を投稿しました。TeX のインターフェースが嫌いだと何気なく言ったところ、誰かが LaTeX3 を紹介してくれました。マニュアルに謳われているように、LaTeX3 はより現代的なプログラミング言語のはずです。私は TeX プログラミングを始めたばかりなので、マニュアルを理解するのに苦労しています。マニュアルが経験豊富な TeX ユーザー向けに書かれているためだと思いますが、LaTeX3/TeX を始めたばかりの人向けの代替手段がないようで、手元にあるもので作業するしかありません。そのため、この投稿をしています。マニュアルはわかりにくいので、構文に関する簡単な質問をいくつかして、その混乱を少しでも解消したいと思います。

言っておきますが、LaTeX3 について教えてくれた人は、そのインターフェースを使って私の最初の投稿に対する解決策も教えてくれました。この解決策をマニュアルと併用して、LaTeX3 構文に関する基本的な事実を理解し始めることができました。私が理解できたことについてお話ししますが、公正に警告しておきますが、その一部は私自身の推測に基づいています (stackexchange ユーザーが提供した例を参考にして導き出したものです)。マニュアルの明確な指示ではありませんので、間違いがあるかもしれません。私が時々独自の用語を使うとき、私は問題をわかりにくくしているわけではありません。完全に理解していない主題について体系的に話すのは難しいだけです。

また、長さのため、コメントではなく別の投稿として書いています。よろしくお願いします。

-----------------------------------------------------------------------------------------------------------------------

関数定義

これまでに私が理解できたことは:

新しい関数は、他の方法の中でも、次のコードを使用して定義されます。

\cs_new_<restrictions>:Npn <function name> <function parameters> {<replacement code>}

\cs_new_<restrictions>LaTeX コマンドであり、Npn はインターフェイスの「パーサー」に、\cs_new_<restrictions>: Npnコードの 部分の後に何が期待されるかを指示するためにあります。この場合、単一のトークン制御ワード、つまり<function name>、1 つ以上のパラメータ、つまり、および関数を置き換える<function parameters>トークン リスト、つまり です。{<code>}

たとえば、4つの引数を取る新しい関数を定義したい場合、次のコードで実現できます。

\cs_new_<restrictions>:Npn \myfunction #1 #2 #3 #4 {<code>}

同様に、2つの引数を持つ関数のコードは次のようになります。

\cs_new_<restrictions>:Npn \myfunction #1 #2 {<code>}

もちろん、私はスペースは不要だと想定しています(間違っていたら訂正してください)。なぜなら、パーサーは既に「メタ署名」の助けを借りて「メタ」引数( <function name>、、 )を互いに区別する方法を指示されているからです<parameters>{<code>}いいえ

さて、#を削除したい場合は、次の汎用コマンドを使用できます。

\cs_new_<restrictions>:Nn <function name>:<function signature> {<code>}

同様の処理ですが、今度はパーサーが<function signature>の後に Nn、NnN、TnN などのを期待します<function name>

4つの引数を持つ関数は次のようになります。

\cs_new_<restrictions>:Nn \myfunction:NNNN {<code>}

そして、2つの引数を持つものは次のようになります

\cs_new_<restrictions>:Nn \myfunction:NN {<code>}

他にもコマンドはありますl3基本関数を作成するためのライブラリですが、その一般的な構造は基本的に同じようです。唯一の違いは機能にあります。たとえば、 の\cs_set...代わりにを使用する\cs_new...と、関数はグローバルではなくローカルになります。e 型と x 型の展開が何であるかの詳細を尋ねるフォローアップ投稿を書くつもりですが、今のところは全体像に固執するのが最善だと思います。

とにかく、これまでのところは正しいですか?

さて、次に進みます。

変数の定義

これまでに私が理解できたことは:

LaTeX3には多くのデータ型がありますが、主なものは次のとおりです。トークンリスト文字列整数シーケンス、 そしてカンマ区切りリストそれぞれ独自の略語を使用しますが、一般的には、新しい変数を定義するときは、型を宣言し、次のようなキーワードを続けます。新しいまたは定数変数を初期化するかどうかによって異なります。

例えば、宣言はしたいが初期化はしたくないという場合、トークンリスト変数 次のコードを使用します:

\tl_new:N \mytokenList

\mytokenListそして、その後のどこかで、コードを使用してトークン リストを保存できます。

\tl_set:Nn \mytokenList {<tokens>}

しかし、最初から変数に格納したいデータがわかっている場合は、代わりにこのコマンドを使用できます(シーケンスまたは整数

\tl_const:Nn \mytokenList {<tokens>}

余談ですが、変数にも「関数シグネチャ」があることに気づきました。おそらく、解析方式の定義が簡単になるでしょう。

これは、どのデータ型を参照しているのかを指定する前に、できる限り一般的な説明です。各データ型には、関連する操作が独自にあるためです。

-----------------------------------------------------------------------------------------------------------------------

今のところは以上です。フィードバックをいただければ幸いです。これは独学では簡単ではありません。特に TeX の知識がほとんどない場合はなおさらです。ですから、これを見て「当然だ」と思う方がいたら申し訳ありません。とにかく、ありがとうございました。

答え1

関数を定義するには主に 2 つの方法があります。

\cs_new<restrictions>:Npn

\cs_new<restrictions>:Nn

_protectedここで、 、_noparまたは となります_protected_nopar

どちらの方法でも、N後続の引数(つまり単一のトークン)が現在未定義の制御シーケンス(またはアクティブ文字)であるかどうかがチェックされ、世界的に制御シーケンスを定義します。

違いは何でしょうか? 最初のファミリでは、制御シーケンスを定義した後、{関数の「置換テキスト」を区切る前に「パラメーター テキスト」が必要です。

「パラメータテキスト」は、 、 などを含むトークンの任意のシーケンスにすることができます#1#2ただし#9、この自由度の威力を十分に理解するには、TeXbook の第 20 章と「区切られた引数」の概念を理解している必要があります。

ただし、簡単にしておきましょう。次の 2 つのコードは完全に同等です。

\cs_new:Npn \harry_foo:nn #1 #2 { -#1-#2- }
\cs_new:Nn \harry_foo:nn { -#1-#2- }

後者は、#1#2定義される関数のシグネチャ(この場合は )に基づいてパラメータ テキストを自動的に提供するためです:nn

署名は、nおよびN文字のシーケンス (空の場合もある) で構成する必要があります。

\ExplSyntaxOnがアクティブな場合、スペースは無視されるので、

\cs_new:Npn \harry_foo:nn #1 #2 { -#1-#2- }
\cs_new:Npn \harry_foo:nn #1#2 { -#1-#2- }
\cs_new:Npn \harry_foo:nn #1#2{ -#1-#2- }

はすべて同等です。 の後にスペースを入れることもできます#が、お勧めしません。

TeXの構文規則では、「パラメータテキスト」を期待する場合(基本的には、\defまたは同様の割り当てを行うとき、および定義するマクロの名前を保存した後)すべて最初の までは{パラメータ テキストの一部です。パラメータ テキストが何であるかを予測する方法はないため、p単に「 までのすべて{」を意味する特別な引数指定子が使用されます。

#1、などの単純なパラメータ テキストのみを#1#2自動的に生成できます。これは、2 番目のファミリ を使用すると実行されます\cs_new<restrictions>:Nn

Tどこが間違っているのでしょうか?署名内の指定子として を使用できると想定しています。が実行されるときに引数指定子Tまたは がF追加されます。\prg_new_conditional<restrictions>:Nnn

また、前に示したように、パラメータ テキストの分析も間違っています。

\cs_set<restrictions>:Npnとはどうでしょうか:Nn? 上記はすべて適用されますが、定義される関数が定義されているかどうかはチェックされず、その意味は暗黙的に上書きされますが、宣言のスコープは現在のグループと一致するという違いがあります。通常、 は、\cs_set...コンテキストに適応する必要がある一時的な関数に使用されるため、その意味は固定されません。


変数の命名規則推奨名前がl、 、 で始まるgことc。実際には、コード内で使用される変数は規則に従う必要があります。ドキュメント内で使用される 型(おそらく も)の変数にはexpl3、 などの「通常の」名前を使用することもできます。\myTokenListtlclist

で始まる変数はl常にローカルに処理される必要があります (\tl_set:Nnなど)。一方、 で始まる変数はg常にグローバルに処理される必要があります (\tl_gset:Nnなど)。

で始まる変数c定数そしてそうあるべきだ一度もない値が割り当てられた後に実行されますが、使用されるだけです。

定数は次のように定義できる。

\tl_const:Nn \c_harry_foo_tl {<tokens>}
\str_const:Nn \c_harry_foo_str {<tokens>}
\clist_const:Nn \c_harry_foo_clist {<comma list>}
\seq_const_from_clist:Nn \c_harry_foo_seq {<comma list>}
\prop_const_from_keyval:Nn \c_harry_foo_prop {<key-value list>}
\int_const:Nn \c_harry_foo_int {<integer expression>}
\fp_const:Nn \c_harry_foo_int {<fp expression>}
\bool_const:Nn \c_harry_foo_bool {<boolean expression>}
\dim_const:Nn \c_harry_foo_dim {<dimen expression>}
\skip_const:Nn \c_harry_foo_dim {<skip expression>}
\muskip_const:Nn \c_harry_foo_dim {<muskip expression>}
\intarray_const_from_clist:Nn \c_harry_foo_intarray {<comma list>}
\regex_const:Nn \c_harry_foo_regex {<regex>}
\cc_tab_const:Nn \c_harry_foo_cctab {<code>}

関連情報