> 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/dybtgaende-artikler/09-an-introduction-to-luatex-part-2-understanding-directlua.md).

# En introduktion til LuaTeX (del 2): Forstå \directlua

## Målet med denne artikel

I den første del af denne artikel, [En introduktion til LuaTeX (del 1): Hvad er det — og hvad gør det så anderledes?](/latex/da/dybtgaende-artikler/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md), gennemgik vi kort LuaTeX som en yderst alsidig TeX-motor: et sofistikeret, programmerbart satsningssystem, som tilbyder en bred vifte af værktøjer til at konstruere løsninger til dokumentteknik og produktion.

I denne afsluttende del ser vi nærmere på den vigtigste komponent i LuaTeX-værktøjskassen:  `\directlua` kommandoen, som giver “indgangen” til programmatisk styring af LuaTeX’s satsning via Lua-skriptsproget.

Men at udnytte LuaTeX fuldt ud via `\directlua` kræver noget baggrundsviden om flere TeX-emner: TeX’s tokens, tokenlister og ekspansionsmekanismen. Målet med denne artikel er at udforske og forklare disse grundlæggende TeX-begreber: at sætte TeX-relaterede processer bag `\directlua`  sammen for at opnå en forståelse af, hvordan det virker, og give det fundament, du kan bygge dine egne satsningsløsninger på ved hjælp af LuaTeX.

Denne artikel indeholder adskillige korte eksempler, der demonstrerer og forklarer nøgleaspekter af `\directlua`’s adfærd, samtidig med at den bevidst undgår alt for kompleks kode til fordel for korte kodefragmenter. Når det er nødvendigt, bruger eksemplerne grundlæggende (rå/ren) TeX — selv om de fleste bruger og foretrækker LaTeX (makroer), har grundlæggende TeX-kommandoer den fordel, at de er enkle.

## Introduktion til Lua i LuaTeX

