Latex3: definiere \tl_if_integer:n

Erstellt am 5. Juli 2021  ·  19Kommentare  ·  Quelle: latex3/latex3

Hallo,

Es ist schön zu testen, ob eine Token-Liste eine Ganzzahl ist oder nicht, ohne auf die Verwendung von internem __int_to_ roman:w zurückzugreifen:

\prg_new_conditional:Npnn \tl_if_integer:n #1 { p, T, F, TF }
{
  \tl_if_blank:oTF { \__int_to_roman:w -0#1 }
   {
    \prg_return_true:
   }
   {
    \prg_return_false:
   }
}

Hilfreichster Kommentar

Ich stimme zu, dass es sinnvoll wäre, \str_if_integer:nTF , aber es ist noch nicht klar, was die zulässigen Ganzzahlen sein sollten. Vermutlich sollten Leerzeichen zwischen Zeichen erlaubt sein, aber nicht innerhalb einer Ganzzahl, da TeX dies nicht zulässt?

Code, der auf \romannumeral -Umbrüchen für lange Ziffernfolgen basiert, mit dem Fehler „Zahl zu groß“. Vermutlich brauchen wir einen langsameren Prozess, der nur ein paar Ziffern auf einmal erfasst, aber dann wird es lästig, Leerzeichen zwischen Ziffern zu erkennen.

Eine Alternative/Ergänzung wäre \str_to_integer:nF , die den String bereinigt, wenn er "ausreichend" wie eine Ganzzahl aussieht (wir könnten uns entscheiden, etwas lasch zu sein (aber gut dokumentiert)) und ansonsten sein zweites Argument im Eingabestrom belässt.

Alle 19 Kommentare

Besser hier:

\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:
      }
    }
}

Der Name scheint seltsam: Er prüft nicht wirklich auf eine ganze Zahl (zB -5 ist eine ganze Zahl, gibt aber falsch zurück, +7 gibt auch falsch zurück). Es scheint eher ein Test zu sein, wenn nur Ziffern vorhanden sind.

@zauguin Ok für den Namen, aber die Funktion ist nützlich, und passen Sie das alte Tick des Textbuchs an, um zu prüfen, ob die Ziffer. Ich stimme zu, dass Integer mit Regex implementiert werden könnten, aber es wird langsam sein

Verbessert durch Ihre Kommentare:

\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:
    }
  }
}

@bastien-roucaries TeX akzeptiert mehrere Zeichen vor einer Zahl, daher reicht Ihr Test normalerweise aus, aber nicht immer. Sollte dies implementiert werden, könnte es mehrere Zeichen wie dieses zulassen:

\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

Der Test ist str , um die Erweiterung von Tokens im Argument zu verhindern. Sowohl meine als auch Ihre Implementierung erweitern das Zeichen nicht, erweitern jedoch die Ziffern mit \romannumeral . Eine tl -Version müsste wohl alles nach Bedarf erweitern.

Ich stimme zu, dass es sinnvoll wäre, \str_if_integer:nTF , aber es ist noch nicht klar, was die zulässigen Ganzzahlen sein sollten. Vermutlich sollten Leerzeichen zwischen Zeichen erlaubt sein, aber nicht innerhalb einer Ganzzahl, da TeX dies nicht zulässt?

Code, der auf \romannumeral -Umbrüchen für lange Ziffernfolgen basiert, mit dem Fehler „Zahl zu groß“. Vermutlich brauchen wir einen langsameren Prozess, der nur ein paar Ziffern auf einmal erfasst, aber dann wird es lästig, Leerzeichen zwischen Ziffern zu erkennen.

Eine Alternative/Ergänzung wäre \str_to_integer:nF , die den String bereinigt, wenn er "ausreichend" wie eine Ganzzahl aussieht (wir könnten uns entscheiden, etwas lasch zu sein (aber gut dokumentiert)) und ansonsten sein zweites Argument im Eingabestrom belässt.

@blefloch Was ist die dokumentierte Grenze von \romannumeral ?

@bastien-roucaries Die größte Ganzzahl, die TeX verarbeiten kann: 2³¹−1 = 2147483647.

@PhelypeOleinik Es scheint, dass @blefloch bedeutet, dass +-+-+-+-+-+-+-+-+-+-+-+-+0000000000000000000000000000000000000000000000000000000000000000000000 könnte \romannumeral brechen ...

Was ist also die maximale Saitengröße?

@bastien-roucaries \romannumeral bricht nur mit „Zahl zu groß“ für eine Zahl ungleich Null. TeX kann eine beliebig lange Folge von Nullen annehmen, solange die resultierende Ganzzahl innerhalb des Bereichs [−2³¹−1, 2³¹−1] liegt.

@bastien-roucaries @blefloch Ich würde ganze Zahlen im Hexadezimal- oder Oktalformat nicht vergessen. Und

