> 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/24-how-tex-macros-actually-work-part-6.md).

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

[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: het verhaal tot nu toe

In de vorige 5 delen van deze serie hebben we gezien:

* hoe TeX de tekens binnen een invoerbestand leest en categoriecodes gebruikt om verschillende “klassen” van tekens te herkennen en deze vervolgens om te zetten in karaktertokens en commandotokens;
* dat een macro in feite uit vier secties bestaat:

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

waarbij:

* `<TeX macro primitive>` = een van `\def`, `\edef`, `\gdef` of `\xdef`;
* `<macro name>`=de naam van uw macro, zoals `\foo`;
* `<parameter text>` kan “null” (niet aanwezig) zijn of het kan een tekenreeks zijn van scheidingstoken en macroparametertokens;
* `<replacement text>` is de eigenlijke inhoud van uw macro: de sectie die wordt “uitgevoerd” (uitgebreid) wanneer u de macro aanroept.
* hoe de `<parameter text>` sectie een breed scala aan tokens kan bevatten en dat TeX deze sectie gebruikt als een “tokensjabloon” om een macroaanroep te koppelen aan de oorspronkelijke definitie en de argumenten die bij de macro worden gebruikt te achterhalen—en hoe TeX verwacht dat uw gebruik van een macro overeenkomt met de oorspronkelijke definitie;
* dat, binnen TeX, een macrodefinitie wordt opgeslagen als een doorlopende reeks tokens die de `<parameter text>` en `<replacement text>` secties voorstellen.

Wanneer u een macrocommando gebruikt, controleert TeX eerst of er parameters aan zijn gekoppeld. Zo ja, dan moet TeX vervolgens de daadwerkelijke *argumenten* identificeren die in uw macroaanroep worden gebruikt. TeX moet uw macroaanroep toetsen aan de “tokensjabloon”-definitie die het in het geheugen heeft opgeslagen. Concreet gebruikt TeX de interne (opgeslagen) definitie van de `<parameter text>` sectie van uw macro als sjabloon waarmee het kan onderscheiden *tokens* die de eigenlijke argumenten zijn, en welke *tokens* er alleen zijn als scheidingstekens.

## De betekenis van macro-expansie

We zijn nu eindelijk klaar om door te gaan naar het belangrijkste onderwerp: hoe TeX macroargumenten verwerkt en de macro daadwerkelijk uitvoert: een proces waar TeX naar verwijst als *macro-expansie*.

### Maar eerst, een kort voorbeeld: iets vreemds?

Om de mechanismen te schetsen waarmee TeX macro's en hun argumenten verwerkt, gebruiken we een kort voorbeeld om de kwesties aan te geven waarmee we rekening moeten houden.

#### Argumenten worden eerst omgezet in tokens

Het volgende voorbeeld is gebaseerd op een voorbeeld dat wordt besproken op pagina 114–5 van [The Advanced TeXbook](https://www.amazon.co.uk/Advanced-Texbook-David-Salomon/dp/0387945563) geschreven door David Salomon. Het is gekozen omdat het de kernideeën mooi samenvat in een zeer korte TeX-macro.

Tijdens normale TeX/LaTeX-bewerkingen heeft het `$` teken categorisatiecode 3 (“math shift”), waarmee TeX in en uit de inline wiskundemodus schakelt (`$...$`) of weergave-wiskundemodus (`$$...$$`)—natuurlijk gebruikt LaTeX `\(..\)` en `\[..\]` voor hetzelfde doel.

Stel dat we een macro willen die de categorisatiecode van een `$` teken wijzigt naar bijvoorbeeld 11, zodat we het kunnen zetten als elk gewoon teken. We kunnen het TeX-primitiefcommando `\catcode` gebruiken en ons eerste poging van zo'n macro, `\docat`, zou kunnen zijn

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

Wanneer we het echter proberen te gebruiken, zoals hier

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
I paid \docat{$90} for that book.
\end{document}
```

verwachten we dat TeX zet `Ik betaalde $90 voor dat boek.` maar het faalt met een foutmelding:

```
! Ontbrekende $ ingevoegd.
<ingevoegde tekst>
                $
<opnieuw te lezen>
                   \par
l.7
```

Uit de fout blijkt dat de `$` die in het argument van onze macro wordt gebruikt, nog steeds TeX ertoe aanzet wiskunde te zetten; duidelijk heeft TeX *niet* de categorisatiecode van de `$` die in het argument van onze macro wordt gebruikt (`$90`). De vraag is *waarom* waarom heeft TeX de categorisatiecode van `$` niet gewijzigd naar 11 en het als een gewoon teken gezet? Het korte antwoord is dat TeX eerst macroargumenten omzet in tokens **voordat** en ze vervolgens in de tokenlijst van de `<replacement text>`invoert—maar we zullen de onderliggende mechanismen veel gedetailleerder bekijken.

Wat we moeten onthouden is dat ons idee van TeX dat met tekst/tekens werkt alleen relevant is voor de inhoud van het bestand dat TeX leest: zodra TeX tekens heeft ingelezen, bevinden we ons in de wereld van *tokens*tokens. TeX-macroaanroepen werken met *tokens*, niet met de eigenlijke *geschreven/tekstuele representatie* van TeX/LaTeX-commando's—dit zal duidelijker worden naarmate we het voorbeeld uitwerken.

Aanvankelijk zouden we kunnen denken dat ons gebruik van de `\docat` macro in `I paid \docat{$90} for that book.` hetzelfde is als rechtstreeks de equivalente TeX- (of LaTeX-)code schrijven—zoals het volgende, wat *doet* werkt:

```
\begin{document}
I paid \catcode`\$=11 $90 for that book.
\end{document}
```

![Sommige TeX-code die op Overleaf wordt uitgevoerd](/files/e03afdfa5ca359657e10e24525c5abad14529626)

Zoals we hierboven zagen, levert de manier waarop TeX macroargumenten verwerkt echter een resultaat op (`! Ontbrekende $ ingevoegd.`) dat heel anders is dan het uitschrijven van de TeX-code: nu zullen we verkennen *waarom* dat gebeurt.

### Macro's en argumenten als tokenlijsten

Om het gedrag van de `\docat` macro en zijn argument (`$90`) volledig te begrijpen, en waarom die faalt, moeten we opnieuw de definitie van de `\docat` macro en eventuele gebruikte argumenten (wanneer \docat wordt aangeroepen) visualiseren als *lijsten van tokens*, niet als een reeks tekens.

Terwijl TeX uw invoertekst scant, zou het `\docat` herkennen als een macrocommando; daarna controleert het of het parameters heeft—hoe TeX dat doet wordt in de volgende sectie uitgelegd voor lezers die geïnteresseerd zijn in de fijnere details.

#### Voor degenen die van de details houden...

Nadat de macro is aangeroepen, controleert TeX of het allereerste token (in de opgeslagen definitietokenlijst van de macro) het **eindovereenkomst** token is: zo ja, dan kan TeX er zeker van zijn dat de macro geen parameters heeft.

**Een voorbeeld**

De volgende node-lijndiagrammen vergelijken de tokenlijsten van twee macro's:

* `\def\foo A#1B{#1}`: dit heeft `<parameter text>` van `A#1B`, bijgevolg is het **eindovereenkomst** token **niet** het eerste token, dus zou TeX doorgaan met het zoeken naar parameters;
* `\def\foo{X}`: dit heeft geen `<parameter text>` sectie, bijgevolg is het **eindovereenkomst** token het eerste in de tokenlijst en TeX weet dat het niet naar parameters hoeft te zoeken.

![Hoe TeX controleert of een macro parameters heeft](/files/23e7b76a7cf376b518e1a1e32efb75d38a9fb95d)

## Op weg naar de “grote finale”: expansie

Laten we de vraag nog eens in herinnering brengen: waarom werkte de volgende macro niet; d.w\.z. waarom wijzigt TeX niet de categorisatiecode van eventuele `$` tekens die in het argument van de `\docat` macro worden gebruikt, zoals `\docat{$90}`?

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
I paid \docat{$90} for that book.
\end{document}
```

Zoals hierboven uitgelegd, wanneer TeX uw invoer scant en een macrocommando herkent—op een moment dat TeX het gaat uitvoeren—controleert TeX eerst of die macro parameters heeft. Zo ja, dan moet TeX verder door het invoerbestand scannen om de daadwerkelijke *argumenten* die de gebruiker voor deze specifieke macroaanroep heeft opgegeven: TeX moet dit doen **voordat** voordat het de eigenlijke macrocode kan aanroepen. Duidelijk moet TeX de gegevens bepalen die de gebruiker aan de macro wil doorgeven.

Om de argumenten die in de invoer aanwezig zijn (de macroaanroep van de gebruiker) te identificeren, wordt TeX geleid door de intern opgeslagen definitie van die macro: meer bepaald de `<parameter text>` sectie van de opgeslagen macrodefinitie (tokenlijst)—die een soort “tokensjabloon” biedt. Met behulp van dat “tokensjabloon” moet TeX bepalen welke *tokens* in de macroaanroep van de gebruiker gewoon *scheidingstekens* (eigenlijk “interpunctie”) zijn en welke *tokens* deel uitmaken van een *argument*. Het is wanneer TeX een **match-parameter** token in de opgeslagen macrodefinitie `<parameter text>` sectie (“tokensjabloon”) tegenkomt dat het weet dat het moet beginnen met het vormen van een *tokenlijst* voor dat specifieke argument.

Zodra TeX de noodzaak herkent om het argument van de gebruiker te identificeren, scant TeX de invoer om tokens te genereren en controleert die zeer zorgvuldig, token voor token, tegen de opgeslagen macrodefinitie. TeX blijft tokens voor een argument verzamelen totdat het een token detecteert dat daadwerkelijk een scheidingsteken is, of als het het **eindovereenkomst** token detecteert: in beide gevallen weet TeX dan dat het tijd is om te stoppen met zoeken naar tokens die deel uitmaken van dat argument.

### Waarom de \docat-macro mislukte

Zoals opgemerkt, *voordat* Om een macro daadwerkelijk aan te roepen, moet TeX eventuele argumenten die met die macro zullen worden gebruikt identificeren en voorbereiden. Maar om de argument(en) te identificeren, klaar om in de macro te worden gevoed, moet TeX elk argument genereren als een *tokenlijst*: en dat is de reden voor `\docat`'s mislukking.

In ons voorbeeld hebben we `\docat` voorzien van een argument van `$90` maar dat argument wordt eerst *omgezet in een lijst van tokens* terwijl TeX de macroaanroep scant—het argument wordt omgezet in tokens *voordat* voordat de macro daadwerkelijk wordt aangeroepen. Hier, voor het argument `$90`, zal TeX drie karaktertokens genereren: één token voor elk van `$`, `9` en `0`.

De volgende afbeelding toont de tokenlijst die voor het argument is gegenereerd `$90`, voordat deze in de inhoud van de `\docat` macro:

![Door TeX gegenereerde tokenlijst voor een macroargument](/files/58d815cfcf36844e33d8c89116f17ada55f53951)

In de bovenstaande afbeelding kunnen we duidelijk zien dat de argumenttokenlijst de `$` als een karaktertoken bevat op basis van een categorisatiecode van 3.

Zoals we in delen 1 tot en met 3 zagen, worden karaktertokens gemaakt met de categorisatiecodewaarden *die van kracht zijn op het moment dat het teken wordt ingelezen*—d.w\.z. op het moment dat de tokenlijst van het argument wordt gemaakt (omgezet in tokens). Op het moment dat de argumenten worden getokeniseerd, heeft de `\docat` macro nog niet uitgevoerd, dus de wijziging van de categorisatiecode die we in de macroaanroep hebben geplaatst (``\catcode`\$=11``) *doet niet* beïnvloedt de categorisatiecodes die worden gebruikt om de tokens van het argument te genereren niet.

Zodra TeX een tokenlijst heeft gegenereerd die het argument van `$90`voorstelt, worden die drie karaktertokens ingevoerd in de eigenlijke macro `<replacement text>`. Dat resulteert echter in de `$` ingevoerd als een *tekentoken* gemaakt met categorisatiecode 3: “wiskunde aan” en we hebben gezien dat zodra een karaktertoken gevormd is, de gekoppelde categorisatiecode permanent is. De `$` is *niet* die in de macro wordt ingevoerd *als een karakter*, maar als een *tekentoken* gebaseerd op het `$` met categorisatiecode 3.

### \docat uitvoeren: macro-expansie

TeX noemt het proces van het “uitvoeren” van een macro *macro-expansie*; een term die naar de mening van deze auteur wat verwarrend is, maar het is de geaccepteerde terminologie, dus we blijven die gebruiken.

#### De echte betekenis van macro-expansie

Nadat TeX het `\docat` commando in de invoer van de gebruiker detecteert, scant het de argumenten en genereert het een tokenlijst voor zijn argument(`$90`). Om de macro uit te voeren (uit te breiden), verlegt TeX zijn aandacht van het invoerbestand van de gebruiker en begint het de tokens te lezen die zich bevinden `\docat`voorstelt: `<replacement text>` tokenlijst die in het geheugen van TeX is opgeslagen.

Terwijl TeX `\docat`'s definitie verwerkt, zal het vervolgens de reeks tokens zien en uitvoeren die oorspronkelijk werden gebruikt om de macro te definiëren (`**catcode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**#1**`).

De volgende afbeelding toont het proces van het uitbreiden van de `\docat` macro: TeX stopt met tokens uit het invoerbestand te halen en begint tokens te lezen uit de `<replacement text>` sectie van de `\docat` macrodefinitie die in het geheugen is opgeslagen. TeX gaat door met het uitvoeren van deze vooraf voorbereide tokens totdat het een **outputparameter** token ziet dat TeX instrueert om de argumenttokens op dit punt te lezen ('in te voegen') en uit te voeren. In ons voorbeeld zijn dat drie karaktertokens die `$90` voorstellen, en dat resulteert in een fout omdat het vooraf voorbereide karaktertoken voor `$` categorisatiecode 3 heeft. Omdat we met karaktertokens werken, niet met tekens, wordt de `$` niet beïnvloed door de eerdere wijziging van de categorisatiecode veroorzaakt door de tokens in ``\catcode`\$=11``.

![Het proces van het uitbreiden van de \docat-macro tonen](/files/80f19f9526ba848f2c5cf4cc23d0c86683fc1ba1)

Nadat TeX de tokens heeft verwerkt die ``\catcode`\$=11``voorstellen, zal de wijziging van de categorisatiecode voor `$` nu van kracht zijn. TeX komt dan het “speciale token” tegen dat **outputparameter** heet en dat TeX vertelt om **voegen** de tokenlijst voor het argument. Die tokenlijst bestaat echter uit drie karakter *tokens*, waarvan de eerste een token is voor een `$` met categorisatiecode 3 (“wiskunde aan”) eraan toegewezen: de eerdere wijziging van de categorisatiecode binnen de macro kan dit karaktertoken niet beïnvloeden, dus TeX behandelt dat token als een signaal om wiskundeverwerking te beginnen, waardoor de macro mislukt.

### Kan de \docat-macro worden gerepareerd?

Uit de bovenstaande bespreking is duidelijk dat alle tekens die in macroargumenten voorkomen worden getokeniseerd met behulp van de categorisatiecodes die van kracht zijn op het moment dat die tokenisatie plaatsvindt—wat in ons voorbeeld *altijd* vóórdat de `<replacement text>` van de `\docat` macro daadwerkelijk wordt uitgevoerd. Hoe kunnen we er dan voor zorgen dat de categorisatiecodes van de argumenten van een macro worden gewijzigd?

Een manier is om `\docat` aan te passen tot een parameterloze macro die alleen de categorisatiecode wijzigt—deze heeft geen argumenten die getokeniseerd moeten worden. Vervolgens gebruiken we een tweede macro, `\getarg`, die één enkele parameter neemt, en zorgen we ervoor dat dat macro zijn argument getokeniseerd krijgt wanneer de juiste categorisatiecode voor `$` van kracht is.

```
\begin{document}
\def\docat{\catcode`\$=11 \getarg} % Geen parameters, roept een tweede macro \getarg aan
\def\getarg#1{#1} %1 parameter waarvan het argument getokeniseerd wordt
Nu kunt u het als volgt uitvoeren en dan werkt het:

I paid \docat{$90} for that book.
\end{document}
```

Wanneer we onze nieuwe versie van `\docat` (zoals dit `\docat{$90}`) gebruiken, *lijkt* het alsof de `$90` nog steeds wordt gebruikt als een argument voor de `\docat` macro. Maar zoals hierboven besproken, wanneer TeX `\docat` in de invoer detecteert, controleert het of die argumenten heeft: nu heeft het die niet, dus TeX gaat verder met het uitvoeren (uitbreiden) ervan. De expansie van `\docat` is de reeks tokens `**catcode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**spatie**`, `**getarg**` en dit gebeurt *voordat* TeX begint de volgende tekens in het invoerbestand te lezen (tokeniseren)—d.w\.z. de groep `{$90}`. Onthoud dat wanneer TeX een macro uitbreidt, het zijn volgende invoer krijgt door de tokens te lezen die in de tokenlijst van de definitie van die macro staan; d.w\.z. uit de `<replacement text>` sectie die in het geheugen is opgeslagen.

TeX zal de expansie van `\docat` verwerken en uitvoeren en het *token* **`getarg`**, herkennen als een token dat een commando vertegenwoordigt dat parameters aanneemt. Op dit punt scant TeX het invoerbestand op **`getarg`**'s argument: de tekens: `{$90}`. Zoals gewoonlijk worden deze getokeniseerd, maar omdat TeX de expansie van `\docat`heeft gelezen en verwerkt, `$90` worden de tekens `$` getokeniseerd wanneer de categorisatiecode van`<replacement text>`is gewijzigd naar 11. De definitie ( `\getarg` ) van `#1` is eenvoudigweg `$` wat betekent: zet het aangeleverde argument, en dat gebeurt ook, wat resulteert in een

## Slotopmerkingen: het verhaal in knooppunten

De reeks gebeurtenissen die voortkomt uit het herschrijven van `\docat` om de macro `\getarg` te gebruiken, is vastgelegd in het volgende geannoteerde node-lijndiagram dat het expansieproces voor de macro `\docat`toont. Lezers die dit diagram zorgvuldig willen bestuderen, kunnen de afbeelding downloaden als een [PDF](https://assets.ctfassets.net/nrgyaltdicpt/7MOBdavza4WxAEQGISEEht/cabe5097d9063a6415bc553cd38237e6/newdocatexpansion.pdf) of [SVG](https://images.ctfassets.net/nrgyaltdicpt/2FIqqVRXjakdAzTpZsV0m9/10ccc1353741d42d3df18f1692d8aa84/newdocatexpansion--plain.svg) bestand voor offline gebruik.

![Het proces tonen van het uitbreiden van de aangepaste \docat-macro en de \getarg-macro](/files/fe3de89c924091906aecf7451a3f8e33111141da)

[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/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.
