Was ist die bevorzugte Methode zum zweimaligen Erweitern in expl3?

Was ist die bevorzugte Methode zum zweimaligen Erweitern in expl3?

expl3enthält die Argumentspezifizierer o, f, und xfür eine einstufige bzw. die beiden Arten der vollständigen Erweiterung, bevor das Argument an die Basisfunktion übergeben wird. Was ist die bevorzugte Art der Erweiterung eines Arguments?zweimalbevor Sie es an die Basisfunktion übergeben?

Als Beispiel versuche ich, eine l3keysSchlüssel-Wert-Schnittstelle für Makros zu schreiben, die mit \DeclarePairedDelimiterdem mathtoolsPaket erstellt wurden.

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

Normalerweise wird die Größe der Trennzeichen als optionales Argument von \bigusw. oder an das Makro übergeben *, z. B. \abs[\big]{x}wobei . Ich hätte usw. oder \DeclarePairedDelimiter\abs{\lvert}{\rvert}lieber als Schlüssel-Wert-Schnittstelle, wie z. B. .size = bigsize = auto\myabs[size=big]{x}

Das Problem mit dem obigen Code besteht darin, \l__mymodule_size_tldie bigAuswahlmöglichkeiten usw. richtig einzustellen: Ich muss erweitern[ \use:c { \tl_use:N \l_keys_choice_tl } ] zweimalbevor diese Token zugewiesen werden \l__mymodule_size_tl.

  • Wenn ich keine Erweiterung verwende (d. h. \tl_set:Nn), erhält der Aufruf von \abssein Argument in der falschen Form – \l__mymodule_size_tles gilt [ \use:c { \tl_use:N \l_keys_choice_tl } ], nicht [\big].
  • Wenn ich eine einstufige Erweiterung (d. h. \tl_set:No) verwende und [nach Abschluss der Erweiterung voranstelle, \l__mymodule_size_tlgilt [ \cs:w \tl_use:N \l_keys_choice_tl \cs_end: ], nicht [\big].
  • Wenn ich entweder die foder xdie Erweiterung verwende, \l__mymodule_size_tlentsteht ein Haufen „Müll“, nicht [\big].

Was kann ich tun? Hier ist eine Idee: Verwenden Sie zwei oErweiterungen mit etwas Akrobatik dazwischen.

    \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 { [ }

Das ist meiner Meinung nach ziemlich hässlich. Kann ich etwas Besseres tun?

Antwort1

Früher gab es ein dArgument vom Typ - für die doppelte Erweiterung. Es wurde jedoch vor einigen Jahren fallengelassen, da es nur an sehr wenigen Stellen erforderlich war, insbesondere als das Team beschloss, toksgenerell keine Register zu verwenden. Soweit ich mich erinnere, expl3gab es zwei Stellen, an denen wir eine Konstruktion der Form \exp_args:NNo \exp_args:Nooder einer ähnlichen Form verwenden mussten.

Der Grund, warum wir -type-Argumente nicht beibehalten haben, ist zweifach. Erstens möchten wir es möglichst vermeiden, uns auf die Kenntnis der Erweiterungsdetails von Funktionen zu verlassen: Dies ist für die Arbeit auf niedriger Ebene erforderlich, sollte aber idealerweise relativ begrenzt sein. Der andere Grund ist, dass es sehr selten benötigt wird, da wir e-TeX zur Verfügung haben. Der Schlüssel zum Erinnern ist, dass dies uns ermöglicht, die Erweiterung in -type-Kontexten dzu steuern.x

\tl_set:Nx \l__mymodule_size_tl
  { [ \exp_not:c { \tl_use:N \l_keys_choice_tl } ] }

Obwohl es hier nicht benötigt wird, dokumentieren wir \cs:w... \cs_end:für Situationen, in denen genau eine Erweiterung erforderlich ist, sodass Sie Folgendes haben könnten:

\tl_set:No \l__mymodule_size_tl
  { \exp_after:wN [ \cs:w \tl_use:N \l_keys_choice_tl \cs_end: ] }

obwohl ich das hier selbst nicht verwenden würde.

Antwort2

Mein Eindruck ist, dass Sie

\tl_set:Nx \l__mymodule_size_tl
 {
  [ \exp_not:c { \tl_use:N \l_keys_choice_tl } ]
 }

Mit wird xdie Erweiterung \exp_not:causgelöst, sodass das Argument wie immer vollständig erweitert wird, wenn cbeteiligt ist (es ist \csname...\endcsname); dann wird das resultierende Token nicht erweiterbar gemacht, wenn Sie also haben

size=big

Sie gelangen [\big]in Ihre Token-Liste.

verwandte Informationen