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

# Sådan virker TeX-makroer egentlig: Del 6

[Del 1](/latex/da/flere-emner/19-how-tex-macros-actually-work-part-1.md) [Del 2](/latex/da/flere-emner/20-how-tex-macros-actually-work-part-2.md) [Del 3](/latex/da/flere-emner/21-how-tex-macros-actually-work-part-3.md) [Del 4](/latex/da/flere-emner/22-how-tex-macros-actually-work-part-4.md) [Del 5](/latex/da/flere-emner/23-how-tex-macros-actually-work-part-5.md) [Del 6](/latex/da/flere-emner/24-how-tex-macros-actually-work-part-6.md)

## Introduktion og overblik: Historien indtil nu

I de foregående 5 dele af denne serie har vi set:

* hvordan TeX læser tegnene i en inputfil og bruger kategori-koder til at genkende forskellige “klasser” af tegn og derefter konvertere dem til tegntokens og kommando-tokens;
* at en makro i praksis består af fire sektioner:

```
<TeX-makro-primitive><makronavn><parametertekst>{<erstatningstekst>}
```

hvor:

* `<TeX-makro-primitive>` = en af `\def`, `\edef`, `\gdef` eller `\xdef`;
* `<makronavn>`=navnet på din makro, såsom `\foo`;
* `<parametertekst>` kan være “null” (ikke til stede), eller det kan være en streng af delimiter-tokens og makroparameter-tokens;
* `<erstatningstekst>` er selve kroppen af din makro: den sektion, der “eksekveres” (ekspanderes), når du kalder makroen.
* hvordan  `<parametertekst>` sektionen kan indeholde en bred vifte af tokens, og at TeX bruger denne sektion som en “token-skabelon” til at matche et makrokald med dets oprindelige definition og finde ud af de argumenter, der bruges med makroen—og hvordan TeX forventer, at din brug af en makro matcher dens oprindelige definition;
* at en makrodefinition inde i TeX gemmes som en sammenhængende sekvens af tokens, der repræsenterer `<parametertekst>` og `<erstatningstekst>` sektionerne.

Når du bruger en makrokommando, vil TeX først tjekke, om den tager nogen parametre. Hvis ja, må TeX derefter identificere de faktiske *argumenter* der bruges i dit makrokald. TeX må afprøve dit makrokald mod den “token-skabelon”-definition, den har gemt i hukommelsen. Mere specifikt bruger TeX den interne (gemte) definition af din makros `<parametertekst>` sektion som skabelonen, hvorigennem den kan udpege *tokens* som er de faktiske argumenter, og hvilke *tokens* der blot er der for at fungere som afgrænsere.

## Betydningen af makroekspansion

Vi er nu endelig klar til at gå videre til det vigtigste emne: hvordan TeX behandler makroargumenter og faktisk eksekverer makroen: en proces som TeX kalder *makroekspansion*.

### Men først, et kort eksempel: noget mærkeligt?

For at “sætte scenen” til at forklare den mekanisme, hvormed TeX behandler makroer og deres argumenter, vil vi bruge et kort eksempel til at pege på de spørgsmål, vi skal overveje.

#### Argumenter konverteres først til tokens

