> 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/nl/meer-onderwerpen/22-how-tex-macros-actually-work-part-4.md).

# Hoe TeX-macro's echt werken: Deel 4

[Deel 1](/latex/nl/meer-onderwerpen/19-how-tex-macros-actually-work-part-1.md) [Deel 2](/latex/nl/meer-onderwerpen/20-how-tex-macros-actually-work-part-2.md) [Deel 3](/latex/nl/meer-onderwerpen/21-how-tex-macros-actually-work-part-3.md) [Deel 4](/latex/nl/meer-onderwerpen/22-how-tex-macros-actually-work-part-4.md) [Deel 5](/latex/nl/meer-onderwerpen/23-how-tex-macros-actually-work-part-5.md) [Deel 6](/latex/nl/meer-onderwerpen/24-how-tex-macros-actually-work-part-6.md)

## Inleiding en overzicht

In delen 1–3 hebben we ons verdiept in enkele details op laag niveau ter voorbereiding op het begrijpen van hoe TeX-macro's werken. In dit artikel gaan we weer even “op adem komen” om enkele basisprincipes uit de praktijk van TeX-macro's te bespreken, als voorbereiding op een nieuwe diepe duik in delen 5 en 6. In dit artikel zullen we voorbeeldmacro's laten zien die zijn gedefinieerd met behulp van het TeX-primitiefcommando `\def`: we zullen niet het, wellicht bekendere, LaTeX-commando gebruiken `\newcommand`. Daar is een heel goede reden voor: ons doel is de fundamentele principes te begrijpen die ten grondslag liggen aan het macrogedrag van TeX, maar om dat te doen moeten we kerncommando's gebruiken *die zijn ingebouwd in* TeX-software. LaTeX-commando's, zoals `\newcommand`, zijn zelf macro's: commando's met specifiek geprogrammeerd gedrag die uiteindelijk zijn opgebouwd uit lagen van TeX-primitiefcommando's op een lager niveau. Om het fundamentele gedrag van TeX beter te begrijpen, moeten we TeX-primitieven gebruiken, niet LaTeX-macro's.

### Waar gaan we naartoe?

In wezen werken we toe naar een uitleg van macro's als een gespecialiseerde vorm van tokenlijst: wanneer je TeX opdraagt een macro te definiëren, maakt het een reeks tokens aan (een tokenlijst) en slaat die op in zijn geheugen, gekoppeld aan een naam die jij definieert. In delen 5 en 6 zullen we macro-tokenlijsten wat gedetailleerder bekijken, maar als je liever even van dit artikel afspringt om achtergrondinformatie te lezen, kun je die vinden in [Wat is een TeX-tokenlijst?](/latex/nl/diepgaande-artikelen/54-what-is-a-tex-token-list.md)

Tokenlijsten voor macro's, en hun parameters, bevatten een paar extra bijzonderheden waar we in detail doorheen zullen werken—en daarbij veel voorbeelden gebruiken. Om het macroverwerkingsgedrag van TeX beter te begrijpen, is er eigenlijk één sleutelfactor om te onthouden: TeX denkt alleen aan tekens in de vroegste fase van de invoerverwerking: vanaf dat punt gaat het uitsluitend om tokens! In dit artikel, en in de resterende artikelen in deze reeks, zullen we de rol onderzoeken die tokens spelen in TeX-macro's.

## De vier onderdelen van een macro

### Herinnering: macroparameters en macroargumenten

Voordat we beginnen is het de moeite waard om onszelf te herinneren aan het verschil tussen een macro's *parameters* en een macro's *argumenten*, omdat we beide termen in dit artikel zullen gebruiken. Stel dat je een macro \foo definieert

```
\def\foo#1#2{Dit is #1, dit is #2}
```

De constructies (tokens) `#1`, `#2` (tot `#9`) worden de *parameters*van de macro genoemd: zie ze als “plaatsvervangers” voor de daadwerkelijke gegevens die je zult gebruiken wanneer je de macro aanroept:

```
\foo{alpha}{beta}
```

Hier zijn `alpha` en `beta` de *argumenten* die met deze aanroep van \foo worden gebruikt: de argumenten van een macro zijn de werkelijke waarden die in de parameterplaatsvervangers worden ingevoerd (`#1`, `#2`... `#9`) die je gebruikte toen je de macro definieerde.

### Macrodefinitie: heeft 4 elementen

