ここでより良い:
\prg_new_conditional:Npnn \tl_if_integer:n #1 { p, T, F, TF }
{
\tl_if_blank:nTF{#1}
{
\prg_return_false:
}
{
\tl_if_blank:oTF { \__int_to_roman:w -0#1 }
{
\prg_return_true:
}
{
\prg_return_false:
}
}
}
名前は奇妙に思えます。実際には整数をチェックしません(たとえば、 -5
は整数ですが、falseを返し、 +7
もfalseを返します)。 数字だけが存在する場合は、テストのように見えます。
@zauguin名前はわかりましたが、関数は便利です。texbookの古い目盛りと一致して、数字かどうかを確認します。 整数は正規表現を使用して実装できることに同意しますが、遅くなります
あなたのコメントで改善されました:
\prg_new_conditional:Npnn \tl_if_digit:n #1 { p, T, F, TF }
{
\tl_if_blank:nTF{#1}
{
\prg_return_false:
}
{
\tl_if_blank:oTF { \__int_to_roman:w -0#1 }
{
\prg_return_true:
}
{
\prg_return_false:
}
}
}
\prg_generate_conditional_variant:Nnn \tl_if_digit:n { o } { p, T, F, TF }
\prg_new_conditional:Npnn \__tl_if_integer:n #1 { p, T, F, TF }
{
\exp_args:No\str_if_eq:onTF{\tl_head:n{#1}}{+}
{
\exp_args:No\tl_if_digit:oTF{\tl_tail:n{#1}}
{
\prg_return_true:
}
{
\prg_return_false:
}
}
{
\exp_args:No\str_if_eq:onTF{\tl_head:n{#1}}{-}
{
\exp_args:No\tl_if_digit:oTF{\tl_tail:n{#1}}
{
\prg_return_true:
}
{
\prg_return_false:
}
}
{
\prg_return_false:
}
}
}
\prg_new_conditional:Npnn \tl_if_integer:n #1 { p, T, F, TF }
{
% fast path
\tl_if_digit:nTF{#1}
{
\prg_return_true:
}
{
% slow path
\__tl_if_integer:nTF{#1}
{
\prg_return_true:
}
{
\prg_return_false:
}
}
}
@ bathien-roucaries TeXは数字の前に複数の記号を受け入れるため、通常はテストで十分ですが、常にそうとは限りません。 これを実装すると、次のような複数の兆候が発生する可能性があります。
\ExplSyntaxOn
\prg_new_conditional:Npnn \str_if_integer:n #1 { p, T, F, TF }
{ \exp_after:wN \__str_if_integer_sign:N \tl_to_str:n {#1} \scan_stop: }
\cs_new:Npn \__str_if_integer_sign:N #1
{
\if:w $
\if_meaning:w - #1 F \fi:
\if_meaning:w + #1 F \fi: $
\exp_after:wN \__str_if_integer_digits:w \exp_after:wN #1
\else:
\exp_after:wN \__str_if_integer_sign:N
\fi:
}
\cs_new:Npn \__str_if_integer_digits:w #1 \scan_stop:
{
\tl_if_blank:nTF {#1}
{ \prg_return_false: }
{
\tl_if_blank:oTF { \__int_to_roman:w -0#1 }
{ \prg_return_true: }
{ \prg_return_false: }
}
}
\cs_new:Npn \test #1
{ \typeout { #1: \str_if_integer:nTF {#1} { INT } { NOT } } }
\test { }
\test { ~ }
\test { 1 }
\test { - }
\test { -1 }
\test { +1 }
\test { +-+-+-1 }
\stop
引数のトークンの拡張を防ぐためのテストはstr
です。 私とあなたの実装はどちらも記号を拡張しませんが、 \romannumeral
で数字を拡張します。 tl
バージョンは、おそらく必要に応じてすべてを拡張する必要があります。
\str_if_integer:nTF
を提供することは理にかなっていることに同意しますが、許可される整数がどうあるべきかはまだ明確ではありません。 おそらく、記号の間にスペースを入れる必要がありますが、TeXではスペースが許可されていないため、整数内には入れないでください。
\romannumeral
に基づくコードは、数字の長い文字列に対して「数値が大きすぎます」というエラーで中断します。 おそらく、一度に数桁しか取得できない低速のプロセスが必要ですが、桁間のスペースを検出するのは面倒になります。
代替/追加は\str_to_integer:nF
で、整数のように「十分」に見える場合は文字列をサニタイズし(多少緩い(ただし十分に文書化されている)と判断できます)、それ以外の場合は2番目の引数を入力ストリームに残します。
@blefloch \ romannumeralの文書化された制限は何ですか?
@ bathient-roucaries TeXが処理できる最大の整数:2³¹−1 = 2147483647。
@PhelypeOleinik @bleflochは、+-+-+-+-+-+-+-+-+-+-+-+-+ 000000000000000000000000000000000000000000000000000000000000000が\ romannumeralを壊す可能性があることを意味しているようです...
では、最大文字列サイズはいくつですか?
@ bathient-roucaries \romannumeral
は、ゼロ以外の数値の場合、「数値が大きすぎます」でのみ中断します。 TeXは、結果の整数が[-2³¹-1、2³¹-1]の範囲内にある限り、任意の長さのゼロの文字列を取ることができます。
@ bastien-roucaries @ blefloch16進または8進形式の整数を忘れません。 と
-`a
も整数です。
l3bitset \__bitset_test_digits:nTF
の数字の内部テストがあります。 これは不要であるため、符号は処理されませんが、整数式を処理する必要があります。
@ eg9がほのめかしたように、ここでの実際のユースケースは何ですか? 数字の文字列に対するユーザーレベルのドキュメントチェックですか、それとも文字列がexpl3整数関数への有効な入力であるかどうかのチェックです。 後者はexpl3コンテキストでより有用であるように思われ、基本的に\numexpr#1
の後に何も残らないことを意味するため、数字のリテラル文字列をゆっくりチェックする必要はありません。
@davidcarlisleこのバグは最初のケースに関するものですが、2回目の使用を希望します
特別な状況では(おそらく)役立つが、定期的に必要な明確なユースケースがないランダムな拡張機能でL3プログラミングレイヤーを拡張することに賛成ではないと思います。 私にとって、これはそのような例の1つです。 それから始めたら、どこで終わりますか? それでは、いくつの特別な「これはXですか?」をサポートする必要がありますか? これに対する私の投票はノーです。 コア言語ではありません。
@FrankMittelbach TLで計算を実行できるかどうかを知っていると、便利です。 もう1つは正規表現を使用して実行できますが、拡張コンテキストでは機能しないという落とし穴があります(拡張コンテキストで機能するにはこのテストが必要です)
間違いない。 しかし、コア言語に含めることを保証するのに十分有用ですか(または実際に必要なときにパッケージコードの一部としてのみ提供される)? それがここでの私にとっての質問であり、これまでのところ、それを含めることを支持する議論は実際には見ていません。
「ディメンションですか」、「スキップとしてですか」、「単なる文字ですか」、「ASCII以外の文字が含まれていますか」、「日付形式ですか」、および、についても同じ質問をすることができます。そして...可能性は非常にオープンエンドであり、それらのほとんどについては、ユースケースを1つか2つ構築することができます。 しかし、99%の確率で、彼らはただそこに座ってスペースを取ります。 また、スペースは以前のようにプレミアムではありませんが、それでもコアシステムの複雑さと保守性が増します。 繰り返しになりますが、この機能は広く繰り返し使用されていますか? もしそうなら、そして私はそれが包含の候補と見なされる可能性があるという説得力のある議論を聞きます。 そうでない場合は、それを必要とするコードの一部として実装する必要があります。
@FrankMittelbachここでの問題はbiblatexに固有のものです。 あるフィールドが整数であるかどうかをテストする必要があり(ページ数について考えてください)、拡張可能なコンテキストで、そのフィールドに対していくつかの算術を行います。
Ok tiは具体的ですが、注意が必要なのは拡張可能なものです。
この種のテストは文書化する必要があるだけかもしれません。 ドキュメントを読んで、私はその方法がわかりません。さらに、biblatexコアは、トークンが整数であるかどうかをテスト(拡張可能)することは不可能であると考えています。
解決策は、正規表現を拡張可能にすることかもしれません(私はそれがいいと思います)
誤解しないでください。私は、この機能を実現するためにbiblatex側で支援することにまったく反対していません。コアでは、それをサポートするためにコアに必要な機能が不足している可能性があります。 私のポイントは、コアは「一般的な」ニーズに限定し、特別なコードを書くための基本的な一般的な基盤を提供する必要があるが、ほとんど使用されないすべての種類の拡張機能を提供する必要はないということです(この場合はbiblatexの場合など)使用されません)。 そうしないと、最終的には非常に肥大化したコマンドのセットになってしまいます。
物事を拡張可能に機能させるには、通常、機能が制限されているか、速度が低下するか、またはその両方で、高額な費用がかかります。 したがって、正規表現を拡張可能にすることを試みるのは良い考えではないと思いますが、 @ bleflochにコメントさせます。
しかし、ユースケースをより詳細に知ることなく、フィールドが設定されていて、割り当てが必要になるため拡張可能に行われていないため、その段階で、整数か何か他のものがあるかどうかを判断し、その事実を記録することができます。次に、拡張可能に使用されます(それが役立つか、実行可能かはわかりませんが、フィールドを何度もテストすることは避けられます)。
最も参考になるコメント
\str_if_integer:nTF
を提供することは理にかなっていることに同意しますが、許可される整数がどうあるべきかはまだ明確ではありません。 おそらく、記号の間にスペースを入れる必要がありますが、TeXではスペースが許可されていないため、整数内には入れないでください。\romannumeral
に基づくコードは、数字の長い文字列に対して「数値が大きすぎます」というエラーで中断します。 おそらく、一度に数桁しか取得できない低速のプロセスが必要ですが、桁間のスペースを検出するのは面倒になります。代替/追加は
\str_to_integer:nF
で、整数のように「十分」に見える場合は文字列をサニタイズし(多少緩い(ただし十分に文書化されている)と判断できます)、それ以外の場合は2番目の引数を入力ストリームに残します。