Følgende eksempel er baseret på et, der diskuteres på side 114–5 i [The Advanced TeXbook](https://www.amazon.co.uk/Advanced-Texbook-David-Salomon/dp/0387945563) skrevet af David Salomon. Det er valgt, fordi det på en fin måde indkapsler de centrale ideer i en meget kort TeX-makro.

Under normale TeX/LaTeX-operationer har `$` tegnets kategori-kode 3 (“math shift”), som skifter TeX ind og ud af inline-matematiktilstand (`$...$`) eller display-matematiktilstand (`$$...$$`)—selvfølgelig bruger LaTeX `\(..\)` og `\[..\]` til de samme formål.

Antag, at vi vil have en makro, der ændrer kategori-koden for et `$` tegn til f.eks. 11, så vi kan sætte det som et almindeligt tegn. Vi kan bruge TeX-primitive-kommandoen `\catcode` og vores første forsøg på en sådan makro, `\docat`, kunne være

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

Men når vi prøver at bruge den, sådan her

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
Jeg betalte \docat{$90} for den bog.
\end{document}
```

forventer vi, at TeX sætter `Jeg betalte $90 for den bog.` men det mislykkes med en fejlmeddelelse:

```
! Mangler $ indsat.
<indsat tekst>
                $
<skal læses igen>
                   \par
l.7
```

Af fejlen ser det ud til, at `$` brugt i vores makros argument stadig udløser, at TeX sætter matematik; tydeligvis *gjorde det ikke* ændre kategori-koden for `$` brugt i vores makros argument (`$90`). Spørgsmålet er *hvorfor* hvorfor ændrede TeX ikke kategori-koden for `$` til 11 og satte det som et almindeligt tegn? Det korte svar er, at TeX først konverterer makroargumenter til tokens **før** og derefter føder dem ind i tokenlisten for `<erstatningstekst>`—men vi ser nærmere på de underliggende mekanismer i meget større detaljer.

Det, vi skal huske, er, at vores forestilling om, at TeX bruger tekst/tegn, kun er relevant for indholdet af den fil, som TeX læser: så snart TeX har læst nogle tegn ind, er vi i verdenen af *tokens*. TeX-makrokald arbejder med *tokens*, ikke den faktiske *skrevne/tekstlige repræsentation* af TeX/LaTeX-kommandoer—det bliver tydeligere, når vi arbejder os gennem eksemplet.

I første omgang kunne vi tro, at vores brug af `\docat` makroen i `Jeg betalte \docat{$90} for den bog.` er det samme som direkte at skrive den tilsvarende TeX- (eller LaTeX-) kode—såsom følgende, som *gør* virker:

```
\begin{document}
Jeg betalte \catcode`\$=11 $90 for den bog.
\end{document}
```

![Noget TeX-kode, der kører på Overleaf](/files/33b2258be7929829326a3c528bf60efa0259fbd3)

Men som vi så ovenfor, giver den måde TeX behandler makroargumenter på et resultat (`! Mangler $ indsat.`) der er ganske anderledes end at skrive TeX-koden ud: nu vil vi udforske *hvorfor* det, der sker.

### Makroer og argumenter som tokenlister

For fuldt ud at forstå opførslen af `\docat` makroen, og dens argument (`$90`), og hvorfor den fejler, må vi igen visualisere definitionen af `\docat` makroen og eventuelle argumenter, der bruges (når \docat kaldes), som *lister af tokens*, ikke som en sekvens af tegn.

Når TeX scanner din inputtekst, ville den genkende `\docat` som en makrokommando; derefter tjekker den, om den tager nogen parametre—hvordan TeX gør det, forklares i det følgende afsnit for læsere, der er interesserede i de finere detaljer.

#### For dem, der kan lide detaljerne...

Efter makroen er kaldt, tjekker TeX, om det allerførste token (i makroens gemte definitions-tokenliste) er **slutmatch** token: hvis ja, kan TeX være sikker på, at makroen ikke tager nogen parametre.

**Et eksempel**

Følgende node-liste-diagrammer sammenligner tokenlisterne for to makroer:

* `\def\foo A#1B{#1}`: denne har `<parametertekst>` på `A#1B`, derfor er **slutmatch** tokenet **ikke** det første token, så TeX ville gå videre til at lede efter parametre;
* `\def\foo{X}`: denne har ikke en `<parametertekst>` sektion, derfor er **slutmatch** tokenet det første i tokenlisten, og TeX ved, at den ikke skal lede efter nogen parametre.

![Hvordan TeX tjekker, om en makro tager parametre](/files/21f0d6d2bd2fdb375accd5b77bed2642125d987c)

## Mod den “store finale”: ekspansion

Lad os minde os selv om spørgsmålet: hvorfor virkede den følgende makro ikke; dvs. hvorfor ændrer TeX ikke kategori-koden for nogen `$` dollartegn brugt i argumentet til `\docat` makroen, såsom `\docat{$90}`?

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
Jeg betalte \docat{$90} for den bog.
\end{document}
```

Som forklaret ovenfor, når TeX scanner dit input og genkender en makrokommando—på et tidspunkt hvor TeX skal til at eksekvere den—tjekker TeX først, om den makro tager nogen parametre. Hvis ja, må TeX scanne inputfilen yderligere for at identificere de faktiske *argumenter* som brugeren har angivet for netop dette makrokald: TeX må gøre dette **før** før den kan kalde den egentlige makrokode. Det er tydeligt, at TeX skal bestemme de data, som brugeren ønsker at give til makroen.

For at identificere de argumenter, der findes i inputtet (brugerens makrokald), vil TeX blive styret af den internt gemte definition af den makro: specifikt `<parametertekst>` sektionen af den gemte makrodefinition (tokenliste)—som giver en slags “token-skabelon”. Ved hjælp af den “token-skabelon” må TeX afgøre, hvilke *tokens* tokens *afgrænsere* i brugerens makrokald blot er *tokens* afgrænsere *(i praksis “tegnsætning”) og hvilke*udgør en del af et **matchparameter** token `<parametertekst>` sektion (“token-skabelon”), at den ved, at den skal begynde at danne en *tokenliste* for det pågældende argument.

Så snart TeX erkender behovet for at identificere brugerens argument, scanner TeX inputtet for at generere tokens og kontrollerer dem meget omhyggeligt, token for token, mod den gemte makrodefinition. TeX fortsætter med at samle tokens til et argument, indtil den registrerer et token, der faktisk er en afgrænser, eller hvis den registrerer **slutmatch** sluttokenet: i begge tilfælde ved TeX derefter, at det er tid til at holde op med at lede efter tokens, der udgør en del af det argument.

### Hvorfor \docat-makroen fejlede

Som nævnt, *før* For at TeX faktisk kan kalde en makro, må den identificere og forberede eventuelle argumenter, der skal bruges med den makro. Men for at identificere argumentet/argumenterne, klar til at blive ført ind i makroen, må TeX generere hvert argument som en *tokenliste*: og det er grunden til `\docat`’s fiasko.

I vores eksempel gav vi `\docat` makroen `$90` et argument på *konverteret til en tokenliste* mens TeX scanner makrokaldet—argumentet konverteres til tokens *før* før `$90`, genererer TeX tre karaktertokens: ét token for hver af `$`, `9` og `0`.

Følgende grafik viser tokenlisten, der genereres for argumentet `$90`, før det føres ind i kroppen af `\docat` makroen:

![TeX-tokenliste genereret for et makroargument](/files/144b5355ce6540468b42c6f4a324d009cb8d4953)

I ovenstående grafik kan vi tydeligt se, at argument-tokenlisten indeholder `$` som et karaktertoken baseret på en kategori-kode på 3.

Som vi så i Del 1 til 3, oprettes karaktertokens ved hjælp af kategori-kodeværdierne *der er i brug på det tidspunkt, hvor karakteren læses ind*—dvs. på det tidspunkt, hvor argumentets tokenliste oprettes (omdannes til tokens). På det tidspunkt, hvor argumenterne tokeniseres, har `\docat` makroen endnu ikke været eksekveret, så den kategori-kodeændring, vi satte ind i makrokaldet (``\catcode`\$=11``) *ikke* påvirker ikke de kategori-koder, der bruges til at generere argumentets tokens.