[Lua](https://www.lua.org/about.html) er et skriptsprog, hvis [kildekode](https://www.lua.org/download.html) er yderst portabel og let at indlejre i softwareapplikationer, hvilket gør det muligt for udviklere at integrere skriptfunktionalitet i deres programmer. Lua er blevet indlejret i [mange applikationer](https://en.wikipedia.org/wiki/List_of_applications_using_Lua) og er et populært valg i spilsoftwareindustrien — måske er det mest berømte eksempel [World of Warcraft](https://wowwiki.fandom.com/wiki/Lua_functions).

LuaTeX, som navnet antyder, er en TeX-motor, der indlejrer Lua-skriptsproget og giver brugerne mulighed for at styre LuaTeX’s satsningsadfærd ved at inkludere Lua-programmer (scripts) i deres dokumenter. Ud over direkte styring af LuaTeX kan brugerne udnytte Lua som et meget kompetent programmeringssprog til at udføre opgaver, der kan være ekstremt vanskelige at opnå ved hjælp af TeX-sproget — som, efter enhver rimelig vurdering, er en udfordring at lære og mestre. Gennem tilføjelsen og integrationen af Lua bliver LuaTeX en meget alsidig og kraftfuld TeX-motor, der direkte understøtter to programmeringssprog.

### Brug af Lua og TeX i dit dokument: skriv \directlua

Lua og TeX er to *meget forskellige* programmeringssprog: Lua ligger meget tættere på det, de fleste opfatter som et programmeringssprog, men TeX, med sine kategorikoder, tokens, makroer og ekspansionsmekanisme, ligger langt fra de flestes erfaringer/forventninger til et sprog, man skriver programmer i. Men som historien har vist, har TeX-sproget overlevet, fordi det er godt til det, det blev designet til: at styre satsning, selv om dets måde at fungere på er noget esoterisk.

For at imødekomme udfordringen med at blande Lua- og TeX-sprogene i et enkelt TeX-dokument introducerede LuaTeX’s udviklere en ny kommando kaldet `\directlua` som er vejen til at bruge Lua — både som et selvstændigt programmeringssprog i egen ret og til at styre LuaTeX’s satsningsadfærd.

Den `\directlua` kommandoen giver brugerne mulighed for at indlejre Lua-kode i deres TeX-dokumenter; den kode sendes derefter videre til LuaTeX’s indbyggede Lua-sprogtolk. Men `\directlua` giver dig også mulighed for at *kombinere* Lua- og (La)TeX-kode sammen i den samme `\directlua` kommando — selv om det medfører yderligere kompleksitet på grund af de grundlæggende forskelle mellem Lua- og TeX-baserede programmeringssprog. Den centrale udfordring ved at bruge en kombination af (La)TeX- og Lua-kode er at sikre, at de to sprog sameksisterer fredeligt og ikke kommer “i vejen for hinanden”.

`\directlua` egner sig bedst til brug med kortere Lua-kodefragmenter inde i dokumentet, men du kan bruge det med mere omfattende Lua-programmer, hvis du ønsker det. Generelt gemmes større Lua-programmer og Lua-kodebiblioteker i eksterne filer, som kan indlæses ved hjælp af Lua’s `dofile()` funktion inden for en `\directlua` kommando. Fra TeX-behandlingssynspunktet er en væsentlig fordel ved at bruge eksterne Lua-kodefiler, at man undgår komplikationer, der opstår som følge af TeX’s kategorikodemekanisme — et emne, der udforskes fuldt ud i denne artikel.

### Mere formel beskrivelse af \directlua

Den [LuaTeX Reference Manual](http://www.pragma-ade.com/general/manuals/luatex.pdf) beskriver `\directlua` det således (let ændret):

> For at sammenflette Lua-kode med TeX-input er der behov for nogle få nye primitiver. Primitivet `\directlua` bruges til at udføre Lua-kode med det samme. Den grundlæggende syntaks er `\directlua{⟨code⟩}`. `⟨code⟩` bliver fuldt ekspanderet og derefter sendt til Lua-fortolkeren. Efter at læsning og ekspansion er blevet anvendt på `⟨code⟩`, omdannes den resulterende tokenliste til en streng, som om den blev vist ved hjælp af `\the\toks`.

Det er naturligvis teknisk korrekt, men måske ikke så let at forstå uden kendskab til TeX-processer på lavere niveau — såsom tokens og ekspansion.

## Forstå \directlua: Hvilke emner vil vi dække?

I denne artikel ser vi nærmere på nogle vigtige baggrundsemner og giver en række eksempler, der er designet til at demonstrere, hvordan `\directlua` virker, og hvor (eller hvorfor) du skal være forsigtig, når du kombinerer TeX og Lua i dit `⟨code⟩`.

Vi udforsker følgende emner i tilstrækkelig detaljeringsgrad til at skabe et fundament for at forstå `\directlua` og dens “forbehandling” af den kode, du bruger inde i den:

* kategorikoder og TeX-tokens: konvertering af tekst til tokens og tokens til tekst;
* TeX’s ekspansionsproces (og hvordan man forhindrer ekspansion);
* Lua-escape-sekvenser/-mekanismer for tegn og strenge;
* brug af Lua-stil kommentarer;
* en kort introduktion til LuaTeX’s Lua-API.

Hvis du forstår, hvordan TeX-motorer opretter og bruger tokens og udvikler en forståelse af TeX’s ekspansionsmekanisme, så har du det nødvendige fundament til at frigøre den utrolige alsidighed i LuaTeX’s `\directlua` kommandoen.

## Fundamenterne: fra tekst til tokens og tokens til tekst

Overleaf har udgivet flere artikler, som går i dybden med TeX-tokens og beslægtede begreber, så vi vil ikke gentage alt det materiale her; i stedet skitserer vi de områder/emner, der er relevante for at udvikle en bedre forståelse af `\directlua`.

Her er en liste over tidligere udgivne artikler, som kan være interessante:

* [Hvad er en TeX-token?](/latex/da/dybtgaende-artikler/53-what-is-a-tex-token.md)
* [Hvad er en TeX-tokenliste?](/latex/da/dybtgaende-artikler/54-what-is-a-tex-token-list.md)
* [Hvordan virker \expandafter: En introduktion til TeX-tokens](/latex/da/dybtgaende-artikler/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)
* [En serie på seks dele: Hvordan virker TeX-makroer egentlig?](/latex/da/flere-emner/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### Forstå karaktertokens

Ethvert tegn, som en TeX-motor kan læse fra en tekstfil, repræsenteres ved to numeriske værdier:

* dets *tegnkode* (ASCII-værdi eller i dag dets Unicode-kodepunkt);
* en anden, TeX-orienteret værdi kaldet dets *kategorikode*.

Læsere, der gerne vil vide mere om kategorikoder, kan være interesserede i at læse denne introduktion udgivet af Overleaf: [Så hvor begynder vi? Med kategorikoder](/latex/da/flere-emner/19-how-tex-macros-actually-work-part-1.md#so2c-where-do-we-start3f-with-category-codes).

For eksempel, hvis en TeX-motor læser tegnet ind `Et` ville den have adgang til to oplysninger: `Et`’s tegnkode (65) og dets kategorikode (normalt 11). Når TeX først har input det tegn `Et`, ændres dets kategorikode ikke, men brugermakroer kan lave kategorikodeændringer, som kan påvirke enhver *efterfølgende* tegn `Et` som *endnu ikke er blevet læst* af TeX. Derfor er TeX nødt til at registrere, at det *dette* tegn `Et`, *lige læste ind*, har kategorikode 11. For at gøre det bruger TeX heltalsparret (65,11) til at beregne en anden heltalsværdi, som det kalder en *karaktertoken*. Ved at beregne den tokerværdi, som sendes videre til TeX’s interne behandling, er det pågældende `Et` og dets kategorikode *knyttet sammen*; i praksis indkapsler det karaktertoken *de data, TeX har brug for at kende til dette tegn, til brug i efterfølgende satsningsaktiviteter dybere inde i TeX-motoren.* Hvordan beregnes karaktertokens?

#### Hvordan beregnes karaktertokens?

Først skal vi huske, at TeX-motorer bruger kategorikode 13 til at skabe såkaldte *aktive tegn*: ethvert tegn med kategorikode 13 opfører sig som en minimakro; derfor, og som vi vil se nedenfor, beregnes tokens for aktive tegn anderledes end for almindelige tegn med andre kategorikoder såsom 10, 11 eller 12.

For *ikke-aktive* tegn:

* ældre 8-bit-motorer (Knuths TeX, e-TeX, pdfTeX) beregner karaktertokens for *ikke-aktive* tegn ved hjælp af

$$\text{(non-active) character token} = (256 \times \text{category code}) + (\text{ASCII character code})$$

* for LuaTeX, som skal håndtere Unicode-tegnværdier, er beregningen for *ikke-aktive* tegn lignende, men giver langt større heltalsværdier:

$$\text{(non-active) character token} = (2^{21} \times \text{category code}) + (\text{Unicode value})$$

Hvis vi går tilbage til vores tidligere eksempel med bogstavet A med kategorikode 11, ville LuaTeX beregne en karaktertokenværdi på $$2^{21} \times 11 + 65 = 23068737$$. Når den er beregnet, binder den tokerværdi *binder* det pågældende tegn A til en kategorikodeværdi på 11. Brugermakroer kan ændre kategorikoden for ethvert efterfølgende tegn A, men dette tegns kategorikode er blevet fastlagt ved at konvertere det til en token, som bruges, når det passerer gennem LuaTeX’s indre mekanik. LuaTeX har bevaret eller indkapslet den tilsigtede betydning af det tegn, sådan som den blev bestemt, da det blev læst ind.

TeX-motorer bruger i alt [16 forskellige kategorikoder](/latex/da/flere-emner/43-table-of-tex-category-codes.md) og *Enhver* af disse kategorikoder kan tildeles via `\catcode` kommandoen til *Enhver* ethvert tegn, som TeX-motoren er i stand til at læse. Ændringer i kategorikoder bruges til at ændre den måde, TeX-motorer behandler bestemte tegn i inputtet på, hvilket gør det muligt for TeX-brugere at skrive makroer, der producerer særlige satsningsresultater eller adfærd.

**Aktive tegn**

Som nævnt bruger TeX-motorer kategorikode 13 til at knytte en “særlig betydning” til et tegn, hvilket gør det til et såkaldt *aktivt tegn* som opfører sig som en minimakro: intet indledende `\` er påkrævet, det isolerede tegn er, på grund af sin kategorikode, nok til at udløse dets makrolignende adfærd.

Fordi et aktivt tegn fungerer som en minimakro, konverteres det ikke til en *karaktertoken* men til en anden (heltals-)tokentype kaldet en *kommandotoken*. Disse beregnes som følger:

* for ældre 8-bit-motorer (Knuths TeX, e-TeX, pdfTeX) beregnes tokens for aktive tegn via:

1. beregn en mellemliggende værdi kaldet $$\text{curcs}$$ (**nuvæ**rende **c**kontrol **s**ekvens) hvor $$\text{curcs} = \text{character code} + 1$$3. beregn tokerværdien, hvor $$\text{active character token} = \text{curcs} + \text{4095}$$

* for LuaTeX er beregningen lidt mere kompleks, fordi den skal håndtere hele spektret af Unicode-tegn, hvoraf ethvert kan gøres aktivt:

1. beregn den mellemliggende heltalsværdi $$\text{curcs}$$ ved at anvende en såkaldt *hashfunktion* på det aktive tegns Unicode-kodepunktværdi udtrykt i UTF-8: $$\text{curcs}=\texttt{hashfunction}\text{(UTF-8 text for Unicode value of active character)}$$3. beregn den heltalsmæssige tokerværdi: $$\text{active character token} = \text{curcs} + 2^{29} - 1$$

**Eksempler**

* 8-bit-motorer: tokenberegningen for det aktive tegn `~` (tegnkode 126) resulterer i $$\text{curcs} = 126 + 1 = 127$$, hvilket giver en tokerværdi på $$4095 + 127 = 4222$$.
* LuaTeX: tokenberegningen for det aktive tegn `~` resulterer i $$\text{curcs}=3186$$ hvilket giver en tokerværdi på $$3186 + 2^{29} - 1 = 536874097$$. LuaTeX-tokens bruger langt større heltalsværdier!

### Forstå kommandotokens

Ud over at behandle *individuelle* tegn kan TeX-motorer naturligvis behandle *sekvenser* af tegn kaldet *kommandoer* (eller mere korrekt, *kontrolsekvenser*). Traditionelt bruges `\` tegnet til at markere begyndelsen på en kommando, men det er blot en konvention — faktisk kunne ethvert tegn med kategorikode 0 (escape-tegnet) bruges i stedet.

TeX-motorer genkender to typer kommandoer, som kaldes *kontrolord* og *kontrolsymboler*:

* **kontrolord**: kommandoer, der er konstrueret af ét eller flere tegn, som har kategorikode 11;
* **kontrolsymboler**: enkelttegnskommandoer, hvor det pågældende tegns kategorikode *ikke* 11: såsom `\$`, `\#` eller `\\`.

**Bemærk**: TeX-primitiverne `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` og `\toksdef`  bruges også til at definere kontrolsekvenser, men i modsætning til almindelige makrodefinitioner er de resulterende kontrolsekvenser (kontrolord eller kontrolsymboler) *ikke ekspanderbare*—dem ser vi nærmere på nedenfor.

#### Hvordan beregnes kommandotokens?

Ligesom aktive tegn bruger TeX-motorer den anden type heltalstokenværdi til at repræsentere kommandoer: *kommandotokens*—husk, at aktive tegn også genererer kommandotokens, fordi de opfører sig som minimakroer.

Beregningerne, som 8-bit-motorer bruger til at oprette heltal for kommandotokens, kan findes i denne [Overleaf-artikel](/latex/da/dybtgaende-artikler/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#how-tex-calculates-token-values). Her sammenfatter vi de vigtigste trin i kommandotokenberegninger for LuaTeX — som er lidt forskellige, fordi LuaTeX skal behandle Unicode-tegnkodeværdier, der kan være betydeligt større end 8-bit-værdier; dog følger LuaTeX’s beregninger de samme generelle principper, som bruges af ældre 8-bit-motorer.

Efter at have registreret en indkommende kommando ignorerer TeX-motorer, inklusive LuaTeX, `\` tegnet: det bruges ikke i beregninger af kommandotokerværdier, men fungerer blot som en “kontakt”, der informerer en TeX-motor om, at den skal behandle en kommando. Kommandotokerværdien beregnes ved hjælp af den sekvens af (ét eller flere) tegn, som findes i kommandoens navn — LuaTeX beregner kommandotokens for kontrolsymboler og kontrolord ved hjælp af den samme algoritme:

1. beregn den mellemliggende heltalsværdi $$\text{curcs}$$ ved at anvende en såkaldt [hashfunktion](https://en.wikipedia.org/wiki/Hash_function) til den Unicode UTF-8-streng af tegn, der findes i kommandoens navn: $$\text{curcs}=\texttt{hashfunction}\text{(Unicode UTF-8 string of characters in command name)}$$3. beregn kommandotokerværdien, hvor $$\text{command token} = \text{curcs} + 2^{29} - 1$$

**Eksempler**

* for `\\` kommando (et kontrolsymbol) beregner LuaTeX $$\text{curcs}=94$$, hvilket resulterer i en tokerværdi for `\\` på $$94 + 2^{29} - 1 = 536871005$$.
* for `\vskip` primitiv kommando (et kontrolord) beregner LuaTeX $$\text{curcs}=3560$$, hvilket resulterer i en tokerværdi for `\vskip` på $$3560 + 2^{29} -1 = 536874471$$.
* for den brugerdefinerede makro `\mynewmacro` (et kontrolord) beregner LuaTeX $$\text{curcs} = 2971$$, hvilket resulterer i en tokerværdi for `\mynewmacro` på $$2971 + 2^{29} -1 = 536873882$$.

Når tokens er oprettet, kan de gemmes til senere brug via såkaldte *tokenlister* eller de kan straks sendes videre til yderligere behandling inde i TeX-motoren. At bruge heltalsværdier til at repræsentere tokens virker ikke blot på tværs af alle typer computerplatforme/operativsystemer, det er også en meget effektiv måde for TeX at lagre/behandle data på.

### Hvordan en TeX-motor identificerer tokentypen (kommando eller tegn)

Givet en bestemt heltals-tokerværdi $$T$$, kan en TeX-motor let afgøre om $$T$$ repræsenterer en kommando eller et tegn ved at teste om $$T$$ overstiger en bestemt $$\text{threshold value}$$—det $$\text{threshold value}$$ afhænger af TeX-motoren. Hvis $$T \geq \text{threshold value}$$ så $$T$$ er en kommandotoken, ellers $$T$$ er det en karaktertoken. Den $$\text{threshold value}$$ er $$4095$$ for 8-bit-motorer og $$2^{29}-1$$ (536.870.911) for LuaTeX. Knuth designede metoderne, der bruges i tokenberegningsformler, så hans TeX-motor og alle efterfølgende motorer baseret på hans kode/arkitektur hurtigt og let kan teste tokerværdier.

## Tokens kan opdeles (og konverteres tilbage til tekst)

Tokens (heltal) er den mekanisme, hvorigennem en TeX-motor “indkapsler” alt, hvad den behøver at registrere om et inputelement (tegn eller kommando). Der er dog tidspunkter, hvor en TeX-motor har brug for at vende tokeniseringsprocessen om — for at finde ud af, hvad der oprindeligt blev læst ind for at frembringe den tokerværdi — et enkelt tegn eller en sekvens af ét eller flere tegn, der danner navnet på en kommando:

* **for karaktertokens**: Ethvert karaktertoken kan opdeles i sine to bestanddele: tegnkoden og den tilsvarende kategorikode, der blev tildelt dette tegn *på det tidspunkt, hvor det oprindeligt blev læst ind*. Som alle TeX-motorer vil LuaTeX ikke ændre denne oprindelige kategorikodetildeling, men vil bruge den under videre intern behandling.
* **for kommandotokens:** Disse er lidt mere detaljerede, men hvis du ser på LuaTeX’s beregning af kommandotokens, inklusive tokens for aktive tegn, ser du, at de følger et mønster: $$\text{command token} = \text{curcs} + 2^{29} -1$$

hvor $$\text{curcs}$$ beregnes i henhold til den type kommandotoken, der genereres: aktivt tegn, kontrolsymbol eller kontrolord. Variablen $$\text{curcs}$$ er en *ekstremt* vigtig komponent i en TeX-motors indre funktioner: givet en hvilken som helst kommandotoken-værdi (heltal) kan LuaTeX meget let udtrække værdien af $$\text{curcs}$$ fra den kommandotoken ved hjælp af $$\text{curcs} = \text{token value} - (2^{29} -1)$$.

### Hvorfor er $$\text{curcs}$$ så vigtig?

Den interne TeX-variabel $$\text{curcs}$$ (**nuvæ**rende **c**kontrol **s**sekvens) er en yderst vigtig komponent i en TeX-motors indre “under motorhjelmen”-funktioner. Selvom du ikke vil, og ikke kan, bruge eller tilgå den direkte i din kode, $$\text{curcs}$$ spiller en afgørende rolle, fordi TeX-motorer bruger den aktuelle værdi af $$\text{curcs}$$ som indeks i interne tabeller, der gemmer data om enhver kommando, som motoren i øjeblikket kender. Disse tabeller gemmer oplysninger om en kommandos aktuelle betydning: hvad gør den, eller hvad repræsenterer den, og derudover registrerer de den sekvens af tegn, der oprindeligt blev brugt til at beregne den $$\text{curcs}$$ værdi. Ved at udtrække værdien af $$\text{curcs}$$ fra en kommandotoken kan en TeX-motor bestemme navnet, dvs. den menneskelæselige tekst, der svarer til enhver (kommando)token, hvilket gør den i stand til at udføre de token-til-tekst-konverteringer, som er et nøgleaspekt af `\directlua`’s funktion.

### Konvertering af heltalstokens tilbage til tegn eller tegnsekvenser (kommandonavne)

Vi har set, at TeX-motorer konverterer inputtegn eller tegnsekvenser til heltals-tokerværdier, men der er tilfælde, hvor en TeX-motor har brug for at *vende om* den proces — for at outputte den menneskelæselige tekst, der oprindeligt blev brugt til at skabe disse heltals-tokerværdier; for eksempel:

* at skrive fejl- eller advarselsmeddelelser til skærmen eller `.log` fil;
* at outputte TeX/LaTeX-kode til en tekstfil via `\write` kommandoen;
* når man konverterer en sekvens af tokens til tekst inde i `\directlua` (som vi snart skal se!)

#### Konvertering af karaktertokens til tekst

Som nævnt beregnes tokens for ikke-aktive tegn ved hjælp af et inputtegns kategorikode og tegnkode (Unicode-værdi). LuaTeX bruger formlen:

$$\text{character token} = (2^{21} \times \text{category code}) + (\text{Unicode value})$$

Det er en ligetil programmeringsopgave at splitte heltals- $$\text{character token}$$ værdien for at få dens bestanddele tegnkode ($$\text{Unicode value}$$) og $$\text{category code}$$.

#### Konvertering af kommandotokens til tekst

Alle TeX-motorer gemmer navnet (sekvensen af tegn) på hver kommando, de “kender til”: uanset om den kommando er en brugerdefineret makro eller en indbygget primitiv — lagringen af primitive kommandonavne finder sted, når TeX-motoren starter op, længe før den begynder at behandle din kode. For brugerdefinerede kommandoer (makroer) gemmes navnet på den makro (minus det indledende `\`) som en del af makrodefinitionsprocesserne inde i TeX-motorer.

Når en TeX-motor har brug for at tilgå eller outputte den menneskelæselige tekst, som en heltals kommandotoken oprindeligt blev beregnet fra, vil den først bestemme $$\text{curcs}$$ værdien for den token; i LuaTeX $$\text{curcs} = \text{token} - (2^{29} -1$$). Ved at bruge værdien af $$\text{curcs}$$ udtrukket fra en kommandotoken kan en TeX-motor få adgang til en intern datastruktur kaldet *strengpuljen* for at bestemme sekvensen af menneskelæselige tegn, der oprindeligt blev brugt til at beregne netop den værdi for $$\text{curcs}$$ og dermed den tilsvarende kommandotoken.

Som vi vil se, er disse tokenbehandlingsaktiviteter — konvertering af tegnsekvenser til heltals-tokerværdier og konvertering af heltals-tokerværdier tilbage til tegnsekvenser (“de-tokenisering”) — de *grundlæggende mekanismer* der bruges inde i `\directlua`.

## Tokenlister

Når en TeX-motor læser input, genererer karakter- og kommandotokens (og behandler dem), kan den støde på visse kommandoer, som instruerer motoren til (midlertidigt) at stoppe med at sende tokens videre til yderligere behandling, men i stedet gemme dem til senere brug. Det mest almindelige eksempel er at definere en makro ved hjælp af en af makrodefinitionskommandoerne `\def`, `\edef`, `\gdef` eller `\xdef`—LaTeX-kommandoer såsom `\newcommand` er makroer, der giver yderligere funktionalitet bygget op omkring lavniveauprimitiver, som i sidste ende udfører den egentlige makrodefinitionsproces. En makro kan betragtes som det navn, der gives til en bestemt liste af gemte tokens: en tokenliste.

TeX-motorer gør *udstrakt* brug af tokenlister, især [midlertidige interne lister](/latex/da/dybtgaende-artikler/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) brugt til interne behandlingsformål. Hver TeX-motor tilbyder også kommandoer på brugerniveau til at oprette tokenlister, som gemmes væk til, når brugeren eller TeX-motoren selv har brug for dem. Antallet af kommandoer til oprettelse af tokenlister (indbyggede primitiver) varierer afhængigt af TeX-motoren, men de har alle et fælles minimumssæt, som understøttes af hver motor, såsom `\toks` primitiven.

I praksis er en tokenliste bare en gemt sekvens af heltalsværdier:

* inputtet læses for at generere (beregne) individuelle tokens, der repræsenterer et tegn eller en kommando;
* hver token gemmes derefter væk og bevarer den rækkefølge, hvori tokens blev genereret fra inputtet.

TeX-motorer gemmer tokenlister ved hjælp af en datastruktur kaldet en [kædet liste](https://en.wikipedia.org/wiki/Linked_list) (den enkeltkædede type). Læsere, der ønsker at vide mere om tokenlister, inviteres til at læse Overleaf-artiklen [Hvad er en TeX-tokenliste?](/latex/da/dybtgaende-artikler/54-what-is-a-tex-token-list.md) som bruger en analogi til at opbygge begreberne/idéerne bag en tokenliste. En dybtgående udforskning af TeX’s tokenlister, og hvordan de bruges i makrobehandling, kan findes i Overleaf-artikelserien [Hvordan virker TeX-makroer egentlig?](/latex/da/flere-emner/01-a-six-part-series-how-do-tex-macros-actually-work.md)

#### En tokenliste i grafisk form

Den følgende grafik viser en LuaTeX-genereret tokenliste med tilsvarende tokerværdier produceret ud fra følgende input

`Hi, \TeX! \hskip 5bp`

Hvis vi for eksempel definerer `\mymacro` as `\def\mymacro{Hi, \TeX! \hskip 5bp}` definitionen af `\mymacro` ville blive gemt i hukommelsen ved hjælp af en tokenliste som denne:

![](/files/a6bca2912dc300ef67b5345e18b57eb154a14c60)

Tokenlisten er en sekvens af kædede elementer kaldet *noder*, navnet på en lille del af LuaTeX’s hukommelse, der er reserveret til at holde hvert element i listen (som individuelle led i en kæde). Hver knude indeholder en heltals-tokerværdi og hukommelsesadressen til den *næste* knude i kæden, hvilket danner en datastruktur kaldet en [kædet liste](https://en.wikipedia.org/wiki/Linked_list)enkeltkædet liste. Den sidste node angiver slutningen på listen ved hjælp af en særlig “nulværdi” for den næste node — fordi der ikke er en.

**Bemærkninger:**

* Af praktiske grunde har vi inkluderet adressen for hver enkelt node, men i praksis gemmes de data ikke i tokenlisteknuderne; kun adressen til den *næste node* næste knude er nødvendig for at opbygge TeX-motorers tokenlister.
* Den anden kolonne i grafikken med titlen “Hvad hver token betyder” viser en række grå bokse med oplysninger om tokenen indeholdt i hver node: disse er udelukkende til information og *bliver ikke* udgør ikke en del af de faktiske data, der gemmes i tokenlisten.

Her er en tabel over tokerværdierne indeholdt i tokenlisten vist ovenfor:

|                  |                     |                                                                          |                |
| ---------------- | ------------------- | ------------------------------------------------------------------------ | -------------- |
| **Inputelement** | **Type af input**   | <p><strong>Kategorikode</strong><br><br><strong>(hvis tegn)</strong></p> | **Tokerværdi** |
| H                | tegn                | 11                                                                       | 23068744       |
| i                | tegn                | 11                                                                       | 23068777       |
| ,                | tegn                | 12                                                                       | 25165868       |
|                  | tegn                | 10                                                                       | 20971552       |
| \TeX             | kommando (makro)    |                                                                          | 536871539      |
| !                | tegn                | 12                                                                       | 25165857       |
|                  | tegn                | 10                                                                       | 20971552       |
| \hskip           | kommando (primitiv) |                                                                          | 536874247      |
| 5                | tegn                | 12                                                                       | 25165877       |
| b                | tegn                | 11                                                                       | 23068770       |
| p                | tegn                | 11                                                                       | 23068784       |

**Bemærk:** Vores oprindelige inputtekst har et efter `\hskip` kommandoen, men der er ingen token, der repræsenterer det tegn i tokenlisten. Det tegn blev absorberet af LuaTeX’s inputscannings- (læse-) proces, fordi det blev brugt til at afslutte LuaTeX’s søgning efter tegn, der udgør `\hskip` kommandoen.

## Sådan fungerer \directlua egentlig

Nu hvor vi har udforsket tokens, tokenlister og konvertering af tokens til tekst, er den næste udfordring at forstå TeX-motorens begreb om token *udvidelse*.

Som nævnt, `\directlua{⟨code⟩}` kan blive bedt om at behandle `⟨code⟩` som indeholder både Lua- og TeX/LaTeX-kode, men LuaTeX’s indbyggede Lua-sprogtolk forstår ikke TeX eller LaTeX: så hvordan kan dette fungere? Hvordan er det muligt for `⟨code⟩` at indeholde TeX/LaTeX-instruktioner uden fuldstændigt at forvirre Lua-fortolkeren med kommandoer, den ikke forstår? For eksempel bruger følgende `\directlua` kommando kun TeX-makroer, men den virker:

```
\def\aa{tex}
\def\bb{.}
\def\cc{print}
\def\dd{("Hej")}
\directlua{
   \aa\bb\cc\dd
}
```

Denne `\directlua` kommando resulterer i, at LuaTeX sætter `Hej` men hvorfor og hvordan virker dette, når Lua-sproget ikke forstår TeX-makroer?

Svaret findes i den tidligere beskrivelse, vi lånte fra [LuaTeX Reference Manual](http://www.pragma-ade.com/general/manuals/luatex.pdf) men vi kan betragte det som om `\directlua{⟨code⟩}` fungerer ved, at LuaTeX i første omgang “forbehandler” `⟨code⟩` før noget overhovedet sendes til Lua-fortolkeren. Denne “forbehandling” — dvs. hvad den egentlig betyder og dens konsekvenser for din `⟨code⟩`— er det næste emne, vi vil behandle for at hjælpe læsere, der gerne vil udnytte styrken og fleksibiliteten i `\directlua`.

### Sådan behandler LuaTeX \directlua: Et første blik

For at opbygge vores forståelse af `\directlua`’s “forbehandlings”-aktiviteter kan vi begynde med følgende forenklede diagram, som giver et overblik over, hvad der sker. Det `⟨code⟩` givet til `\directlua{⟨code⟩}` konverteres først til tokens ved hjælp af de processer og beregninger, der er diskuteret ovenfor; den sekvens af tokens gemmes i en tokenliste. Når tokenlisten er opbygget, konverteres hver token i listen tilbage til sin tekstlige repræsentation: teksten, der produceres af hver token — karaktertoken eller kommandotoken — kombineres (sammenkædes) for at skabe en enkelt streng af kode, som sendes videre til Lua-fortolkeren til udførelse.

![](/files/ee4fa1b198023523dbc77715515049aed26db6ea)

Men vent, hvad skulle meningen være med at gå fra tekst til tokens og konvertere disse tokens direkte tilbage til tekst? Du bliver måske ikke overrasket over at høre, at der ja, er en ekstra og afgørende proces, som vi ikke har inkluderet i denne grafik: *tokenudvidelse*. Hver token, der frembringes af teksten i din `⟨code⟩` underkastes en form for “inspektion”, hvor LuaTeX anvender en test for at se, om denne token repræsenterer en kommando, som hører til delmængden kendt som *udvidelige kommandoer*. Hvis den gør, filtrerer LuaTeX den kommando fra ved *at fjerne* den fra din `⟨code⟩` og *og erstatter den* med resultatet/resultaterne af en proces, som TeX-motorer kalder *tokenudvidelse*.

### Sådan behandler LuaTeX \directlua: Et andet blik (på udvidelse)

TeX’s udvidelsesmekanisme er en kernekomponent i alle TeX-baserede satsningsmotorer, fordi hver enkelt i sidste ende er afledt af (eller baseret på) Knuths oprindelige kildekode og design af TeX. Begrebet udvidelse er imidlertid vanskeligt at forklare i et kortfattet, men stadig tilgængeligt sprog, fordi udvidelse i praksis er en “paraply”-betegnelse, der bruges til at beskrive en enkelt proces — men en proces, der producerer en række forskellige uddata. Disse varierende udfald er en følge af det noget eklektiske sæt kommandoer, som udvidelse kan anvendes på, så du kan betragte det sådan, at hver udvidelig kommando har en bestemt “udvidelsesadfærd”.

Som en *første tilnærmelse* til at forstå udvidelse kan vi sige, at udvidelse af en token (kommando) betyder *at fjerne* at fjerne denne kommando (token) fra TeX’s aktuelle input og *erstatte* erstatte den med en sekvens af tokens, som er resultatet af udførelsen af netop den udvidelige kommando — dvs. at erstatte den oprindelige token med resultaterne/konsekvenserne af dens udvidelse *adfærd*. Denne første “definition” af udvidelse — forstået som at generere nye tokens, som TeX skal læse — er dog ikke helt korrekt for alle udvidelige kommandoer, men den er god nok som udgangspunkt.

For at give et enkelt eksempel: TeX-primitive `\jobname` er en udvidelig kommando, og dens *udvidelse* er en sekvens af karaktertokens, som repræsenterer navnet på den primære TeX-inputfil. Hvis TeX beslutter at udvide en `\jobname` kommando (token), bliver den *fjernet* fra TeX’s aktuelle inputkilde og *erstattet* af den sekvens af karaktertokens, den genererer — som TeX derefter fortsætter med at læse/behandle.

Inden for `\directlua`, efter at en udvidelig token er blevet behandlet (fjernet) og erstattet af nye tokens, vil LuaTeX fortsætte med at læse disse nye tokens, som den netop har sat i stedet — men nogle af disse nye tokens kan også være udvidelige. Fordi `\directlua` udfører den såkaldte *fulde udvidelse*, vil LuaTeX læse disse nye tokens og igen gennemgå udvidelsesprocessen for at udvide (fjerne) eventuelle nye (udvidelige) tokens — denne udvidelsesproces fortsætter, indtil der ikke er flere udvidelige tokens tilbage. Der er dog to vigtige undtagelser fra denne regel om at “blive ved med at udvide”, og dem vil vi begge diskutere nedenfor:

* ved hjælp af konstruktionen `\the\toks`;
* bevidst forhindring (undertrykkelse) af udvidelse for en eller flere valgte tokens.

Som nævnt dækker vores arbejdsdefinition (første tilnærmelse) til at forstå udvidelse ikke hele spektret af udvidelsesadfærd, som demonstreres af delmængden af udvidelige kommandoer. For eksempel genererer nogle udvidelige kommandoer ikke tokens på den måde, som `\jobname` gør, men de kan måske:

* “filtrere” tokens fra inputtet: en TeX-motors betingede kommandoer (`\if`, `\ifcat`, `\ifnum`, `\ifdim`, `\ifodd`, `\ifvmode`, …) er udvidelige. Deres udvidelsesadfærd er en form for “tokenfiltrering” — betingelser kan bruges i `\directlua`.
* “jonglere” med tokens i inputtet:  [`\expandafter` kommandoen](/latex/da/dybtgaende-artikler/03-a-six-part-article-series-on-expandafter-tex-tokens-and-expansion.md) er udvidelig og ændrer den rækkefølge, hvori to tokens udvides.
* forhindre udvidelse: de udvidelige kommandoer `\noexpand` og `\unexpanded` undertrykker udvidelse af kommandotokens i inputtet.
* konvertere tegnsekvenser i inputtet til kommandotokens: `\csname … \endcsname.`
* konvertere interne størrelser til en sekvens af karaktertokens: `\number` og `\the` er udvidelige kommandoer, der genererer en sekvens af karaktertokens, som repræsenterer værdien af en intern størrelse.
* konvertere kommandotokens til karaktertokens: `\string` og `\detokenize` er udvidelige kommandoer, som konverterer deres argumenter til en sekvens af karaktertokens med kategorikode 12. Bemærk, at `\detokenize` adskiller sig fra `\string`: `\detokenize` kan behandle flere tokens og indsætter et mellemrumstegn med kategorikode 10 efter behandling af kommandotokens oprettet ud fra *kontrolord*. I praksis `\detokenize` tilføjer et afsluttende mellemrumstegn efter kommandonavnet — vi vil se nogle eksempler senere i artiklen.

#### Forfining af vores “definition” af udvidelse

Vi kan nu generalisere vores definition og sige, at udvidelse af en kommando (token) indebærer *fjernelse* af denne kommando (token) fra TeX’s aktuelle inputkilde og *og erstatter den* erstatning *token-operation(er)* udført af den kommando. I det væsentlige får udvidelsesprocessen en udvidelig kommando til at udføre en form for “operation” på tokens i TeX’s aktuelle input, som påvirker antallet af tokens eller deres adfærd, som TeX efterfølgende vil læse — den præcise karakter af denne “operation” afhænger af, hvilken kommando der udvides. Alle makroer og aktive tegn er udvidelige, men kun et lille antal af en TeX-motors indbyggede kommandoer (primitive) klassificeres som udvidelige — listen over udvidelige kommandoer afhænger af den TeX-motor, du bruger.

Hver ny TeX-motor arver de primitive kommandoer, der er indbygget i dens forfader(e) — den/det tidligere generations TeX-motor(er), som den er afledt af — og nogle af disse arvede primitive kommandoer vil være udvidelige. Selvfølgelig kan en ny TeX-motor vælge ikke at implementere nogle af de primitive kommandoer, der findes i de tidligere motorer, eller at ændre deres adfærd for at passe til den nye motors behov. Derudover implementerer nye TeX-motorer typisk ekstra primitiver for at understøtte deres egen forbedrede funktionalitet — nogle af disse kan også være udvidelige. Derfor vil antallet af tilgængelige udvidelige kommandoer variere afhængigt af den TeX-motor, du bruger — LuaTeX har en ganske stor samling af dem.

En anden vanskelighed ved at forklare/forstå udvidelse, og måske den virkelige udfordring, er at vide præcis *hvornår* en TeX-motor faktisk er — eller ikke er — i færd med at udføre udvidelsesprocessen. Det er et stort og komplekst emne, fordi udvidelse er dybt indlejret i TeX-motorernes indre virkemåde: vi har ikke plads til at behandle dette i detaljer ud over brugen af udvidelse i `\directlua`.

### Sådan behandler LuaTeX \directlua: Et afsluttende blik

Det følgende diagram opsummerer `\directlua` forbehandlingsaktiviteterne, der finder sted inde i selve LuaTeX-motoren. I dette diagram viser vi også to lavniveau-funktioner (interne) i LuaTeX, som faktisk udfører arbejdet: `scan_toks()` og `tokenlist_to_cstring()`. Disse funktioner er skrevet i C-sproget og befinder sig dybt inde i den eksekverbare LuaTeX-software: de er en del af LuaTeX’s indre maskineri og er ikke *direkte* tilgængelige for din TeX/LaTeX-kode.

![](/files/50c310adddb3126d340241c968209ed95f5a311c)

Den følgende beskrivelse af `\directlua ⟨code⟩`’s forbehandlingsaktivitet opsummerer diagrammet ovenfor.

1. Sekvensen af tegn i din ⟨code⟩ behandles af `scan_toks()`. Dens formål er at læse din ⟨code⟩ tegn for tegn for at generere karaktertokens og kommandotokens. Fordi den opretter tokens, er kategorikoden, der er tildelt hvert tegn i ⟨code⟩ på det tidspunkt, hvor det læses ind, ekstremt vigtig.
2. Under `scan_toks()`’s tokenbehandling (generering) udvides enhver udvidelig kommando (token) *medmindre* forhindres via kommandoer som `\protected` (makrodefinitioner), `\noexpand`, `\unexpanded` osv. Aktive tegn (kategorikode 13) udvides også (medmindre det forhindres).
3. Tokenstrømmen, der oprettes af `scan_toks()` bygges ind i en lang tokenliste — tokens i denne liste inkluderer dem, der er frembragt ved, at udvidelse anvendes på udvidelige kommandoer (såsom makroer) i din `⟨code⟩`. Bemærk også, at `scan_toks()` *ikke* udløser eller får ikke udførelse af nogen token, der repræsenterer en ikke-udvidelig kommando: sådanne ikke-udvidelige tokens sendes blot videre for at blive indarbejdet i den tokenliste, der er under opbygning.
4. Når tokenlisten er færdig, og al udvidelsesaktivitet er afsluttet, behandles tokenlisten af en anden funktion kaldet `tokenlist_to_cstring()` som konverterer hver token i den endelige tokenliste tilbage til dens tekstlige repræsentation. Dette genererer en tekststreng, som er den Lua-kode, der skal sendes videre til Lua-fortolkeren. For at kunne udføres korrekt skal den streng indeholde syntaktisk korrekt Lua-kode.
5. Luas behandling af den kode sker i to trin:
6. LuaTeX’s indbyggede Lua-fortolker parser og “kompilerer” den Lua-kode, der er genereret i de foregående trin. Hvis denne parsing/kompilering mislykkes, vil Lua-fortolkeren generere fejl (såsom syntaksfejl) — disse fejl kan få LuaTeX-kørslen til at fejle, medmindre du valgte at bruge `--interaction=nonstopmode` i kommandolinjen.
7. Hvis parsing/kompilering lykkes, udfører Lua-fortolkeren koden, der blev kompileret i trin (5a).

I det væsentlige er `scan_toks()` funktionen kernen i LuaTeX’s forbehandlingsaktiviteter: dens hovedopgave er at udvide alle udvidelige TeX/LaTeX-kommandoer, der findes i teksten i din `⟨code⟩` og konstruere en tokenliste ud fra alt, hvad den har behandlet. Vi understreger igen, at `scan_toks()` *ikke udfører ikke-udvidelige kommandoer* (tokens): den *gemmer* disse tokens i den tokenliste, den er i færd med at konstruere. Når den er færdig, konverteres tokenlisten efterfølgende *tilbage til en tekstlig repræsentation* af `tokenlist_to_cstring()`— en tokenliste er et rent TeX-begreb, som er fuldstændig fremmed for en Lua-fortolker, og derfor er der behov for at konvertere den til tekst, så den bliver til Lua-kode, der kan sendes videre til Lua-fortolkeren.

## Udvidelse som en grænseflade for programmeringssprog

Man kan tænke på `\directlua`’s udvidelsesproces som en mekanisme, eller grænseflade, til at overføre data/oplysninger fra “TeX-verdenen” over i “Lua-verdenen”: en metode til, at TeX-sproget kan kommunikere data til Lua-sproget. For eksempel kan TeX-kode som `\number\count75` bruges til at overføre en værdi fra “TeX-verdenen”, der er gemt i tællerregister 75, over til den hele Lua-variabel x:

```
\count75=1564 % Data eksisterende i "TeX-verdenen"
\directlua{
   local x=\number\count75 \space % Overfør TeX-data til "Lua-verdenen"
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" og y = "..y)
}
```

Dette genererer Lua-koden

```
 local x=1564 tex.print("x= "..x) local y = (2*x-65)/5 tex.print(" og y = "..y)
```

**Bemærk**: Vi tilføjede `<space>\space` efter `\number\count75` for at sikre, at et mellemrumstegn blev bevaret mellem `1564` og `tex.print`— det er ikke strengt nødvendigt her, fordi Lua stadig ville fortolke koden korrekt, hvis vi udelod det. Mellemrumstegnet, der umiddelbart følger efter `\count75` absorberes under den proces, som TeX-motorer bruger til at lede efter numeriske værdier — her den værdi, der leveres til `\count`. Mellemrumstegnet efter `75` bruges til at afslutte LuaTeX’s søgning efter digit-sekvensen `75` og absorberes fra inputtet.  `\space` makroen udvides for at levere det mellemrumstegn, der er nødvendigt for at adskille teksten `1564` og `tex.print`.

Ved at bruge koden ovenfor vil LuaTeX sætte

`x= 1564 og y = 612.6`

Her opnås mekanismen til “dataoverførsel” ved hjælp af `\number`: en udvidelig kommando, som i dette tilfælde instruerer TeX i at hente den værdi, der er gemt i `\count` register `75` og fra denne værdi (`1546`) generere en række karaktertokens, én karaktertoken for hvert ciffer, hvilket resulterer i en tokensekvens for cifrene `1`, `5`, `6` og `4`. Disse 4 karaktertokens indgår i den hovedtokenliste, som opbygges af `\directlua` og konverteres efterfølgende tilbage til deres tekstlige repræsentation, når tokenlisten konverteres til tekst. Det er uden tvivl en meget snørklet vej at gå fra `\count75` registerværdi gemt inde i LuaTeX til cifre bestemt til Lua-kode, men i sidste ende virker det.

**TIP:** Hvis du vil inspicere resultaterne af LuaTeX’s udvidelsesaktiviteter, kan du skrive kode som denne:

```
\directlua{
   local foo=[[local x=\number\count75
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" og y = "..y)]]
   print(foo)
}
```

I dette eksempel bruger vi lang-klammer-metoden til at oprette en strengvariabel `foo` hvis formål er at indeholde strengen af Lua-kode, der genereres ved udvidelse af alt mellem `[[` og `]]`. Den streng skrives ud til konsollen via Lua-funktionskaldet `print(foo)`.

På Overleaf kan du se lignende resultater ved at skrive indholdet af `foo` til `.log` fil ved hjælp af LuaTeX Lua-funktionen `texio.write()`:

```
\directlua{
   local foo=[[local x=\number\count75
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" og y = "..y)]]
   texio.write(foo)
}
```

## Tokens i \directlua-tokenlisten: ikke-udvidelige tokens og ikke-udvidede tokens

Vi har bemærket, at `\directlua{⟨code⟩}` udfører *fulde udvidelse* af din `⟨code⟩`: den fjerner og udvider alle udvidelige kommandoer, indtil der kun er ikke-udvidelige tokens tilbage. Sekvensen af tokens, der oprettes af `\directlua`’s behandling (i `scan_toks()` funktionen) kædes sammen for at danne en tokenliste, hvis enkelte tokens vil blive konverteret tilbage til tekst for at blive sendt videre til Lua.

Men vi har endnu ikke behandlet den sidste del af denne historie, fordi vi er nødt til at overveje de to “klasser” af kommandotoken, som kan nå frem til tokenlisten, der bygges inde i `\directlua`: vi vil omtale dem som *forkortede kommandotokens* og *ikke-udvidede* tokens:

* **forkortede kommandotokens**: Denne type kommandotoken opstår fra kontrolsekvenser, der er defineret ved hjælp af en af TeX-primitiverne `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` og `\toksdef`. Disse primitive kommandoer bruges til at definere kontrolsekvenser, som repræsenterer en numerisk værdi — de resulterende kontrolsekvenser er *ikke* udvidelige.
* **ikke-udvidede tokens**: Denne tokentype opstår fra kommandoer, som normalt ville blive udvidet, men `\directlua` har enten:
* blevet udtrykkeligt instrueret *ikke* til at udvide dem; for eksempel undertrykkelse af udvidelse ved kommandoerne `\noexpand` eller `\unexpanded`— vi vil om lidt forklare, hvordan dette gøres;
* indsatte tokens ved at behandle sekvensen `\the\toks` (mere om det nedenfor).

### To “grupper” af tokens i en \directlua-tokenliste

Baseret på vores diskussioner kan vi sige, at tokens, der findes i tokenlisten, som opbygges under første trin af `\directlua`’s forbehandling (i `scan_toks()` funktionen), falder i to grupper:

1. *iboende ikke-udvidelige* tokens

* enhver token, der repræsenterer en ikke-aktiv *tegn*;
* enhver token, der repræsenterer en ikke-udvidelig *primitiv* *kommandoen*;
* enhver token, der repræsenterer en *forkortet kommando* (disse er ikke udvidelige, se nedenfor).

3. *ikke-udvidede* tokens:

* enhver token, der repræsenterer en udvidelig kommando, hvis udvidelse blev *undertrykt* (eller undgået) under `\directlua`’s forbehandling.

#### Forkortede kommandotokens: oprettelse af ikke-udvidelige kommandoer

Som nævnt stiller TeX-motorer et sæt primitiver (indbyggede kommandoer) til rådighed, som kan bruges til at konstruere *ikke-udvidelige* kontrolsekvenser (angivet her ved `⟨command⟩`). Disse primitiver har formen:

* `\chardef ⟨command⟩ = ⟨numeric value⟩`
* `\mathchardef ⟨command⟩ = ⟨numeric value⟩`
* `\countdef ⟨command⟩ = ⟨numeric value⟩`
* `\dimendef ⟨command⟩ = ⟨numeric value⟩`
* `\skipdef ⟨command⟩ = ⟨numeric value⟩`
* `\muskipdef ⟨command⟩ = ⟨numeric value⟩`
* `\toksdef ⟨command⟩ = ⟨numeric value⟩`

hvor `⟨numeric value⟩` er en heltalsværdi, der passer til hver kommando.

Her vil vi kort gennemgå brugen af `\chardef` for at demonstrere den vigtigste egenskab ved disse primitiver — at de producerer en `⟨command⟩` der ikke er udvidelig. Du kan bruge ``\chardef\mydollar=`\$`` til at oprette kontrolsekvensen `\mydollar` og bruge den til at sætte en `$`:

`Jeg betalte \mydollar30.`

Dette vil sætte `Jeg betalte $30.` Kontrolsekvensen `\mydollar` oprettet af `\chardef` er ikke udvidelig, som vi kan se af følgende eksempel:

```
\chardef\mydollar=`\$
\directlua{
   local x =[[Jeg betalte \mydollar30.]]
   texio.write(x)
}
```

Hvilket producerer følgende tekst i `.log` fil

`Jeg betalte \mydollar 30.`

Dette viser `\mydollar` blev *ikke* udvidet under `\directlua`’s forbehandling. Mellemrumstegnet, der vises efter `\mydollar` tilføjes, når et kommandotoken konverteres til sin repræsentation som tekst.

Når du bruger `\chardef` til at oprette en kontrolsekvens, resulterer TeX’s interne klassifikation af den kontrolsekvens (kommando) i, at den bliver *ikke-udvidelige* hvilket er en meget anderledes adfærd sammenlignet med kontrolsekvenser defineret af en af makrodefinitionskommandoerne: \def, \edef, \gdef eller \xdef. Som nævnt ovenfor undersøger `\directlua` hver indkommende kommandotoken for at kontrollere udvidelighed. Hvis en kommandotoken ikke er udvidelig, går den direkte videre til tokenlisten, og dens tekstlige repræsentation vil senere dukke op igen i strengen af Lua-kode, der opstår, når tokens i tokenlisten konverteres tilbage til deres tekstlige form.

**Korte noter om plain TeX vs. LaTeX**

Historisk set definerede Knuths oprindelige plain TeX de almindeligt anvendte kontrolsymboler `\%`, `\&`, `\#` og `\$` ved hjælp af `\chardef`— ikke ved hjælp af en af de standard makrodefinitionskommandoer `\def`, `\edef`, `\gdef` eller `\xdef`. For eksempel:

```
   \chardef\#=`\#
   \chardef\$=`\$
   \chardef\%=`\%
   \chardef\&=`\&
```

Den mærkelige `` `\ `` syntaks er en TeX-metode til at få den numeriske værdi af tegnkoden. I det gamle plain TeX-system er disse kontrolsymboler ikke udvidelige (på grund af `\chardef`) men LaTeX (eller pakker) kan redefinere dem som *makroer* for at give forbedret funktionalitet — det ville gøre dem udvidelige, så det kan være vigtigt at være opmærksom på dette.

**Hvordan påvirker dette \directlua?**

Lad os sammenligne resultatet af følgende kode kørt under plain TeX og LaTeX. For enkelheds skyld skriver vi resultaterne til `.log` filen ved hjælp af LuaTeX’s Lua-API-funktion `texio.write()`.

```
\directlua{
   local x=[[\$150 for the "\#1" produkt---20\%! mere end dets konkurrent, Widget \& Co.]]
   texio.write(x)
}
```

Når denne kode køres med **plain TeX** får vi følgende output i `.log` filen, som viser resultatet af eventuelle udvidelser:

```
\$150 for the "\#1" produkt---20\%! mere end dets konkurrent, Widget \& Co.
```

Det er tydeligt, at under plain TeX blev ingen af kontrolsymbolerne`\$`, `\#`, `\%` eller `\&` udvidet — fordi de alle er oprettet ved hjælp af `\chardef`.

Når man kører den kode med **LaTeX** dokumentet:

```
\documentclass{article}
\begin{document}
   \directlua{local x=[[\$150 for the "\#1" produkt---20\%! mere end dets konkurrent, Widget \& Co.]] texio.write(x)}
\end{document}
```

får vi følgende output i `.log` fil

```
\protect \TU\textdollar 150 for the "\#1" produkt---20\%! mere end dets konkurrent, Widget \& Co.
```

Det er tydeligt, at kørsel i LaTeX giver et andet resultat end plain TeX, fordi under LaTeX er kommandoen `\$` blevet udvidet, hvilket viser, at den er en makro.

**Bemærk:** I både plain TeX og LaTeX `\directlua` behandlede ikke nogen af kontrolsymbolerne fuldt ud `\%`, `\&`, `\#` og `\$` for at generere det tilsvarende tegn. Under den udvidelsesproces, der udføres af `\directlua` passerer tokens, der repræsenterer disse kontrolsymboler — eller, for LaTeX, deres udvidelse — direkte videre til den hovedtokenliste, der er under opbygning.

**Bemærk:** Kontrolsymboler dannes af et enkelt tegn, der ikke har kategorikode 11, såsom `\#`. Når et token, der repræsenterer et kontrolsymbol, konverteres tilbage til sin tekstlige repræsentation, indsætter TeX-motorer ikke et mellemrumstegn efter denne tekst. Denne særlige behandling af kontrolsymboler er en indbygget regel for, hvordan TeX-motorer fungerer.

### Ikke-udvidede tokens: undertrykkelse af udvidelse

`\directlua`’s forbehandling er et eksempel, hvor en TeX-motor udfører ekspansion, men du måske vil *forhindre* at ekspansion anvendes på én eller flere tokens, som ellers ville blive ekspanderet. Som et andet eksempel udfører LuaTeX (og alle TeX-motorer) en ekspansionsproces, der minder om den for `\directlua`, når de behandler `\write` kommandoen:

`\write filnummer {⟨materiale⟩}`

\write instruerer en TeX-motor i at skrive `⟨materiale⟩`—ofte indeholdende TeX/LaTeX-kommandoer—til en tekstfil (`filnummer`); eventuelle ekspanderbare kommandoer i `⟨materiale⟩` vil, medmindre det forhindres, blive ekspanderet, før `⟨materiale⟩` faktisk skrives til den fil.

Som du måske forventer, tilbyder TeX-motorer kommandoer til at undertrykke eller styre ekspansion:

* `\noexpand⟨token⟩`: forhindrer ekspansion af det enkelte `⟨token⟩`;
* `\unexpanded{⟨materiale⟩}`: forhindrer ekspansion af alle ekspanderbare kommandoer (tokens) i `⟨materiale⟩`. Det er i praksis en version med flere tokens af `\noexpand`;
* `\protected`: et præfiks, der føjes til makrodefinitioner, og som forhindrer ekspansion af den makro under bestemte omstændigheder (f.eks. under `\directlua`, `\write` eller `\edef`).

På trods af navne, der antyder noget andet, er både `\noexpand` og `\unexpanded` er *udvidelige kommandoer* og giver gode eksempler på at se en TeX-motors ekspansionsproces som udførelse af “tokenoperationer”: Operationen her er at forhindre ekspansion af ét eller flere efterfølgende tokens (kommandoer). Fordi `\noexpand` og `\unexpanded` begge er ekspanderbare kommandoer, fjernes og behandles (udføres) de under `\directlua`’s forbehandling, når den konstruerer tokenlisten ud fra din `⟨code⟩`.

#### \noexpand ⟨token⟩

`\noexpand ⟨token⟩` forhindrer ekspansion af det enkelte `⟨token⟩`. `\noexpand` i `\directlua` vil blive ekspanderet (fjernet fra inputtet) og erstattet af resultaterne af dets “ekspansionsadfærd”. Resultatet af at ekspandere `\noexpand` er at oprette et særligt (skjult) `⟨markørtoken⟩` som placeres foran det oprindelige `⟨token⟩` hvis ekspansion skal undertrykkes: dette `⟨markørtoken⟩` fungerer som et flag, der siger “ekspandér ikke det næste token”. Fordi `\directlua` udfører fuld ekspansion, vil den genbehandle alle tokens, som er resultatet af en ekspanderbar kommandos “ekspansionsadfærd”. Derfor, når ekspansionen af `\noexpand ⟨token⟩` er fuldført, går LuaTeX tilbage for at læse resultaterne og ser sekvensen med to tokens `⟨markørtoken⟩⟨token⟩` som får det oprindelige `⟨token⟩` til at passere uekspanderet ind i den tokenliste, der konstrueres af `\directlua`.

**Eksempel**

Hvis vi skriver

```
\directlua{
   local x= "\TeX"
}
```

den `\TeX` ekspanderes makroen til sine bestanddelstokens, hvilket i almindelig TeX medfører, at følgende tekst sendes til Lua (bemærk: Lua kan ikke behandle denne kode; den er blot et eksempel, der demonstrerer processen):

`local x = "T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX"`

Hvis vi *undertrykker* ekspansion af `\TeX` makroen ved brug af `\noexpand`

`\directlua{local x= "\noexpand\TeX"}`

produceres følgende Lua-kode (igen kan Lua ikke køre denne kode; den er blot et eksempel, der demonstrerer `\noexpand`):

`local x= "\TeX "`

På grund af `\noexpand`, `\directlua` vil ikke ekspandere `\TeX` men blot lade tokenværdien, der repræsenterer `\TeX` kommandoen, passere uskadt ind i den tokenliste, der opbygges under det første trin af `\directlua`’s forbehandling.

**Bemærk:** Mellemrumstegnet, der vises efter `\TeX` indsættes ved LuaTeXs efterfølgende konvertering af `\TeX` heltallige tokenværdi tilbage til dens tekstlige repræsentation (i `tokenlist_to_cstring()` funktionen).

#### \unexpanded{⟨materiale⟩}

`\unexpanded` er en ekspanderbar kommando, som undertrykker ekspansion af alle tokens dannet ud fra `⟨materiale⟩`. Som vi har bemærket, fjernes enhver ekspanderbar kommando, når en TeX-motor udfører ekspansion, *fjernet* fra inputtet og *erstattet* af resultaterne af dens “ekspansionsadfærd”; så hvad betyder det egentlig for `\unexpanded`? Normalt under *fulde udvidelse*, når ekspansionsprocessen for en bestemt kommando er afsluttet, fortsætter TeX-motoren med at læse/behandle eventuelle tokens, der opstår fra kommandoens “ekspansionsadfærd”—den skal ekspandere eventuelle producerede tokens yderligere. Men `\unexpanded` *omgår* al yderligere ekspansion: Her er, hvordan den gør det.

Inde i TeX-motoren konverterer `\unexpanded` kommandoen først tegnene og kommandoerne i `⟨materiale⟩` til en midlertidig tokenliste, der består af *ikke-udvidede* tokens. Når alle tokens er blevet oprettet og lagret i den midlertidige tokenliste, får `\unexpanded` kommandoen `\directlua` til *til at springe* tilbage for at læse og behandle dem—selv om \directlua udfører fuld ekspansion. I stedet passerer disse *ikke-udvidede* tokens direkte igennem og indgår i den primære tokenliste, der opbygges af `\directlua` (i `scan_toks()` funktionen). På denne måde konverteres alt i `⟨materiale⟩` til tokens, og ekspansionsprocessen springes over for dette sæt tokens. Funktionen af `\unexpanded{⟨materiale⟩}` ligner brugen af `\the\toks`, som vi diskuterer nedenfor.

**Eksempel**

`\unexpanded` producerer resultater på en måde, der ligner `\noexpand` bortset fra at den kan forhindre ekspansion af flere tokens; her er et eksempel:

```
\directlua{
   local x = "\unexpanded{\foo\bar\foobar}. But Lua can't process this code!"
}
```

som producerer følgende tekst som kode til Lua:

`local x = "\foo \bar \foobar . But Lua can't process this code!"`

**Bemærk**: Der er mellemrumstegn efter hvert kommandonavn. Disse er igen en følge af LuaTeXs efterfølgende konvertering af de uekspanderede tokens `\foo`, `\bar` og `\foobar` tilbage til tekst i `tokenlist_to_cstring()` funktionen.

#### \protected-makrodefinitioner

Den `\protected` kommandoen er et præfiks, der anvendes på en makrodefinition for at forhindre den makro i at blive ekspanderet, når TeX opbygger en ekspanderet tokenliste, såsom tokenlisten opbygget af `\directlua`’s forbehandling.

**Eksempel**

Antag, at du definerer følgende makroer med og uden brug af `\protected` præfikset:

```
\def\macroA{"This unprotected macro contains a string"}
\protected\def\macroB{"This protected macro also contains a string"}
```

Hvis du bruger Luas operator til strengsammenkædning (`..`) til at skrive

```
\directlua{
   local x=\macroA..\macroB
}
```

`\directlua`’s forbehandling ville producere følgende kode til at sende til Lua:

`local x="This unprotected macro contains a string"..\macroB`

`\macroA` er ikke defineret ved brug af `\protected` så den ekspanderes og producerer den første del af den streng, der skal sammenkædes, men `\macroB` er defineret ved brug af `\protected` så den er ikke blevet ekspanderet.

Under forbehandling har LuaTeXs `scan_toks()` funktion oprettet et token for `\macroA`, genkendt, at det var en almindelig ekspanderbar kommando, og ekspanderet den: Denne ekspansion producerer en sekvens af tegntokens, ét tegntoken for hvert tegn i `"This unprotected macro contains a string"`. Hvert tegntoken sendes videre og føjes til den tokenliste, der opbygges.

Når `scan_toks()` opretter tokenet for `\macroB` den bemærker, at kommandoen var defineret som `\protected` og ekspanderer den ikke: Tokenet, der repræsenterer `\macroB` passerer uberørt (ikke ekspanderet) ind i den tokenliste, der opbygges. Når tokenlisten er opbygget, er næste trin af forbehandlingen, i `tokenlist_to_cstring()` funktionen, at konvertere alle tokens i tokenlisten tilbage til deres tekstlige repræsentation. Det uekspanderede token, der repræsenterer `\macroB` detekteres og konverteres til sin tekstrepræsentation, hvilket medfører, at teksten `\macroB` vises i koden, der er bestemt til Lua. Bemærk, at Lua faktisk ikke kan sammenkæde `"This unprotected macro contains a string"..\macroB` for at producere den endelige streng, fordi `\macroB` ikke har nogen betydning i Luas syntaks, hvilket resulterer i fejlen `unexpected symbol near '\'`.

**Trivia**: Den `\protected` kommandoen blev introduceret af $$\varepsilon\text{-}\mathrm{\TeX}$$, den første større udvidelse af Knuths oprindelige TeX-software, og understøttes af alle TeX-motorer, hvis kodearv omfatter $$\varepsilon\text{-}\mathrm{\TeX}$$.

### Uekspanderede tokens: Brug af \the\toks i \directlua

Livet i programmering ville ikke være det samme uden de “særtilfælde”, der skal håndteres, og brug af `\the` sammen med `\toks` i en `\directlua` kommando er ét sådant særtilfælde.

#### Kort baggrund om \toks

TeX-primitiven `\toks` instruerer en TeX-motor i at gemme nogle tokens til senere brug: I stedet for at blive sendt videre til yderligere behandling lægges disse tokens til side og lagres på en hukommelsesplacering, der angives ved brug af et *tokenregister*. Vi kan f.eks. bede en TeX-motor om at oprette nogle tokens og gemme dem på tokenregisterplaceringen `100` ved hjælp af

`\toks100={Hi, \TeX! \hskip 5bp}`

Her bruger TeX tokenregisteret `100` til at få adgang til en kendt placering i sin hukommelse: et lagerområde, der er udpeget til at indeholde lister af tokens.

Tokens, der repræsenterer alt mellem `{` og `}` oprettes, *men ekspanderes ikke*, og kædes sammen i en tokenliste—svarende til den tokenliste, vi udforskede tidligere i denne artikel. For at genbruge disse tokens ville vi skrive `\the\toks100` hvori `\the` (en ekspanderbar kommando) instruerer TeX i at hente de lagrede tokens og indsætte dem på det sted, hvor du skrev `\the\toks100`. En anden måde at tænke på dette på er, at `\the\toks` får TeX til at indsætte nogle tokens på den placering.

Den `\toks` kommandoen *ekspanderer ikke* nogen af de tokens, som den bliver bedt om at oprette og gemme: Den konverterer blot tegn og kommandoer mellem `{` og `}` til tokens og gemmer dem.

#### Tilbage til \directlua

I diskussionen om ekspansion bemærkede vi `\directlua{⟨code⟩}` udfører *fulde udvidelse* på `⟨code⟩`: at fjerne alle ekspanderbare kommandoer og erstatte dem med resultatet af deres ekspansionsadfærd—idet man fortsætter med at *ekspandere yderligere* eventuelle tokens, der opstår fra den indledende ekspansion af en ekspanderbar kommando.

`\the` er en ekspanderbar kommando, så `\directlua` vil ekspandere den; når `\the` imidlertid bruges sammen med `\toks` i `\directlua`, som i `\the\toks⟨tokenregister⟩`, bliver de indsatte tokens *ikke ekspanderet yderligere*. Ekspansion af `\the\toks⟨tokenregister⟩` indsætter sekvensen af *ikke-udvidede* tokens, som er lagret i `⟨tokenregister⟩`, direkte i tokenlisten, der konstrueres af `\directlua`: denne adfærd omgår den sædvanlige proces med fuld ekspansion. I praksis passerer disse tokens igennem, *ikke-udvidede*, så de indgår i den primære tokenliste, der konstrueres af `\directlua`—denne gennemløbsproces for uekspanderede tokens ligner i funktion `\unexpanded`, som diskuteret tidligere.

**Eksempel**

Antag, at vi definerer makroen `\mymacro` as `\def\mymacro{\TeX}`. Den indeholder kun ét token for `\TeX` kommandoen (som er en makro): Så vi har en ekspanderbar kommando `\mymacro` der indeholder en anden makro `\TeX`, som også er ekspanderbar.

Følgende kode får Lua til at forsøge at oprette en strengvariabel `x`:

```
\def\mymacro{\TeX}
\directlua{
   local x="\mymacro"
}
```

Inden i \\`directlua`, ekspanderes tokenet for `\mymacro` men det resulterer i et andet ekspanderbart token, `\TeX`, som ekspanderes yderligere. I almindelig TeX resulterer disse ekspansioner i følgende tekst, der sendes til Lua:

`local x = "T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX"`

Denne kode forsøger at definere en streng, som indeholder tekst, der repræsenterer den ekspanderede version af `\TeX` makroen. Hvis du forsøger at køre dette eksempel, vil Lua forsøge at konstruere den streng, men det vil mislykkes og generere en fejl:

`invalid escape sequence near ' "T\k'.`

Senere i denne artikel vil vi udforske betydningen af “invalid escape sequence”.

Lad os nu sammenligne brugen af `\mymacro` med at placere `\TeX` tokenet i en tokenliste, der er genereret af en `\toks` kommandoen:

```
\toks100={\TeX}
\directlua{
   local x="\the\toks100"
}
```

LuaTeXs `\directlua` behandling vil generere denne tekststreng til Lua:

`local x = "\TeX "`

Mellemrumstegnet efter `\TeX` genereres af LuaTeXs konverteringsproces fra kommandotoken til streng.

**Men bemærk**: Den `\TeX` makroen er *ikke* blevet ekspanderet til sine bestanddelstokens. `\the\toks100` fik de tokens, der var lagret i register 100, indsat, men det var alt: De bliver *ikke* ekspanderet yderligere og indgår i den primære tokenliste, der opbygges af `\directlua` (i funktionen `scan_toks()`). At lægge tokens i en tokenliste oprettet af `\toks` er endnu en måde at forhindre tokens i at blive ekspanderet.

Hvis vi kører dette eksempel, producerer det også en fejl:

`invalid escape sequence near ' "\T'.`

Vi udforsker Lua-escape-sekvenser senere i artiklen.

## Andre kommandoer/teknikker brugt ved ekspansion

I dette afsnit ser vi på nogle yderligere TeX-kommandoer/-metoder, som kan være nyttige i situationer, hvor ekspansion anvendes (såsom i `\directlua`).

### \string ⟨token⟩

`\string` er en ekspanderbar kommando, der konverterer ⟨token⟩ til en serie af tegntokens, hver med kategorikode 12.

For eksempel `\string\TeX` ville producere en serie af 4 tegntokens `\`, `T`, `e` og `X` hvor hvert tegn tildeles kategorikode 12 (herunder det indledende `\` tegn).

Hvis vi skriver

```
\directlua{
   local x="I will use \string\newcommand"
   print(x)
}
```

den `\string` kommandoen vil blive ekspanderet, hvilket resulterer i en sekvens af tegntokens med kategorikode 12. Efter `\string` er ekspanderet, vil de resulterende tegntokens (der repræsenterer hvert tegn i `\newcommand`) indgå i den primære tokenliste, der konstrueres af `\directlua`. Når `\directlua` er færdig med at konstruere sin primære tokenliste, konverteres dens bestanddelstokens tilbage til deres tekstlige repræsentation, hvilket producerer følgende kode til at sende videre til Lua-fortolkeren:

`local x="I will use \newcommand" print(x)`

Når denne kode sendes til Lua, `print(x)` vil udskrive strengen `x` på skærmen (konsollen). Vi har imidlertid været lidt snedige og bevidst brugt en eksempelkommando, der begynder med `\n`. Hvis du kan køre dette eksempel på en lokal TeX-installation, vil du bemærke, at Lua udskriver følgende tekst på skærmen:

```
   I will use
   ewcommand
```

For at køre denne kode på Overleaf kan du instruere LuaTeX i at skrive direkte til `.log` filen ved hjælp af LuaTeX’s Lua-API-funktion `texio.write(*string*)`:

```
\directlua{
   local x="I will use \string\newcommand"
   texio.write(x)
}
```

Hvis du undersøger den resulterende `.log` fil, vil du se, at den også indeholder

```
   I will use
   ewcommand
```

Dette uventede output skyldes, at Lua fortolker `\n` i begyndelsen af `**\n**ewcommand` som escape-sekvensen for linjeskifttegnet (tegnkode 10): Den antager, at du vil begynde en ny tekstlinje, som starter med `ewcommand`. Vi diskuterer Lua-escape-sekvenser senere i denne artikel.

### \detokenize{⟨materiale⟩}

`\detokenize` er med hensyn til sine virkninger en version med flere tokens af `\string` og den er også en ekspanderbar kommando, der konverterer alt i `⟨materiale⟩` til en sekvens af tegntokens med kategorikode 12—*undtagen* mellemrumstegn (ASCII/Unicode-værdi 32), der får kategorikode 10. `\detokenize` indsætter også et afsluttende mellemrumstegn efter kommandonavne, der er *kontrolord* (f.eks., `\foo`) men der indsættes intet mellemrumstegn efter *kontrolsymboler* (f.eks., `\#`, `\%` osv.).

### Eksempel

Selv hvis makroerne `\foohoo`, `\foo`, `\bar` og `\foobar` ikke er defineret, hvis du skriver dette:

```
\directlua{
   local x = "\string\foohoo\detokenize{\foo\bar\foobar}"
}
```

ville det producere følgende tekst som kode til at sende til Lua-fortolkeren

`local x = "\foohoo\foo \bar \foobar "`

Hvis du ikke bruger `\string` og `\detokenize` og skriver:

`\directlua{local x = "\foohoo\foo\bar\foobar"}`

`\directlua` ville behandle `\foohoo`, genkende, at det er en kommando, og forsøge at ekspandere den; men fordi `\foohoo` ikke er defineret, ville det resultere i en fejl:

```
   ! Udefineret kontrolsekvens.
   l.1 \directlua{local x = "\foohoo
                      \foo\bar\foobar"}
         ?
```

Fordi `\string` og `\detokenize` konverterer deres argumenter til en serie af tegntokens, `\directlua`’s ekspansionsproces får mulighed for at detektere ekspanderbare kommandotokens `\foohoo`, `\foo`, `\bar`, eller `\foobar`: De omdannes til sekvenser af tegntokens længe før, de kan udløse ekspansion.

Som tidligere nævnt indebærer ekspansion af en kommando, at den fjernes fra inputtet og erstattes med resultatet af dens “ekspansionsadfærd”. Resultaterne af ekspansionen (normalt tokens) læses efterfølgende af TeX-motoren. Her er “ekspansionsadfærden” for `\string` og `\detokenize` at absorbere tegn- og kommandotokens fra inputtet og konvertere dem til sekvenser af tegntokens, som indledningsvis lagres i en midlertidig tokenliste, og som `\directlua` efterfølgende læser. Disse tegntokens indgår i den primære tokenliste, der konstrueres af `\directlua`.

Følgende grafik viser, hvordan `\string` konverterer `\foohoo` kommandoen til en sekvens af tegntokens og producerer en midlertidig tokenliste, som efterfølgende læses af `\directlua` for at indarbejde disse tegntokens i den primære tokenliste, der konstrueres.

![](/files/b3679e7656b6ae579eb3edebcf5a8742901c43a0)

Hvis `\string` eller `\detokenize` møder tegn i deres argument, f.eks. `\string a` eller `\detokenize{abc}` producerer disse tegn (her med kategorikode 11) tegntokens, men med kategorikode 12.

Bemærkninger:

Hvis vi vender tilbage til eksemplet ovenfor:

`\directlua{local x = "\string\foohoo\detokenize{\foo\bar\foobar}"}`

som producerer følgende tekst som kode til at sende til Lua-fortolkeren

`local x = "\foohoo\foo \bar \foobar "`

kan vi observere følgende:

* `\detokenize` har indsat et mellemrumstegn efter hvert makronavn, men `\string` gjorde ikke.
* `\string` virker på et enkelt token.
* I strengen `"\foohoo\foo \bar \foobar "` bruges til at definere `x` vil vi endnu en gang støde på Luas escape-tegnsmekanisme (diskuteret nedenfor):

  * `\bar` begynder med `\b` som er Lua-escape-sekvensen, der bruges til at repræsentere [backspace-tegnet](https://en.wikipedia.org/wiki/Backspace) (tegnkode 8);
  * kommandoer `\foohoo`, `\foo` og `\foobar` begynder alle med `\f`, Lua-escape-sekvensen, der bruges til at repræsentere [formfeed-tegnet](https://en.wikipedia.org/wiki/Page_break#Form_feed) (tegnkode 12).

  Fordi tegnsekvenserne `\b` og `\f` bruges i en streng, der er oprettet med dobbelte anførselstegn `"..."` de vil give uønskede resultater, medmindre der tages skridt til at forhindre det ved hjælp af Lua’s såkaldte *lange klammer* strengmetode: et emne, vi nu kan diskutere sammen med Lua-escape-sekvenser.

## Hvad er “Lua-escape-sekvenser”?

Programmeringssprog reserverer bestemte tegn til “særlig brug” som en del af sprogets syntaks: i praksis er disse tegn defineret til at have en form for særlig betydning. Der er dog tidspunkter, hvor du midlertidigt skal “slå” et sådant tegns særlige betydning “fra” — for eksempel hvis du vil have det pågældende tegn indlejret som en del af en længere streng, hvor dets normale opførsel ville medføre syntaksfejl. I bund og grund skal det tegn behandles *uden* så dets normale fortolkning udløses — og det kan glide igennem ubemærket. For at gøre dette bruger programmører en teknik kaldet *escape* hvor et “specialtegn” repræsenteres af dets såkaldte *escape-sekvens*.

Et standardeksempel (som også understøttes af Lua) er at bruge dobbelte anførselstegn inde i en streng, hvor du undslipper de indre dobbelte anførselstegn ved hjælp af escape-sekvensen `\"`:

`"Da de blev spurgt om LuaTeX, svarede de: \"Det er en fantastisk TeX-motor!\" Jeg var enig."`

Lua-sproget tilbyder en række mekanismer til at arbejde med escape-sekvenser:

* standardsekvenser, herunder `\n` (ny linje), `\r` (vognretur), `\\` (omvendt skråstreg), `\"` (dobbelte anførselstegn), `\t` (vandret tabulator), `\v` (lodret tabulator) og `\'` (enkelt anførselstegn);
* `\xXX`, hvor `XX` er en sekvens af præcis to hexadecimale cifre;
* `\ddd`, hvor `ddd` er en sekvens på op til tre decimale cifre;
* på det tidspunkt denne artikel blev skrevet (august 2019), bruger den nyeste version af LuaTeX, selv om den endnu ikke var tilgængelig på Overleaf, version 5.3 af Lua, som introducerede understøttelse af UTF-8-escape-sekvenser: `\u{XXX}`. Denne escape-mekanisme er til UTF-8-kodede Unicode-tegn, hvor `XXX` er en sekvens af et eller flere hexadecimale cifre, der repræsenterer tegnets kodepunkt. Bemærk, at de omgivende klammer `{ }` er obligatoriske.

### Styring af escape-sekvenser

Traditionelt defineres strenge med dobbelte anførselstegn som i `"dette er en streng"`; i en sådan streng kan du bruge escape-sekvenser: `"dette er en streng.\nJeg begynder nu på en ny linje."`. Men Lua har en anden og *meget* praktisk mekanisme til at definere strenge: dets såkaldte *lange klammer* mekanisme, hvor du definerer en streng ved at omslutte teksten i `[[` og `]]`:

`[[I am a long brackets string]]`

Inden for en streng oprettet med metoden med lange klammer er Lua’s tegn-escape-mekanisme *slået fra*: escape-sekvenser behandles som almindelige tegn. For eksempel i strengen

`[[I am a long brackets\n string]]`

den `\n` escape-sekvensen behandles ikke som det enkelte vognreturstegn (ASCII-kode 13), men som to almindelige tegn: `\` efterfulgt af `n`.

### Hvorfor er strenge med lange klammer så nyttige?

Som vi senere skal se, tilbyder LuaTeX en samling specialiserede indbyggede Lua-funktioner, som du kan bruge sammen med `\directlua` til at styre LuaTeX’s satsningsadfærd. Blandt de mange funktioner er der en, der hedder `tex.print(*string*)` som gør det muligt at sende `*string*` materiale fra Lua-kode tilbage til LuaTeX til satsning. Et meget enkelt eksempel er:

`\directlua{tex.print("Hello, World!")}`

hvilket får LuaTeX til at sætte `Hej, verden!`

Den `*string*` brugt i `tex.print(*string*)` kan også indeholde tekst, der repræsenterer TeX- og LaTeX-kommandoer, som LuaTeX skal behandle. TeX-/LaTeX-kommandoer begynder dog med et `\` tegn, hvilket er problematisk med strenge oprettet med dobbelte anførselstegn, fordi Lua ville forsøge at fortolke strengen, opdage det indledende `\` tegn og fortolke det som begyndelsen på en escape-sekvens. Når Lua forsøger at behandle escape-sekvensen, vil det normalt mislykkes, fordi det indledende `\` kombineret med det første tegn i mange TeX-/LaTeX-kommando-navne ikke danner en gyldig escape-sekvens, som Lua kender. For eksempel når man behandler en streng som `"Jeg kan godt lide \LaTeX"` ville Lua se `\L` og fejle med fejlen “ugyldig escape-sekvens”, og det er årsagen til de fejl, der er nævnt ovenfor.

#### Strenge med lange klammer kommer til undsætning!

Metoden med lange klammer til at oprette (definere) strenge er yderst nyttig, fordi selv om TeX-/LaTeX-kommandoer begynder med et `\` tegn, deaktiverer metoden med lange klammer Lua’s escape-sekvensmekanisme. Her er et kort eksempel, idet vi husker, at vi skal forhindre makroer i at blive udvidet ved hjælp af for eksempel `\protected` eller `\noexpand`.

Antag, at vi definerer en `\newtest` makro sådan her

`**\protected**\def\newtest#1{The argument: #1}`

og bruger den i `\directlua` med LuaTeX Lua API-funktionen `tex.print()`:

```
\directlua{
   tex.print("\newtest{Hello}")
}
```

På grund af brugen af `\protected`, `\newtest` udvides makroen

`ikke, hvilket resulterer i følgende tekst sendt til Lua:`

Mellemrummet tilføjet efter `\newtest` og før den åbne klamme (`{`) er en bivirkning af `\directlua`’s konvertering af kommandotokens tilbage til deres tekstlige repræsentation.

Denne kode sendes til Lua, som derefter udfører LuaTeX-funktionen `tex.print()` men der er et problem, som viser sig på måder, der afhænger af de skrifttyper, du bruger. I LaTeX på Overleaf ville du se output som dette:

![](/files/af4c4b2e2115cf56f13ba29ed3f31ebf18bc6f4f)

sammen med en advarsel i logfilen:

```
   Manglende tegn: Der findes ingen
   (U+000A) i skrifttypen [lmroman10-regular]:+tlig;!
```

I ren TeX kan du se output, der ser nogenlunde sådan ud:

![](/files/5b25c53beeeb863a0db7a029348be43068c553fb)

I begge tilfælde bliver `\newtest` makroen ikke kaldt, og outputtet er ikke, som vi havde tænkt os. Fejlen skyldes Lua’s escape-tegnmekanisme: i teksten `\newtest {Hello}` begynder makronavnet med `\n` som Lua genkender som escape-sekvensen for et linjeskifttegn, så det erstatter `\n` med ASCII-tegn 10, eller i hex 0A. I LaTeX-fejlmeddelelsen, `U+000A` er en måde at repræsentere Unicode-værdien på ved hjælp af 4 hexadecimale cifre.

Fordi `\n` bliver konverteret til linjeskifttegnet, ser LuaTeX ikke et makrokald, men tror i stedet, at det bliver bedt om at sætte noget tekst, der begynder med ASCII-tegnkode 10:

`⟨ASCII 10⟩ewtest {Hello}`

Afhængigt af den anvendte skrifttype kan LuaTeX måske eller måske ikke sætte `⟨ASCII 10⟩` tegnet, men den resterende tekst udskrives uændret med `{` og `}` behandlet som en gruppe og ikke udskrevet.

Ren TeX giver et andet resultat, fordi standardskriften er Computer Modern Roman, som har en mærkelig kodning, der resulterer i, at der sættes et stort Omega, når tegnkode 10 ses.

For at forhindre disse problemer er vi nødt til at bruge strenge med lange klammer for at forhindre, at Lua’s escape-mekanisme anvendes. Det korrekte resultat opnås med

`\directlua{tex.print([[\newtest{Hello}]])}`

hvilket giver det resultat, der vises i det følgende skærmbillede:

![](/files/37db4d4522f07bd408317a9d2479ca3aef29771d)

### Udvidelse og ikke-udførelse af ikke-udvidelige kommandoer

Da vi diskuterede udvidelse, bemærkede vi, at det er en proces, hvor en TeX-motor *fjerner* en udvidelig kommando (token) fra det aktuelle input og *erstatter* den med det/de resultat(er), som den udvidelige kommando producerer. Fordi \directlua udfører *kun-udvidelses-* aktiviteter (for at generere en tokenliste), så *ikke* fører ikke LuaTeX’s behandling videre end det. Når en udvidelig kommando først er blevet læst og fuldt udvidet, vil resultaterne af denne udvidelse — som ofte omfatter ikke-udvidelige kommandoer (tokens) — blive indarbejdet i den tokenliste, der er ved at blive bygget, klar til at blive konverteret tilbage til tekst og sendt videre til Lua.

Der er et vigtigt princip på spil her: under *kun-udvidelses-* aktiviteter, der er designet til at producere en tokenliste, udfører TeX-motorer, inklusive LuaTeX, *udfører ikke* nogen ikke-udvidelige primitive, indbyggede TeX-kommandoer.

I tilfælde af `\directlua{⟨code⟩}`, hvis den fuldt udvidede version af din `⟨code⟩` producerer eller indeholder ikke-udvidelige TeX-/LaTeX-kommandoer, vil de *blive sendt videre til Lua* (repræsenteret som tekst).

#### Eksempel

Her er et eksempel, der viser, at ikke-udvidelige primitiver ikke udføres under kun-udvidelsesbehandling (som i `\directlua`). Antag, at vi definerer en makro `\setcountreg` som dette:

`\def\setcountreg#1#2{\count#1=#2\relax}`

**Bemærk**: Vi bruger `\relax` efter parameter `#2` for at forhindre LuaTeX i at læse for langt, når den gennemgår inputtet i sin søgen efter den numeriske værdi (argument), der skal matche parameter `#2`.

Hvis vi uden for `\directlua`, senere kører makroen sådan her

```
   \setcountreg{100}{50}
   Værdien i tællerregister 100 er \the\count100.
```

ville det udskrive

`Værdien i tællerregister 100 er 50.`

I denne sammenhæng ville enhver TeX-motor behandle makroen `\setcountreg`— udvide makroen, bestemme argumenterne og fortsætte med at læse *og udføre* (eksekvere) kommandoer, der findes i makroens erstatningstekst (definition). Resultatet her er at tildele `50` som den værdi, der er gemt i register `\count100`.

Men når en TeX-motor udfører *kun-udvidelses-* aktiviteter, som den gør med `\directlua`, vil den *ikke udføre* de ikke-udvidelige kommandoer, der findes i makroens definition.

Hvis vi skriver

```
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{50}]]
}
```

producerer den følgende tekst som kode til Lua:

`local x = [[\count 100=50\relax ]]`

Lua-koden ovenfor viser, at inden for `\directlua` den `\setcountreg` er blevet udvidet, dens argumenter identificeret og indsat i den passende parameter (`#1` og `#2`) men den går ikke længere end det: den ikke-udvidelige primitive TeX-kommando `\count` blev *ikke udført* under `\directlua`’s udvidelsesbehandling.

LuaTeX vil dog udføre TeX-koden, hvis vi sender den resulterende streng `x` *tilbage til LuaTeX* via `tex.print(x)` som dette

```
\count100=50 % set \count100 to a starting value of 50
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{250}]]
   tex.print(x)
}
Den værdi, der er gemt i tællerregister 100, er \the\count100.
```

Efter `\directlua` er færdig, ville outputtet være

`Den værdi, der er gemt i tællerregister 100, er 250.`

hvilket viser, at tællerregister `100` nu indeholder værdien `250`.

Lua-koden, der produceres ud fra ovenstående eksempel, er

`local x = [[\count 100=250\relax ]] tex.print(x)`

Denne kode definerer `x` som en streng oprettet ved hjælp af metoden med lange klammer, som bruges til at undgå fejl med fejlagtige escape-sekvenser. Hvis vi brugte dobbelte anførselstegn `"..."` til at definere x, ville tegnkombinationen `\c` i begyndelsen af `\count` udløse en fejl: `ugyldig escape-sekvens nær ' "\c'`.

LuaTeX Lua API-kaldet `tex.print(x)` medfører, at LuaTeX udfører TeX-kodesekvensen `\count 100=250\relax` og `\count100` tildeles værdien `250` som det ses af det satsede output:

`Den værdi, der er gemt i tællerregister 100, er 250.`

#### Forsigtig: makroer og LuaTeX Lua API

I ovenstående eksempel så vi, at under `\directlua`’s forbehandling (udvidelse) udførte LuaTeX ikke koden `\count 100=250`, som indeholder den `ikke-udvidelige` primitive kommando `\count`: for at køre (udføre) den kode måtte vi *sende den tilbage til LuaTeX* via `tex.print()`.

`\directlua` er blot et eksempel på, at LuaTeX udfører kun-udvidelsesbehandling for at konstruere en tokenliste. Der er andre kommandoer, som udfører lignende udvidelsesbehandling og aktiviteter til generering af tokenlister, såsom `\write` og `\edef`: disse kommandoer udfører heller ikke ikke-udvidelige primitiver under deres udvidelsesbehandling. Det er et generelt princip, at TeX-motorer ikke udfører ikke-udvidelige primitiver, når de konstruerer en tokenliste under kun-udvidelsesbehandlingsaktiviteter.

**Omskrivning af vores makro til at bruge LuaTeX Lua API**

Vi kan omskrive `\setcountreg` makroen ved hjælp af en LuaTeX Lua API-funktion kaldet `tex.setcount()`, og dermed undgår TeX-kommandoer til at ændre værdien, der er gemt i tællerregister `100`:

```
   \def\setcount#1#2{\directlua{tex.setcount(#1,#2)}}
   \count100=50
   tællerregister 100 indeholder \the\count100\par
   \setcount{100}{250}
   tællerregister 100 indeholder nu \the\count100\par
```

Denne kode vil sætte:

```
tællerregister 100 indeholder 50
tællerregister 100 indeholder nu 250
```

Her bruger vi `tex.setcount()`, en af LuaTeX’s mange Lua API-funktioner, til at *få direkte adgang til* LuaTeX’s interne datalagerområde for at placere værdien `250` i hukommelsesplaceringen, der repræsenterer tællerregister `100`. Vi har i virkeligheden *omgået* LuaTeX’s standardmetoder til inputbehandling i TeX-motoren: læsning af input, oprettelse af tokens og udførelse af primitive TeX-kommandoer. Men der er en advarende pointe: ved at bruge LuaTeX’s Lua API-funktioner kan kun-udvidelsesbehandlingsaktivitet *føre til bivirkninger*: ændringer i værdier, der er gemt inde i TeX-motoren, som ellers ikke ville være mulige med rene TeX-/LaTeX-kommandoer.

**Eksempel: uventede bivirkninger**

Her er et eksempel, der viser *uventede* bivirkninger, som kan opstå med makroer, der bruger `\directlua`. Antag, at vi skriver følgende kode:

```
\def\dochange{\directlua{tex.setcount(999,12345)}}
\edef\careful{\dochange}
\the\count999
```

Når denne kode køres, sættes `12345`!

Hvordan kan det være? Vi gjorde ikke *udtrykkeligt* kalde nogen kode eller makroer for at lægge den værdi i tællerregister `999`. Eller gjorde vi?

Vi definerede `\dochange` med en `\directlua` kommando, der bruger `tex.setcount()` til at gemme værdien `12345` i tællerregister `999`: i TeX-kode er det ækvivalent med `\count999=12345`. Derefter brugte vi den standard TeX-primitive `\edef` til at definere makroen `\careful`— det er brugen af `\edef` som udløser den uventede bivirkning.

`\edef` fuldt udvider sit argument: her registrerer den en udvidelig makro `\dochange` og udvider den. Makroen `\dochange` bruger den udvidelige kommando `\directlua` som indeholder et Lua API-kald; så udvidelsen af `\dochange` resulterer i udvidelse af `\directlua` og det får `tex.setcount()` til at blive kaldt, hvilket ændrer værdien i tællerregister `999`.

Hvis vi omdefinerer `\dochange` til at bruge TeX-kommandoer:

```
   Før: tællerregister 999 indeholder \the\count999.\par
   \def\dochange{\count999=12345\relax}
   \edef\careful{\dochange}
   Efter: tællerregister 999 indeholder \the\count999.\par
```

når denne kode køres, sættes

```
Før: tællerregister 999 indeholder 0.
Efter: tællerregister 999 indeholder 0.
```

Det var tydeligt, at der ikke var nogen effekt på `\count999`. Når `\edef` definerer `\careful` udvider den `\dochange` men denne udvidelse producerer kun ikke-udvidelige TeX-primitiver: de er *ikke udført* men blot *gemt* i tokenlisten, der udgør definitionen af `\careful`.

Som en ekstra god illustration forklarer det samme princip, hvorfor dette giver sat output:

```
\def\dochange{\directlua{tex.print("Hello")}}
\edef\careful{\dochange}
```

## Kort introduktion til LuaTeX’s Lua API

Som vi har set, `\directlua` gør det ikke blot muligt at skrive almindelig Lua-kode eller en blanding af Lua- og TeX-/LaTeX-kode, men giver også adgang til en samling ekstra Lua-funktioner (specifikke for LuaTeX), som du kan bruge (kalde) til at kommunikere med eller direkte styre den indre funktion af LuaTeX-satssoftwaren. Vi har brugt flere Lua-funktioner i denne artikel, `tex.print()`, `texio.write()`, `tex.setcount()` og disse, sammen med *mange* flere, er dokumenteret i [LuaTeX Reference Manual](http://www.pragma-ade.com/general/manuals/luatex.pdf) hvor grupper af beslægtede funktioner omtales som *biblioteker*.

Du kan opfatte disse Lua-funktioner som LuaTeX’s Lua API (**Et**plikation **P**rogrammering **I**grænseflade), som giver værktøjerne til at konstruere avancerede satsnings- og dokumenttekniske løsninger ved at styre LuaTeX’s satsningsadfærd ved hjælp af Lua som drivkraft.

Som nævnt organiserer LuaTeX sit API i et sæt funktioner, som det kalder biblioteker: grupper af funktioner, der hænger sammen gennem deres formål eller handlinger. Hvert sæt funktioner er designet til at give adgang til et bestemt aspekt af LuaTeX’s interne processer, datastrukturer, datalagring og satsalgoritmer. Internt er LuaTeX opbygget af flere komponenter: softwarebiblioteker/værktøjer (for det meste skrevet i C), der ikke blot omfatter selve TeX-motoren, men også andre delsystemer, herunder Lua, MetaPost, Kpathsea, FontForge, libpng og zlib. Disse biblioteker er integreret for at opbygge funktionerne i den eksekverbare LuaTeX-software, og det er via Lua API’et, at brugerne får adgang til LuaTeX’s funktionalitet, der stammer fra dets integration og koordinering af disse flere softwarekomponenter.

## Nogle eksempler og faldgruber

I dette afsnit præsenterer vi nogle yderligere eksempler, som gør brug af de emner, begreber og forklaringer, der er givet i denne artikel.

### Brug af tilde-tegnet (\~)

Lua-sproget bruger `~` tegn (kaldet tilde) som en del af dets syntaks, herunder dets syntaks til at udføre en “ikke lig med”-test; for eksempel, for at teste om en variabel `x` ikke er lig med `4` kan vi skrive:

```
   local x=3
   if x ~= 4 then
   print("x er ikke lig med 4")
   end
```

Hvis vi prøver at køre denne simple Lua-kode via `\directlua`:

```
\directlua{
   local x=3
   if x ~= 4 then
   print("x er ikke lig med 4")
   end
}
```

får vi en fejl:

`[\directlua]:1: 'then' forventet nær '\'.`

Det er mærkeligt, for vores kode er korrekt: vi har brugt `'then'` og der er intet `\` tegn i vores kode, så hvad gik galt? For at forstå dette må vi huske, at for TeX/LaTeX er `~` normalt defineret som et “specialtegn” med kategori-kode 13: såkaldte aktive tegn, som er minikroer og derfor underlagt ekspansion. Når `\directlua` opdager `~` tegnet, bliver det ekspanderet ved *at fjerne det* fra inputtet og *og erstatter den* med resultatet af dets ekspansion. Ved brug af ren TeX indeholder den resulterende tekst (kode), som LuaTeX producerer og sender til Lua-fortolkeren, faktisk ikke `~` tegnet, og er:

`local x=3 if x \penalty \@M \ = 4 then print("x er ikke lig med 4") end`

Den `~` tegnet er blevet *fjernet* og *ekspanderet* til dets bestanddele kommandoer—Lua-koden ovenfor stammer fra ren TeX’s definition af det aktive tegn `~`. Nu kan vi se, hvorfor Lua svarer med fejlen `'then' forventet nær '\'`—den begynder at parse denne kode, men støder på ordet `\penalty` som ikke betyder noget for Lua og giver en syntaksfejl.

For at rette dette må `~` tegnet have en sikker kategori-kode på det tidspunkt `\directlua` behandler din kode; f.eks. kan vi midlertidigt ændre kategori-koden for `~` til 11 (bogstav) ved at omslutte koden i en gruppe:

```
\begingroup
\catcode`\~=11
\directlua{
   local x=3
   if x ~= 4 then
   print("x er ikke lig med 4")
   end
}
\endgroup
```

Denne kode virker som forventet, og `x er ikke lig med 4` udskrives til konsollen. Der er andre muligheder: vi kan bruge de ekspanderbare kommandoer `\noexpand` eller `\string`.

#### Ved brug af \string⟨token⟩

Vi kan anvende `\string` på det enkelttegnede `⟨token⟩` `~` som har kategori-kode 13 (aktivt tegn); `\string` konverterer `~` tegn til at generere et tegntoken, som har kategori-kode 12. Hvis vi gør

```
\directlua{
   local x=3
   if x \string~= 4 then
   print("x er ikke lig med 4")
   end
}
```

producerer det den Lua-kode, vi har brug for:

`local x=3 if x ~= 4 then tex.print("x er ikke lig med 4") end`

#### Ved brug af \noexpand⟨token⟩

Vi kan bruge `\noexpand~` til at undertrykke ekspansionen af det aktive tegn `~`

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x er ikke lig med 4")
   end
}
```

Det uekspanderede `~` token passerer videre til tokenlisten, der bygges i `\directlua` og vil blive konverteret tilbage til tekst, hvilket giver fungerende Lua-kode.

### Ved brug af #-tegnet

Inden for Lua-sproget kan `#` tegnet bruges til at finde længden af en tabel. Men hvis vi prøver følgende kode

```
\directlua{
   local tbl = {}
   tbl[1] = "Hej"
   tbl[2] = "Verden"
   tex.print("Tabellens længde er "..#tbl)
}
```

ville vi måske forvente, at LuaTeX typograferer

`Tabellens længde er 2`

men den genererer en fejl:

`\directlua]:1: forsøg på at få længden af en talværdi`

Denne fejl udløses, fordi `#` tegnet normalt har kategori-kode 6 (makroparameter)—tegnet `#` tegnet har to anvendelser i TeX/LaTeX: til at angive makroparametre (`#1`, `#2`… `#9`) og erstatningsteksten i justeringsskabeloner (for `\halign` og `\valign`).

Når `\directlua` genererer tokens til at opbygge sin tokenliste, ser den `#` tegnet med kategori-kode 6 og opretter et passende tegntoken til at repræsentere det. Når tiden kommer til at konvertere den endelige tokenliste tilbage til tekstform, får tegntokenet for # (med kategori-kode 6) særlig behandling: det udskrives som *to på hinanden følgende tegn*: `##`, hvilket resulterer i, at følgende kode sendes til Lua:

`local tbl = {} tbl[1] = "Hej" tbl[2] = "Verden" print(##tbl)`

Ved konvertering til Lua-kode er det oprindelige `#` blevet fordoblet, og det giver en fejl:

`\directlua]:1: forsøg på at få længden af en talværdi`

Dette problem opstår på grund af TeX’s syntaks, som bruger et dobbelt hash-symbol `##` til at repræsentere eller generere et enkelt `#` token; denne syntaks bruges i makroer, som definerer andre makroer, der tager parametre, eller i makroer, der bruges til at oprette skabeloner for `\halign` eller `\valign` tabelkonstruktionskommandoerne. Det er ret forvirrende, så lad os se på et eksempel.

#### Eksempel

Antag, at vi definerer en makro `\mymacro` som tager et enkelt parameter, `#1`, men den definerer også en anden makro `\foo` som selv tager et enkelt parameter. For at skelne mellem parameteren `#1` brugt med `\mymacro` og behovet for at definere `\foo` til at bruge sin egen parameter `#1` kræver TeX-syntaksen, at du bruger `##1` inde i `\mymacro` for at repræsentere parameteren, der skal bruges med `\foo`:

`\def\mymacro#1{\def\foo##1{#1 Hej##1}}`

Hvis du skulle skrive `\mymacro{Hej!}` ville det definere makroen `\foo` til at være

`\def\foo#1{Hej! Hej#1}`

Bemærk, at `\mymacro`s parameter `#1` (`Hej!`) er blevet indarbejdet i definitionen af `\foo` og sekvensen `##1` er blevet konverteret til `#1` i definitionen af `\foo`. Så vi kan bruge `\foo` som dette:

`\foo{, Verden!}`

at sætte i tryk `Hej! Hej, Verden!`

Vi kan løse `\directlua`behandling af `#` tegnet ved midlertidigt at ændre dets kategori-kode, før LuaTeX behandler koden. For eksempel:

```
\begingroup
   \catcode`\#=11
   \directlua{
   local tbl = {}
   tbl[1] = "Hej"
   tbl[2] = "Verden"
   tex.print("Tabellens længde er "..#tbl)
}
\endgroup
```

Dette genererer Lua-koden

```
local tbl = {} tbl[1] = "Hej" tbl[2] = "Verden" tex.print("Tabellens længde er "..#tbl)
```

hvilket sætter det forventede resultat i sats:

`Tabellens længde er 2`

### Ved brug af %-tegnet

Inden for TeX/LaTeX bruges `%` tegnet typisk til at indsætte enkeltlinjekommentarer i din kode: for at signalere til TeX-motoren, at den skal ignorere alt fra dette punkt og frem til slutningen af den linje, hvor `%` er skrevet. Men i Lua-sproget bruges `%` tegnet i nogle meget nyttige strengbehandlingsfunktioner, såsom `string.format(...)`, `string.gmatch(...)`, og `string.gsub(...)` hvori `%` tegnet spiller en vigtig rolle som en del af disse funktioners syntaks.

Når det bruges med TeX/LaTeX, `%` fungerer det som kommentartegnet, fordi det er tildelt kategori-kode 14. For at få det til at opføre sig som et almindeligt tegn og slå dets sædvanlige TeX/LaTeX-adfærd fra, skal vi ændre dets kategori-kode til noget sikkert, f.eks. 12. Følgende `\directlua` eksempel bruger en række teknikker, der er diskuteret tidligere i artiklen, sammen med en, vi endnu ikke har nævnt: ``\catcode`\^^M=12``, hvilket gør det muligt for os at bruge Lua-kommentarer i vores kode; dette diskuteres nedenfor.

#### Eksempel

Følgende eksempler er lånt fra [lua-users.org](http://lua-users.org/wiki/StringLibraryTutorial), passende modificeret til brug i `\directlua`.

```
\documentclass{article}
\begin{document}
\begingroup
\ttfamily
\let\\\relax
\catcode`\^^M=12 %<---vi udforsker dette nærmere nedenfor!
\catcode`\%=12
\directlua{
   local str -- deklarer en lokal variabel til at holde resultatet

   tex.print("Brug af string.format():".."\\par")

   str=string.format("%s %q", "Hej", "Lua-bruger!") -- streng og citeret streng
   tex.print(str.."\\par")
   str = string.format("%c%c%c", 76, 117, 97) -- tegn
   tex.print(str.."\\par")
   str=string.format("%e, %E", math.pi, math.pi) -- eksponent
   tex.print(str.."\\par")
   str=string.format("%f", math.pi) -- flydende tal
   tex.print(str.."\\par")
   str=string.format("%g, %g", math.pi, 10^9) -- flydende tal eller eksponent
   tex.print(str.."\\par")
   str = string.format("%o, %x, %X", 99, 125, 125)  -- oktal, hexadeksimal, hexadeksimal
   tex.print(str.."\\par")

   tex.print("\\vskip3mm".."Brug af string.gmatch():".."\\par")

   for word in string.gmatch("Hej TeX-bruger", "%a+") do
      tex.print(word.."\\par")
   end

   tex.print("\\vskip3mm".."Brug af string.gsub():".."\\par")
   str=string.gsub("banana", "(an)", "%1-") -- fang alle forekomster af "an" og erstat
   tex.print(str.."\\par")
}
\endgroup
\end{document}
```

Følgende skærmbillede viser det satsede resultat af koden ovenfor:

![Brug af Lua-strengfunktioner i \directlua](/files/facc7694dbb308ecba5ec225995ed6480f223c2b)

## Hvorfor vises Lua-kode på en enkelt linje?

Som du måske har bemærket, præsenteres alle de (genererede) Lua-kodefragmenter, der vises i eksemplerne i denne artikel, som en enkelt tekstlinje: linjeskift, der oprindeligt var i `\directlua` kodeuddragene, følges ikke. Hvorfor? Det er fordi linjeskift i Lua-koden er blevet *fjernet* under LuaTeX’s forbehandling i `\directlua`, hvilket får Lua-koden til at blive én lang tekstlinje. Denne adfærd kan føres tilbage til den måde, TeX-motorer håndterer tegn for linjeslut—angivet med `\r` (vognretur) og `\n` (linjefeed) i programmeringslitteraturen. Hvorfor vi måske skal bekymre os om disse fine detaljer, bliver klart, når vi diskuterer brugen af Luals mekanismer til at kommentere dele af kode ud.

Når software skriver (gemmer) en tekstfil, afsluttes hver enkelt tekstlinje af såkaldte “nylinje”-tegn—de faktiske nylinje-tegn afhænger af det program og operativsystem, der bruges til at skrive filen. Wikipedia har en [interessant artikel](https://en.wikipedia.org/wiki/Newline) som udforsker historien/udviklingen af de nylinje-tegn, der bruges i dag.

I en vilkårlig tekstfil kan de enkelte tekstlinjer afsluttes af forskellige kombinationer af tegn, kaldet vognretur (ASCII-/Unicode-tegn 13) og/eller linjefeed (ASCII-/Unicode-tegn 10), som betegnes med `\r` og `\n` henholdsvis. Fordi TeX-motorer er designet til at være platformsuafhængige, har de brug for en metode til at omgå den iboende platformsafhængige karakter af linjeafslutninger, der bruges i tekstfiler. Naturligvis har TeX-motorer en indbygget (men konfigurerbar) metode til at håndtere linjeafslutningstegn.

### Hvordan TeX-motorer håndterer linjeafslutninger

Når LuaTeX behandler `\directlua{⟨code⟩}` læser den teksten, der findes i din `⟨code⟩` og anvender standardmetoder fra TeX-motoren til at behandle eventuelle linjeafslutninger i din `⟨code⟩`. Som standard medfører disse standardmetoder fra TeX, at alle linjeafslutningstegn (vognreturer og linjefeeds) fjernes og erstattes af mellemrumstegn. Vi siger “som standard”, fordi en TeX-motors håndtering af linjeafslutningstegn kan ændres via en brugerindstillelig parameter kaldet `\endlinechar`. Her giver vi et kort overblik i to trin, men flere detaljer kan findes i Overleaf-artiklen [En introduktion til \endlinechar: Sådan læser TeX linjer fra tekstfiler](/latex/da/dybtgaende-artikler/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

#### Trin 1: TeX indsætter sit eget linjesluttegn

Efter at have læst en tekstlinje fra din inputfil fjerner TeX-motorer straks eventuelle `\r` eller `\n` tegn fra slutningen af den linje. Derefter *indsætter TeX-motorerne* (tilføjer igen) deres eget linjeafslutningstegn til slutningen af den linje. Det tegn bestemmes af værdien af en brugerindstillelig TeX-parameter kaldet `\endlinechar` og det er gennem denne mekanisme, at TeX-motorer kan behandle linjesluttegn på en platformsuafhængig måde: de vælger og indstiller linjesluttegn uanset hvad der oprindeligt stod i inputtekstfilen.

Typisk bruger TeX-motorer indstillingen

`\endlinechar=13`

som er vognreturtegnet (`\r`). Brugere kan dog altid tildele en anden tegnekode som værdien af `\endlinechar`—hvilket vi ser senere i denne artikel.

Følgelig bliver eventuelle linjeafslutningstegn i din `⟨code⟩` som skal behandles af `\directlua{⟨code⟩}` fjernet og erstattet af et enkelt tegn bestemt af selve TeX-motoren. Bemærk, at TeX-motorer udfører denne linjeslutbehandling straks efter at have læst en ny tekstlinje fra en fil og *før* behandlet eventuelle tegn i den linje (for at generere tokens). Men det er ikke hele historien: hvad TeX-motoren *gør* gør med disse linjesluttegn (den har indsat) forklarer, hvorfor Lua-koden bliver til én enkelt linje.

#### Trin 2: TeX konverterer sit linjesluttegn til et mellemrum

Ud over at indsætte deres eget linjeafslutningstegn, defineret af værdien af `\endlinechar`, bruger TeX-motorer også kategori-kode 5 for tegn, der skal *behandles som* et linjesluttegn. Dette betyder, at TeX-motorer normalt arbejder med:

1. et linjesluttegn defineret af `\endlinechar`;
2. det samme tegn *som regel* tildelt kategori-kode 5.

Det er, hvad TeX gør ved dette linjesluttegn, der forklarer vores dilemma med enkelte linjer af Lua-kode. Når en TeX-motor behandler en inputlinje, vil den til sidst opdage det sidste tegn i den linje: tegnet defineret af `\endlinechar`. Normalt har det tegn kategori-kode 5, hvilket får TeX til *erstatte det* med et mellemrumstegn: dvs. ved linjeslut fjerner TeX i praksis sit linjeafslutningstegn og erstatter det med et mellemrum. Som en sidebemærkning bruger TeX-motorer også tegn med kategori-kode 5 til at registrere blanke linjer og starte et nyt afsnit, men det behandler vi ikke her.

Selvfølgelig kan man i TeX lave alverdens specielle makroprogrammeringstricks ved at nulstille `\endlinechar` til et andet tegn og/eller give tegnet tildelt `\endlinechar` en kategori-kodeværdi efter eget valg.

Hvis du vil forhindre, at Lua-koden bliver til én enkelt tekstlinje, kan du enten (midlertidigt) ændre værdien tildelt til `\endlinechar` eller ændre kategori-koden for den standardiserede linjeslutmarkør `\r`.

### TeX’s sære ^^-notation

I de følgende afsnit vil vi støde på TeX’s usædvanlige `^^` notation, som er kendt som “den udvidede tegnmekanisme”. Den blev designet af Knuth som en måde at gøre det lettere at skrive “kontroltegn” såsom linjeslutmarkører, tabulatorer og så videre. For eksempel:

* `^^J` repræsenterer tegnekode 10 (`\n`, linjefeed);
* `^^M` repræsenterer tegnekode 13 (`\r`, vognretur).

Tegnsekvenser som `^^M` konverteres til deres tilsvarende tegnekoder tidligt i TeX’s inputscanningsproces, når TeX læser inputtegn for at generere de tilsvarende tegntokens.

### Ændring af tegnet tildelt til \endlinechar

Når vi husker, at vi stadig skal forhindre ekspansion af `~` tegnet, kan vi skrive

```
\begingroup
\endlinechar=10 % Ændr linjesluttegnet til \n
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x er ikke lig med 4")
   end
}% ønsker ikke, at \n skal stå her
\endgroup% eller en \n her
```

Ovenstående indstilling for `\endlinechar` får LuaTeX til at tilføje tegnekode 10 (`\n`, linjefeed) til slutningen af hver linje, den læser ind. Vi gør dette, fordi `\n` (linjefeed) normalt har kategori-kode 12, hvilket du kan teste ved at skrive ``\the\catcode`\^^J``. Fordi `\n` ikke har kategori-kode 5, vil LuaTeX ikke konvertere det til et mellemrumstegn, så det forbliver i slutningen af hver linje, der læses ind af LuaTeX. Dette medfører, at et tegn med kode 10 forbliver i slutningen af hver linje og dermed kommer med ind i tokenlisten, der bygges af `\directlua` og derefter dukker op igen i Lua-koden, når tokenlisten er konverteret til tekst. Med ovenstående ændring sendes Lua-koden til Lua-fortolkeren som følgende tegnsekvens:

**\n**local x=3\*\*\n**if x \~= 4 then**\n**print("x er ikke lig med 4")**\n**end**\n\*\*

hvor **\n** notationen er ment til at repræsentere tegnkode 10 *ikke* en eller anden ukendt makro `\n`. Nu vil Lua-fortolkeren se linjeskift i koden, præcis som den oprindeligt blev skrevet i `\directlua` kommandoen:

```
   local x=3
   if x ~= 4 then
   print("x er ikke lig med 4")
   end
```

Bemærk i øvrigt, at det allerførste tegn i Lua-kodestrengen er `\n` (før `lokale` nøgleordet). Det `\n` opstår fra linjen

`\directlua{`

fordi der er et linjeskift lige efter den åbნende `{` og dette bevares også. For at forhindre det kan du skrive

`\directlua{%`

### Ændring af kategori-koden for \r

For at bevare linjeskift i vores Lua-kode kan vi også ændre kategori-koden for `\r` til noget andet end 5, så `\r` ikke længere genkendes (behandles som) som et linjesluttegn. Med denne teknik bruger LuaTeX stadig `\endlinechar=13` og vil fortsat tilføje en `\r` til slutningen af hver linje; men fordi `\r` ikke længere har kategori-kode 5, vil LuaTeX ikke genkende `\r` tegnet som et linjesluttegn: det vil ikke konvertere det til et mellemrum og sender det videre uskadt, så det optræder i Lua-koden.

Når vi husker, at vi stadig skal forhindre ekspansion af `~` tegnet, kan vi skrive

```
\begingroup
\catcode`\^^M=12 % ændr kategori-koden for \r til 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x er ikke lig med 4")
   end
}
\endgroup
```

I dette tilfælde sendes Lua-koden til Lua-fortolkeren som:

**\r**local x=3\*\*\r**if x \~= 4 then**\r**print("x er ikke lig med 4")**\r**end**\r\*\*

hvor `\r` notationen er ment til at repræsentere tegnkode 13 og ikke en eller anden ukendt makro `\r`. Som med `\endlinechar` eksempel vil Lua-fortolkeren nu se linjeskift i koden, præcis som den oprindeligt blev skrevet i `\directlua` kommandoen:

```
   local x=3
   if x ~= 4 then
   print("x er ikke lig med 4")
   end
```

Bemærk i øvrigt igen, at det allerførste tegn i Lua-kodestrengen er `\r` (før local-nøgleordet): dette stammer også fra linjen

`\directlua{`

#### Hvorfor brugte \r kategori-kode 12 og ikke kategori-kode 11?

Svaret skyldes risikoen for ved et uheld at indføre fejl udløst af `\r` (med kategori-kode 11) bliver tilføjet til slutningen af TeX/LaTeX-kommandoer læst fra vores inputfil. Tag dette eksempel:

```
\begingroup
\catcode`\^^M=11 % ændr kategori-koden for \r til 11
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x er ikke lig med 4")
   end
}
\endgroup
```

som giver en fejl:

```
   ! Udefineret kontrolsekvens.
   l.9 \endgroup
```

Hvordan kan det være sandt, når `\endgroup` er en standard TeX-primitive kommando? Årsagen til fejlen er ret subtil: Når LuaTeX læste den sidste tekstlinje—den, der indeholder `\endgroup`—tilføjede den også `\endlinechar` tegn `\r` til slutningen af den linje. Nu ser LuaTeX i sin hukommelse tegnsekvensen

`\endgroup\r`

hvor vi bruger `\r` til at angive tegnet med kode 13—ikke navnet på en ukendt TeX-makro `\r`.

På det tidspunkt, hvor LuaTeX læste denne linje fra vores tekstfil, er den oprindelige `\begingroup` er stadig aktiv: vi befinder os inde i en gruppe, som endnu ikke er blevet lukket ved at udføre den tilsvarende `\endgroup` kommando—hvilket ville få `\r` til at gå tilbage til sin tidligere kategori-kodeværdi på 5.

Når LuaTeX begynder at behandle (oprette tokens fra) tekstlinjen `\endgroup\r` genkender den det første tegn `\` som escape-tegnet, hvilket får LuaTeX til at begynde at lede efter navnet på en kommando. For at identificere et kommandonavn leder LuaTeX efter en sekvens af tegn med kategori-kode 11, men fordi `\r` også har kategori-kode 11, tror LuaTeX, at `\r` tegnet (stadig med kategori-kode 11) udgør *en del af en kommando* kaldet `\endgroup\r` som naturligvis ikke findes, så LuaTeX rapporterer en `Udefineret kontrolsekvens` fejl. Derfor brugte vi kategori-kode 12 og ikke 11.

Fordi LuaTeX’s fejlmeddelelse blev skrevet til konsollen, kunne vi ikke let se/lægge mærke til `\r` tegnet, så det var ikke tydeligt, hvad der havde forårsaget fejlen.

### Hvorfor bekymrer vi os om linjeslutninger?

Årsagen er at muliggøre brugen af Luals kommenteringsmetode i din kode! Du kan bruge LuaTeX’s standardmekanisme til at tilføje `%` tegn til at kommentere enkeltlinjer ud i din kode; men Lua-sproget har sine egne, meget nyttige, *flerlinje-* kommenteringsmekanismer, som du måske vil udnytte.

Lad os begynde med at se, hvad der sker, hvis vi prøver at bruge enkeltlinjede Lua-kommentarer uden at håndtere linjeskifteproblemer. Hvor TeX bruger `%` tegnet til at kommentere enkeltlinjer af kode ud, bruger Lua en dobbelt bindestreg: `--`.

Hvad sker der, hvis vi prøver at køre dette:

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Jeg vil udskrive resultatet af denne komplekse test
   print("x er ikke lig med 4")
   end
}
```

Vi får en fejl:

`[\directlua]:1: 'end' forventet nær <eof>`

Denne fejl skyldes fraværet af linjeskift i Lua-koden, der sendes til fortolkeren, som kun ser én enkelt sammenhængende streng, hvori kommentaren starter midtvejs i strengen:

```

local x=3 if x ~= 4 then -- Jeg vil udskrive resultatet af denne komplekse test print("x er ikke lig med 4") end
```

Alt efter `**local x=3 if x ~= 4 then**` behandles som kommenteret ud, hvilket får fortolkeren til at se et ufuldstændigt stykke Lua-kode, hvilket resulterer i fejlen

`'end' forventet nær <eof>`.

hvor `<eof>` betyder filslut.

Som du sikkert har gættet, må vi afhjælpe dette ved at sikre, at linjeskift overføres til den resulterende Lua-kode, hvilket vi for eksempel kan gøre ved at ændre kategori-koden for `\r` til 12:

```
\begingroup
\catcode`\^^M=12 % ændr kategori-koden for \r til 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Jeg vil udskrive resultatet af denne komplekse test
   print("x er ikke lig med 4")
   end
}
\endgroup
```

Nu ser Lua-fortolkeren en streng, men den indeholder `\r` linjeskift som skrevet i `\directlua` fragment:

**\r**local x=3\*\*\r**if x \~= 4 then**\r\*\*-- Jeg vil udskrive resultatet af denne komplekse test\*\*\r**tex.print("x is not equal to 4")**\r**end**\r\*\*

Dette svarer i praksis til at skrive

```
   local x=3
   if x \noexpand~= 4 then
   -- Jeg vil udskrive resultatet af denne komplekse test
   print("x er ikke lig med 4")
   end
```

hvilket betyder, at Lua er i stand til at behandle denne kode korrekt og ignorere den linje, vi kommenterede ud.

**Blokkommentarer**

Lua-sproget understøtter også en syntaks, som det kalder [“blokkommentar”](https://www.lua.org/pil/1.3.html) (eller *lang kommentar*): disse starter med `--[[` og gælder, indtil den tilsvarende `]]`. Vi kan bruge denne praktiske syntaks til at skrive kommentarer over flere linjer eller kommentere sektioner af kode ud, som vi midlertidigt vil fjerne:

```
\begingroup
\catcode`\^^M=12 % ændr kategori-koden for \r til 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   --[[ Jeg vil udskrive resultatet af denne komplekse test
   simpelthen fordi det virkelig er
   en så fantastisk konklusion]]
   print("x er ikke lig med 4")
   end
}
\endgroup
```

## Afslutningsvis

Først og fremmest tillykke, hvis du har formået at læse hele denne omfattende artikel! Vi har forsøgt at udarbejde en forholdsvis dækkende guide til TeX-relaterede begreber og emner, som giver den baggrund, der er nødvendig for at få mest muligt ud af LuaTeX via `\directlua` kommandoen. Det er vores håb at have skrevet en artikel, som er lærerigt og bidrager med noget nyttigt og værdifuldt til Overleaf-brugersamfundet og videre ud over det. Som altid modtager vi meget gerne feedback, så send endelig [kontakte os](https://www.overleaf.com/contact) kommentarer til denne artikel eller forslag til yderligere emner, du gerne vil have os til at skrive om.

God $$\text{Lua}\mathrm{\TeX}\text{-ing!}$$ fra Graham Douglas og Overleaf-teamet.

### Og til sidst... brug blot luacode-pakken

Selvom TeX og Lua fungerer på fundamentalt forskellige måder, deler disse sprog en række tegn, som har “særlige betydninger” i hvert sprogs kontekst—såsom \\\\, %, \~, #, ^, &—selvfølgelig tillægger Lua og TeX disse særlige betydninger for *meget* forskellige formål. Vores gennemgang af problematiske tegn viser, hvorfor der kan opstå vanskeligheder, og hvordan du kan løse dem; det kan dog være temmelig besværligt manuelt at rette mange små Lua-kodefragmenter, så de fleste brugere foretrækker at bruge LaTeX-pakker, som fjerner disse udfordringer. En sådan pakke er [`luacode`](https://ctan.org/pkg/luacode?lang=en) som leverer en række funktioner, der er designet til at gøre arbejdet med `\directlua`, men du har i det mindste nu måske en bedre forståelse af de problemer `luacode` som den løser for dig.


---

# 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/dybtgaende-artikler/09-an-introduction-to-luatex-part-2-understanding-directlua.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.
