> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/de/weitere-themen/24-how-tex-macros-actually-work-part-6.md).

# Wie TeX-Makros eigentlich funktionieren: Teil 6

[Teil 1](/latex/de/weitere-themen/19-how-tex-macros-actually-work-part-1.md) [Teil 2](/latex/de/weitere-themen/20-how-tex-macros-actually-work-part-2.md) [Teil 3](/latex/de/weitere-themen/21-how-tex-macros-actually-work-part-3.md) [Teil 4](/latex/de/weitere-themen/22-how-tex-macros-actually-work-part-4.md) [Teil 5](/latex/de/weitere-themen/23-how-tex-macros-actually-work-part-5.md) [Teil 6](/latex/de/weitere-themen/24-how-tex-macros-actually-work-part-6.md)

## Einführung und Überblick: Die Geschichte bisher

In den vorherigen 5 Teilen dieser Reihe haben wir gesehen:

* wie TeX die Zeichen innerhalb einer Eingabedatei liest und Kategoriecodes verwendet, um verschiedene „Klassen“ von Zeichen zu erkennen und sie anschließend in Zeichentokens und Befehlstokens umzuwandeln;
* dass ein Makro im Wesentlichen aus vier Abschnitten besteht:

```
<TeX macro primitive><macro name><parameter text>{<replacement text>}
```

wobei:

* `<TeX macro primitive>` = eines von `\def`, `\edef`, `\gdef` oder `\xdef`;
* `<macro name>`= der Name Ihres Makros, z. B. `\foo`;
* `<parameter text>` kann „null“ (nicht vorhanden) sein oder eine Zeichenkette aus Trennertokens und Makro-Parametertokens;
* `<replacement text>` ist der eigentliche Inhalt Ihres Makros: der Abschnitt, der „ausgeführt“ (expandiert) wird, wenn Sie das Makro aufrufen.
* wie die `<parameter text>` der Abschnitt eine breite Palette von Tokens enthalten kann und dass TeX diesen Abschnitt als „Tokentemplate“ verwendet, um einen Makroaufruf mit seiner ursprünglichen Definition abzugleichen und die mit dem Makro verwendeten Argumente zu ermitteln — und wie TeX erwartet, dass Ihre Verwendung eines Makros mit seiner ursprünglichen Definition übereinstimmt;
* dass im Inneren von TeX eine Makrodefinition als fortlaufende Sequenz von Tokens gespeichert wird, die die `<parameter text>` und `<replacement text>` Abschnitte.

Wenn Sie einen Makrobefehl verwenden, prüft TeX zuerst, ob er irgendwelche Parameter annimmt. Falls ja, muss TeX dann die tatsächlichen *Argumente* die in Ihrem Makroaufruf verwendet werden. TeX muss Ihren Makroaufruf anhand der im Speicher abgelegten „Tokentemplate“-Definition prüfen. Genauer gesagt verwendet TeX die interne (gespeicherte) Definition des `<parameter text>` Abschnitts Ihres Makros als Vorlage, anhand derer es *Tokens* Tokens herausfiltern kann, die die tatsächlichen Argumente sind, und welche *Tokens* nur als Trennzeichen dienen.

## Die Bedeutung der Makroexpansion

Wir sind nun endlich bereit, zum wichtigsten Thema überzugehen: wie TeX Makroargumente verarbeitet und das Makro tatsächlich ausführt: ein Prozess, den TeX als *Makroexpansion*.

### Aber zuerst ein kurzes Beispiel: etwas Seltsames?

Um den Mechanismus zu erläutern, mit dem TeX Makros und ihre Argumente verarbeitet, setzen wir die Szene mit einem kurzen Beispiel, um die zu berücksichtigenden Punkte aufzuzeigen.

#### Argumente werden zuerst in Tokens umgewandelt