Når TeX har genereret en tokenliste, der repræsenterer argumentet til `$90`, føres disse tre karaktertokens ind i den egentlige makro `<erstatningstekst>`. Men det resulterer i, at `$` bliver ført ind som et *karaktertoken* oprettet ved hjælp af kategori-kode 3: “math on”, og vi har set, at når først et karaktertoken er dannet, er den tilknyttede kategori-kode permanent. Det `$` er *ikke* føres ind i makroen *som et karakter*, men som et *karaktertoken* token `$` baseret på, at

### Kører \docat: makroekspansion

TeX omtaler processen med at “eksekvere” en makro som *makroekspansion*; en term som efter denne forfatters mening er lidt forvirrende, men det er den accepterede terminologi, så vi fortsætter med at bruge den.

#### Den egentlige betydning af makroekspansion

Efter TeX registrerer `\docat` kommandoen i brugerens input, scanner den argumenterne og genererer en tokenliste for dens argument(`$90`). For at eksekvere (ekspandere) makroen vender TeX blikket væk fra brugerens inputfil og begynder at læse de tokens, der er indeholdt `\docat`’s `<erstatningstekst>` tokenlisten, der er gemt i TeXs hukommelse.

Når TeX behandler `\docat`s definition, vil den derefter se og eksekvere den række tokens, der oprindeligt blev brugt til at definere makroen (`**catcode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**#1**`).

Følgende grafik viser processen med at ekspandere `\docat` makroen: TeX holder op med at hente tokens fra inputfilen og begynder at læse tokens fra `<erstatningstekst>` sektionen af `\docat` makrodefinitionen gemt i hukommelsen. TeX fortsætter med at eksekvere disse forberedte tokens, indtil den ser et **outputparameter** token, som instruerer TeX i at læse (“indsætte”) og “eksekvere” argumentets tokens på dette punkt. I vores eksempel er det tre karaktertokens, der repræsenterer `$90` og det resulterer i en fejl, fordi det forberedte karaktertoken for `$` har kategori-kode 3. Fordi vi har med karaktertokens at gøre, ikke tegn, er `$` upåvirket af den tidligere kategori-kodeændring forårsaget af tokens i ``\catcode`\$=11``.

![Viser processen med at ekspandere \docat-makroen](/files/bd0462c50b28564467d88ef2da4d2f002a8e7a60)

Efter TeX har behandlet de tokens, der repræsenterer ``\catcode`\$=11``, vil kategori-kodeændringen for `$` nu være gældende. TeX støder derefter på det “særlige token” kaldet **outputparameter** som fortæller TeX at **indsætter TeX-motorerne** tokenlisten for argumentet. Men den tokenliste er tre karakter *tokens*, hvoraf den første er et token for en `$` med en kategori-kode på 3 (“math on”) tildelt: den tidligere kategori-kodeændring inde i makroen kan ikke påvirke dette karaktertoken, så TeX behandler det token som et signal til at begynde matematikbehandling, hvilket får makroen til at fejle.

