\@firstofone verstehen

\@firstofone verstehen

Ich habe mir diese Antwort angesehen und versucht, den Code zu verstehen. Ich bin ein absoluter Neuling (mein zweiter Tag) in LaTeX und bin beim folgenden Teil des Codes hängen geblieben, den ich in einer Umgebung ohne Tabellen nicht zum Laufen bringen konnte. Hier ist die einfachste Form dessen, was ich nicht verstehe.

\documentclass{article}
\begin{document}
    \newcommand*\f[3]{#1-#2-#3}
    \newcommand*\ex[1]{\f#1 - \expandafter\f\@firstofone}
     Try \ex{111}{221}
\end{document}

Aus irgendeinem Grund, der mir nicht klar ist, wird im verlinkten Code das letzte Argument nicht verwendet, sondern bleibt für die Verwendung durch die expandafter\f\...Konstruktion übrig. So wie ich es verstehe, \expandaftersollte zuerst „ausgeführt“ werden \@firstofone, das {221}Argument abrufen, die Klammern entfernen und es an übergeben \f. Dies geschieht nicht und ich kann nicht herausfinden, warum.

Antwort1

\makeatletterDamit dies funktioniert, müssen Sie verwenden , aber das ist das Mindeste.

Der Aufruf \ex{111}{221}erweitert sich zunächst auf

\f 111 - \expandafter\f\@firstofone{221}

Jetzt \fwird erweitert und sucht nach drei Argumenten. Dabei werden 1, 1und gefunden 1, da TeX ein einzelnes Token verwendet, wenn eine Klammer fehlt.

Durch die Definition \fwird dieser erweitert und der Ersetzungstext wieder in den Eingabestrom eingefügt:

1-1-1 - \expandafter\f\@firstofone{221}

Die Token 1-1-1 -sind nicht erweiterbar und werden daher an die nächste Stufe gesendet. Jetzt bleibt es

\expandafter\f\@firstofone{221}

Dies wird \fbeiseite gelegt und erweitert, \@firstofonewas einfach sein (ungeschränktes Argument) zurückgibt, also erhalten wir

\f221

das wird 2-2-1. Der Nettoeffekt Ihres Codes besteht also darin, zu drucken

1-1-1 - 2-2-1

was nicht wirklich nützlich erscheint. Wo auch immer Sie es gefunden haben, vertrauen Sie ihm nicht.

Antwort2

Wie egreg in seiner Antwort betonte, \@firstofoneist die Verwendung von nicht sehr nützlich und macht in diesem speziellen Fall keinen Unterschied. Es gibt jedoch Fälle, in denen esIstnützlich. Der Vollständigkeit halber möchte ich zwei Beispiele nennen.

Erweiterbare Makros

InWarum diese \expandafter\@firstoftwoRedewendung?Es wird ein typischer Anwendungsfall für \@firstoftwound \@secondoftwoin vollständig erweiterbaren Makros angegeben. \@firstofone, eine Art „Identitätsfunktion“ von LaTeX, ist in ähnlichen Kontexten nützlich, in denen nur ein einziger Parameter verarbeitet werden soll:

\def\gobbleIfZero#1{%
  \ifnum#1=0
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
}

foo\gobbleIfZero{0}{bar}

foo\gobbleIfZero{123}{bar}

wird geben

foo

foobar

\@gobble(wie \@firstofone) nimmt einen einzelnen Parameter an, verwirft ihn aber und erweitert ihn zu „nichts“.

Korrektur von Catcodes

Etwas kniffliger, aber auch interessanter ist der Fall, in dem Catcode-Änderungen beteiligt sind. Wenn TeX Argumente für Makros analysiert, korrigiert es Catcodes, wenn der Argumenttext gelesen wird. Dies spielt in Ihrem Fall keine Rolle, da es hier keine Catcode-Änderungen gibt. Aber nehmen wir an, das folgende, etwas konstruierte Beispiel wird gegeben:

\begingroup
\catcode`4=\active
\gdef 4{four}
\endgroup

\newcommand*\f{\catcode`4=\active}
\newcommand*\exA{\f}
\newcommand*\exB{\expandafter\f\@firstofone}

{\exA{345}--{345}}

{\exB{345}--{345}}

Das führt zu

3vier5-3vier5

345-3vier5

Die ersten vier Zeilen definieren ein globales Makro 4, das sich zu erweitert four. Normalerweise 4hat es den Catcode 12 (anderes), also ändern wir ihn in 13 (aktiv), um daraus ein Makro machen zu können. \fHier wird dieses Makro bei Ausführung wieder in den Gültigkeitsbereich gebracht.

Wenn \exAausgeführt wird, 4wird der Catcode von in 13 geändert, was anschließend 4eine Erweiterung fourin die beiden folgenden Gruppen ermöglicht. Hier gibt es überhaupt keine Parameter, daher ist dies unkompliziert.

Im Makro hingegen wird \exBder erste {345}Teil verarbeitet, \@firstofoneder einfach den gleichen Text zurückgibt,behebt aber den Catcodevon 4auf 12. Sobald es behoben ist, kann es nicht mehr geändert werden! Auch wenn die Catcode-Änderung von \fverarbeitet wirdVordie erste 345, es wird keine Auswirkungen darauf haben. Da die Catcodes der zweiten {345}noch nicht behoben wurden, gelten die Änderungen trotzdem für diese Gruppe.

Dieses Verhalten ist sehr praktisch, wenn Sie zusätzlichen Code in vorhandene Makros einfügen möchten, die sich mit Catcode-Änderungen befassen, z. B. \verb(inspiriert vondiese TeX-Perle):

\begingroup
\catcode`\/\active
\catcode`\_\active
\@firstofone{%
  \verb|%
  \catcode`\/\active \def/{\par}%
  \catcode`\_\active \def_#1_{\textcolor{blue}{#1}}%
}_\documentclass_{article}/_\begin_{document}/  We all love _\LaTeX_!/_\end_{document}|
\endgroup

welche Ausgänge

Ausgabe

Ich weiß nicht, wo Sie \@firstofoneüberhaupt davon gelesen haben, aber es könnte in einem dieser Zusammenhänge gewesen sein.

verwandte Informationen