-`a

ist auch eine ganze Zahl.

Es gibt einen internen Test für Ziffern in l3bitset \__bitset_test_digits:nTF . Es verarbeitet keine Zeichen, da dies unnötig war, aber es sollte ganzzahlige Ausdrücke verarbeiten.

Wie @eg9 gerade angedeutet hat, was ist hier der eigentliche Anwendungsfall? Handelt es sich um eine Dokumentenprüfung auf Benutzerebene für eine Ziffernfolge oder um eine Prüfung, ob die Zeichenfolge eine gültige Eingabe für eine expl3-Ganzzahlfunktion ist. Letzteres scheint in einem expl3-Kontext nützlicher zu sein und bedeutet im Grunde, dass nach \numexpr#1 nichts übrig bleibt, sodass die langsame Prüfung auf wörtliche Ziffernfolgen nicht erforderlich wäre.

@davidcarlisle Dieser Fehler betrifft den ersten Fall, aber ich möchte den zweiten verwenden

Ich glaube nicht, dass ich dafür bin, die L3-Programmierschicht mit zufälligen Erweiterungen zu erweitern, die (möglicherweise) in besonderen Situationen nützlich sind, aber keine klaren, regelmäßig benötigten Anwendungsfälle haben. Für mich ist dies ein solches Beispiel. Wenn wir damit anfangen, wo hören wir auf? Wie viele spezielle "ist das tl irgendein X" sollten wir dann unterstützen? Meine Stimme dazu ist nein; nicht für die Kernsprache.

@FrankMittelbach Zu wissen, ob wir einige Berechnungen mit TL durchführen können oder nicht, ist nützlich. Der andere könnte mit Regex durchgeführt werden, aber mit dem Fallstrick, dass es im erweiterten Kontext nicht funktioniert (und ich brauche diesen Test, um im erweiterten Kontext zu arbeiten).

Ohne Zweifel. Aber ist es nützlich genug, um seine Aufnahme in die Kernsprache zu rechtfertigen (oder nur als Teil eines Paketcodes bereitgestellt zu werden, wenn es tatsächlich benötigt wird)? Das ist hier die Frage für mich und bisher habe ich keine wirklichen Argumente gesehen, die für seine Aufnahme sprechen.

Sie können dieselbe Frage stellen für „Ist es eine Dimension“, „Ist es als Sprung“, „Ist es nur Buchstaben“, „Enthält es Nicht-ASCII-Zeichen“, „Ist es ein Datumsformat“ und, und, und ... die Möglichkeiten sind ziemlich offen und für die meisten von ihnen können Sie einen oder zwei Anwendungsfälle konstruieren. Aber 99 % der Zeit sitzen sie einfach da und nehmen Platz ein. Und obwohl Platz nicht mehr so ​​wichtig ist wie in der Vergangenheit, trägt er dennoch zur Komplexität und Wartbarkeit des Kernsystems bei. Also noch einmal, wird diese Funktionalität häufig und wiederholt verwendet? Wenn ja, und ich höre überzeugende Argumente dafür, dass es ein Kandidat für die Aufnahme sein könnte. Wenn nicht, sollte es als Teil des Codes implementiert werden, der es benötigt.

@FrankMittelbach Das Problem ist hier spezifisch für biblatex. Wir müssen testen, ob ein Feld eine Ganzzahl ist (denken Sie an die Seitenzahl) und damit in einem erweiterbaren Kontext arithmetisch arbeiten.
Ok ti ist spezifisch, aber der knifflige Teil ist das erweiterbare Zeug.
Möglicherweise sollte diese Art von Test nur dokumentiert werden. Beim Lesen des Dokuments weiß ich nicht, wie ich vorgehen soll, und außerdem glaubt der Biblatex-Kern, dass es nicht möglich ist, zu testen (expand comptabible), ob ein Token eine Ganzzahl ist.

Vielleicht besteht die Lösung darin, Regex erweiterbar zu machen (ich denke, es wird schön sein)

Verstehen Sie mich nicht falsch, ich bin überhaupt nicht dagegen, dass wir Ihnen auf der Biblatex-Seite helfen, damit dies funktioniert, und es kann durchaus sein, dass uns im Kern einige Funktionen fehlen, die im Kern vorhanden sein sollten, um dies zu unterstützen. Mein Punkt ist, dass der Kern sich auf "allgemeine" Bedürfnisse beschränken und die grundlegende allgemeine Grundlage zum Schreiben von speziellem Code bereitstellen sollte, aber nicht alle Arten von Erweiterungen bereitstellen sollte, die sehr selten oder gar nicht verwendet werden (z. B. in diesem Fall, wenn biblatex wird nicht verwendet). Andernfalls werden wir am Ende mit einem sehr aufgeblähten Befehlssatz enden.

Dinge erweiterbar zum Laufen zu bringen, ist normalerweise mit einem hohen Preis verbunden, entweder durch eingeschränkte Funktionalität oder Geschwindigkeitsverlust oder beides. Daher bezweifle ich, dass es eine gute Idee ist, zu versuchen, Regex erweiterbar zu machen, aber ich lasse @blefloch dazu kommentieren.

Aber ohne Ihren Anwendungsfall genauer zu kennen: Irgendwo werden Ihre Felder eingerichtet, und das geschieht nicht erweiterbar, da Zuweisungen erforderlich sind. In diesem Stadium können Sie also feststellen, ob Sie eine Ganzzahl oder etwas anderes haben, und diese Tatsache aufzeichnen, die dies könnte dann erweiterbar verwendet werden (nicht sicher, ob das hilft oder machbar ist, aber es würde vermeiden, das Feld immer wieder zu testen).

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen