> 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/diepgaande-artikelen/17-how-does-expandafter-work-a-detailed-macro-case-study.md).

# Hoe werkt \expandafter: een gedetailleerde casestudy van een macro

&#x20;[Deel 1](/latex/nl/diepgaande-artikelen/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [Deel 2](/latex/nl/diepgaande-artikelen/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [Deel 3](/latex/nl/diepgaande-artikelen/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [Deel 4](/latex/nl/diepgaande-artikelen/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [Deel 5](/latex/nl/diepgaande-artikelen/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [Deel 6](/latex/nl/diepgaande-artikelen/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)&#x20;

## Casestudy: \expandafter-voorbeeld uit De $$\varepsilon\mathrm{\text{-}{\TeX}}$$ Handleiding

De $$\varepsilon\mathrm{\text{-}{\TeX}}$$ zetengine is afgeleid van Knuths TeX-software en was oorspronkelijk bedoeld als een ‘tussentijdse’ stap in de ontwikkeling van het [Nieuw zetsysteem](https://en.wikipedia.org/wiki/New_Typesetting_System) (NTS), geschreven in de programmeertaal Java. $$\varepsilon\mathrm{\text{-}{\TeX}}$$ werd eind jaren 1990 voor het eerst ontwikkeld om een reeks nieuwe primitieve opdrachten toe te voegen die extra functionaliteit bieden die niet beschikbaar is in Knuths oorspronkelijke programma. Hoewel $$\varepsilon\mathrm{\text{-}{\TeX}}$$ het sinds de eerste release periodieke updates heeft ontvangen, wordt het vandaag de dag niet veel gebruikt als zelfstandige zetengine, hoewel de innovaties zijn overgenomen in latere generaties van TeX: pdfTeX, XeTeX en LuaTeX.

De [$$\varepsilon\mathrm{\text{-}{\TeX}}$$ manual](http://mirror.ox.ac.uk/sites/ctan.org/systems/doc/etex/etex_man.pdf) bevat een verhelderend voorbeeld van een macro die slim gebruikmaakt van `\expandafter`:

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter\foo
    \expandafter{\number\numexpr#1+1\expandafter}%
    \expandafter{\number#2\expandafter}%
    \fi}
```

`\foo` implementeert een lusmechanisme, zodat `\foo{7}{13}` oplevert `7, 8, 9, 10, 11, 12, 13`; echter, `\foo` maakt geen gebruik van enige *toekenningen aan variabelen* om het lusproces te beheersen—waardoor het een interessante macro is om in enig detail te onderzoeken.

### Enige achtergrond: expressies en toekenningen

Een belangrijk element van `\foo`’s code is het gebruik van het commando `\numexpr`, een commando uit een reeks van vier verwante primitieve commando’s dat voor het eerst werd geïntroduceerd door $$\varepsilon\mathrm{\text{-}{\TeX}}$$: `\numexpr`, `\dimexpr`, `\glueexpr` en `\muexpr`. *expressies* die berekening/manipulatie van TeX-waarden van het type number, dimen, glue of muglue mogelijk maken (respectievelijk). Zoals besproken op pagina’s 8–9 van de $$\varepsilon\mathrm{\text{-}{\TeX}}$$ Handleiding, is een belangrijk kenmerk van *expressies* dat hun evaluatie (berekening) niet vereist dat TeX enige *toekenningen*.

In programmeertermen is toekenning het proces waarbij een variabele wordt ingesteld (toegewezen) om een bepaalde waarde te hebben; bijvoorbeeld, het toekennen van `\count` register `99` in om de waarde `12345` via `\count99=12345`. Veel andere soorten toekenningen vinden plaats tijdens de verwerking van TeX—zoals het toekennen van tokenregisters om een reeks tokens te bevatten, het toekennen van boxregisters om boxinhoud te bevatten, enzovoort.

Om een toekenning uit te voeren, zoals `\count99=12345`, moet TeX de interne code activeren (uitvoeren) die het gedrag implementeert van `\count` of een andere primitieve functie die een of andere toekenning uitvoert. Er zijn echter momenten waarop TeX zuivere *expansie* en op zulke momenten worden dergelijke toekenningen niet geactiveerd—*op dat punt in de verwerking door TeX*. Voorbeelden van deze situatie zijn de volgende commando’s:

* `\edef\command {*token list*}` het macro-definitiecommando ‘uitgebreide definitie’ dat tokens in *tokenlijst* en slaat de resultaten op als de definitie van `\command`.
* `\write *number* {*token list*}` breidt tokens in `*tokenlijst*` en schrijft ze naar een bestand weergegeven door `*number*`.
* `\directlua {*token list*}` dit LuaTeX-primitieve commando wordt gebruikt om Lua-code door te geven aan de ingebouwde Lua-interpreter. Alle tokens in `*tokenlijst*` worden volledig uitgebreid voordat ze aan de Lua-interpreter worden doorgegeven voor uitvoering.

#### Snel voorbeeld van \edef

Als we de volgende basismacro’s schrijven:

```
     \def\mycount{\count99=12345}
     \edef\mymacro{\mycount}
```

`\edef` zal uitbreiden `\mycount` in zijn samenstellende tokens, maar gaat niet verder: geen van de commando’s in de definitie van `\mymacro` zal worden geactiveerd: d.w\.z. de toekenning van `12345` om `\count99` *vindt op dit punt niet plaats*; pas wanneer we `\mymacro` zal die toekenning plaatsvinden terwijl TeX de code uitvoert om de `\count` primitieve functie te verwerken. Wanneer TeX *alleen-uitbreidingsactiviteiten* zullen eventuele toekenningen later in de verwerking door TeX worden geactiveerd, niet tijdens het uitbreidingsproces zelf.

#### Waarom zijn toekenningen hier interessant?

Wanneer code wordt geschreven om een lus uit te voeren—in welke programmeertaal dan ook—is het gebruikelijk om een variabele aan te wijzen als ‘lus-teller’: gebruikt om het aantal keren dat een lus wordt uitgevoerd te regelen. Het lussen wordt doorgaans geregeld door te testen of die aangewezen lus-teller-variabele een bepaalde waarde heeft bereikt—die variabele wordt bij elke iteratie van de lus verhoogd (of verlaagd). Het wijzigen van een lus-teller-variabele betekent echter dat er een nieuwe waarde aan wordt toegekend, wat voor TeX meestal het primitieve commando vereist `\advance` om een waarde op te hogen (of te verlagen) die is opgeslagen in een `\count` register. Zoals we hebben gezien kunnen dergelijke toekenningen (inclusief het verhogen van variabelen) tijdens TeX’ zuivere uitbreidingsproces niet plaatsvinden: de macro `\foo` omzeilt deze beperking op slimme wijze.

### Terug naar de uitleg van \foo

De macro `\foo` kan het lusproces beheersen *zonder* zonder waarden aan variabelen toe te kennen: het bepaalt hoe vaak de lus plaatsvindt met behulp van gegevens die voortkomen uit uitbreiding: gegevenswaarden opgeslagen in tijdelijke tokenlijsten. Met onze kennis van TeX’ gebruik (aanmaak) van tijdelijke tokenlijsten kunnen we dit nader bekijken om precies te zien hoe `\foo` zijn resultaten bereikt.

**Vergeet niet**: We werken de uitvoering van een macro door nadat de oorspronkelijke tekst van zijn definitie—in een fysiek `.tex` bestand—is gescand (door TeX ingelezen) en omgezet in een tokenlijst die de macrodefinitie weergeeft. In wezen volgen we de verwerking door TeX van die opgeslagen *tokens* terwijl het tokens leest en verwerkt in de macrodefinitie die ergens in het geheugen van TeX is opgeslagen. Eventuele spaties die oorspronkelijk aanwezig waren in de TeX-code van de definitie van de macro (tekst binnen het `.tex` bestand) zullen zijn geabsorbeerd terwijl TeX die tekst op commando’s scande (spaties als scheidingstekens), of ze zullen zijn omgezet in tokens, zoals het spatieteken na de komma (`,`) `\ifnum#1<#2,` dat is ontstaan door omzetting van het regeleindeteken (`\r`) in een spatie.

Omdat de TeX-code in `\foo` meerdere `\expandafter` commando’s gebruikt, zullen we onze uitleg ondersteunen door indices toe te voegen aan elk `\expandafter`, `\expandafter` om $$\mathrm{T^i\_1}$$ en $$\mathrm{T^i\_2}$$die tokens vertegenwoordigen $$\mathrm{T\_1}$$ en $$\mathrm{T\_2}$$ voor `\expandafter<sub>i</sub>`: `\expandafter<sub>i</sub>` $$\mathrm{T^i\_1T^i\_2}$$

Hier is de geannoteerde macrocode:

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}%
    \expandafter4{\number#2\expandafter5}%
    \fi}
```

`\foo` begint met `\number#1` dat het uitbreidbare commando gebruikt `\number` om de waarde van het eerste argument om te zetten in zijn zetweergave. Het `\number` commando werkt door een tijdelijke tokenlijst te genereren met tekentokens die de afzonderlijke cijfers weergeven in de numerieke waarde waarop `\number` het werkt. Die tokenlijst wordt TeX’ volgende invoerbron. Hier wordt die tokenlijst gelezen en worden de tokens uitgevoerd om de waarde van `#1`.

Vervolgens voert de macro de test uit `\ifnum#1<#2` om te controleren of het argument voor `#1` kleiner is dan het argument dat is doorgegeven voor `#2`.`,`) token wordt uitgevoerd (gezet) gevolgd door een spatie die voortkomt uit het token dat werd gegenereerd uit het regeleindeteken na de komma (`,`). Dat spatieteken werd eerst gegenereerd toen TeX deze regel uit het `.tex` bestand.

De macro gaat verder met het verwerken van dit volgende codegedeelte, dat de kern van zijn werking vormt:

```
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}%
    \expandafter4{\number#2\expandafter5}%
    \fi}
```

In wezen genereert deze code een reeks tijdelijke tokenlijsten die leiden tot meerdere aanroepen van de `\foo` macro, waarbij wordt beëindigd wanneer de if-test `\ifnum#1<#2` niet langer waar is. Maar *hoe* wordt het lussen beheerst omdat er geen toekenningen plaatsvinden: waar is de ‘lus-teller’?

Laten we beginnen met het bekijken van de code `\expandafter<sub>1</sub>\foo\expandafter<sub>2</sub>`. Merk op dat we de indexnotatie `<sub>token</sub>` (of `<sub>(token)</sub>`) om ons eraan te herinneren dat TeX hier numerieke (gehele) tokenwaarden leest/verwerkt.

Hier hebben we de volgende tokens als invoer voor `\expandafter<sub>1</sub>`:

* $$\mathrm{T^1\_1} =$$`\foo<sub>token</sub>` dat wordt ingelezen en opgeslagen voor latere *opnieuw invoegen* terug in de invoer
* $$\mathrm{T^1\_2} =$$`\expandafter<sub>2 (token)</sub>` dat wordt uitgebreid

Voor `\expandafter<sub>2</sub>` hebben we:

* $$\mathrm{T^2\_1} =$$`{<sub>token</sub>` dat wordt opgeslagen voor later *opnieuw invoegen* terug in de invoer
* $$\mathrm{T^2\_2} =$$ `\number<sub>token</sub>` dat wordt uitgebreid

**Opmerking:**`\number` is een uitbreidbaar commando met als doel ‘omzetten naar tokens’: d.w\.z. een numerieke grootheid omzetten in een reeks tekentokens die die grootheid vertegenwoordigen. Wanneer `\number` wordt uitgebreid, is het eerste wat TeX doet de invoer scannen op zoek naar gehele getallen: een proces dat verdere uitbreiding uitlokt.

**De sleutel tot het verhaal:** Hier zijn `\number` werkt op de *expressie* `\numexpr#1+1` die de waarde berekent van `#1+1`. `\number` om het om te zetten in een tijdelijke tokenlijst met tekentokens die de waarde van weergeven `#1 + 1`. `\number`, zal uiteindelijk worden ingelezen als het eerste argument voor een andere aanroep van `\foo`. In plaats van een lus-teller te verhogen (via `\advance` en toekenning), zorgt het gebruik van `\numexpr` voor een nieuwe waarde, zonder dat een toekenning nodig is. Via dit mechanisme wordt de variabele die de lus aanstuurt (`\foo`parameter van `#1`) verhoogd en wordt de iteratie door de lus beheerst en beëindigd: behoorlijk ingenieus!

Vervolgens, `\expandafter<sub>3</sub>` wordt verwerkt, wat oplevert:

* $$\mathrm{T^3\_1} =$$`}<sub>token</sub>` dat wordt opgeslagen voor later *opnieuw invoegen* terug in de invoer
* $$\mathrm{T^3\_2} =$$`\expandafter<sub>4 (token)</sub>`, dat wordt uitgebreid:

Voor `\expandafter<sub>4</sub>` hebben we:

* $$\mathrm{T^4\_1} =$$`{<sub>token</sub>` dat wordt opgeslagen voor later *opnieuw invoegen* terug in de invoer
* $$\mathrm{T^4\_2} =$$`\number<sub>token</sub>` dat wordt uitgebreid en `#2` omzet in nog een tijdelijke tokenlijst.

Ten slotte,`\expandafter<sub>5</sub>` wordt uitgebreid:

* $$\mathrm{T^5\_1} =$$`}<sub>token</sub>` dat wordt opgeslagen voor later *opnieuw invoegen* terug in de invoer
* $$\mathrm{T^5\_2} =$$`\fi<sub>token</sub>`, wat een uitbreidbaar commando is.

  De uitbreiding van `\fi` beëindigt effectief de `\ifnum` en sluit in feite deze iteratie van de macro af. TeX voltooit nu het opnieuw invoegen van alle tokens die tijdelijk zijn opgeslagen door de meerdere `\expandafter` commando’s: dit genereert een reeks tokenlijsten met één token, voortkomend uit de tokens die door elk `\expandafter`. Bovendien heeft TeX ook tokenlijsten gemaakt uit door de werking van `\number`.

### Het samenstellen van de tokenlijsten

In wezen genereert de `\foo` macro een reeks tokenlijsten: je kunt `\foo` zien als een ‘productiefaciliteit’ voor tokenlijsten. Die tokenlijsten worden door TeX gelezen om de volgende invoerbronnen te worden. Het slimme deel zit in een van de eerdere acties van `\foo`:

```
    \expandafter1\foo\expandafter2
```

waardoor `\foo` ervoor zorgt dat het zichzelf opnieuw aanroept, maar met andere argumenten die zijn opgeslagen in tokenlijsten die zijn geconstrueerd door `\number`. Om deze tokenlijsten samen als een macro-aanroep te laten gedragen, zijn de accolades `{` en `}` allemaal opgeslagen en opnieuw in de invoer ingevoegd (als tokenlijsten met één token) door de werking van `\expandafter` commando’s.

![tokenlijsten gegenereerd door de \foo-macro](/files/d9772cd0841a79a208c3c952a2cb48c7653d6472)

&#x20;[Deel 1](/latex/nl/diepgaande-artikelen/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [Deel 2](/latex/nl/diepgaande-artikelen/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [Deel 3](/latex/nl/diepgaande-artikelen/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [Deel 4](/latex/nl/diepgaande-artikelen/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [Deel 5](/latex/nl/diepgaande-artikelen/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [Deel 6](/latex/nl/diepgaande-artikelen/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.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/diepgaande-artikelen/17-how-does-expandafter-work-a-detailed-macro-case-study.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.