### Kan \docat-makroen rettes?

Af diskussionerne ovenfor fremgår det tydeligt, at alle tegn, der optræder i makroargumenter, tokeniseres ved hjælp af de kategori-koder, der er i brug på det tidspunkt, hvor tokeniseringen finder sted—hvilket i vores eksempel er *altid* før `<erstatningstekst>` af `\docat` makroen faktisk eksekveres. Så hvordan kan vi sikre, at en makros argumenter får ændret deres kategori-koder?

En måde er at ændre `\docat` til at være en parameterløs makro, som kun laver kategori-kodeændringen—den har ingen argumenter, der skal tokeniseres. Derefter bruger vi en anden makro, `\getarg`, som tager en enkelt parameter, og sørger for, at den makro får tokeniseret sit argument, når den relevante kategori-kode for `$` er aktiv.

```
\begin{document}
\def\docat{\catcode`\$=11 \getarg} % Ingen parametre, kalder en anden makro \getarg
\def\getarg#1{#1} % 1 parameter, hvis argument vil blive tokeniseret
Nu kan du køre det sådan her, og det vil virke:

Jeg betalte \docat{$90} for den bog.
\end{document}
```

Når vi bruger vores nye version af `\docat` (sådan her `\docat{$90}`) ser det *ud* som om `$90` dollartegnet stadig bruges som et argument til `\docat` makroen. Men som nævnt ovenfor, når TeX registrerer `\docat` i inputtet, tjekker det, om det har nogen argumenter: nu har det ikke, så TeX går videre med at eksekvere (ekspandere) det. Ekspansionen af `\docat` er sekvensen af tokens `**catcode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**mellemrum**`, `**getarg**` og dette sker *før* begynder TeX at læse (tokenisere) de næste tegn i inputfilen—dvs. gruppen `{$90}`. Husk, at når TeX ekspanderer en makro, får den sit næste input ved at læse de tokens, der er indeholdt i tokenlisten for den makros definition; dvs. fra dens `<erstatningstekst>` sektion gemt i hukommelsen.

TeX vil behandle og eksekvere ekspansionen af `\docat` og registrere *token* **`getarg`**, idet den genkender det som et token, der repræsenterer en kommando, der tager parametre. På dette tidspunkt vil TeX scanne inputfilen for **`getarg`**’s argument: tegnene: `{$90}`. Som sædvanligt tokeniseres disse, men fordi TeX har læst og behandlet ekspansionen af `\docat`, tokeniseres tegnene `$90` når kategori-koden for `$` er blevet ændret til 11. Definitionen (`<erstatningstekst>`) af `\getarg` er ganske enkelt `#1` som betyder typesæt det leverede argument, og det er, hvad der sker, hvilket resulterer i, at en `$` med kategori-kode 11 bliver genereret og sikkert typesat.

## Afsluttende bemærkninger: historien i noder

Sekvensen af hændelser, der opstår ved at omskrive `\docat` til at bruge makroen `\getarg` findes i det følgende annoterede node-liste-diagram, som viser ekspansionsprocessen for makroen `\docat`. Læsere, der ønsker nøje at studere dette diagram, kan downloade grafikken som en [PDF](https://assets.ctfassets.net/nrgyaltdicpt/7MOBdavza4WxAEQGISEEht/cabe5097d9063a6415bc553cd38237e6/newdocatexpansion.pdf) eller [SVG](https://images.ctfassets.net/nrgyaltdicpt/2FIqqVRXjakdAzTpZsV0m9/10ccc1353741d42d3df18f1692d8aa84/newdocatexpansion--plain.svg) fil til offline brug.

![Viser processen med at ekspandere den modificerede \docat-makro og \getarg-makroen](/files/a7c0f706e8e2e5373300e9bec94e9eaf62cb10a7)

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