We beginnen met wat misschien lijkt op een iets formele definitie van een macro, maar die wel een nuttig kader biedt voor verdere bespreking.

Elke macrodefinitie bestaat uit 4 delen:

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

waarbij:

* `<TeX macro primitive>`: een van `\def`, `\edef`, `\gdef` of `\xdef`;
* `<macro name>`: de naam die aan je macrocommando wordt gegeven, zoals `\foo`;
* `<parameter text>`: dit kan ontbreken, maar als het aanwezig is, is het een reeks van *tokens* die vóór de `<replacement text>` van de macro verschijnen. De `<parameter text>` kan macroparameters bevatten (`#1`, `#2`... `#9`) en andere tokensoorten. In wezen, en zoals we in detail zullen zien, biedt de `<parameter text>` een soort *tokensjabloon* dat TeX gebruikt om uit te zoeken welke tokens de gebruiker als argumenten voor de macro wil gebruiken: wanneer je een macro aanroept, voert TeX de *argument* tokens in je macro `<replacement text>` in (dat ook een tokenlijst is);
* `{<replacement text>}`: dit is de eigenlijke inhoud van je macro: het is een reeks tokens waarin de *argumenten* worden “ingevoegd” wanneer de macro wordt verwerkt (uitgevouwen). De argumenten worden ingevoerd op de posities die worden aangegeven door macroparameters die in de oorspronkelijke definitie zijn gebruikt.

**OPMERKING**: In de bespreking gaan we ervan uit dat `<macro name>` zal worden gevolgd door een spatiekarakter met categoriewaarde 10 om als scheidingsteken te dienen en het `<macro name>`. Wij *hebben die* expliciet niet

```
spatiekarakter in onze tekst/bespreking getoond, maar we nemen aan dat het daar staat. Strikt genomen zouden we het ongeveer zo moeten weergeven:
```

We zullen echter de expliciete opname van een `<space>` karakter weglaten en impliciet aannemen dat het aanwezig is.

#### Opmerkingen over {}

We hebben het gebruik van twee accolades laten zien: `{` en `}` die de eigenlijke inhoud van je macro `<replacement text>`omringen (afbakenen). Het gebruik van `{` en `}` is echter slechts een overgenomen conventie, omdat TeX in feite verwacht dat de tekst van je macro `<replacement text>` begint met een karakter met categoriewaarde 1 (“Start een groep”) en eindigt met een karakter met categoriewaarde 2 (“Einde van een groep”). Volgens conventie zijn dat respectievelijk de `{` en `}` tekens. Je kunt echter, als je wilt, elk paar tekens daarvoor toewijzen. Bijvoorbeeld

