編集:懸賞金について私は以下の質問に満足しており、この懸賞金はその質問に対するものです。これ以上のものは思いつきません。
LaTeX でのオプション引数の使用について少し調べてみましたが、まだよくわからない点がいくつかあります。
いつ
私の質問は、コマンドやパッケージに特有のものではなく、両方に関するものです。
パッケージまたはコマンドに対して 1 つ以上のオプション引数を指定する必要がある場合があります。次のようなコマンドがあります。
\Foo[OptArg1,OptArg2]{Arg1}{Arg2}
そして次のように:
\Foo[OptArg1][OptArg2]{Arg1}{Arg2}
1 つ目は、コンマで区切られた 2 つのオプション引数を持つ 1 つのファミリです。2 つ目は、それぞれに 1 つのオプション引数を持つ 2 つのファミリです。
これら 2 つの方法では何かが違うのだと思いますが、コマンドがいつ最初の方法を使用し、いつ 2 番目の方法を使用する必要があるのか正確にはわかりません。
たとえば、最初のオプション引数を使用して最初の非オプション引数を分割するコマンドが必要だとします。最初の方法では区切り文字としてのコンマが認識されないため (すでに区切り文字になっています)、2 番目の方法の方が適しています。ただし、次のようなコマンドを使用することもできます。
\Foo[separator={,},OptArg2]{Arg1}{Arg2}
同じことをする。
もちろん、2 番目のファミリのオプション引数を \Foo[separator={/}}][OptArg2//OptArg3] で区切る方法が唯一の (または少なくともより良い) 選択肢になります。これは、2 番目のファミリ引数を読み取る前に区切り文字を定義する必要があるためです。
どうやって
また、コマンドは、2 つのファミリが指定されている場合と 1 つのファミリが指定されている場合で異なる動作をしなければならない場合があります。たとえば、上記の例では、最初の引数が指定されていない場合、2 番目のファミリのオプション引数を区切るためにコンマが使用されます。ただし、が指定されている場合は、それが区切り文字として使用され、コマンドは引数の読み取り時に異なる動作をします。
このような状況では、引数の読み取り時に選択肢が増えるため、newcommand よりも \def の方がコマンドを記述する一般的なオプションだと思います。(\newcommand は、最初の引数を読み取る前に 2 番目の引数を分割します。2 番目の引数ファミリに含まれる ']' も検討してください...)
私の質問は次のとおりです:
- いつ (標準 LaTeX) 最初の方法を使用し、いつ 2 番目の方法を使用する必要がありますか?
- 引数の数がまだわからない場合や、上記のような区切り文字や ']' が使用されている場合など、一般的な状況でコマンドを定義するには、\def が唯一の方法でしょうか、それともより優れた方法でしょうか?
PS: 2 番目の質問では、次の文字を読み取ることで多くの状況を処理できるようにコマンドを作成したいと考えています。(たとえば、コマンドの後の文字を 1 つずつ読み取り、通常の引数が 2 つ見つかった場合やコマンド \stop などがある場合にのみ停止したいとします。このコードを尋ねているのではなく、\newcommand でそれが実行できるかどうか (そしてそれが良い選択であるかどうか)、または \def が唯一の選択肢であるかどうかを尋ねているだけです)
答え1
あなたの質問は2つの別々のことを混ぜています。LaTex2eにはオプションの引数[]
と必須の引数があるので{}
、
\Foo[OptArg1,OptArg2]{Arg1}{Arg2}
オプションの引数が 1 つと、必須の引数が 2 つあります。
\Foo[OptArg1][OptArg2]{Arg1}{Arg2}
オプションの引数が 2 つと必須の引数が 2 つあります。
2つ目の問題は、カンマ区切りのリストです。これは構文の一部ではなく、カンマが文字として扱われるだけなので、例えば
\newcommand\Foo[3][]{(#1)-(#2)(#3)}
となり、 と#1
なり、となり、結果はタイプセットされるOptArg1,OptArg2
#2
Arg1
#3
Arg2
(オプション引数1、オプション引数2)-(引数1)-(引数2)
カンマには特別なルールはありません。
もちろん、コマンドは引数を好きなように扱うことができ、これにはカンマの繰り返し処理も含まれる。LaTeX形式にはそのための機能がある(\@for
)か、いくつかのパッケージではカンマ区切りのリストを解析するマクロを提供している。ただし、これはオプションの引数検出とは無関係である。(正当な)構文例では
\usepackage[foo,bar]{array,longtable}[2015/01/01 packages by you, me and someone]
オプションの引数が 2 つと必須の引数が 1 つあります。最初のオプションの引数と必須の引数は、 の処理の一部として、後で\usepackage
カンマで分割されます。2 番目のオプションの引数はカンマで分割されませんが、実際には/
引数の先頭から日付を抽出するために、 とスペースで分割されます。
定義に関しては、最初にオプション引数が1つしかない場合は、 を使用できます。2\newcommand
つ以上の場合は、 も使用できます\newcommand
が、段階的にマクロを定義する必要がありますが、 または xparse
同様のパッケージを使用する方がおそらく簡単です。これにより、より単純な仕様が可能になり、必要な内部マクロの定義が自動的に処理されます。ただし、次のように連続したオプション引数が多すぎると、最善ではありません。
\Foo[OptArg1][OptArg2]{Arg1}{Arg2}
OptArg1
を指定する必要がある場合、これは実際にはオプションではありませんOptArg2
。次のような構文は
\Foo[opt1=a,opt2=b]{Arg1}
各オプションを個別に省略することができます。しかし、このようなキー=値の解析は、必須引数かオプション引数かに関係なく、任意のトークン文字列に適用できます。たとえば、パッケージgraphicx
を使用して、オプション引数のandをkeyval
解析します。,
=
\includegraphics[width=10pt,height=8pt]{image}
hyperref
同じ構文解析を使用して、必須引数の同じ構文を解析します。
\hypersetup{colorlinks=false,plainpages=true}