> 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/54-what-is-a-tex-token-list.md).

# Wat is een TeX-tokenlijst

## Dus, wat is nu precies een "TeX-tokenlijst"?

In een [eerder artikel](/latex/nl/diepgaande-artikelen/53-what-is-a-tex-token.md)—ook onderdeel van deze [reeks over low-level TeX-onderwerpen](/latex/nl/diepgaande-artikelen/01-a-new-series-of-articles-tex-tokens-and-related-concepts-but-why-and-how.md)—verkenden we de processen waarmee TeX je `.tex` bestand scant om nieuwe tokens te genereren: we onderzochten de fundamentele aard van een TeX-token en hoe TeX ze maakt (zie [Wat is een "TeX-token"?](/latex/nl/diepgaande-artikelen/53-what-is-a-tex-token.md)).

In dit vervolgartikel bekijken we *tokenlijst*s: wat zijn ze en hoe maken/gebruiken TeX-engines ze. Het kan lastig zijn om tokenlijsten te begrijpen omdat ze diep in de interne werking van TeX zijn opgeslagen: die details worden voor de gebruiker verborgen gehouden—hoewel dat tegenwoordig niet altijd zo is als je geavanceerder programmeert met LuaTeX. Maar voorlopig kun je tokenlijsten zien als TeX’ manier om een reeks integerwaarden op te slaan, waarbij elke integer een token is dat is afgeleid van een karakter of commando dat TeX uit je invoerbestand had gelezen.

Tokenlijsten spelen een centrale rol in de interne werking van TeX, vaak op verrassende manieren, zoals bij de interne werking van commando's als `\uppercase` en `\lowercase`. Een bijzonder belangrijk gebruik van tokenlijsten is het opslaan en uitvoeren van macro's, een onderwerp dat we in een toekomstig artikel in deze reeks uitgebreid zullen onderzoeken.

### TeX haalt zijn invoer uit bestanden en tokenlijsten

TeX-engines hebben drie invoerbronnen—twee die je misschien al kent:

* fysieke tekstbestanden opgeslagen op schijf;
* tekst die een gebruiker in de terminal typt (opdrachtregel);

maar het heeft ook een derde manier om invoer te lezen/verkrijgen: tokenlijsten!

Tokenlijsten zijn in feite een interne gegevensopslagfaciliteit die TeX gebruikt als onderdeel van zijn bewerkingen. Omdat TeX’ tokenlijsten als een “opslagfaciliteit” fungeren voor eerder gemaakte tokens, is het logisch dat TeX ze kan hergebruiken als een andere invoerbron. Wanneer het nodig wordt om de volgende invoer uit een bepaalde tokenlijst te halen (of wanneer TeX daartoe opdracht krijgt), zal TeX het lezen van invoer uit een fysiek bestand tijdelijk onderbreken (dus nieuwe tokens creëren) en overschakelen naar het verkrijgen van zijn invoer uit bestaande tokens: de locatie in het geheugen waar de tokenlijst is opgeslagen. Duidelijk: bij een tokenlijst heeft het proces van scannen + het genereren van tokens al plaatsgevonden, dus TeX hoeft alleen maar elk token in de lijst te bekijken en te beslissen wat ermee te doen. *nieuwe tokens*) *bestaande tokens*: de locatie in het geheugen waar de tokenlijst is opgeslagen. Duidelijk: bij een tokenlijst heeft het proces van scannen + het genereren van tokens al plaatsgevonden, dus TeX hoeft alleen maar elk token in de lijst te bekijken en te beslissen wat ermee te doen.

Als snel voorbeeld kun je met het low-level (TeX-primitief) `\toks` commando een lijst van tokens maken die TeX in het geheugen opslaat voor later hergebruik:

```latex
\toks100={Hello}
```

Om die tokens terug te halen (d.w\.z. TeX te vertellen ze als volgende invoerbron te behandelen) geef je een commando zoals

```latex
\the\toks100
```

Dit zorgt ervoor dat TeX overschakelt van het maken van nieuwe tokens uit je invoerbestand naar het ophalen van zijn volgende invoer uit waar die tokens (gemaakt door `\toks`) *tokenregister* staan—een zogenoemde interne geheugenlocatie die bij TeX bekend is (hier is dat register 100).

Daarnaast kunnen tokenlijsten intern, on-the-fly, worden gegenereerd door een aantal TeX-commando's. Een voorbeeld is het commando `\jobname` dat een reeks karaktertokens genereert—één token voor elk karakter in de naam van het hoofdbestand dat TeX aan het verwerken is. Een ander voorbeeld is het `\string` commando; bijvoorbeeld

```latex
\string\mymacro
```

genereert een reeks karaktertokens voor elke letter in de naam `\mymacro`—inclusief het begin- `\` teken. Aan het einde van dit artikel kijken we nader naar enkele “token-genererende commando's”.

## Tokenlijst: uitgelegd aan de hand van een analogie

Tenzij je een programmeerachtergrond en/of enige kennis van informatica hebt, kan het begrip “tokenlijsten” enigszins vaag en misschien een beetje verwarrend zijn. Als je echter vaardig wilt worden in het schrijven van TeX/LaTeX-macro's, dan zal een goed begrip van onderwerpen zoals TeX-tokens, tokenlijsten en categoriecodes (`\catcode`)

In deze sectie gaan we een analogie gebruiken om de kernideeën/-principes van een TeX-tokenlijst uit te leggen/illustreren: hoe TeX tokens in het geheugen opslaat. Het is de moeite waard dit rustig door te lezen, omdat tokenlijsten een *fundamenteel* aspect van TeX vormen en het waard zijn om iets nader te begrijpen.

### Tokenlijsten: een analogie (gedachte-experiment)

We gaan een “gedachte-experiment” uitwerken om een basis te bieden voor het begrijpen van TeX-tokenlijsten. Stel je voor dat je toegang had tot een grote verzameling containers, zoals honderden blikken—we kunnen de term “box” niet gebruiken om onze containers in het gedachte-experiment te beschrijven, omdat “box” natuurlijk een heel specifieke betekenis heeft in TeX, die niets met onze discussie hier te maken heeft. We noemen onze containers daarom “blikken”, waarbij elk blik:

* een uniek identificatienummer op de buitenkant heeft gedrukt;
* intern twee compartimenten heeft.

Die twee compartimenten zijn als volgt ontworpen:

* het linker compartiment het item bevat dat je in het blik wilt doen;
* het rechter compartiment bedoeld is voor een stukje papier waarop je één getal kunt schrijven: het nummer waarmee een ander blik wordt geïdentificeerd.

![test](/files/e95f1f4bf24063007f0b70251cf881d39ed82852)

Stel dat je een verzameling van bijvoorbeeld 5 items hebt en die verzameling in die blikken wilt opslaan; maar helaas kan elk blik slechts 1 item van het type dat je wilt opslaan bevatten.

Voor de eenvoud nemen we aan dat we 5 gekleurde cirkels willen opslaan:

![{{{alt}}}](/files/277464867155f711116dc9b36443bae6f2d0fb53)

Bovendien, wanneer je teruggaat om die items uit je opslagsysteem (blikken) op te halen, moeten die items *moeten* in een bepaalde volgorde worden opgehaald/gevonden—de volgorde waarin ze zijn opgeslagen: die volgorde moet behouden blijven. Hoe kun je dat bereiken?

We kunnen gebruikmaken van het feit dat elk blik:

* een uniek identificatienummer aan de buitenkant heeft;
* 2 compartimenten heeft—waarvan we er slechts 1 gebruiken om ons item in op te slaan; het andere bevat een stukje papier waarop het nummer van een ander blik staat.

We nemen aan dat elk blik leeg is—maar niets houdt je tegen om een bepaald blik te openen om te controleren of het leeg is; als dat niet zo is, probeer dan het volgende totdat je een leeg blik vindt.

We kunnen het als volgt doen. Plaats ons eerste item (donkergroene cirkel) in een van onze blikken (bijv. blik 124) en noteer het nummer van dit eerste blik—het maakt niet uit welk nummer dat eerste blik heeft, zolang we het maar ergens opschrijven en bewaren voor later gebruik.

![{{{alt}}}](/files/860d14242e355cc8811296d55bcd5dfadf3eb7f3)

Zoek een tweede blik—elk bliknummer (bijv. blik 432)—en noteer het nummer ervan. Schrijf het nummer van dat tweede blik (432) op een stukje papier en plaats die notitie *in het eerste blik* (blik 124). We plaatsen ons tweede item (lichtgroene cirkel) in het tweede blik. Dus, momenteel hebben we de volgende situatie:

* een geschreven notitie—niet opgeslagen in een blik—waarin staat dat het eerste blik nummer 124 heeft (het bevat ons eerste item);
* in blik 124 hebben we nog een notitie toegevoegd waarop staat dat het volgende item in blik 432 te vinden is.

In wezen hebben we *gekoppeld* onze eerste twee blikken aan elkaar gekoppeld: we weten waar we moeten beginnen (blik 124) en dat een notitie in blik 124 ons vertelt welk blik het volgende item bevat (blik 432).

![{{{alt}}}](/files/f0475841189db5fe3758f6d963bf09c3a890bf70)

We vinden vervolgens een derde blik, schrijven het nummer ervan (bijv. blik 543) op een stukje papier en plaatsen dat in het *tweede* blik (nummer 432). Vervolgens plaatsen we ons derde item (rode cirkel) in het derde blik.

Nu hebben we drie blikken in de volgende volgorde gekoppeld: ons startpunt, blik 124 (donkergroene cirkel) → blik 432 (lichtgroene cirkel)→ blik 543 (rode cirkel) →…

![{{{alt}}}](/files/b039fc0739f71d148f9e70aa124446434030db23)

Herhaal dit proces voor de laatste twee items (lichtblauwe en donkerblauwe cirkels) met blik 213 (lichtblauwe cirkel) en blik 102 (donkerblauwe cirkel).

![{{{alt}}}](/files/8a0425b5f7ffc7d1cc40ca01e3d58fb2b44d5221)

Nu hebben we alle 5 blikken aan elkaar gekoppeld (met behulp van de numerieke identificatie van elk blik) en kunnen we al onze opgeslagen items ophalen—in de juiste volgorde—door eenvoudig elk blik om de beurt te bezoeken, ons item eruit te halen en naar de notitie te kijken die ons vertelt welk blik ons volgende item bevat.

### En wat gebeurt er met het laatste item in onze lijst (blik 102)?

Waarom zouden we ons juist hierover zorgen maken? Tot nu toe hebben we elk item in een blik opgeslagen, samen met een notitie die zegt welk blik het volgende item bevat: wat moet die notitie zeggen voor het laatste item in onze lijst—want er is geen volgend blik.

Wanneer we het laatste item (blik) bereiken, moet duidelijk zijn dat dit blik (met het laatste item) het laatste item in onze lijst is—we hoeven niet naar een ander blik te zoeken, want dat is er niet. Een manier om dat te doen is een “speciaal” bliknummer in ons laatste blik (102) te plaatsen. We kunnen elk gewenst nummer gebruiken, zolang we maar een uniek nummer kiezen dat niet het nummer van een echt blik is—bijvoorbeeld “blik -1”, “blik 0”: het maakt niet uit, zolang we maar weten dat “blik -1” of “blik 0” enz. ons meteen vertelt dat we moeten stoppen met zoeken: we hoeven niet verder te zoeken naar blikken, want dit is de laatste en er zijn dus geen verdere items om op te halen.

### Van “items” en “blikken” naar tokens en TeX

Nu moeten we overstappen van onze analogie naar een beschrijving die dichter bij de realiteit van TeX staat. Ten eerste: in plaats van verschillend gekleurde cirkels op te slaan in onze denkbeeldige blikken, is het duidelijk dat we die blikken kunnen zien als opslag voor TeX-tokens: simpele gehele getallen. Dat is het gemakkelijkere deel van het verplaatsen van onze analogie naar het domein van software (TeX). Maar wat zou het software-equivalent kunnen zijn van onze fysieke genummerde blikken met “compartimenten”?

We willen niet te ver gaan in programmeerconcepten, maar je kunt onze “blikken” zien als een paar bytes computergeheugen die zijn “verpakt” in een handige opslageenheid. Het gebruik van een numerieke identificatie voor elk blik kan worden opgevat als de locatie in het computergeheugen waar elk klein geheugenpakket zich bevindt. Binnen TeX zelf worden die kleine opslagpakketjes “memory words” genoemd—een term die de tijd/het tijdperk weerspiegelt waarin TeX werd gecreëerd (jaren 70). Deze “memory words” zijn de fundamentele bouwsteen binnen TeX, maar we hoeven ze hier niet verder uit te diepen—wie meer details wil, kan een artikel raadplegen op [de persoonlijke blog van de auteur](http://www.readytext.co.uk/?p=3537).

In computerprogrammeringstermen wordt wat we hier hebben besproken een [*gekoppelde lijst*](https://en.wikipedia.org/wiki/Linked_list): een TeX-tokenlijst is een gelinkte lijst opgebouwd uit TeX’ opslagcontainers genaamd *memory words* waarbij elk memory word kan worden gebruikt om op te slaan:

* een *waarde*: de waarde van het token (een geheel getal);
* een *koppeling*: de geheugenlocatie van het volgende memory word met het volgende token in onze lijst.

## Waar gebruikt TeX tokenlijsten?

Overal! Dat klopt omdat een TeX/LaTeX-macrodefinitie (bijv. een LaTeX-commando) wordt opgeslagen als een (licht gespecialiseerde) vorm van tokenlijst—gespecialiseerd in die zin dat deze tokens bevat die je niet ziet in “standaard” tokenlijsten (gerelateerd aan het matchen van macroparameters enz.). Maak je daar geen zorgen over, want die details behandelen we in een toekomstig artikel.

### Een voorbeeldmacro

Je kunt een macro zien als opgebouwd uit drie delen:

```
\def\<macro name><parameter text>{<replacement text>}
```

Merk op dat je in plaats van `\def` je had kunnen gebruiken `\edef`, `\gdef` of `\xdef`.

**Opmerking voor LaTeX-gebruikers**: Hier definiëren we macro's met ruwe, low-level TeX-commando's (genoemd *primitieven*). LaTeX-gebruikers zijn waarschijnlijk beter bekend met het maken van macro's via LaTeX’ `\newcommand` (dat zelf ook een macro is).

Wanneer je TeX vraagt een macro te maken (te definiëren), zal het een token creëren dat de `<macro name>` en een *tokenlijst* gecombineerde `<parameter text>` en `<replacement text>`. `<macro name>` is gekoppeld aan de tokenlijst die de definitie ervan voorstelt (`<parameter text>` en `<replacement text>`).

Als we bijvoorbeeld definiëren `\mymacro` als volgt:

```latex
\def\mymacro abc #1 defz{I typed "#1"!}
```

We kunnen zien dat de samenstellende delen zijn:

* `<macro name>` = `mymacro`
* `<parameter text>` = `abc #1 defz`
* `<replacement text>` = `Ik typte "#1"!`