Das folgende Beispiel basiert auf einem Beispiel, das auf den Seiten 114–5 von [The Advanced TeXbook](https://www.amazon.co.uk/Advanced-Texbook-David-Salomon/dp/0387945563) von David Salomon verfasst wurde. Es wurde ausgewählt, weil es die zentralen Ideen in einem sehr kurzen TeX-Makro schön zusammenfasst.

Im normalen TeX/LaTeX-Betrieb hat das `$` Zeichen den Kategoriecode 3 („math shift“), der TeX in den bzw. aus dem Inline-Mathematikmodus (`$...$`) oder Display-Mathematikmodus (`$$...$$`) schaltet — natürlich verwendet LaTeX `\(..\)` und `\[..\]` für denselben Zweck.

Angenommen, wir möchten ein Makro, das den Kategoriecode eines `$` Zeichens auf z. B. 11 ändert, damit wir es wie ein normales Zeichen setzen können. Wir können den TeX-Primitive-Befehl `\catcode` verwenden, und unser erster Versuch eines solchen Makros, `\docat`, könnte sein

```
\def\docat #1{\catcode\`\$=11 #1}
```

Wenn wir es jedoch verwenden, etwa so

```
\begin{document}
\def\docat #1{\catcode\`\$=11 #1}
Ich zahlte \docat{$90} für dieses Buch.
\end{document}
```

erwarten wir, dass TeX `Ich zahlte $90 für dieses Buch.` setzt, aber es schlägt mit einer Fehlermeldung fehl:

```
! Fehlendes $ eingefügt.
<eingefügter Text>
                $
<wird erneut gelesen>
                   \par
l.7
```

Aus dem Fehler scheint hervorzugehen, dass das `$` in unserem Makroargument verwendete Zeichen TeX immer noch dazu veranlasst, Mathematik zu setzen; offensichtlich hat TeX *nicht* den Kategoriecode des `$` in unserem Makroargument verwendeten`$90`geändert ( *warum* ). Die Frage ist `$` warum hat TeX den Kategoriecode von **bevor** nicht auf 11 geändert und es als normales Zeichen gesetzt? Die kurze Antwort ist, dass TeX Makroargumente zuerst in Tokens umwandelt `<replacement text>`bevor es sie in die Tokenliste des

einspeist — aber wir werden die zugrunde liegenden Mechanismen viel genauer ansehen. *Tokens*Wichtig ist, dass unsere Vorstellung davon, dass TeX mit Text/Zeichen arbeitet, nur für den Inhalt der Datei relevant ist, die TeX liest: Sobald TeX irgendwelche Zeichen eingelesen hat, befinden wir uns in der Welt von *Tokens*. TeX-Makroaufrufe arbeiten mit *, nicht mit der tatsächlichen* schriftlichen/textuellen Darstellung

von TeX/LaTeX-Befehlen — das wird klarer, wenn wir das Beispiel durchgehen. `\docat` Anfangs könnten wir denken, dass unsere Verwendung des `Ich zahlte \docat{$90} für dieses Buch.` Makros in *nicht* dasselbe ist wie das direkte Schreiben des entsprechenden TeX- (oder LaTeX-) Codes — etwa wie der folgende, der

```
\begin{document}
Ich zahlte \catcode\`\$=11 $90 für dieses Buch.
\end{document}
```

![TeX-Code, der auf Overleaf ausgeführt wird](/files/7d67437afe5ceb7db049fa387a62a47d29abb709)

Allerdings erzeugt die Art, wie TeX Makroargumente verarbeitet, wie wir oben gesehen haben, ein Ergebnis (`! Fehlendes $ eingefügt.`), das sich stark vom Ausschreiben des TeX-Codes unterscheidet: Wir werden nun untersuchen *warum* was dabei geschieht.

### Makros und Argumente als Tokenlisten

Um das Verhalten des `\docat` Makros und seines Arguments (`$90`) sowie den Grund für sein Scheitern vollständig zu verstehen, müssen wir uns erneut die Definition des `\docat` Makros und aller verwendeten Argumente (wenn \docat aufgerufen wird) als *Token-Listen*, nicht als eine Zeichenfolge.

Während TeX Ihren Eingabetext scannt, würde es `\docat` als Makrobefehl erkennen; danach prüft es, ob er Parameter annimmt — wie TeX das macht, wird im folgenden Abschnitt für Leser erklärt, die an den feineren Details interessiert sind.

#### Für diejenigen, die Details mögen...

Nachdem das Makro aufgerufen wurde, prüft TeX, ob das allererste Token (in der gespeicherten Definitions-Tokenliste des Makros) das **End-Match** Token ist: Wenn ja, kann TeX sicher sein, dass das Makro keine Parameter annimmt.

**Ein Beispiel**

Die folgenden Node-Listen-Diagramme vergleichen die Tokenlisten zweier Makros:

* `\def\foo A#1B{#1}`: dieses hat `<parameter text>` von `A#1B`, folglich ist das **End-Match** Token das **nicht** erste Token, also würde TeX mit der Suche nach Parametern fortfahren;
* `\def\foo{X}`: dieses hat keinen `<parameter text>` Abschnitt, folglich ist das **End-Match** Token das erste in der Tokenliste, und TeX weiß, dass es nicht nach Parametern suchen soll.

![Wie TeX prüft, ob ein Makro Parameter annimmt](/files/095864e86a1c2b4b659b35e5b3ccc32c8b0309ab)

## Auf zum „großen Finale“: Expansion

Erinnern wir uns an die Frage: Warum hat das folgende Makro nicht funktioniert; d. h., warum ändert TeX den Kategoriecode irgendwelcher `$` Zeichen, die im Argument des `\docat` Makros verwendet werden, wie etwa `\docat{$90}`?

```
\begin{document}
\def\docat #1{\catcode\`\$=11 #1}
Ich zahlte \docat{$90} für dieses Buch.
\end{document}
```

Wie oben erklärt, prüft TeX, wenn es Ihre Eingabe scannt und einen Makrobefehl erkennt — zu einem Zeitpunkt, an dem TeX ihn ausführen wird — zuerst, ob dieses Makro irgendwelche Parameter annimmt. Falls ja, muss TeX die Eingabedatei weiter scannen, um die tatsächlichen *Argumente* der Benutzer für diesen speziellen Makroaufruf bereitgestellt hat: TeX muss dies **bevor** tun, bevor es den eigentlichen Makrocode aufrufen kann. Offensichtlich muss TeX die Daten ermitteln, die der Benutzer dem Makro geben möchte.

Um die in der Eingabe vorhandenen Argumente (den Makroaufruf des Benutzers) zu identifizieren, wird TeX von der intern gespeicherten Definition dieses Makros geleitet: genauer gesagt vom `<parameter text>` Abschnitt der gespeicherten Makrodefinition (Tokenliste) — dieser bietet eine Art „Tokentemplate“. Mithilfe dieses „Tokentemplates“ muss TeX bestimmen, welche *Tokens* im Makroaufruf des Benutzers nur *Begrenzer* sind (im Wesentlichen „Interpunktion“) und welche *Tokens* Teil eines *Arguments*. Wenn TeX auf ein **Match-Parameter** Token in der gespeicherten Makrodefinition `<parameter text>` Abschnitt („Tokentemplate“) trifft, weiß es, dass es beginnen muss, eine *Tokenliste* für dieses spezielle Argument zu bilden.

Sobald TeX erkennt, dass es das Argument des Benutzers identifizieren muss, scannt TeX die Eingabe, um Tokens zu erzeugen, und prüft sie sehr sorgfältig, Token für Token, gegen die gespeicherte Makrodefinition. TeX sammelt Tokens für ein Argument so lange, bis es ein Token erkennt, das tatsächlich ein Trennzeichen ist, oder wenn es das **End-Match** Token erkennt: In beiden Fällen weiß TeX dann, dass es Zeit ist, mit der Suche nach Tokens aufzuhören, die Teil dieses Arguments sind.

### Warum das Makro \docat fehlgeschlagen ist

Wie bereits erwähnt, *bevor* Um ein Makro tatsächlich aufrufen zu können, muss TeX alle Argumente identifizieren und vorbereiten, die mit diesem Makro verwendet werden sollen. Um jedoch die Argument(e) zu identifizieren und für das Einspeisen in das Makro bereitzustellen, muss TeX jedes Argument als *Tokenliste*: und das ist der Grund für `\docat`s Scheitern.

In unserem Beispiel haben wir `\docat` mit einem Argument von `$90` versehen, aber dieses Argument wird zuerst *in eine Tokenliste umgewandelt* während TeX den Makroaufruf scannt — das Argument wird in Tokens umgewandelt *bevor* bevor `$90`das Makro tatsächlich aufgerufen wird. Hier wird für das Argument `$`, `9` und `0`.

, TeX drei Zeichentokens erzeugen: ein Token für jedes von `$90`Die folgende Grafik zeigt die Tokenliste, die für das Argument erzeugt wurde `\docat` Makros ansehen:

![, bevor sie in den Rumpf des](/files/4c4cea7305a326703e493f45d10821835ecbfe07)

Von TeX erzeugte Tokenliste für ein Makroargument `$` In der obigen Grafik können wir klar sehen, dass die Argument-Tokenliste das

als Zeichentoken enthält, basierend auf einem Kategoriecode von 3. *Wie wir in den Teilen 1 bis 3 gesehen haben, werden Zeichentokens mithilfe der Kategoriecode-Werte erstellt*die zum Zeitpunkt des Einlesens des Zeichens in Kraft sind `\docat` — d. h. zu dem Zeitpunkt, an dem die Tokenliste des Arguments erstellt (in Tokens umgewandelt) wird. Zu dem Zeitpunkt, an dem die Argumente tokenisiert werden, ist das``\catcode\`\$=11``) *nicht* Makro noch nicht ausgeführt worden, sodass die Kategoriecode-Änderung, die wir in den Makroaufruf eingefügt haben (

Sobald TeX eine Tokenliste erzeugt hat, die das Argument von `$90`, werden diese drei Zeichentokens in das eigentliche Makro `<replacement text>`. Das führt jedoch dazu, dass das `$` eingespeist wird als ein *Zeichen-Token* mit Kategoriecode 3 erstellt: „math on“, und wir haben gesehen, dass der zugehörige Kategoriecode dauerhaft ist, sobald ein Zeichentoken gebildet wurde. Das `$` ist *nicht* in das Makro eingespeist *als ein Zeichen*, sondern als ein *Zeichen-Token* basierend auf dem `$` mit Kategoriecode 3.

### Ausführen von \docat: Makroexpansion

TeX bezeichnet den Prozess des „Ausführens“ eines Makros als *Makroexpansion*; ein Begriff, der meiner Meinung nach etwas verwirrend ist, aber es ist die akzeptierte Terminologie, also werden wir ihn weiter verwenden.

#### Die eigentliche Bedeutung der Makroexpansion

Nachdem TeX den `\docat` Befehl in der Eingabe des Benutzers erkannt hat, scannt es die Argumente und erzeugt eine Tokenliste für sein Argument(`$90`). Um das Makro auszuführen (zu expandieren), wendet TeX seinen Blick von der Eingabedatei des Benutzers ab und beginnt, die darin enthaltenen Tokens zu lesen `\docat`s `<replacement text>` Tokenliste, die im Speicher von TeX gespeichert ist.

Während TeX `\docat`s Definition verarbeitet, sieht und führt es dann die Folge von Tokens aus, die ursprünglich zur Definition des Makros verwendet wurde (`**Kategoriecode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**#1**`).

Die folgende Grafik zeigt den Prozess der Expansion des `\docat` Makros: TeX hört auf, Tokens aus der Eingabedatei zu beziehen, und beginnt, Tokens aus dem `<replacement text>` Abschnitt der `\docat` im Speicher abgelegten Makrodefinition zu lesen. TeX fährt fort, diese vorab vorbereiteten Tokens auszuführen, bis es auf ein **Ausgabeparameter** Token trifft, das TeX anweist, die Argument-Tokens an dieser Stelle zu lesen („einzuspeisen“) und „auszuführen“. In unserem Beispiel sind das drei Zeichentokens, die `$90` darstellen, und das führt zu einem Fehler, weil das vorab vorbereitete Zeichentoken für `$` den Kategoriecode 3 hat. Da wir mit Zeichentokens und nicht mit Zeichen zu tun haben, wird das `$` durch die vorherige Kategoriecode-Änderung, die durch die Tokens in ``\catcode\`\$=11``.

![Darstellung des Prozesses der Expansion des \docat-Makros](/files/fb6f134ea6a19a45e02a53baaf00f338ad5d10bb)

Nachdem TeX die Tokens verarbeitet hat, die ``\catcode\`\$=11``darstellen, wird die Kategoriecode-Änderung für `$` nun wirksam sein. TeX trifft dann auf das „Spezial-Token“ namens **Ausgabeparameter** das TeX anweist, **fügen** die Tokenliste für das Argument. Diese Tokenliste besteht jedoch aus drei Zeichen *Tokens*, von denen das erste ein Token für ein `$` mit einem zugewiesenen Kategoriecode 3 („math on“) ist: Die vorherige Kategoriecode-Änderung innerhalb des Makros kann dieses Zeichentoken nicht beeinflussen, sodass TeX dieses Token als Signal zum Beginn der mathematischen Verarbeitung behandelt, was dazu führt, dass das Makro fehlschlägt.

### Kann das Makro \docat repariert werden?

Aus den obigen Ausführungen wird klar, dass alle Zeichen, die in Makroargumenten erscheinen, mit den zum Zeitpunkt der Tokenisierung gültigen Kategoriecodes tokenisiert werden — was in unserem Beispiel *immer* vor der `<replacement text>` der `\docat` Makro tatsächlich ausgeführt wird. Wie können wir also sicherstellen, dass die Kategoriecodes der Argumente eines Makros geändert werden?

Ein Weg besteht darin, `\docat` so zu ändern, dass es ein parameterloses Makro ist, das nur die Kategoriecode-Änderung vornimmt — es hat keine zu tokenisierenden Argumente. Dann verwenden wir ein zweites Makro, `\getarg`, das einen einzelnen Parameter annimmt, und sorgen dafür, dass sein Argument tokenisiert wird, wenn der passende Kategoriecode für `$` wirksam ist.

```
\begin{document}
\def\docat{\catcode\`\$=11 \getarg} % Keine Parameter, ruft ein zweites Makro \getarg auf
\def\getarg#1{#1} %1 Parameter, dessen Argument tokenisiert wird
Jetzt können Sie es so ausführen, und es wird funktionieren:

Ich zahlte \docat{$90} für dieses Buch.
\end{document}
```

Wenn wir unsere neue Version von `\docat` (etwa so `\docat{$90}`) dann *erscheint* es so, `$90` als ob das `\docat` immer noch als Argument für das `\docat` Makro verwendet wird. Wie oben diskutiert, wenn TeX `\docat` in der Eingabe erkennt, prüft es, ob es irgendwelche Argumente hat: Jetzt hat es keine, also fährt TeX mit der Ausführung (Expansion) fort. Die Expansion von `**Kategoriecode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `ist die Folge von Tokens`, `**Leerzeichen**` \*\*getarg\*\* *bevor* und dies geschieht `{$90}`TeX beginnt die nächsten in der Eingabedatei enthaltenen Zeichen zu lesen (zu tokenisieren) — d. h. die Gruppe `<replacement text>` . Denken Sie daran, dass TeX beim Expandieren eines Makros seine nächste Eingabe erhält, indem es die Tokens liest, die in der Tokenliste der Definition dieses Makros enthalten sind; d. h. aus seinem

Abschnitt, der im Speicher abgelegt ist. `\docat` TeX wird die Expansion von *Token* **`verarbeiten und das`**&#x67;etarg **`verarbeiten und das`**, erkennen und es als Token identifizieren, das einen Befehl repräsentiert, der Parameter annimmt. An diesem Punkt scannt TeX die Eingabedatei nach `{$90}`s Argument: die Zeichen: `\docat`. Wie üblich werden diese tokenisiert, aber da TeX die Expansion von `$90` , werden die Zeichen `$` tokenisiert, wenn der Kategoriecode von`<replacement text>`auf 11 geändert wurde. Die Definition ( `\getarg` ) von `#1` ist einfach `$` was bedeutet: Gib das bereitgestellte Argument aus, und genau das passiert, wodurch ein

## Abschließende Bemerkungen: die Geschichte in Nodes

Die Abfolge der Ereignisse, die aus dem Umschreiben von `\docat` resultiert, um das Makro `\getarg` zu verwenden, ist im folgenden kommentierten Node-Listen-Diagramm enthalten, das den Expansionsprozess für das Makro `\docat`. Leser, die dieses Diagramm sorgfältig studieren möchten, können die Grafik als eine [PDF](https://assets.ctfassets.net/nrgyaltdicpt/7MOBdavza4WxAEQGISEEht/cabe5097d9063a6415bc553cd38237e6/newdocatexpansion.pdf) oder [SVG](https://images.ctfassets.net/nrgyaltdicpt/2FIqqVRXjakdAzTpZsV0m9/10ccc1353741d42d3df18f1692d8aa84/newdocatexpansion--plain.svg) Datei für die Offline-Verwendung herunterladen.

![Darstellung des Prozesses der Expansion des modifizierten \docat-Makros und des \getarg-Makros](/files/926ae9780b383b9c3fab4bef9384047f23c7dae7)

[Teil 1](/latex/de/weitere-themen/19-how-tex-macros-actually-work-part-1.md) [Teil 2](/latex/de/weitere-themen/20-how-tex-macros-actually-work-part-2.md) [Teil 3](/latex/de/weitere-themen/21-how-tex-macros-actually-work-part-3.md) [Teil 4](/latex/de/weitere-themen/22-how-tex-macros-actually-work-part-4.md) [Teil 5](/latex/de/weitere-themen/23-how-tex-macros-actually-work-part-5.md) [Teil 6](/latex/de/weitere-themen/24-how-tex-macros-actually-work-part-6.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/de/weitere-themen/24-how-tex-macros-actually-work-part-6.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