```
\catcode`\(=1
\catcode`\)=2
```

Nu kun je macro's als volgt definiëren en gebruiken:

```
\def\foo #1(Hello, #1)
\foo(World!)
```

En je kunt nog steeds `{` en `}` gebruiken, omdat we hun categoriewaarden niet hebben veranderd—meerdere tekens kunnen dezelfde categoriewaarde hebben en hebben dat ook, dus je kunt macro's gewoon op de gebruikelijke manier blijven definiëren:

```
\def\foo #1{Hello, #1}
\foo{World!}
```

### en {}

De onderdelen van een macrodefinitie die voor onze bespreking het meest relevant zijn, zijn `<parameter text>` en `{<replacement text>}`. Wanneer je een macro definieert, is de `<parameter text>` in feite een strikt tokensjabloon dat bepaalt hoe de macro moet worden gebruikt. Zoals vermeld, `<parameter text>` kan leeg zijn, bijvoorbeeld `\def\foo{Some text}` waar niets staat tussen onze commandonaam (`\foo`) en de openingsaccolade `{` die hier het begin van de `<replacement text>`.

**Opmerking**: Sommige lezers kennen misschien TeX' “hashquote”-mechanisme (`#{`) maar daar gaan we hier niet op in.

### en macro-afbakeners

Dit specifieke artikel is niet bedoeld als een volledig uitgebreide bespreking van het schrijven van macro's, maar het is de moeite waard om even kort op te frissen, met enkele voorbeelden, dat de `<parameter text>` complex kunnen worden omdat TeX toestaat dat `<parameter text>` bevatten:

* **macroparameters**: (`#1`, `#2`,... `#9`) die als “plaatsvervangers” fungeren voor waarden die de gebruiker zal aanleveren wanneer ze de macro uitvoeren—de *argumenten*;
* **scheidingstokens**: willekeurige tokens, verspreid tussen/om de parametertokens heen, en gebruikt om de grens tussen macroparameters aan te geven. Je kunt die scheidingstekens zien als een soort “interpunctie” die de `<parameter text>` een “tokensjabloon” vormen dat je moet volgen wanneer je de macro gebruikt. Scheidingstokens worden niet gezet.

Wat betekent dit nu eigenlijk—laten we naar enkele voorbeelden kijken. De `<parameter text>` staat tussen de naam van de macro en de linkeraccolade `{` van de macrodefinitie.

#### Scheidingstokens: voorbeeld 1

Stel dat we een eenvoudige macro definiëren `\foo` als volgt:

```
\def\foo ABC{hello, there}
```

* `<parameter text>` = `ABC`
* Er zijn geen parametertokens (`#1`, `#2`,... `#9`)
* De scheidingstekens zijn de *drie tekens* `ABC` maar in dit voorbeeld zijn ze enigszins overbodig en slechts als voorbeeld bedoeld.

De drie tekens `ABC` worden behandeld als scheidingstekens: niet iets om te zetten, maar “interpunctie” waarvan wordt verwacht dat die aanwezig is wanneer de macro wordt aangeroepen—wanneer je de macro gebruikt `\foo` moet je dezelfde scheidingstekens aanleveren die aanwezig waren toen hij werd gedefinieerd.

Als je typt `\foo ABC` in je tekst, dan wordt dit gezet als `hello, there`—de tekens `ABC` worden niet gezet, maar TeX heeft heel zorgvuldig gecontroleerd of ze aanwezig waren in je aanroep (call) van `\foo`. TeX zoekt naar die scheidingstekens (“interpunctie”) en verwijdert (absorbeert) ze, zoals je kunt zien in de volgende Overleaf-schermafbeelding: `ABC` wordt niet gezet:

![Overleaf dat een TeX-macro uitvoert](/files/a0da8e841ba1e46ba91a06dcbb7cf5afb30c97fd)

Als je probeert `\foo` zonder de `ABC` scheidingstekens zal TeX klagen `Gebruik van \foo komt niet overeen met de definitie.`:

![Een TeX-fout tonen op Overleaf](/files/afbfc22c49315797bcbf8eac63a7544ee4fcd8fa)

In het voorbeeld hierboven verwacht TeX, nadat het `\foo` heeft gedetecteerd, de drie tekens `ABC` te zien, maar dat doet het niet: het ziet het karaktertoken voor `w` en detecteert meteen dat er iets mis is.

#### Scheidingstokens: voorbeeld 2

Een interessant, en misschien verrassend, feit is dat scheidingstokens willekeurige commando-tokens kunnen zijn—zelfs commando's die nog *helemaal niet zijn gedefinieerd*. We zouden bijvoorbeeld `\foo` als:

```
\def\foo A\bob B\anne{Hello \TeX{}}
```

* `<parameter text>` = `A\bob B\anne`
* Er zijn geen parametertokens (`#1`, `#2`,... `#9`)
* De scheidingstekens zijn de tokens `A\bob B\anne` maar ook hier zijn ze in dit voorbeeld overbodig en alleen bedoeld voor bespreking. Merk op dat `\bob` en `\anne` fictieve commando's zijn die *niet gedefinieerd waren*—en dat hoeven ze ook niet te zijn.

Wanneer je een macro aanroept, controleert TeX (scant het) de `<parameter text>` dat aanwezig is *in je macroaanroep* en vergelijkt het, token voor token, met de “tokensjabloon”-versie *die in het geheugen is opgeslagen*—de versie die is aangemaakt op het moment dat de macro werd gedefinieerd. TeX scant de *die in je macroaanroep worden gebruikt* en zet simpelweg alle commando's die het daar vindt om naar hun numerieke tokenwaarde: het probeert die commando's niet uit te voeren, dus het maakt niet uit dat `\bob` en `\anne` nooit gedefinieerd waren. TeX gebruikt simpelweg het tokensjabloon dat in het geheugen is opgeslagen als leidraad om uit te werken welke tokens in de `<parameter text>` van je macroaanroep de daadwerkelijke argumenten zijn die in de `<replacement text>`.

Zoals je kunt zien aan het volgende Overleaf-schermfragment, werd geen van de tekens (`A` en `B`) binnen `A\bob B\anne` gezet en veroorzaakten onze ongedefinieerde commando's `\bob` en `\anne` geen problemen. Al deze tokens werden *geabsorbeerd* door TeX toen het je gebruik van `\foo` afstemde op de definitie (tokensjabloon) van `\foo` (een tokenlijst) die in het geheugen is opgeslagen.

![Overleaf dat een TeX-macro uitvoert](/files/3e72d5560920dc8d85f80e1793414fe83993947e)

#### Scheidingstokens: voorbeeld 3

Je kunt verschillende scheidingstokens (karaktertokens, commando-tokens) tussen macroparameters plaatsen, zoals in dit voorbeeld:

```
\def\foo A\bob#1B\anne#2\jane#3bye!{Hello from \TeX{} to \#1=#1, \#2=#2 and \#3=#3}
```

* `<parameter text>` = `A\bob#1B\anne#2\jane#3bye!`
* Er zijn 3 macroparametertokens: `#1`, `#2`, `#3`
* Deze keer worden de parameters (`#1`, `#2`, `#3`) afgebakend door een combinatie van tokens:

  `A\bob#1B\anne#2\jane#3bye!`

Hier heb je in feite TeX voorzien van een sjabloon dat het heel zorgvuldig zal proberen te laten overeenkomen, en waarvan het verwacht dat het overeenkomt wanneer je `\foo`aanroept: het zal door je macroaanroep gaan, *token voor token*, en verwachten dat het overeenkomt met (vindt):

* de twee tokens `A` en `\bob` voordat `#1`
* de twee tokens `B` en `\anne` voordat `#2`
* het token `\jane` vóór parameter `#3` en de *vier tekens* `b`, `en`,`e` en `!` na `#3`.

**Vergeet niet**: TeX denkt in tokens, dus `bye!` is *vier tekens*.

Er zijn twee manieren waarop we deze macro kunnen gebruiken—we kunnen alle argumenten met meerdere tokens tussen accolades zetten om een groep te vormen:

```
\foo A\bob{This}B\anne{That}\jane{Other}bye!
```

Daarvoor is *echter niet nodig* omdat onze macrodefinitie scheidingstokens heeft die een tokensjabloon bieden. TeX kan dat sjabloon gebruiken om de tokens voor elk argument te selecteren uit tokens die uitsluitend scheidingstekens zijn. We kunnen onze macro als volgt gebruiken:

```
\foo A\bob ThisB\anne That\jane Otherbye!
```

en TeX kan de argumenten eruit halen om hetzelfde resultaat te produceren als bij het gebruik van groepen `{...}`:

![Overleaf dat een TeX-macro uitvoert met scheidingstokens](/files/ac485ef3b246b795d75136eae24d05bfe87da499)

Merk op hoe TeX precies kon detecteren welke tokens overeenkwamen met parameters `#1` en `#3`:

![Overleaf dat een TeX-macro uitvoert met scheidingstokens](/files/3658c813c3cbc9ae63b34d489290b8246342a5d4)

#### Scheidingstokens: voorbeeld 4 (het draait allemaal om tokens, niet om tekens!)

Hier is een kort voorbeeld om te laten zien dat het, wanneer je met macro's werkt, belangrijk is om te onthouden dat we echt in de wereld van *tokens* en **niet** *tekens*…

We definiëren de volgende korte macro waarbij A en B tekens zijn die als scheidingstekens fungeren en beide categoriewaarde 11 hebben. Dit werkt zonder problemen:

```
\documentclass{article}
\begin{document}
\def\foo A#1B{Hello, #1}
\foo AGrahamB
\end{document}
```

en zet vervolgens `Hello, Graham`.

Als je echter de categoriewaarde van A of B verandert in iets anders dan 11, zal de macroaanroep mislukken. Stel dat we de categoriewaarde van B veranderen in 12, met behulp van ``\catcode`B=12`` en de macro opnieuw proberen aan te roepen, zoals eerder:

```
\documentclass{article}
\begin{document}
\def\foo A#1B{Hello, #1}
\foo AGrahamB % Dit werkt
\catcode`\B=12\relax
\foo AGrahamB
\end{document}
```

Het mislukt met een enigszins raadselachtige fout:

```
Weglopend argument?
GrahamB \end {document}
! Bestand eindigde tijdens het scannen van het gebruik van \foo.
<ingevoegde tekst>
                \par
<*> main.tex

Ik vermoed dat je een `}' bent vergeten, waardoor ik
voorbij de plek heb gelezen waar je wilde dat ik zou stoppen.
Ik zal proberen te herstellen; maar als de fout ernstig is,
je kunt nu beter `E' of `X' typen en je bestand herstellen.