Je zou bijvoorbeeld kunnen aanroepen `\mymacro` als volgt:

```latex
\mymacro abc THIS TEXT defz
```

wat resulteert in `Ik typte "THIS TEXT"!` gezet te worden—the `abc` en `defz` bent *niet* gezet. `abc` en `defz` zijn reeksen karaktertokens die worden gebruikt om *af te bakenen* het macroparameter `#1` en worden geabsorbeerd en weggegooid wanneer je macroaanroep succesvol door TeX is verwerkt.

Wanneer je `\mymacro`, fungeert het patroon van tokens in het opgeslagen als een “sjabloon” dat TeX kan gebruiken om uit te zoeken:

* welke tokens in je invoer de scheidingstokens zijn;
* welke tokens in je invoer daadwerkelijk de parameter(s) van je macro vormen (hier, wat je gebruikt voor `#1` in je aanroep van `\mymacro`).

Je moet aanroepen `\mymacro` met een `<parameter text>` met scheidingstekens die identiek zijn aan die welke gebruikt zijn om het te definiëren—daaronder valt ook het gebruik van tekenscheidingstekens met identieke categoriecodes. Als de scheidingstekens in de `<parameter text>` gebruikt om aan te roepen `\mymacro` anders zijn dan degene die gebruikt zijn om het te definiëren (het “sjabloon” dat in het geheugen is opgeslagen), dan kan TeX behoorlijk in de war raken—wanneer het probeert `\mymacro` het kan het “sjabloon” dat het in zijn geheugen heeft opgeslagen niet matchen.