! Noodstop.
<*> main.tex

*** (taak afgebroken, geen geldige \end gevonden)
```

![Overleaf dat een TeX-macrofout toont](/files/91df073fb695fabbea19901e2cd288e4318ef67c)

Helaas is de standaardsuggestie van TeX ``Ik vermoed dat je een `}' bent vergeten`` is **onjuist**, het wordt niet veroorzaakt door een ontbrekende accolade (`}`).

#### Wat is er gebeurd?

TeX probeert de `\foo` macro *aanroep* af te stemmen op de `\foo` macro *definition* die het in het geheugen heeft opgeslagen. Wanneer je een macro aanroept die één of meer argumenten nodig heeft, moet TeX je gebruik van de macro onderzoeken (scannen) om de *argumenten* te bepalen die je aan die macro levert. Hier verwacht TeX dat het argument tussen een A (categoriewaarde 11) en een B (categoriewaarde 11) zit. Onthoud: TeX denkt in *tokens*, **niet** *tekens*.

De tokenwaarden voor A en B, $$\mathrm{T\_A}$$ en $$\mathrm{T\_B}$$ respectievelijk, zijn:

$$\mathrm{T\_A = 256 \times 11 + 65 = 2881}$$ $$\mathrm{T\_B = 256 \times 11 + 66 =2882}$$

Maar terwijl TeX zijn zoektocht voortzet, ziet het de B *maar* nu heeft die categoriewaarde 12 en dat resulteert in een andere tokenwaarde:

$$\mathrm{T'\_B= 256 \times 12 + 66 =3138}$$

In de `\foo` macrodefinitie was de tokenwaarde voor B (gebruikt als scheidingsteken) 2882, maar TeX ziet nu een tokenwaarde van 3138: het denkt dat dit gewoon nog een token is dat bestemd is voor gebruik in de *argument* aan geleverd aan `\foo`. Voor TeX is de laatste token van het argument nog niet gevonden, dus gaat het verder op zoek naar een B met categoriewaarde 11. Dáár, en daarom, faalt de macro: in zijn poging het argument te vinden “schiet” TeX voorbij en begint het tokens te lezen die jij niet bedoelde als deel van het argument voor de `\foo` macroaanroep. Wat er daarna gebeurt, hangt af van de tokens die TeX na de B ontdekt—die zullen verschillende `Weglopend argument?` fouten veroorzaken.

In ons voorbeeld schiet TeX voorbij en verbruikt het de stroom van tokens `\end {document}` en bereikt snel het einde van het bestand, vandaar de foutmelding:

```
! Bestand eindigde tijdens het scannen van het gebruik van \foo
```

## Deel 5

Zoals we hierboven zagen, kan de `<parameter text>` sectie van de definitie van onze macro variëren van uiterst eenvoudig tot een complexe mix van macroparameters afgewisseld met karaktertokens en commando-tokens die als scheidingstekens fungeren. TeX is in staat de verschillende combinaties van tokens te verwerken die aanwezig zijn in `<parameter text>` om de argumenten uit een macro te halen — en te detecteren wanneer we proberen een macro onjuist te gebruiken. Hoe het dat doet is het onderwerp van het volgende artikel in de reeks.

[Deel 1](/latex/nl/meer-onderwerpen/19-how-tex-macros-actually-work-part-1.md) [Deel 2](/latex/nl/meer-onderwerpen/20-how-tex-macros-actually-work-part-2.md) [Deel 3](/latex/nl/meer-onderwerpen/21-how-tex-macros-actually-work-part-3.md) [Deel 4](/latex/nl/meer-onderwerpen/22-how-tex-macros-actually-work-part-4.md) [Deel 5](/latex/nl/meer-onderwerpen/23-how-tex-macros-actually-work-part-5.md) [Deel 6](/latex/nl/meer-onderwerpen/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/nl/meer-onderwerpen/22-how-tex-macros-actually-work-part-4.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.