Wanneer TeX ziet dat je een macro aanroept, scant het je invoertekst om nieuwe tokens te maken en probeert het, token voor token, deze te matchen met de tokenlijst `<parameter text>` sjabloon dat als onderdeel van je macrodefinitie is opgeslagen. Als de scheidingstekens in je invoertekst resulteren in een reeks tokens die niet overeenkomen met de tokens die in het “sjabloon” zijn opgeslagen, dan geeft TeX meestal een foutmelding.

TeX is erg nauwgezet—onthoud dat karaktertokens een combinatie zijn van karaktercode en categoriecode: als je de categoriecode van een teken wijzigt, krijg je een andere tokenwaarde die uit dat teken voortkomt.

Stel dat we de categoriecode van `z` veranderen in bijvoorbeeld 12—normaal is die 11—en proberen onze macro zo aan te roepen:

```latex
\catcode`z=12
\mymacro abc THIS TEXT defz more text here...
```

Deze keer werkt het niet omdat de categoriecode van `z` is gewijzigd. Je ziet dan een fout zoals deze:

```latex
Weglopend argument?
THIS TEXT defz
! De alinea eindigde voordat \mymacro compleet was.
<opnieuw te lezen>
\par
l.22
```

Wanneer TeX de `z` in `defz` leest en scant, kan het niet herkennen als het einde van `\mymacro`voorstelt: `<parameter text>` dat in je invoerbestand wordt gebruikt. Tot het die foutieve `z` had TeX de eerste 3 tekens correct gematcht `def` maar dat `z` (met categoriecode 12) brengt TeX’s scanning in de war. Als we aannemen `z` een categoriecode van 11 had toen we *definieerden* `\mymacro`: dat zou resulteren in een tokenwaarde van 256×11 + 122 = 2938 die wordt opgeslagen als onderdeel van de `\mymacro`’s definitie (d.w\.z. opgeslagen als onderdeel van het “sjabloon”). Echter, met categoriecode 12, `z` zal nu een tokenwaarde van 256×12 + 122 = 3194 creëren. Omdat de tokenwaarde (voor `z`) die uit je invoer wordt gelezen (waarde 3194) niet overeenkomt met de `z`-token in de opgeslagen `<parameter text>` tokenlijstsjabloon (waarde 2938), zal TeX doorgaan met het scannen van je invoer. TeX blijft de tekst scannen die volgt op je macro (*meer tekst hier* ...) om extra tokens te zoeken—en probeert het opgeslagen sjabloon te matchen met de tokens die het in je invoer vindt. Het zal waarschijnlijk niet het juiste patroon van tokens vinden en er zullen fouten optreden doordat TeX je invoer “overschiet” en ten onrechte extra tekst leest om extra tokens te creëren—die extra tokens hadden op dit punt niet gelezen mogen worden en zullen vrijwel zeker een fout veroorzaken.

Hier gaan we in een toekomstig artikel dieper op in.

## Andere toepassingen van tokenlijsten

Andere commando's die worden gebruikt om tokenlijsten te maken/op te slaan zijn onder meer:

```latex
\toks<n>={...}
\everypar={...}
\everymath={...}
\everydisplay={...}
\everyhbox={...}
\everyvbox={...}
\output={...}
\everyjob={...}
\everycr={...}
\errhelp={...}
```

Elk van deze commando's maakt een tokenlijst van de tekens en commando's binnen de accolades ‘{...}’ en die tokenlijst is bedoeld om onder bepaalde omstandigheden opnieuw te worden gebruikt. Bijvoorbeeld, `\everypar={...}` maakt en slaat een reeks tokens op (een tokenlijst) die TeX in de invoer injecteert vlak voordat het een nieuwe alinea begint.

## Verborgen toepassingen van tokenlijsten: voorbeelden

In deze laatste sectie bekijken we enkele praktische voorbeelden van tokenlijsten die op manieren worden gebruikt die je misschien niet verwacht.

### Voorbeeld 1: \uppercase{...} en \lowercase{....}—tijdelijke tokenlijsten

Naast expliciete commando's om tokenlijsten te genereren, zijn er omstandigheden waarin TeX een verborgen en tijdelijke interne tokenlijst genereert om een speciale verwerking uit te voeren. Vergeet niet dat wanneer TeX je invoertekens/-commando's leest/verwerkt, deze worden omgezet in tokens: de fundamentele bouwsteen waarmee TeX-engines werken.

Een goed voorbeeld zijn de commando's `\uppercase{...}` of `\lowercase{...}` omdat hun werking bij eerste kennismaking nogal verwarrend kan zijn. Zodra je begrijpt wat ze doen—diep in TeX en onzichtbaar voor de gebruiker—wordt hun werking veel gemakkelijker te begrijpen.

Stel dat je een eenvoudige reeks letters hebt die je hoofdletters wilt maken—bijv. abcde en dat wilt omzetten naar ABCDE. Nou, dat is vrij eenvoudig met TeX’ `\uppercase` commando:

```latex
\uppercase{abcde}
```

zal TeX ertoe brengen uit te voeren `ABCDE`. Stel nu dat we onze eenvoudige reeks letters wilden bewaren voor later gebruik—dus we willen ze niet meteen uitvoeren, daarom gebruiken we TeX’ enige *interne* mechanisme—niet een extern (bestand-)mechanisme—om gegevens op te slaan: gebruik een tokenlijst. Dat kunnen we doen door óf een macro te maken óf een expliciet tokenlijst-commando te gebruiken:

```latex
\toks100={abcde}
\def\mychars{abcde}
```

Dan kun je op een gegeven moment besluiten dat je je reeks letters opnieuw wilt gebruiken, maar deze keer in hoofdletters; dus probeer je

```latex
\uppercase{\the\toks100}
```

en

```latex
\uppercase{\mychars}
```

Maar helaas werkt geen van beide. Waarom is dat?

### Geheime tokenlijsten!

Om te begrijpen hoe de commando's `\uppercase{...}` `\lowercase{...}` echt werken, moest ik in de binnenste werking van TeX kijken, dus de volgende uitleg is daarop gebaseerd.

Wanneer TeX een van beide detecteert `\uppercase{<material>}` of `\lowercase{<material>}` in je invoer, is het eerste wat TeX doet het maken van een (tijdelijke) interne tokenlijst van het `<material>` materiaal tussen de ‘{’ en ‘}’ die volgen op de `\uppercase{...}` of `\lowercase{...}` commando's—die tijdelijke tokenlijst is intern voor TeX.

Een cruciaal punt, en essentieel om te begrijpen hoe `\uppercase{<material>}` en `\lowercase{<material>}` echt werken, is dat alle commando's of macro's die in het `<material>` worden niet *uitgebreid*: alles wat TeX doet is tokens genereren uit tekens en commando's die tussen `{...}`. Tijdens de werking van `\uppercase{<material>}` of `\lowercase{<material>}` wordt niets tussen de accolades uitgevoerd: het wordt simpelweg omgezet in tokens.

Na de `<material>` binnen de `{...}` is omgezet in een (tijdelijke) tokenlijst, bezoekt TeX vervolgens elk token in die lijst opnieuw en test of het een *teken* token of een *commando* token is (met behulp van de numerieke waarde van het token). Als TeX een karaktertoken detecteert, wijzigt het dat token om de hoofdletter-/kleinelettervorm van het karakter aan te passen (afhankelijk van of `\uppercase` of `\lowercase` wordt verwerkt). TeX negeert simpelweg alle commando-tokens en kijkt niet “in” commando-tokens om te zien wat ze voorstellen of bevatten (bijv. een macro met tekens)—ze worden gewoon overgeslagen: alleen karaktertokens worden daadwerkelijk verwerkt/bij casewijzigingen betrokken.

Dus, als we bijvoorbeeld een TeX-commando geven zoals `\uppercase{abcde}` zal TeX een tokenlijst maken van `abcde` die niets anders bevat dan karaktertokens: ze worden allemaal aangepast om een reeks gewijzigde tokens te creëren die A, B, C, D en E voorstellen. Die gewijzigde tokens worden teruggevoerd in TeX’ invoerverwerker, wat resulteert in `ABCDE` het zetten van tekst. Maar als we onze tekens hebben opgeslagen *in een macro*—bijvoorbeeld `\def\mychars{abcde}`—en proberen ze zo in hoofdletters om te zetten:

```latex
\uppercase{\mychars}
```

dan zal het mislukken en wordt abcde gezet—not ABCDE zoals je misschien zou verwachten. Als we vervolgens proberen onze tekens op te slaan in een tokenlijst zoals `\toks0={abcde}` en doen `\uppercase{\the\toks0}` dan zal opnieuw, `\uppercase` het mislukken omdat de tokenlijst volledig zal bestaan uit tokens die niet worden beïnvloed door `\uppercase`.

Als we het voorbeeld van onze macro nemen, `\mychars`, nadat TeX `\uppercase` in de invoer heeft gedetecteerd, zoekt TeX de betekenis op van `\uppercase` en voert het uit, waarbij een tijdelijke tokenlijst wordt gemaakt van `{\mychars}`. Duidelijk: die tijdelijke tokenlijst bevat slechts één token dat geen karaktertoken is, maar een token dat ons macrocommando voorstelt `\mychars`: daarom is, voor het uitvoeren van `\uppercase`, dat token genegeerd—`\mychars` vertegenwoordigt geen karaktertoken. Maar zoals hierboven opgemerkt, zodra `\uppercase` zijn werk heeft gedaan, wordt de tijdelijke tokenlijst (gemaakt door de actie van `\uppercase`) teruggevoerd in TeX’ volledige invoerverwerkings- (scan-)mechanisme. Wanneer TeX die tokenlijst opnieuw leest, detecteert het een token dat onze `\mychars` macro voorstelt, die TeX uitvoert (uitbreidt) en een reeks tekens genereert om abcde te zetten—nog steeds in kleine letters omdat ze waren “opgeborgen” in een macro en dus onzichtbaar waren voor de acties van `\uppercase`.

Zodra TeX de tijdelijke tokenlijst opnieuw heeft bekeken die is gemaakt voor `\uppercase{...}` of `\lowercase{...}`, en eventuele karaktertokens heeft verwerkt, schakelt het vervolgens over op het gebruik van die tijdelijke tokenlijst als bron van invoer: tekens zetten (verwerkte karaktertokens) en commando's en macro's uitvoeren.

### Hoe kan dit worden opgelost?

Omdat `\uppercase{...}` of `\lowercase{...}` zal alleen op karaktertokens reageren, dus hebben we een manier nodig om de tekens in onze macro te “deverpakken” `\mychars` (of in een `\toks` register) voordat `\uppercase{...}` of `\lowercase{...}` erop reageert. Met “deverpakken” bedoelen we eigenlijk TeX’ proces van *expansie*:

* het vervangen van een TeX/LaTeX-commando door de *reeks* tokens *waaruit dat commando* (*bijv. een macro*) *bestaat,* of
* waardoor de reeks tokens ontstaat die een commando ontworpen is om te *genereren*. Een voorbeeld van een commando dat tokens genereert is `\jobname`, dat een reeks karaktertokens produceert die de naam van het hoofd-TeX-bestand dat wordt verwerkt voorstellen.

#### Lagere-niveau magie: scantoks(..., ...)

Hier duiken we echt in enkele donkere hoeken van TeX’ binnenste werking, dus je kunt deze sectie gerust overslaan tenzij je van details houdt…

Nadat TeX `\uppercase` of `\lowercase` in de invoerstroom detecteert, voert het een interne functie uit genaamd `scantoks(..., ...)` waarvan de taak is de tokenlijst te genereren met behulp van de items tussen de openings-‘{’ en sluitende ‘}’—zoals besproken wordt die tokenlijst vervolgens onderzocht om eventuele karaktertokens te detecteren (en daarna aan te passen) om de hoofd-/kleinelettervorm van het teken zo nodig te wijzigen. Let goed op dat we hier verwijzen naar `scantoks(..., ...)` als de interne functie die in de broncode van TeX-engines is ingebouwd—hier wordt het niet bedoeld als de naam van een controle-sequentie.

Als onderdeel van zijn werk, `scantoks(..., ...)` kan worden opgedragen om de tokenlijst die het aan het construeren is al dan niet uit te breiden en voor `\uppercase` en (`\lowercase`) breidt het de tokens niet uit: het maakt ze slechts aan en plaatst ze in een tokenlijst.

Een van de eerste dingen die `scantoks(..., ...)` moet doen is controleren op een openings-‘{’ (of elk teken met `\catcode` categoriecode 1) omdat het moet controleren of de gebruiker geen syntaxisfout heeft gemaakt en de openings-‘{’ vergeten is (of elk teken met categoriecode 1)—omdat een teken met categoriecode 1 vereist is om het begin van een lijst met items die getokeniseerd moeten worden af te bakenen.

En hier is de truc: de taak om naar een openings-‘{’ te zoeken activeert `scantoks(..., ...)` het expansieproces van TeX, wat betekent dat de volgende voorbeelden zullen werken:

```latex
\let\ob={
\uppercase\ob abcde}
\def\obb{\ob}
\uppercase\obb xyz}
```

Als we het voorbeeld nemen van `\obb`, een macro, wordt het herkend als een *expandeerbare opdracht* en wordt het netjes door TeX uitgebreid (via de `scantoks(..., ...)` functie) in zijn zoektocht naar een openingsaccolade (elk teken met categoriecode 1). Dat betekent dat we de “`\expandafter` truc” kunnen gebruiken om ons doel te bereiken: onze tekens uit de beperkingen van onze macro “deverpakken”—oftewel deze uit te breiden. Merk op dat `\expandafter` ook in de categorie valt van een *expandeerbare opdracht*, dus TeX voert het hier uit en laat het zijn werk doen als onderdeel van het zoeken naar een openings-‘{’ (of elk teken met categoriecode 1).

Dus als je definieert:

```latex
\toks0={abcde}
\def\mychars{abcde}
```

En dit doet:

```latex
\uppercase\expandafter{\mychars}
\uppercase\expandafter{\the\toks0}
```

zal je nu in beide gevallen ABCDE gezet zien omdat de `\expandafter` zorgt voor het “deverpakken” (uitbreiden) van `\mychars` en `\the\toks0`—beide resulteren in `\uppercase` het zien van een stroom karaktertokens, die ze kunnen verwerken om de hoofd-/kleinelettervorm te wijzigen.

### Voorbeeld 2: \\\string—meer tijdelijke tokenlijsten

Intern gebruikt TeX `\string` het als een van zijn zogenaamde “convert”-commando’s: het uitvoert de bewerking “omzetten naar tekst”. De `\string` opdracht is ontworpen om een token om te zetten in een voor mensen leesbare tekstversie—d.w\.z. de voor mensen leesbare tekenreeks van tekens waaruit dat token oorspronkelijk is gemaakt.

Bijvoorbeeld `\\string\\hello` maakt een tijdelijke tokenlijst aan die de tekens \\, h, e, l, l, o bevat — ja, zelfs inclusief de begin-‘\\\’. Zodra die tokenlijst is aangemaakt, wordt deze opnieuw ingelezen door TeX en wordt de tekst van het commando “`\\hello`” wordt gezet—ja, inclusief ‘\\\’ als je het juiste lettertype kiest…

Je vraagt je misschien af hoe/waarom TeX het escape-teken kan zetten terwijl het gewoonlijk wordt gebruikt om de scanner van TeX aan te zetten tot het maken van een commando-token: waarom doet het dat hier niet? Het antwoord heeft te maken met categoriecoden: normaal heeft een ‘\\\’-teken catcode 0 (escape-teken), maar wanneer `\string` genereert zijn interne tokenlijst, doet het iets anders. Wanneer het een teken-tokenlijst maakt, kent het categoriecode 12 toe aan alle tekens behalve het spatie-teken, waaraan catcode 10 wordt toegekend—onthoud dat teken-tokens worden berekend als 256 × catcode + ASCII-waarde. Dus wanneer TeX de tijdelijke tokenlijst die `\string` is gegenereerd uit `\\hello`, *ziet geen escape-teken* omdat het token voor ‘\\\’ met catcode 12 en niet 0 is berekend: TeX behandelt ‘\\\’ gewoon als een normaal teken en zet het.

Strikt genomen moeten we waarschijnlijk opmerken dat TeX eigenlijk geen token voor escape-tekens genereert wanneer het ze in de invoer detecteert. Zodra het een teken met categoriecode 0 heeft herkend, wordt dat teken alleen gebruikt om het genereren van een token voor een controlesequentie te activeren: zodra het TeX heeft aangezet om dat te doen, heeft het escape-teken zijn werk gedaan en wordt het niet meer meegenomen.

### Technische opmerking

Een opdracht genaamd `\\showtokens{...}` (ingevoerd door de e-TeX-engine) kan tokenlijsten tonen (in het logbestand). Uit de e-TeX-handleiding:

> Het commando `\\showtokens{<token list>}` geeft de tokenlijst weer en maakt het weergeven mogelijk van grootheden die niet kunnen worden weergegeven door `\\show` of `\\showthe`, bijv.:
>
> ```latex
> \\showtokens\\expandafter{\\jobname}
> ```

## Tot slot

In sectie 291 van de TeX-broncode (zie pagina 122 van [TeX: Het programma](https://www.amazon.co.uk/Computers-Typesetting-TeX-Program-TEX/dp/0201134373)) beschrijft Knuth een tokenlijst als volgt:

> “Een tokenlijst is een enkelvoudig gelinkte lijst van nodes van één woord in het geheugen, waarbij elk woord een token en een link bevat. Macrodefinities, uitvoer-routine-definities, markeringen, `\write` teksten en enkele andere dingen worden door TeX onthouden in de vorm van tokenlijsten, meestal voorafgegaan door een node met een referentietelling in het veld “token\_ref\_count”.”

Bij eerste lezing was dit misschien niet makkelijk te begrijpen, maar hopelijk maakt het nu iets meer duidelijk.


---

# 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/54-what-is-a-tex-token-list.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.
