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

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

## Målet med denne artikkelen

I den første delen av denne artikkelen, [En introduksjon til LuaTeX (del 1): Hva er det – og hva gjør det så annerledes?](/latex/no/dybdeartikler/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md), gjennomgikk vi kort LuaTeX som en ekstremt allsidig TeX-motor: et sofistikert, programmerbart satsingssystem som gir et bredt utvalg av verktøy for å bygge løsninger for dokumentteknikk og produksjon.

I denne avsluttende delen ser vi nærmere på den viktigste komponenten i LuaTeX-verktøykassen:  `\directlua` kommandoen, som gir «inngangsporten» til programmatisk kontroll over LuaTeX-satsingen via Lua-skriptspråket.

Men å utnytte LuaTeX fullt ut via `\directlua` krever noe bakgrunnskunnskap om flere TeX-emner: TeXs tokens, tokenlister og ekspansjonsmekanismen. Målet med denne artikkelen er å utforske og forklare disse grunnleggende TeX-begrepene: å sette sammen de TeX-relaterte prosessene bak `\directlua` for å utvikle en forståelse av hvordan det fungerer og gi grunnlaget du kan bygge dine egne satsingsløsninger på med LuaTeX.

Denne artikkelen inneholder en rekke korte eksempler for å demonstrere og forklare sentrale aspekter ved `\directlua`sin oppførsel, og unngår bevisst overdrevent kompleks kode til fordel for korte kodefragmenter. Der det er nødvendig, bruker eksemplene enkel (rå/ren) TeX – selv om de fleste bruker og foretrekker LaTeX (makroer), har grunnleggende TeX-kommandoer fordelen av enkelhet.

## Introduksjon til Lua i LuaTeX

[Lua](https://www.lua.org/about.html) er et skriptspråk hvis [kildekode](https://www.lua.org/download.html) er svært portabel og enkel å bygge inn i programvareapplikasjoner, noe som lar utviklere integrere skriptfunksjonalitet i programmene sine. Lua er innebygd i [mange applikasjoner](https://en.wikipedia.org/wiki/List_of_applications_using_Lua) og er et populært valg i spillindustrien – det mest kjente eksemplet er kanskje [World of Warcraft](https://wowwiki.fandom.com/wiki/Lua_functions).

LuaTeX er, som navnet antyder, en TeX-motor som innebygger Lua-skriptspråket og gir brukerne mulighet til å styre LuaTeXs satsingsoppførsel ved å inkludere Lua-programmer (skript) i dokumentene sine. I tillegg til direkte kontroll over LuaTeX kan brukerne utnytte Lua rent som et svært kapabelt programmeringsspråk til å utføre oppgaver som kan være ekstremt vanskelige å få til ved hjelp av TeX-språket – som etter alle rimelige mål er krevende å lære og mestre. Gjennom tilleggingen og integreringen av Lua blir LuaTeX en svært allsidig og kraftig TeX-motor som direkte støtter to programmeringsspråk.

### Bruke Lua og TeX i dokumentet ditt: skriv inn \directlua

Lua og TeX er to *svært forskjellige* programmeringsspråk: Lua ligger mye nærmere det de fleste tenker på som et programmeringsspråk, men TeX, med sine kategorikoder, tokens, makroer og ekspansjonsmekanisme, ligger langt unna de fleste menneskers erfaringer/forventninger til et språk man skriver programmer i. Men som historien har vist, har TeX-språket overlevd fordi det er godt til det det ble laget for: å styre satsing, selv om virkemåten er noe esoterisk.

For å håndtere utfordringen med å blande Lua- og TeX-språkene i ett enkelt TeX-dokument, innførte LuaTeX-utviklerne en ny kommando kalt `\directlua` som er veien til å bruke Lua – både som et selvstendig programmeringsspråk i egen rett og for å styre LuaTeXs satsingsoppførsel.

Den `\directlua` kommandoen lar brukerne bygge inn Lua-kode i TeX-dokumentene sine; denne koden sendes deretter videre til LuaTeXs innebygde Lua-tolk. Men `\directlua` lar deg også *kombinere* Lua- og (La)TeX-kode sammen, innenfor den samme `\directlua` kommandoen – selv om det fører til ekstra kompleksitet på grunn av de grunnleggende forskjellene mellom Lua- og TeX-baserte programmeringsspråk. Den sentrale utfordringen når man bruker en kombinasjon av (La)TeX- og Lua-kode, er å sørge for at disse to språkene sameksisterer fredelig og ikke kommer «i veien for hverandre».

`\directlua` egner seg best til bruk med kortere Lua-kodefragmenter inne i dokumentet, men du kan bruke det med mer omfattende Lua-programmer hvis du ønsker det. Generelt lagres mer omfattende Lua-programmer og Lua-kodebiblioteker i eksterne filer som kan lastes inn ved hjelp av Lua-funksjonen `dofile()` i en `\directlua` kommando. Fra TeX-prosesseringssynspunkt er en betydelig fordel ved å bruke eksterne Lua-kodefiler at man unngår komplikasjoner som oppstår fra TeXs mekanisme for kategorikoder – et tema som utforskes grundig i denne artikkelen.

### Mer formell beskrivelse av \directlua

Den [LuaTeX Reference Manual](http://www.pragma-ade.com/general/manuals/luatex.pdf) beskriver `\directlua` det slik (lett endret):

> For å flette Lua-kode med TeX-inndata trengs noen få nye primitiver. Primitivet `\directlua` brukes til å kjøre Lua-kode umiddelbart. Den grunnleggende syntaksen er `\directlua{⟨code⟩}`. `⟨kode⟩` utvides fullt ut, og mates deretter inn i Lua-tolken. Etter at lesing og utvidelse er blitt anvendt på `⟨kode⟩`, konverteres den resulterende tokenlisten til en streng, som om den ble vist med `\the\toks`.

Dette er selvfølgelig teknisk korrekt, men kanskje ikke så lett å forstå uten noe kunnskap om lavere nivåer i TeX-prosessene – som tokens og ekspansjon.

## Å forstå \directlua: Hvilke emner skal vi dekke?

I denne artikkelen skal vi se nærmere på noen sentrale bakgrunnsemner og gi en rekke eksempler som er utformet for å demonstrere hvordan `\directlua`  fungerer og hvor (eller hvorfor) du må være forsiktig når du kombinerer TeX og Lua i `⟨kode⟩`.

Vi skal utforske følgende emner i tilstrekkelig detalj til å gi et grunnlag for å forstå `\directlua` og dens «forbehandling» av koden du bruker inni den:

* kategorikoder og TeX-tokens: konvertering av tekst til tokens og tokens til tekst;
* TeXs ekspansjonsprosess (og å forhindre ekspansjon);
* Lua-escape-sekvenser/-mekanismer for tegn og strenger;
* bruk av Lua-stilkommentarer;
* en kort introduksjon til LuaTeXs Lua-API.

Hvis du forstår hvordan TeX-motorer lager og bruker tokens og utvikler en bevissthet om TeXs ekspansjonsmekanisme, har du grunnlaget som trengs for å låse opp den utrolige allsidigheten til LuaTeXs `\directlua` kommandoen.

## Grunnlaget: fra tekst til tokens og tokens til tekst

Overleaf har publisert flere artikler som går grundig inn på TeX-tokens og beslektede begreper, så vi vil ikke gjenta alt dette materialet her; i stedet skisserer vi de områdene/temaene som er relevante for å utvikle en bedre forståelse av `\directlua`.

Her er en liste over tidligere publiserte artikler som kan være av interesse:

* [Hva er en TeX-token?](/latex/no/dybdeartikler/53-what-is-a-tex-token.md)
* [Hva er en TeX-tokenliste?](/latex/no/dybdeartikler/54-what-is-a-tex-token-list.md)
* [Hvordan fungerer \expandafter: En introduksjon til TeX-tokens](/latex/no/dybdeartikler/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)
* [En serie i seks deler: Hvordan fungerer egentlig TeX-makroer?](/latex/no/flere-emner/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### Forstå tegn-tokens

Ethvert tegn en TeX-motor kan lese fra en tekstfil, representeres av to numeriske verdier:

* dens *tegnkode* (ASCII-verdi eller, i dag, Unicode-koden dens);
* en annen, TeX-sentrisk, verdi kalt dens *kategorikode*.

Lesere som vil vite mer om kategorikoder kan ha interesse av å lese denne introduksjonen publisert av Overleaf: [Så hvor begynner vi? Med kategorikoder](/latex/no/flere-emner/19-how-tex-macros-actually-work-part-1.md#so2c-where-do-we-start3f-with-category-codes).

Hvis en TeX-motor for eksempel leser inn et tegn `Et` har den tilgang til to opplysninger: `Et`s tegnkode (65) og kategorikode (vanligvis 11). Når TeX først har lest inn det tegnet `Et`, vil kategorikoden ikke bli endret, men brukermakroer kan gjøre kategorikodeendringer som kan påvirke enhver *påfølgende* tegnet `Et` som *ennå ikke er lest* av TeX. Følgelig må TeX registrere at *denne* tegnet `Et`, *nylig lest inn*, har kategorikode 11. For å gjøre det bruker TeX heltallsparet (65,11) til å beregne en annen heltallsverdi som det kaller en *tegn-token*. Ved å beregne den tokenverdien, som sendes videre til TeXs indre prosessering, er dette bestemte `Et` og dens kategorikode *bundet sammen*; i praksis innkapsler den tegn-tokenen *innkapsler* dataene TeX trenger å vite om det tegnet for bruk i enhver senere satsingsaktivitet dypere inne i TeX-motoren.

#### Hvordan beregnes tegn-tokens?

Først må vi huske at TeX-motorer bruker kategorikode 13 for å lage såkalte *aktive tegn*: ethvert tegn med kategorikode 13 oppfører seg som en minikro; følgelig, og som vi skal se nedenfor, beregnes tokens for aktive tegn annerledes enn vanlige tegn med andre kategorikoder som 10, 11 eller 12.

For *ikke-aktive* tegn:

* eldre 8-bitsmotorer (Knuths TeX, e-TeX, pdfTeX) beregner tegn-tokens for *ikke-aktive* tegn ved å bruke

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

* for LuaTeX, som må håndtere Unicode-tegnverdier, er beregningen for *ikke-aktive* tegn lik, men gir mye større heltallsverdier:

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

Går vi tilbake til det tidligere eksemplet vårt med bokstaven A med kategorikode 11, ville LuaTeX beregne en tegn-tokenverdi på $$2^{21} \times 11 + 65 = 23068737$$. Når den først er beregnet, binder den tegn-tokenverdien *binder* denne bestemte bokstaven A til en kategorikodeverdi på 11. Brukermakroer kan endre kategorikoden for enhver påfølgende bokstav A, men denne bokstavens kategorikode er fastsatt ved å konvertere den til en token som brukes mens den passerer gjennom LuaTeXs indre virkemåte. LuaTeX har bevart, eller innkapslet, den tilsiktede betydningen av det tegnet slik den ble bestemt på tidspunktet det ble lest inn.

TeX-motorer bruker til sammen [16 ulike kategorikoder](/latex/no/flere-emner/43-table-of-tex-category-codes.md) og *enhver* av disse kategorikodene kan tildeles, via `\catcode` kommandoen, til hvilket som helst *enhver* tegn TeX-motoren er i stand til å lese. Endringer i kategorikoder brukes til å endre måten TeX-motorer behandler bestemte tegn i inndata på, og gjør det mulig for TeX-brukere å skrive makroer som gir spesielle satsingsresultater eller oppførsel.

**Aktive tegn**

Som nevnt bruker TeX-motorer kategorikode 13 for å knytte en «spesiell betydning» til et tegn, slik at det blir en såkalt *aktiv tegn* som oppfører seg som en minikro: ingen ledende `\` er nødvendig; det isolerte tegnet er, på grunn av kategorikoden sin, nok til å utløse den makrolignende oppførselen.

Fordi et aktivt tegn virker som en minikro, konverteres det ikke til en *tegn-token* men til en annen (heltalls) token-type kalt en *kommando-token*. Disse beregnes slik:

* for eldre 8-bitsmotorer (Knuths TeX, e-TeX, pdfTeX) beregnes tokens for aktive tegn via:

1. beregne en mellomliggende verdi kalt $$\text{curcs}$$ (**gjeld**ende **c**kontroll **s**sekvens) der $$\text{curcs} = \text{character code} + 1$$3. beregn tokenverdien der $$\text{active character token} = \text{curcs} + \text{4095}$$

* for LuaTeX er beregningen litt mer kompleks fordi den må håndtere hele spekteret av Unicode-tegn, og hvilket som helst av dem kan gjøres aktivt:

1. beregne den mellomliggende heltallsverdien $$\text{curcs}$$ ved å anvende en såkalt *hash-funksjon* på det aktive tegnets Unicode-kodepunktverdi uttrykt i UTF-8: $$\text{curcs}=\texttt{hashfunction}\text{(UTF-8 text for Unicode value of active character)}$$3. beregn heltalls-tokenverdien: $$\text{active character token} = \text{curcs} + 2^{29} - 1$$

**Eksempler**

* 8-bitsmotorer: tokenberegningen for det aktive tegnet `~` (tegnkode 126) gir $$\text{curcs} = 126 + 1 = 127$$, og gir en tokenverdi på $$4095 + 127 = 4222$$.
* LuaTeX: tokenberegningen for det aktive tegnet `~` gir $$\text{curcs}=3186$$ og gir en tokenverdi på $$3186 + 2^{29} - 1 = 536874097$$. LuaTeX-tokens bruker langt større heltallsverdier!

### Forstå kommando-tokens

I tillegg til å behandle *enkeltvise* tegn kan TeX-motorer selvfølgelig behandle *sekvenser* av tegn kalt *kommandoer* (eller, mer korrekt, *kontrollsekvenser*). Etter tradisjon brukes `\` tegnet til å signalisere starten på en kommando, men det er bare en konvensjon – faktisk kunne hvilket som helst tegn med kategorikode 0 (escape-tegnet) brukes i stedet.

TeX-motorer gjenkjenner to typer kommandoer som er kjent som *kontrollord* og *kontrollsymboler*:

* **kontrollord**: kommandoer bygget fra ett eller flere tegn som har kategorikode 11;
* **kontrollsymboler**: enkelttegnskommandoer der det tegnet har kategorikode *ikke* 11: slik som `\$`, `\#` eller `\\`.

**Merk**: De TeX-primitivene `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` og `\toksdef` brukes også til å definere kontrollsekvenser, men i motsetning til vanlige makrodefinisjoner er de resulterende kontrollsekvensene (kontrollord eller kontrollsymboler) *ikke utvidbare*—vi skal se nærmere på disse nedenfor.

#### Hvordan beregnes kommando-tokens?

Akkurat som aktive tegn bruker TeX-motorer den andre typen heltalls-tokenverdi til å representere kommandoer: *kommando-tokens*—husk at aktive tegn også genererer kommando-tokens fordi de oppfører seg som minikroer.

Beregningene som brukes av 8-bitsmotorer for å lage kommando-token-heltall finnes i denne [Overleaf-artikkelen](/latex/no/dybdeartikler/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#how-tex-calculates-token-values). Her skal vi oppsummere de viktigste trinnene i kommando-tokenberegninger for LuaTeX – som er litt forskjellige fordi LuaTeX må behandle Unicode-tegnkodeverdier som kan være betydelig større enn 8-bitsverdier; men LuaTeXs beregninger følger de samme generelle prinsippene som brukes av eldre 8-bitsmotorer.

Etter å ha oppdaget en innkommende kommando, ignorerer TeX-motorer, inkludert LuaTeX, det ledende `\` tegnet: det brukes ikke i beregninger av kommando-tokenverdier, men fungerer bare som en «bryter» for å informere en TeX-motor om at den må behandle en kommando. Kommando-tokenverdien beregnes ved hjelp av sekvensen av (ett eller flere) tegn som finnes i navnet på kommandoen – LuaTeX beregner kommando-tokens for kontrollsymboler og kontrollord ved hjelp av samme algoritme:

1. beregne den mellomliggende heltallsverdien $$\text{curcs}$$ ved å anvende en såkalt [hash-funksjon](https://en.wikipedia.org/wiki/Hash_function) til Unicode UTF-8-strengen av tegn som finnes i kommandoens navn: $$\text{curcs}=\texttt{hashfunction}\text{(Unicode UTF-8 string of characters in command name)}$$3. beregn kommando-tokenverdien der $$\text{command token} = \text{curcs} + 2^{29} - 1$$

**Eksempler**

* for `\\` kommando (et kontrollsymbol), beregner LuaTeX $$\text{curcs}=94$$, noe som gir en tokenverdi for `\\` på $$94 + 2^{29} - 1 = 536871005$$.
* for `\vskip` primitiv kommando (et kontrollord) beregner LuaTeX $$\text{curcs}=3560$$, noe som gir en tokenverdi for `\vskip` på $$3560 + 2^{29} -1 = 536874471$$.
* for den brukerdefinerte makroen `\mynewmacro` (et kontrollord) beregner LuaTeX $$\text{curcs} = 2971$$, noe som gir en tokenverdi for `\mynewmacro` på $$2971 + 2^{29} -1 = 536873882$$.

Når de først er opprettet, kan tokens lagres til senere bruk via såkalte *tokenlister* eller de kan umiddelbart sendes videre for videre behandling inne i TeX-motoren. Bruk av heltallsverdier til å representere tokens fungerer ikke bare på tvers av alle typer datamaskinplattformer/operativsystemer, det er også en svært effektiv måte for TeX å lagre/behandle data på.

### Hvordan en TeX-motor identifiserer typen token (kommando eller tegn)

Gitt en bestemt heltalls-tokenverdi, $$T$$kan en TeX-motor enkelt fastslå om $$T$$ representerer en kommando eller et tegn ved å teste om $$T$$ overstiger en bestemt $$\text{threshold value}$$—det $$\text{threshold value}$$ avhenger av TeX-motoren. Hvis $$T \geq \text{threshold value}$$ så $$T$$ er en kommando-token, ellers $$T$$ er det en tegn-token. Den $$\text{threshold value}$$ er $$4095$$ for 8-bitsmotorer og $$2^{29}-1$$ (536 870 911) for LuaTeX. Knuth utformet metodene som brukes i tokenberegningsformlene slik at TeX-motoren hans, og alle senere motorer basert på koden/arkitekturen hans, raskt og enkelt kan teste tokenverdier.

## Tokens kan deles opp (og konverteres tilbake til tekst)

Tokens (heltall) er mekanismen TeX-motoren bruker for å «innkapsle» alt den trenger å registrere om et inndataelement (tegn eller kommando). Men det finnes tider når en TeX-motor må reversere tokeniseringsprosessen – finne ut hva som opprinnelig ble lest inn for å produsere den tokenverdien – et enkelt tegn eller en sekvens av ett eller flere tegn som danner navnet på en kommando:

* **for tegn-tokens**: Ethvert tegn-token kan deles i sine to bestanddeler: tegnkoden og tilsvarende kategorikode tilordnet det tegnet *på det tidspunktet det opprinnelig ble lest inn*. Som alle TeX-motorer vil ikke LuaTeX endre den opprinnelige kategorikodefordelingen, men vil bruke den under videre intern behandling.
* **for kommando-tokens:** Disse er litt mer detaljerte, men hvis du ser på LuaTeXs beregning av kommando-tokens, inkludert tokens for aktive tegn, ser du at de følger et mønster: $$\text{command token} = \text{curcs} + 2^{29} -1$$

der $$\text{curcs}$$ beregnes i henhold til typen kommando-token som genereres: aktivt tegn, kontrollsymbol eller kontrollord. Variabelen $$\text{curcs}$$ er en *ekstremt* viktig komponent i en TeX-motors indre virkemåte: gitt enhver kommando-tokenverdi (heltall) kan LuaTeX veldig enkelt hente ut verdien av $$\text{curcs}$$ fra den kommando-tokenen ved hjelp av $$\text{curcs} = \text{token value} - (2^{29} -1)$$.

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

Den interne TeX-variabelen $$\text{curcs}$$ (**gjeld**ende **c**kontroll **s**sekvens) er en vitalt viktig komponent i en TeX-motors indre «under panseret»-virkemåte. Selv om du ikke vil, og ikke kan, bruke eller få tilgang til den direkte i koden din, $$\text{curcs}$$ spiller en avgjørende rolle fordi TeX-motorer bruker gjeldende verdi av $$\text{curcs}$$ som en indeks inn i interne tabeller som lagrer data om hver kommando motoren for øyeblikket kjenner til. Disse tabellene lagrer informasjon om den nåværende betydningen av en kommando: hva gjør den, eller hva representerer den, og i tillegg registrerer de sekvensen av tegn som opprinnelig ble brukt til å beregne den $$\text{curcs}$$ verdien. Ved å hente ut verdien av $$\text{curcs}$$ fra en kommando-token er en TeX-motor i stand til å fastslå navnet, altså menneskelesbar tekst, som svarer til enhver (kommando)token, noe som gjør den i stand til å utføre token-til-tekst-konverteringene som er et sentralt aspekt ved `\directlua`sin drift.

### Konvertering av heltalls-tokens tilbake til tegn eller tegnsekvenser (kommandonavn)

Vi har sett at TeX-motorer konverterer inndatategn, eller tegnsekvenser, til heltalls-tokenverdier, men det finnes tilfeller der en TeX-motor trenger å *reversere* den prosessen – å skrive ut den menneskelesbare teksten som opprinnelig ble brukt til å lage disse heltalls-tokenverdiene; for eksempel:

* å skrive feilmeldinger eller advarsler til skjermen eller `.log` fil;
* å skrive ut TeX-/LaTeX-kode til en tekstfil via `\write` kommandoen;
* når en sekvens av tokens konverteres til tekst inne i `\directlua` (som vi snart skal se!)

#### Konvertering av tegn-tokens til tekst

Som nevnt beregnes tokens for ikke-aktive tegn ved hjelp av et inndatategns kategorikode og tegnkode (Unicode-verdi). LuaTeX bruker formelen:

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

Det er en enkel programmeringsoppgave å splitte heltalls $$\text{character token}$$ verdien for å få ut dens bestanddeler tegnkode ($$\text{Unicode value}$$) og $$\text{category code}$$.

#### Konvertering av kommando-tokens til tekst

Alle TeX-motorer lagrer navnet (sekvensen av tegn) til hver kommando de «kjenner til»: enten kommandoen er en brukerdefinert makro eller en innebygd primitiv – lagringen av primitivenes navn skjer når TeX-motoren starter opp, lenge før den begynner å behandle koden din. For brukerdefinerte kommandoer (makroer) lagres navnet på den makroen (minus det ledende `\`) som en del av makrodefinisjonsprosessene inne i TeX-motorer.

Når en TeX-motor trenger å få tilgang til eller skrive ut den menneskelesbare teksten som et heltalls kommando-token opprinnelig ble beregnet fra, vil den først bestemme $$\text{curcs}$$ verdien for det tokenet; i LuaTeX, $$\text{curcs} = \text{token} - (2^{29} -1$$). Ved å bruke verdien av $$\text{curcs}$$ trukket ut fra en kommando-token kan en TeX-motor få tilgang til en intern datastruktur kalt *strenglager* for å fastslå sekvensen av menneskelesbare tegn som opprinnelig ble brukt til å beregne den bestemte verdien for $$\text{curcs}$$ og dermed den tilsvarende kommando-tokenen.

Som vi skal se, er disse tokenbehandlingsaktivitetene – å konvertere tegnsekvenser til heltalls-tokenverdier og konvertere heltalls-tokenverdier tilbake til tegnsekvenser («de-tokenisering») – de *grunnleggende mekanismene* som brukes inne i `\directlua`.

## Tokenlister

Mens en TeX-motor leser inndata, genererer tegn- og kommando-tokens (og behandler dem), kan den støte på bestemte kommandoer som instruerer motoren om å (midlertidig) slutte å sende tokens videre for ytterligere behandling, men i stedet lagre dem for senere bruk. Det vanligste eksemplet er å definere en makro ved hjelp av en av makrodefinisjonskommandoene `\def`, `\edef`, `\gdef` eller `\xdef`—LaTeX-kommandoer som `\newcommand` er makroer som gir tilleggsfunksjonalitet bygget rundt lavnivåprimitiver som til slutt utfører den faktiske makrodefinisjonsprosessen. En makro kan betraktes som navnet som er gitt til en bestemt liste med lagrede tokens: en tokenliste.

TeX-motorer bruker *omfattende* bruk av tokenlister, spesielt [midlertidige interne lister](/latex/no/dybdeartikler/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) som brukes til interne behandlingsformål. Hver TeX-motor tilbyr også brukernivåkommandoer for å opprette tokenlister som lagres for når brukeren, eller TeX-motoren selv, trenger dem. Antallet kommandoer for å opprette tokenlister (innebygde primitiver) varierer etter TeX-motor, men de har alle et kjerne-minimumsett som støttes av hver motor, slik som `\toks` primitivet.

I praksis er en tokenliste bare en lagret sekvens av heltallsverdier:

* inndata leses for å generere (beregne) enkeltstående tokens, som representerer et tegn eller en kommando;
* hver token lagres deretter, og bevarer rekkefølgen tokenene ble generert fra inndata i.

TeX-motorer lagrer tokenlister ved hjelp av en datastruktur kalt en [lenket liste](https://en.wikipedia.org/wiki/Linked_list) (den enkelkoblede varianten). Lesere som vil vite mer om tokenlister, inviteres til å lese Overleaf-artikkelen [Hva er en TeX-tokenliste?](/latex/no/dybdeartikler/54-what-is-a-tex-token-list.md) som bruker en analogi for å konstruere begrepene/idéene bak en tokenliste. En grundig utforskning av TeXs tokenlister, og hvordan de brukes i makrobehandling, finnes i Overleaf-artikkelserien [Hvordan fungerer TeX-makroer egentlig?](/latex/no/flere-emner/01-a-six-part-series-how-do-tex-macros-actually-work.md)

#### En tokenliste i grafisk form

Følgende grafikk viser en LuaTeX-generert tokenliste med tilsvarende tokenverdier produsert fra følgende inndata

`Hi, \TeX! \hskip 5bp`

For eksempel, hvis vi definerer `\mymacro` som `\def\mymacro{Hi, \TeX! \hskip 5bp}` definisjonen av `\mymacro` ville bli lagret i minnet ved hjelp av en tokenliste som denne:

![](/files/d830743c501d9c4c54a7bb7cb8a3482e29593566)

Tokenlisten er en sekvens av lenkede elementer kalt *noder*, navnet gitt til en liten pakke av LuaTeXs minne som er tildelt for å holde hvert element i listen (som individuelle lenker i en kjede). Hver node inneholder en heltalls-tokenverdi og minneadresse til *neste* node i kjeden, og danner en datastruktur kalt en [lenket liste](https://en.wikipedia.org/wiki/Linked_list). Den siste noden indikerer slutten på listen ved hjelp av en spesiell «nullverdi» for neste node – fordi det ikke finnes en.

**Merknader:**

* For enkelhets skyld har vi tatt med adressen til hver enkelt node, men i praksis lagres ikke disse dataene i nodene i tokenlisten; bare adressen til *neste node* er nødvendig for å bygge TeX-motorens tokenlister.
* Den andre kolonnen i grafikken med tittelen «Hva hver token betyr» viser en serie grå bokser som inneholder informasjon om tokenen i hver node: disse er kun for informasjon og *blir ikke* utgjør en del av de faktiske dataene som lagres i tokenlisten.

Her er en tabell over tokenverdiene som finnes i tokenlisten vist ovenfor:

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

**Merk:** Den opprinnelige inndatateksten vår har et etter `\hskip` kommandoen, men det finnes ingen token som representerer det tegnet i tokenlisten. Det tegnet ble absorbert av LuaTeXs inndataskanne- (lese-)prosess fordi det ble brukt til å avslutte LuaTeXs søk etter tegn som inngår i `\hskip` kommandoen.

## Hvordan \directlua egentlig fungerer

Nå som vi har utforsket tokens, tokenlister og konvertering av tokens til tekst, er den neste utfordringen å forstå TeX-motorens konsept token *utvidelse*.

Som nevnt, `\directlua{⟨code⟩}` kan bli bedt om å behandle `⟨kode⟩` som inneholder både Lua- og TeX/LaTeX-kode, men LuaTeXs innebygde Lua-språktolk forstår ikke TeX eller LaTeX: så hvordan kan dette fungere? Hvordan er det mulig for `⟨kode⟩` å inneholde TeX/LaTeX-instruksjoner uten å forvirre Lua-tolkeren fullstendig med kommandoer den ikke forstår? For eksempel fungerer følgende `\directlua` kommandoen bruker bare TeX-makroer, men den fungerer:

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

Denne `\directlua` kommandoen resulterer i at LuaTeX setter `Hallo` men hvorfor og hvordan fungerer dette når Lua-språket ikke forstår TeX-makroer?

Svaret finnes i den tidligere beskrivelsen vi lånte fra [LuaTeX Reference Manual](http://www.pragma-ade.com/general/manuals/luatex.pdf) men vi kan betrakte at `\directlua{⟨code⟩}` fungerer ved at LuaTeX først «forbehandler» `⟨kode⟩` før noe som helst sendes til Lua-tolkeren. Naturen til denne «forbehandlingen» — altså hva den egentlig betyr og hvilke konsekvenser den har for `⟨kode⟩`— er neste tema vi skal ta opp for å hjelpe lesere som er interessert i å utnytte kraften og fleksibiliteten i `\directlua`.

### Hvordan LuaTeX behandler \directlua: Et første blikk

For å bygge ut vår forståelse av `\directlua`’s «forbehandlings»aktiviteter kan vi starte med følgende forenklede diagram som gir en oversikt over hva som skjer. Den `⟨kode⟩` som gis til `\directlua{⟨code⟩}` konverteres først til tokens ved hjelp av prosessene og beregningene som er diskutert ovenfor; den sekvensen av tokens lagres i en tokenliste. Når tokenlisten er bygget, konverteres hvert token i den listen tilbake til sin tekstlige representasjon: teksten som produseres av hvert token — karaktertoken eller kommando-token — kombineres (konkateneres) for å lage en enkelt tekststreng med kode som sendes videre til Lua-tolkeren for kjøring.

![](/files/19b5309d32c02dacb825b86871628bd8ed722ece)

Men vent, hva skulle poenget være med å gå fra tekst til tokens og konvertere disse tokenene rett tilbake til tekst? Du blir kanskje ikke overrasket over å høre at ja, det finnes en ekstra og avgjørende prosess som vi ikke har tatt med i denne grafikken: *tokenutvidelse*. Hvert token som produseres fra teksten i din `⟨kode⟩` underkastes en type «inspeksjon» der LuaTeX bruker en test for å se om tokenet representerer en kommando som tilhører delmengden kjent som *utvidbare kommandoer*. Hvis det gjør det, filtrerer LuaTeX ut den kommandoen ved å *å fjerne* ta det bort fra din `⟨kode⟩` og *og erstatte det* med resultatet/resultatene av en prosess TeX-motorer kaller *tokenutvidelse*.

### Hvordan LuaTeX behandler \directlua: Et andre blikk (på utvidelse)

TeXs utvidelsesmekanisme er en kjernekomponent i alle TeX-baserte satsingsmotorer fordi, i siste instans, er hver av dem avledet fra (eller basert på) Knuths opprinnelige kildekode og design for TeX. Konseptet utvidelse er imidlertid vanskelig å forklare på et kortfattet, men likevel tilgjengelig språk, fordi utvidelse i praksis er en «paraply»-term som brukes til å beskrive én enkelt prosess — men en som produserer en rekke utdata. Disse varierte resultatene er en konsekvens av det noe eklektiske settet av kommandoer som utvidelse kan brukes på, så du kan betrakte at hver utvidbare kommando har en viss «utvidelsesadferd».

Som en *første tilnærming* til å forstå utvidelse kan vi si at utvidelse av et token (en kommando) betyr *å fjerne* at denne kommandoen (tokenet) fjernes fra TeXs gjeldende input og *å erstatte* erstattes av en sekvens av tokens som resultat av å utføre akkurat den utvidbare kommandoen — og dermed erstatte det opprinnelige tokenet med resultatene/konsekvensene av utvidelsen *atferden*. Imidlertid er denne innledende «definisjonen» av utvidelse — i form av å generere nye tokens for TeX å lese — ikke helt nøyaktig for alle utvidbare kommandoer, men den er god nok som et utgangspunkt.

For å gi et enkelt eksempel: TeX-primtivet `\jobname` er en utvidbar kommando og dens *utvidelse* er en sekvens av karaktertokens som representerer navnet på den viktigste TeX-inndatafilen. Hvis TeX bestemmer seg for å utvide en `\jobname` kommando (token) blir den *fjernet* fra TeXs gjeldende inndatakilde og *erstattet* av sekvensen av karaktertokens den genererer — som TeX deretter fortsetter å lese/behandle.

Innen `\directlua`, etter at et utvidbart token er behandlet (fjernet) og erstattet med nye tokens, vil LuaTeX fortsette å lese disse nye tokensene den nettopp har satt inn — men noen av disse nye tokensene kan også være utvidbare. Fordi `\directlua` utfører såkalt *full utvidelse*, vil LuaTeX lese disse nye tokensene og igjen gå gjennom utvidelsesprosessen for å utvide (fjerne) eventuelle nye (utvidbare) tokens — denne utvidelsesprosessen fortsetter til ingen utvidbare tokens er igjen. Det er imidlertid to viktige unntak fra denne «fortsett å utvide»-regelen, og begge vil vi diskutere nedenfor:

* ved å bruke konstruksjonen `\the\toks`;
* bevisst forhindre (undertrykke) utvidelse for ett eller flere valgte tokens.

Som nevnt dekker ikke vår arbeidsdefinisjon (første tilnærming) for å forstå utvidelse hele spekteret av utvidelsesadferd som vises av delmengden av utvidbare kommandoer. For eksempel genererer ikke noen utvidbare kommandoer tokens på samme måte som `\jobname` gjør, men de kan:

* «filtrere» tokens fra inputen: TeX-motorens betingede kommandoer (`\if`, `\ifcat`, `\ifnum`, `\ifdim`, `\ifodd`, `\ifvmode`, …) er utvidbare. Utvidelsesadferden deres er en type «tokenfiltrering» — betingede kommandoer kan brukes i `\directlua`.
* «jonglere» tokens i inputen:  [`\expandafter` kommandoen](/latex/no/dybdeartikler/03-a-six-part-article-series-on-expandafter-tex-tokens-and-expansion.md) er utvidbar og endrer sekvensen som to tokens utvides i.
* forhindre utvidelse: de utvidbare kommandoene `\noexpand` og `\unexpanded` undertrykker utvidelsen av kommando-tokens i inputen.
* konvertere tegnsekvenser i inputen til kommando-tokens: `\csname … \endcsname.`
* konvertere interne størrelser til en sekvens av karaktertokens: `\number` og `\the` er utvidbare kommandoer som genererer en sekvens av karaktertokens som representerer verdien av en intern størrelse.
* konvertere kommando-tokens til karaktertokens: `\string` og `\detokenize` er utvidbare kommandoer som konverterer argumentene sine til en sekvens av karaktertokens med kategori-kode 12. Merk at `\detokenize` skiller seg fra `\string`: `\detokenize` kan behandle flere tokens og den setter inn et mellomromstegn, med kategori-kode 10, etter å ha behandlet kommando-tokens opprettet fra *kontrollord*. I praksis `\detokenize` legger den til et etterfølgende mellomromstegn etter kommandonavnet — vi skal se noen eksempler senere i artikkelen.

#### Finjustering av vår «definisjon» av utvidelse

Vi kan nå generalisere definisjonen vår og si at utvidelse av en kommando (token) innebærer *fjerning* av denne kommandoen (tokenet) fra TeXs gjeldende inndatakilde og *og erstatte det* med resultatet av *token-operasjonene* utført av den kommandoen. I essens får utvidelsesprosessen en utvidbar kommando til å utføre en eller annen type «operasjon» på tokens i TeXs gjeldende input, noe som påvirker antallet eller oppførselen til tokens som TeX senere vil lese — den nøyaktige naturen til den «operasjonen» avhenger av hvilken kommando som utvides. Alle makroer og aktive tegn er utvidbare, men bare et lite antall av en TeX-motors innebygde kommandoer (primtiver) er klassifisert som utvidbare — listen over utvidbare kommandoer avhenger av TeX-motoren du bruker.&#x20;

Hver ny TeX-motor arver de primitive kommandoene som er bygget inn i dens forløper(e) — de tidligere generasjonene av TeX-motorer som den ble avledet fra — og noen av disse arvede primitviene vil være utvidbare. Selvfølgelig kan en ny TeX-motor velge å ikke implementere noen av de primitive kommandoene som finnes i de tidligere motorene eller å modifisere oppførselen deres for å passe behovene til den nye motoren. I tillegg implementerer nye TeX-motorer vanligvis ekstra primitiver for å gi støtte for sin egen forbedrede funksjonalitet — noen av disse kan også være utvidbare. Følgelig vil antallet utvidbare kommandoer som er tilgjengelige for deg variere etter hvilken TeX-motor du bruker — LuaTeX har en ganske stor samling av dem.

En annen vanskelighet med å forklare/forstå utvidelse, og kanskje den virkelige utfordringen, er å vite nøyaktig *når* en TeX-motor faktisk kommer til å utføre utvidelsesprosessen, eller ikke. Det er et stort og komplekst tema fordi utvidelse er dypt innebygd i hele virkemåten til TeX-motorer: vi har ikke plass til å behandle dette i detalj utover bruken av utvidelse i `\directlua`.

### Hvordan LuaTeX behandler \directlua: Et siste blikk

Følgende diagram oppsummerer `\directlua` forbehandlingsaktivitetene som finner sted inne i selve LuaTeX-motoren. I dette diagrammet viser vi også to lavnivå (interne) LuaTeX-funksjoner som faktisk utfører arbeidet: `scan_toks()` og `tokenlist_to_cstring()`. Disse funksjonene er skrevet i C-språket og ligger dypt inne i den kjørbare LuaTeX-programvaren: de er en del av LuaTeXs indre maskineri og ikke *direkte* tilgjengelige for din TeX/LaTeX-kode.

![](/files/ba8ac47b13bf18855f6f58c0d8c2a6ce15a29a8a)

Den følgende beskrivelsen av `\directlua ⟨code⟩`s forbehandlingsaktivitet oppsummerer diagrammet ovenfor.

1. Sekvensen av tegn i din ⟨code⟩ behandles av `scan_toks()`. Hensikten er å lese din ⟨code⟩ tegn for tegn for å generere karaktertokens og kommando-tokens. Fordi den oppretter tokens, er kategori-koden som er tildelt hvert tegn i ⟨code⟩, på tidspunktet det leses inn, ekstremt viktig.
2. Under `scan_toks()`s tokenbehandling (generering) blir enhver utvidbar kommando (token) utvidet *uansett —* forhindret via kommandoer som `\protected` (makrodefinisjoner), `\noexpand`, `\unexpanded` osv. Aktive tegn (kategori-kode 13) blir også utvidet (med mindre det forhindres).
3. Tokenstrømmen som opprettes av `scan_toks()` bygges inn i én lang tokenliste — tokens som finnes i den listen inkluderer de som er produsert fra utvidelse som brukes på utvidbare kommandoer (slik som makroer) som finnes i din `⟨kode⟩`. Legg også merke til at `scan_toks()` *ikke* utløser eller forårsaker utføring av enhver token som representerer en ikke-utvidbar kommando: slike ikke-utvidbare tokens sendes ganske enkelt videre for å bli innlemmet i tokenlisten som bygges opp.
4. Når tokenlisten er ferdig og all utvidelsesaktivitet er fullført, behandles tokenlisten av en annen funksjon kalt `tokenlist_to_cstring()` som konverterer hvert token i den endelige tokenlisten tilbake til sin tekstlige representasjon. Dette genererer en tekststreng som er Lua-koden som skal sendes videre til Lua-tolkeren. For vellykket kjøring må denne strengen inneholde syntaktisk korrekt Lua-kode.
5. Luas behandling av den koden skjer i to trinn:
6. LuaTeXs innebygde Lua-tolk analyserer og «kompilerer» Lua-koden som ble generert i de foregående trinnene. Hvis denne analyseringen/kompileringen mislykkes, vil Lua-tolkeren generere feil (som syntaksfeil) — disse feilene kan føre til at LuaTeX-kjøringen mislykkes med mindre du valgte å bruke `--interaction=nonstopmode` på kommandolinjen.
7. Hvis analysering/kompilering lykkes, utfører Lua-tolkeren koden som ble kompilert i trinn (5a).

I essens er `scan_toks()` funksjonen kjernen i LuaTeXs forbehandlingsaktiviteter: hovedoppgaven er å utvide alle utvidbare TeX/LaTeX-kommandoer som finnes i teksten i din `⟨kode⟩` og konstruere en tokenliste av alt den har behandlet. Igjen understreker vi at `scan_toks()` *utfører ikke ikke-utvidbare kommandoer* (tokens): den bare *lagrer* disse tokenene i tokenlisten den konstruerer. Når den er fullført, konverteres tokenlisten deretter *tilbake til en tekstlig representasjon* av `tokenlist_to_cstring()`— en tokenliste er et rent TeX-begrep som er fullstendig fremmed for en Lua-tolk, derfor behovet for å konvertere den til tekst, som blir til Lua-kode for å sendes videre til Lua-tolkeren.

## Utvidelse som et «grensesnitt» i et programmeringsspråk

Du kan tenke på `\directlua`’s utvidelsesprosess som brukt som en mekanisme, eller et grensesnitt, for å sende data/informasjon fra «TeX-verdenen» over i «Lua-verdenen»: en metode for TeX-språket til å kommunisere data til Lua-språket. For eksempel kan TeX-kode som `\number\count75` brukes til å overføre en verdi fra «TeX-verdenen» som er lagret i telleregister 75 over til heltallsvariabelen x i «Lua-verdenen»:

```
\count75=1564 % Data som finnes 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)
```

**Merk**Vi la til `<space>\space` etter `\number\count75` for å sikre at et mellomromstegn ble bevart mellom `1564` og `tex.print`— det er ikke strengt nødvendig her fordi Lua fortsatt ville tolke koden korrekt hvis vi utelot det. Mellomromstegnet som følger umiddelbart etter `\count75` tas opp under prosessen TeX-motorer bruker for å se etter numeriske verdier — her, verdien som leveres til `\count`. `75` Mellomromstegnet etter `75` brukes til å avslutte LuaTeXs søk etter digitsekvens `\space` makroen utvides for å gi mellomromstegnet som trengs for å skille teksten `1564` og `tex.print`.

Ved å bruke koden ovenfor vil LuaTeX sette

`x= 1564 og y = 612.6`

Her oppnås «dataoverførings»-mekanismen ved hjelp av `\number`: en utvidbar kommando som i dette tilfellet instruerer TeX om å hente verdien lagret i `\count` register `75` og fra den verdien (`1546`) generere en serie med karaktertokens, ett karaktertoken for hvert siffer, noe som resulterer i en tokensekvens for sifrene `1`, `5`, `6` og `4`. Disse 4 karaktertokenene innlemmes i den viktigste tokenlisten som bygges av `\directlua` og deretter konverteres de tilbake til sin tekstlige representasjon når tokenlisten konverteres til tekst. Det er uten tvil en svært omstendelig vei fra `\count75` registerverdien som er lagret inne i LuaTeX, til sifre som er ment for Lua-kode, men til slutt fungerer det.

**TIPS:** Hvis du vil inspisere resultatene av LuaTeXs utvidelsesaktiviteter kan du skrive kode som dette:

```
\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 eksemplet bruker vi metoden med lange klammer for å opprette en strengvariabel `foo` hvis formål er å holde tekststrengen av Lua-kode som genereres fra utvidelsen av alt mellom `[[` og `]]`. Den strengteksten skrives ut til konsollen via Lua-funksjonskallet `print(foo)`.

På Overleaf kan du se lignende resultater ved å skrive innholdet av `foo` til `.log` filen ved hjelp av LuaTeXs Lua-funksjon `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-utvidbare tokens og ikke-utvidede tokens

Vi har lagt merke til at `\directlua{⟨code⟩}` utfører *full utvidelse* av din `⟨kode⟩`fjerner og utvider alle utvidbare kommandoer til bare ikke-utvidbare tokens er igjen. Sekvensen av tokens som opprettes av `\directlua`’s behandling (i `scan_toks()` funksjonen) settes sammen for å danne en tokenliste hvis individuelle tokens deretter konverteres tilbake til tekst for å sendes videre til Lua.

Imidlertid har vi ennå ikke behandlet den siste delen av denne historien fordi vi må vurdere de to «klassene» av kommando-token som kan komme gjennom til tokenlisten som bygges i `\directlua`: vi vil omtale dem som *forkortede kommando-tokens* og *ikke-utvidede* tokens:

* **forkortede kommando-tokens**: Denne typen kommando-token oppstår fra kontrollsekvenser definert ved hjelp av en av TeX-primitivene `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` og `\toksdef`Disse primitive kommandoene brukes til å definere kontrollsekvenser som representerer en numerisk verdi — de resulterende kontrollsekvensene er *inneholder* utvidbare.
* **ikke-utvidede tokens**: Denne token-typen oppstår fra kommandoer som normalt ville blitt utvidet, men `\directlua` har enten:
* blitt uttrykkelig instruert *inneholder* til å utvide dem; for eksempel undertrykkelse av utvidelse ved kommandoene `\noexpand` eller `\unexpanded`— vi forklarer snart hvordan dette gjøres;
* injiserte tokens ved å behandle sekvensen `\the\toks` (mer om det nedenfor).

### To «grupper» av token i en \directlua-tokenliste

Basert på diskusjonene våre kan vi si at tokens som finnes i tokenlisten som bygges under første fase av `\directlua`’s forbehandling (i `scan_toks()` funksjonen) faller i to grupper:

1. *iboende ikke-utvidbare* tokens

* ethvert token som representerer en ikke-aktiv *tegnet*;
* ethvert token som representerer en ikke-utvidbar *primitiv* *kommandoen*;
* ethvert token som representerer en *forkortet kommando* (disse er ikke utvidbare, se nedenfor).

3. *ikke-utvidede* tokens:

* ethvert token som representerer en utvidbar kommando hvis utvidelse ble *undertrykt* (eller unngått) under `\directlua`’s forbehandling.

#### Forkortede kommando-tokens: å lage ikke-utvidbare kommandoer

Som nevnt tilbyr TeX-motorer et sett med primitiver (innebygde kommandoer) som kan brukes til å konstruere *ikke-utvidbare* kontrollsekvenser (vist her ved `⟨kommando⟩` ). Disse primitivene har formen:

* `\chardef ⟨kommando⟩ = ⟨numerisk verdi⟩`
* `\mathchardef ⟨kommando⟩ = ⟨numerisk verdi⟩`
* `\countdef ⟨kommando⟩ = ⟨numerisk verdi⟩`
* `\dimendef ⟨kommando⟩ = ⟨numerisk verdi⟩`
* `\skipdef ⟨kommando⟩ = ⟨numerisk verdi⟩`
* `\muskipdef ⟨kommando⟩ = ⟨numerisk verdi⟩`
* `\toksdef ⟨kommando⟩ = ⟨numerisk verdi⟩`

der `⟨numerisk verdi⟩` er en heltallsverdi som passer for hver kommando.

Her skal vi kort gjennomgå bruken av `\chardef` for å demonstrere nøkkelfunksjonen til disse primitivene — å produsere en `⟨kommando⟩` som er ikke-utvidbar. Du kan bruke ``\chardef\mydollar=`\$`` for å opprette kontrollsekvensen `\mydollar` og bruke den til å sette en `$`:

`Jeg betalte \mydollar30.`

Dette vil sette `Jeg betalte $30.` Kontrollsekvensen `\mydollar` opprettet av `\chardef` er ikke utvidbar, som vi kan se av følgende eksempel:

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

Som gir følgende tekst i `.log` fil

`Jeg betalte \mydollar 30.`

Dette viser `\mydollar` ble *inneholder* utvidet under `\directlua`’s forbehandling. Mellomrommet som vises etter `\mydollar` legges til når et kommando-token konverteres til sin representasjon som tekst.

Når du bruker `\chardef` for å opprette en kontrollsekvens, resulterer TeXs interne klassifisering av den kontrollsekvensen (kommandoen) i at den blir *ikke-utvidbare* noe som er en helt annen oppførsel sammenlignet med kontrollsekvenser definert av en av makrodefinisjonskommandoene: \def, \edef, \gdef eller \xdef. Som nevnt ovenfor, under prosessen med å konstruere tokenlisten sin `\directlua` undersøker hvert innkommende kommando-token for å sjekke om det er utvidbart. Hvis et kommando-token ikke er utvidbart, går det rett gjennom til tokenlisten og tekstrepresentasjonen vil senere dukke opp igjen i strengen med Lua-kode som resultat av at tokenene i tokenlisten konverteres tilbake til tekstlig form.

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

Historisk sett definerte Knuths opprinnelige plain TeX de vanlig brukte kontrollsymbolene `\%`, `\&`, `\#` og `\$` ved å bruke `\chardef`— ikke ved å bruke en av de standard makrodefinisjonskommandoene `\def`, `\edef`, `\gdef` eller `\xdef`. For eksempel:

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

Den merkelige `` `\ `` syntaksen er en TeX-metode for å få den numeriske tegnkodeverdien. I det gamle plain-TeX-regimet er disse kontrollsymbolene ikke utvidbare (på grunn av `\chardef`) men LaTeX (eller pakker) kan redefinere dem som *makroer* for å gi utvidet funksjonalitet — det ville gjøre dem utvidbare, så det kan være lurt å være klar over dette.

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

La oss sammenligne resultatet av følgende kode kjørt under plain TeX og LaTeX. For enkelhets skyld skriver vi resultatene til `.log` filen ved hjelp av LuaTeXs Lua-API-funksjon `texio.write()`.

```
\directlua{
   local x=[[\$150 for "\#1"-produktet---20\%! mer enn konkurrenten, Widget \& Co.]]
   texio.write(x)
}
```

Når du kjører denne koden med **plain TeX** gir følgende utdata i `.log` filen, som viser resultatet av eventuelle utvidelser:

```
\$150 for "\#1"-produktet---20\%! mer enn konkurrenten, Widget \& Co.
```

Tydeligvis ble ingen av kontrollsymbolene`\$`, `\#`, `\%` eller `\&` utvidet under `\chardef`.

Kjører du den koden med den **LaTeX** dokumentet:

```
\documentclass{article}
\begin{document}
   \directlua{local x=[[\$150 for "\#1"-produktet---20\%! mer enn konkurrenten, Widget \& Co.]] texio.write(x)}
\end{document}
```

gir følgende utdata i `.log` fil

```
\protect \TU\textdollar 150 for "\#1"-produktet---20\%! mer enn konkurrenten, Widget \& Co.
```

Tydeligvis gir kjøring i LaTeX et annet resultat enn plain TeX fordi kommandoen `\$` er blitt utvidet, noe som indikerer at den er en makro.

**Merk:** I både plain TeX og LaTeX `\directlua` behandlet ikke noen av kontrollsymbolene fullt ut `\%`, `\&`, `\#` og `\$` for å generere det tilsvarende tegnet. Under utvidelsesprosessen utført av `\directlua` tokens som representerer disse kontrollsymbolene — eller, for LaTeX, deres utvidelse — går rett gjennom til hovedtokenlisten som bygges opp.

**Merk:** Kontrollsymboler dannes av ett enkelt tegn som ikke har kategori-kode 11, for eksempel `\#`Når et token som representerer et kontrollsymbol konverteres tilbake til sin tekstlige representasjon, setter TeX-motorer ikke inn et mellomromstegn etter den teksten. Denne spesielle behandlingen av kontrollsymboler er en innebygd regel for hvordan TeX-motorer fungerer.

### Ikke-utvidede tokens: undertrykkelse av utvidelse

`\directlua`’s forhåndsbehandling er ett eksempel der en TeX-motor utfører utvidelse, men du kan ønske å *forhindre* at utvidelse anvendes på ett eller flere tokens som ellers ville blitt utvidet. Som et annet eksempel utfører LuaTeX (og alle TeX-motorer) en utvidelsesprosess, lik den til `\directlua`, når de behandler `\write` kommandoen:

`\write file-number {⟨material⟩}`

\write instruerer en TeX-motor til å skrive ut `⟨material⟩`—ofte med TeX/LaTeX-kommandoer—til en tekstfil (`filnummer`); eventuelle utvidbare kommandoer innenfor `⟨material⟩` vil, med mindre det hindres, bli utvidet før `⟨material⟩` det faktisk skrives ut til den filen.

Som du kanskje forventer, tilbyr TeX-motorer kommandoer for å undertrykke eller kontrollere utvidelse:

* `\noexpand⟨token⟩`: hindrer utvidelse av den ene `⟨token⟩`;
* `\unexpanded{⟨material⟩}`: hindrer utvidelse av alle utvidbare kommandoer (tokens) i `⟨material⟩`. Det er i praksis en versjon med flere tokens av `\noexpand`;
* `\protected`: et prefiks som legges til makrodefinisjoner og som hindrer utvidelse av den makroen under visse omstendigheter (for eksempel under `\directlua`, `\write` eller `\edef`).

Til tross for navn som antyder noe annet, er både `\noexpand` og `\unexpanded` er *utvidbare kommandoer* og gir gode eksempler på å se en TeX-motors utvidelsesprosess som utførelse av «token-operasjoner»: operasjonen her er å hindre utvidelse av ett eller flere påfølgende tokens (kommandoer). Fordi `\noexpand` og `\unexpanded` er begge utvidbare kommandoer, blir de fjernet og behandlet (utført) under `\directlua`’s forhåndsbehandling når den konstruerer token-listen fra din `⟨kode⟩`.

#### \noexpand ⟨token⟩

`\noexpand ⟨token⟩` hindrer utvidelse av det ene `⟨token⟩`. `\noexpand` inne i `\directlua` vil bli utvidet (fjernet fra inndataene) og erstattet av resultatene av dens «utvidelsesatferd». Resultatet av å utvide `\noexpand` er å opprette en spesiell (skjult) `⟨marker token⟩` som plasseres foran det opprinnelige `⟨token⟩` hvis utvidelse skal undertrykkes: den `⟨marker token⟩` fungerer som et flagg som sier «ikke utvid neste token». Fordi `\directlua` utfører full utvidelse, vil den behandle på nytt alle tokens som følger av «utvidelsesatferden» til en utvidbar kommando. Følgelig, når utvidelsen av `\noexpand ⟨token⟩` er fullført, går LuaTeX tilbake for å lese resultatene og ser den to-token lange sekvensen `⟨marker token⟩⟨token⟩` som får den opprinnelige `⟨token⟩` til å passere gjennom, uten å bli utvidet, inn i token-listen som konstrueres av `\directlua`.

**Eksempel**

Hvis vi skriver

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

den `\TeX` makroen blir utvidet til sine bestanddeler, som i plain TeX vil føre til at følgende tekst sendes til Lua (merk: Lua kan ikke behandle denne koden, det er bare et eksempel for å demonstrere prosessen):

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

Hvis vi *undertrykker* utvidelsen av `\TeX` makroen ved å bruke `\noexpand`

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

frembringes følgende Lua-kode (igjen, Lua kan ikke kjøre denne koden; det er bare et eksempel for å demonstrere `\noexpand`):

`local x= "\TeX "`

På grunn av `\noexpand`, `\directlua` vil ikke utvide `\TeX` men bare la token-verdien som representerer `\TeX` kommandoen passere gjennom uskadd inn i token-listen som bygges under det første trinnet i `\directlua`’s forbehandling.

**Merk:** Mellomromstegnet som vises etter `\TeX` innføres av LuaTeXs påfølgende konvertering av `\TeX` heltalls-tokenverdien tilbake til dens tekstlige representasjon (innenfor `tokenlist_to_cstring()` funksjonen).

#### \unexpanded{⟨material⟩}

`\unexpanded` er en utvidbar kommando som undertrykker utvidelse av alle tokens dannet fra `⟨material⟩`. *fjernet* fra inndataene og *erstattet* med resultatene av dens «utvidelsesatferd»; så hva betyr det egentlig for `\unexpanded`? Vanligvis, under *full utvidelse*, når utvidelsesprosessen for en bestemt kommando er fullført, fortsetter TeX-motoren med å lese/behandle eventuelle tokens som oppstår fra den kommandoens «utvidelsesatferd»—den må videre utvide eventuelle tokens som ble produsert. Men `\unexpanded` *omgår* enhver videre utvidelse: slik gjør den det.

Inne i TeX-motoren, `\unexpanded` konverterer kommandoen først tegnene og kommandoene i `⟨material⟩` til en midlertidig token-liste bestående av *ikke-utvidede* tokens. Etter at alle tokens er opprettet og lagret i den midlertidige token-listen, `\unexpanded` fører kommandoen til at `\directlua` til *hopper over* å gå tilbake for å lese og behandle dem—selv om \directlua utfører full utvidelse. I stedet blir disse *ikke-utvidede* tokens sendt rett gjennom og innlemmet i den hovedtoken-listen som bygges av `\directlua` (i `scan_toks()` funksjonen). `⟨material⟩` På denne måten blir alt i `\unexpanded{⟨material⟩}` konvertert til tokens, og utvidelsesprosessen hoppes over for det settet med tokens. Operasjonen til `\the\toks`, som vi diskuterer nedenfor.

**Eksempel**

`\unexpanded` gir resultater på en måte som ligner `\noexpand` unntatt at den kan hindre utvidelse av flere tokens; her er et eksempel:

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

som gir følgende tekst som kode for Lua:

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

**Merk**: Det er mellomromstegn etter hvert kommandonavn. Dette er igjen en konsekvens av LuaTeXs påfølgende konvertering av de ikke-utvidede tokens `\foo`, `\bar` og `\foobar` til tekst inne i `tokenlist_to_cstring()` funksjonen.

#### Beskyttede makrodefinisjoner

Den `\protected` kommandoen er et prefiks som brukes på en makrodefinisjon for å hindre at makroen blir utvidet når TeX bygger en utvidet token-liste, slik som token-listen bygget av `\directlua`’s forbehandling.

**Eksempel**

Anta at du definerer følgende makroer med og uten å bruke `\protected` prefikset:

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

Hvis du bruker Lua sin strengsammenføyningsoperator (`..`) til å skrive

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

`\directlua`LuaTeXs forhåndsbehandling ville produsere følgende kode for å sende til Lua:

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

`\macroA` er ikke definert med `\protected` så den blir utvidet og produserer den første delen av strengen som skal settes sammen, men `\macroB` er definert med `\protected` så den er ikke blitt utvidet.

Under forhåndsbehandlingen oppretter LuaTeXs `scan_toks()` funksjon et token for `\macroA`, kjente igjen at det var en vanlig utvidbar kommando og utvidet den: den utvidelsen produserer en sekvens av tegn-tokens, ett tegn-token for hvert tegn i `"This unprotected macro contains a string"`. Hvert tegn-token sendes videre og legges til token-listen som bygges.

Når `scan_toks()` oppretter tokenet for `\macroB` legger den merke til at den kommandoen var definert som `\protected` og utvider den ikke: tokenet som representerer `\macroB` passerer gjennom, urørt (ikke utvidet), inn i token-listen som bygges. Etter at den token-listen er bygget, er neste trinn i forhåndsbehandlingen, i `tokenlist_to_cstring()` funksjonen, å konvertere alle tokens i token-listen tilbake til deres tekstlige representasjon. Det ikke-utvidede tokenet som representerer `\macroB` oppdages og konverteres til sin tekstrepresentasjon, noe som resulterer i teksten `\macroB` som vises i koden som er ment for Lua. Merk at Lua faktisk ikke kan sette sammen `"This unprotected macro contains a string"..\macroB` for å produsere den endelige strengen fordi `\macroB` ikke har noen betydning i Lua sin syntaks, noe som fører til feilen `unexpected symbol near '\'`.

**Småfakta**: Pakken `\protected` kommandoen ble introdusert av $$\varepsilon\text{-}\mathrm{\TeX}$$, den første store utvidelsen av Knuths opprinnelige TeX-programvare, og støttes av alle TeX-motorer hvis kodeavstamning inkluderer $$\varepsilon\text{-}\mathrm{\TeX}$$.

### Ikke-utvidede tokens: Bruk av \the\toks i \directlua

Livet i programmering ville ikke vært det samme uten disse «spesialtilfellene» å håndtere, og bruken av `\the` i kombinasjon med `\toks` i en `\directlua` kommando er et slikt spesialtilfelle.

#### Kort bakgrunn om \toks

TeX-primitivet `\toks` instruerer en TeX-motor til å lagre noen tokens for senere bruk: i stedet for å sendes videre for videre behandling, blir disse tokensene lagt til side og lagret på et minneområde angitt ved hjelp av en *tokenregister*. For eksempel kan vi be en TeX-motor opprette noen tokens og lagre dem i tokenregister-plassering `100` ved å bruke

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

Her bruker TeX tokenregister `100` for å få tilgang til en kjent plassering i minnet: et lagringsområde beregnet for å holde tokenlister.

Tokens som representerer alt mellom `{` og `}` opprettes, *men ikke utvides*, og settes sammen i en tokenliste—lik tokenlisten vi undersøkte tidligere i denne artikkelen. For å gjenbruke disse tokensene ville vi skrive `\the\toks100` der `\the` (en utvidbar kommando) instruerer TeX til å hente de lagrede tokensene og sette dem inn på stedet der du skrev `\the\toks100`. `\the\toks` får TeX til å sette inn noen tokens på det stedet.

Den `\toks` kommandoen *utvider ikke* noen av tokensene den blir bedt om å opprette og lagre: den konverterer bare tegn og kommandoer mellom `{` og `}` til tokens og lagrer dem.

#### Tilbake til \directlua

I diskusjonen om utvidelse bemerket vi `\directlua{⟨code⟩}` utfører *full utvidelse* på `⟨kode⟩`: å fjerne alle utvidbare kommandoer og erstatte dem med resultatet av deres utvidelsesatferd—fortsatt å *videreutvide* eventuelle tokens som oppstår fra den opprinnelige utvidelsen av en utvidbar kommando.

`\the` er en utvidbar kommando så `\directlua` vil den utvide den; men når `\the` brukes i kombinasjon med `\toks` inne i `\directlua`, som i `\the\toks⟨token register⟩`, er de innsatte tokensene *ikke utvidet videre*. `\the\toks⟨token register⟩` Utvidelsen av *ikke-utvidede* injiserer sekvensen av `tokens, lagret i`⟨token register⟩ `\directlua`, direkte inn i token-listen som konstrueres av *ikke-utvidede*: denne atferden omgår den vanlige prosessen med full utvidelse. I praksis passerer disse tokensene gjennom, `\directlua`—denne gjennomstrømningsprosessen for ikke-utvidede tokens ligner i virkemåte på `\unexpanded`, som diskutert tidligere.

**Eksempel**

Anta at vi definerer makroen `\mymacro` som `\def\mymacro{\TeX}`. Den inneholder bare ett token for `\TeX` kommandoen (som er en makro): så vi har en utvidbar kommando `\mymacro` som inneholder en annen makro `\TeX`, som også er utvidbar.

Følgende kode vil føre til at Lua forsøker å opprette en strengvariabel `x`:

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

Innenfor \\\\`directlua`, blir tokenet for `\mymacro` \mymacro `\TeX`utvidet, men det resulterer i et annet utvidbart token,

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

Denne koden forsøker å definere en streng som inneholder tekst som representerer den utvidede versjonen av `\TeX` makroen. Hvis du prøver å kjøre dette eksemplet vil Lua forsøke å konstruere den strengen, men det vil mislykkes og gi en feil:

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

Senere i denne artikkelen skal vi utforske betydningen av «ugyldig escape-sekvens».

La oss nå kontrastere bruken av `\mymacro` med å plassere `\TeX` tokenet i en tokenliste generert av en `\toks` kommandoen:

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

LuaTeXs `\directlua` behandling vil generere denne tekststrengen for Lua:

`local x = "\TeX "`

Mellomromstegnet etter `\TeX` genereres av LuaTeXs konverteringsprosess fra kommando-token til streng.

**Men legg merke til**: Pakken `\TeX` at makroen har *inneholder* blitt utvidet til sine bestanddeler. `\the\toks100` fikk tokensene som er lagret i register 100 satt inn, men det er alt: de er *inneholder* ikke utvidet videre og blir innlemmet i hovedtoken-listen som bygges av `\directlua` (innenfor funksjonen `scan_toks()`). Å legge tokens inn i en tokenliste opprettet av `\toks` er enda en måte å forhindre at tokens blir utvidet på.

Hvis vi kjører dette eksemplet, gir det også en feil:

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

Vi utforsker Lua escape-sekvenser senere i artikkelen.

## Andre kommandoer/teknikker brukt i utvidelse

I denne delen ser vi på noen flere TeX-kommandoer/metoder som kan være nyttige i situasjoner der utvidelse blir anvendt (for eksempel innenfor `\directlua`).

### \string ⟨token⟩

`\string` er en utvidbar kommando som konverterer ⟨token⟩ til en serie av tegn-tokens, hver med kategori kode 12.

For eksempel, `\string\TeX` ville produsere en serie på 4 tegn-tokens `\`, `T`, `e` og `X` der hvert tegn tildeles kategori kode 12 (inkludert det innledende `\` tegnet).

Hvis vi skriver

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

den `\string` kommandoen vil bli utvidet, noe som resulterer i en sekvens av tegn-tokens med kategori kode 12. Etter `\string` at det er utvidet, vil de resulterende tegn-tokenene (som representerer hvert tegn i `\newcommand`) bli innlemmet i hovedtoken-listen som bygges av `\directlua`. `\directlua` Når

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

Når denne koden sendes til Lua, `print(x)` vil skrive ut strengen `x` til skjermen (konsollen). Men vi har vært litt lurere og med vilje brukt et eksempel på en kommando som starter med `\n`. Hvis du kan kjøre dette eksemplet på en lokal TeX-installasjon, vil du legge merke til at Lua skriver ut følgende tekst til skjermen:

```
   Jeg vil bruke
   ewcommand
```

For å kjøre denne koden på Overleaf kan du instruere LuaTeX til å skrive direkte til `.log` filen ved hjelp av LuaTeXs Lua-API-funksjon `texio.write(*string*)`:

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

Hvis du undersøker den resulterende `.log` filen vil du se at den også inneholder

```
   Jeg vil bruke
   ewcommand
```

Denne uventede utdataen skyldes at Lua tolker `\n` i starten av `**\n**ewcommand` som escape-sekvensen for linjeskift-tegnet (tegnkode 10): den antar at du vil starte en ny linje med tekst som begynner med `ewcommand`. Vi diskuterer Lua escape-sekvenser senere i denne artikkelen.

### \detokenize{⟨material⟩}

`\detokenize` er i praksis en versjon med flere tokens av `\string` og det er også en utvidbar kommando som konverterer alt i `⟨material⟩` til en sekvens av tegn-tokens med kategori kode 12—*unntatt* mellomromstegn (ASCII/Unicode-verdi 32) som får kategori kode 10. `\detokenize` setter også inn et etterfølgende mellomromstegn etter kommandonavn som er *kontrollord* (f.eks., `\foo`) men intet mellomromstegn settes inn etter *kontrollsymboler* (f.eks., `\#`, `\%` osv).

### Eksempel

Selv om makroene `\foohoo`, `\foo`, `\bar` og `\foobar` ikke er definert, hvis du skriver dette:

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

ville det produsere følgende tekst som kode for å sende til Lua-tolken

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

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

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

`\directlua` ville behandle `\foohoo`, gjenkjenne at det er en kommando og prøve å utvide den; men fordi `\foohoo` ikke er definert, ville det føre til en feil:

```
   ! Undefined control sequence.
   l.1 \directlua{local x = "\foohoo
                      \foo\bar\foobar"}
         ?
```

Siden `\string` og `\detokenize` konverterer argumentene deres til en serie tegn-tokens, `\directlua`sin utvidelsesprosess får faktisk muligheten til å oppdage tokens for utvidbare kommandoer `\foohoo`, `\foo`, `\bar`, eller `\foobar`: de blir gjort om til sekvenser av tegn-tokens lenge før de kan utløse utvidelse.

Som tidligere nevnt innebærer utvidelse av en kommando å fjerne den fra inndataene og erstatte den med resultatet av dens «utvidelsesatferd». Resultatene av utvidelsen (vanligvis tokens) leses deretter av TeX-motoren. Her er «utvidelsesatferden» for `\string` og `\detokenize` å absorbere tegn- og kommando-tokens fra inndataene og konvertere dem til sekvenser av tegn-tokens, som først lagres i en midlertidig tokenliste, som `\directlua` deretter leser. Disse tegn-tokenene blir innlemmet i hovedtoken-listen som bygges av `\directlua`.

Følgende figur viser hvordan `\string` konverterer `\foohoo` kommandoen til en sekvens av tegn-tokens, og produserer en midlertidig tokenliste som deretter leses av `\directlua` for å innlemme disse tegn-tokenene i hovedtoken-listen som bygges.

![](/files/3aa988c2e71c4fb8f31f9200ec6e04167506197f)

Hvis `\string` eller `\detokenize` møter tegn i argumentet sitt, for eksempel `\string a` eller `\detokenize{abc}` disse tegnene (her med kategori kode 11) produserer tegn-tokens, men med kategori kode 12.

Merknader:

Hvis vi går tilbake til eksemplet ovenfor:

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

som gir følgende tekst som kode for å sende til Lua-tolken

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

kan vi observere følgende:

* `\detokenize` har satt inn et mellomromstegn etter hvert makronavn, men `\string` gjorde ikke det.
* `\string` virker på ett enkelt token.
* I strengen `"\foohoo\foo \bar \foobar "` brukt til å definere `x` vil vi igjen møte Lua sin escape-tegn-mekanisme (diskutert nedenfor):

  * `\bar` starter med `\b` som er Lua-escape-sekvensen som brukes til å representere [backspace-tegnet](https://en.wikipedia.org/wiki/Backspace) (tegnkode 8);
  * kommandoer `\foohoo`, `\foo` og `\foobar` og alt starter med `\f`, Lua-escape-sekvensen som brukes til å representere [formfeed-tegnet](https://en.wikipedia.org/wiki/Page_break#Form_feed) (tegnkode 12).

  Fordi tegnsekvensene `\b` og `\f` brukes i en streng opprettet med doble anførselstegn `"..."` de vil gi uønskede resultater med mindre det tas grep for å forhindre det ved å bruke Luas såkalte *langklammer* strengmetode: et emne vi nå kan diskutere sammen med Lua-escape-sekvenser.

## Hva er «Lua-escape-sekvenser»?

Programmeringsspråk reserverer visse tegn til «spesialbruk» som en del av språkets syntaks: i praksis er disse tegnene definert til å ha en form for spesiell betydning. Men noen ganger trenger du midlertidig å «slå av» et slikt tegns spesielle betydning hvis du for eksempel vil at tegnet skal være innebygd som en del av en lengre streng der den vanlige oppførselen ville introdusere syntaksfeil. I praksis må dette tegnet behandles *uten* uten å utløse den vanlige tolkningen — slippe gjennom uten å bli lagt merke til. For å gjøre dette bruker programmerere en teknikk kalt *escaping* der et «spesialtegn» representeres av dets såkalte *escape-sekvens*.

Et standardeksempel (også støttet av Lua) er å bruke doble anførselstegn inni en streng, der du må escape de indre doble anførselstegnene ved hjelp av escape-sekvensen `\"`:

`"Når de ble spurt om LuaTeX svarte de: \"Det er en fantastisk TeX-motor!\" Jeg var enig."`

Lua-språket tilbyr en rekke mekanismer for å arbeide med escape-sekvenser:

* standardsekvenser, inkludert `\n` (linjeskift), `\r` (vognretur), `\\` (bakoverstrek), `\"` (dobbel anførselstegn), `\t` (horisontal tabulator), `\v` (vertikal tabulator) og `\'` (single quote);
* `\xXX`, hvor `XX` er en sekvens av nøyaktig to heksadesimale sifre;
* `\ddd`, hvor `ddd` er en sekvens på opptil tre desimalsifre;
* på det tidspunktet denne artikkelen ble skrevet (august 2019) brukte den nyeste versjonen av LuaTeX, selv om den ennå ikke var tilgjengelig på Overleaf, versjon 5.3 av Lua, som introduserte støtte for UTF-8-escape-sekvenser: `\u{XXX}`. Denne escape-mekanismen er for UTF-8-kodede Unicode-tegn der `XXX` er en sekvens av ett eller flere heksadesimale sifre som representerer tegnets kodepunkt. Legg merke til at de omsluttende klammeparentesene `{ }` er obligatoriske.

### Styring av escape-sekvenser

Tradisjonelt defineres strenger med doble anførselstegn, som i `"dette er en streng"`; inne i en slik streng kan du bruke escape-sekvenser: `"dette er en streng.\nJeg skal nå starte på en ny linje."`. Men Lua har en andre og *svært* praktisk mekanisme for å definere strenger: de såkalte *lange klammer* mekanismen, der du definerer en streng ved å omslutte teksten i `[[` og `]]`:

`[[Jeg er en streng med lange klammer]]`

Innenfor en streng opprettet med metoden med lange klammer er Luas tegn-escape-mekanisme *slått av*: escape-sekvenser behandles som vanlige tegn. For eksempel, i strengen

`[[Jeg er en streng med lange klammer\n streng]]`

den `\n` escape-sekvensen blir ikke behandlet som det enkelte linjeskifttegnet (ASCII-kode 13), men som to vanlige tegn: `\` fulgt av `n`.

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

Som vi senere skal utforske, tilbyr LuaTeX en samling spesialiserte, innebygde Lua-funksjoner som du kan bruke med `\directlua` for å styre LuaTeXs typografiske oppførsel. Blant disse mange funksjonene er en som heter `tex.print(*string*)` som lar deg sende `*string*` materiale fra Lua-kode tilbake til LuaTeX for typografering. Et veldig enkelt eksempel er:

`\directlua{tex.print("Hei, verden!")}`

som vil få LuaTeX til å sette `Hei, verden!`

Den `*string*` brukt i `tex.print(*string*)` kan også inkludere tekst som representerer TeX- og LaTeX-kommandoer som LuaTeX skal behandle. Men TeX/LaTeX-kommandoer begynner med et `\` tegn, noe som er problematisk med strenger opprettet med doble anførselstegn fordi Lua da vil prøve å tolke strengen, oppdage det innledende `\` tegn og tolke det som begynnelsen på en escape-sekvens. Når Lua prøver å behandle escape-sekvensen, vil det vanligvis mislykkes fordi det innledende `\` sammen med det første tegnet i mange TeX/LaTeX-kommandonavn ikke danner en gyldig escape-sekvens som Lua kjenner. For eksempel når man behandler en streng som `"Jeg liker \LaTeX"` Lua vil se `\L` og feile med feilen «ugyldig escape-sekvens», og dette er årsaken til feilene nevnt ovenfor.

#### Strenger med lange klammer kommer til unnsetning!

Metoden med lange klammer for å opprette (definere) strenger er ekstremt nyttig fordi selv om TeX/LaTeX-kommandoer begynner med et `\` tegn, deaktiverer metoden med lange klammer for strenger Luas escape-sekvensmekanisme. Her er et kort eksempel, og husk at vi må forhindre at makroer blir utvidet ved for eksempel å bruke `\protected` eller `\noexpand`.

Anta at vi definerer en `\newtest` makro slik

`**\protected**\def\newtest#1{Argumentet: #1}`

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

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

På grunn av bruken av `\protected`, blir ikke makroen `\newtest` utvidet, noe som resulterer i følgende tekst sendt til Lua:

`tex.print("\newtest {Hei}")`

Mellomromstegnet som legges til etter `\newtest` og før den åpne klammeparentesen (`{`) er en bieffekt av `\directlua`s konvertering av kommandotokens tilbake til deres tekstlige representasjon.

Denne koden sendes til Lua, som deretter utfører LuaTeX-funksjonen `tex.print()` men det er et problem, som viser seg på måter som avhenger av skrifttypene du bruker. I LaTeX på Overleaf vil du se utdata som dette:

![](/files/2ddc8e68bd8dfc270b4ccae7489d50356fc6ab0d)

sammen med en advarsel i loggfilen:

```
   Mangler tegn: Det finnes ingen
   (U+000A) i font [lmroman10-regular]:+tlig;!
```

I plain TeX kan du se utdata som ser omtrent slik ut:

![](/files/e44f74819281a1194f4d4658461519e9f22933e4)

I begge tilfellene blir `\newtest` makroen ikke kalt, og utdata er ikke det vi hadde til hensikt. Feilen skyldes Luas escape-tegnmekanisme: i teksten `\newtest {Hei}` makronavnet begynner med `\n` som Lua gjenkjenner som escape-sekvensen for et linjeskifttegn, så den erstatter `\n` med ASCII-tegn 10, eller i heksadesimal 0A. I LaTeX-feilmeldingen, `U+000A` er en måte å representere Unicode-verdien på med 4 heksadesimale sifre.

Fordi `\n` blir konvertert til linjeskifttegnet, ser ikke LuaTeX et makrokall, men tror i stedet at den blir bedt om å sette tekst som begynner med ASCII-tegnkode 10:

`⟨ASCII 10⟩ewtest {Hei}`

Avhengig av hvilken skrifttype som brukes, kan LuaTeX kanskje, eller kanskje ikke, være i stand til å sette `⟨ASCII 10⟩` tegnet, men resten av teksten blir satt som den er med `{` og `}` behandlet som en gruppe og ikke skrevet ut.

Plain TeX gir et annet resultat fordi standardfonten er Computer Modern Roman, som har en merkelig koding som resulterer i at en stor omega settes når tegnkode 10 sees.

For å forhindre disse problemene må vi bruke strenger med lange klammer for å hindre at Luas escaping-mekanisme brukes. Det riktige resultatet produseres med

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

som gir resultatet vist i det følgende skjermbildet:

![](/files/49b4c8717932fd518c94c75354e8b485c02595c4)

### Utvidelse og ikke-utførelse av ikke-utvidbare kommandoer

Når vi diskuterte utvidelse, bemerket vi at det er en prosess der en TeX-motor *fjerner* en utvidbar kommando (token) fra den gjeldende inputen og *erstatter* den med resultatet/ resultatene produsert av den utvidbare kommandoen. Fordi \directlua utfører *kun-utvidelses-* aktiviteter (for å generere en tokenliste), *ikke* bringer det ikke LuaTeX sin behandling noe lenger enn det. Når en utvidbar kommando er lest og fullt utvidet, vil resultatene av denne utvidelsen — som ofte inkluderer ikke-utvidbare kommandoer (tokens) — bli innlemmet i tokenlisten som bygges, klar til å bli konvertert tilbake til tekst for å sendes videre til Lua.

Det er et viktig prinsipp her: under *kun-utvidelses-* aktiviteter designet for å produsere en tokenliste, gjør TeX-motorer, inkludert LuaTeX, *utfører ikke* noen ikke-utvidbar primitiv, innebygd TeX-kommando.

Når det gjelder `\directlua{⟨code⟩}`, hvis den fullt utvidede versjonen av din `⟨kode⟩` produserer, eller inneholder ikke-utvidbare TeX/LaTeX-kommandoer, vil de *bli sendt videre til Lua* (representert som tekst).

#### Eksempel

Her er et eksempel som viser at ikke-utvidbare primitiver ikke utføres under kun-utvidelsesbehandling (som innenfor `\directlua`). Anta at vi definerer en makro `\setcountreg` slik:

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

**Merk**: Vi bruker `\relax` etter parameter `#2` for å forhindre at LuaTeX går for langt når den skanner inputen i søket etter den numeriske verdien (argumentet) som skal matche parameter `#2`.

Hvis, utenfor `\directlua`, kjører vi senere makroen slik

```
   \setcountreg{100}{50}
   Verdien i telleregister 100 er \the\count100.
```

da ville det gi ut

`Verdien i telleregister 100 er 50.`

I denne sammenhengen vil en hvilken som helst TeX-motor behandle makroen `\setcountreg`—utvide makroen, bestemme argumentene og fortsette å lese *og utføre* (eksekvere) kommandoer som finnes i makroens erstatningstekst (definisjon). Resultatet her er å tilordne `50` som verdien lagret i register `\count100`.

Imidlertid, når en TeX-motor utfører *kun-utvidelses-* aktiviteter, som den gjør med `\directlua`, vil den *ikke utføre* de ikke-utvidbare kommandoene som finnes i makroens definisjon.

Hvis vi skriver

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

den produserer følgende tekst som koden for Lua:

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

Lua-koden produsert ovenfor viser at innenfor `\directlua` den `\setcountreg` har blitt utvidet, argumentene identifisert og substituert inn i den passende parameteren (`#1` og `#2`) men den går ikke lenger enn det: den ikke-utvidbare primitive TeX-kommandoen `\count` ble *ikke utført* under `\directlua`sin utvidelsesbehandling.

Imidlertid vil LuaTeX utføre TeX-koden hvis vi sender den resulterende strengen `x` *tilbake til LuaTeX* via `tex.print(x)` slik

```
\count100=50 % sett \count100 til en startverdi på 50
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{250}]]
   tex.print(x)
}
verdien lagret i telleregister 100 er \the\count100.
```

Etter `\directlua` er ferdig, ville utdataene være

`verdien lagret i telleregister 100 er 250.`

viser at telleregister `100` inneholder nå verdien `250`.

Lua-koden produsert fra eksemplet ovenfor er

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

Denne koden definerer `x` til å være en streng opprettet med metoden med lange klammer, som brukes for å unngå feil med feilaktige escape-sekvenser. Hvis vi brukte doble anførselstegn `"..."` for å definere x, ville tegnkombinasjonen `\c` i starten av `\count` utløse en feil: `ugyldig escape-sekvens nær ' "\c'`.

LuaTeX Lua API-kallet `tex.print(x)` resulterer i at LuaTeX utfører TeX-kodesekvensen `\count 100=250\relax` og `\count100` blir tildelt verdien av `250` som man kan se av den typograferte utdataen:

`verdien lagret i telleregister 100 er 250.`

#### Forsiktighet: makroer og LuaTeX Lua API

I eksemplet ovenfor så vi at under `\directlua`s forbehandling (utvidelse) utførte ikke LuaTeX koden `\count 100=250`, som inneholder `ikke-utvidbare` primitive kommandoen `\count`: for å kjøre (utføre) den koden måtte vi *sende den tilbake til LuaTeX* via `tex.print()`.

`\directlua` er bare ett tilfelle der LuaTeX utfører kun-utvidelsesbehandling for å konstruere en tokenliste. Det finnes andre kommandoer som utfører lignende utvidelsesbehandling og tokenlistegenerering, som `\write` og `\edef`: disse kommandoene utfører heller ikke ikke-utvidbare primitiver under utvidelsesbehandlingen. Det er et generelt prinsipp at TeX-motorer ikke utfører ikke-utvidbare primitiver når de konstruerer en tokenliste under kun-utvidelsesbehandlingsaktiviteter.

**Omskriving av makroen vår for å bruke LuaTeX Lua API**

Vi kan skrive om `\setcountreg` makroen ved å bruke en LuaTeX Lua API-funksjon kalt `tex.setcount()`, og dermed unngå TeX-kommandoer for å endre verdien lagret i telleregister `100`:

```
   \def\setcount#1#2{\directlua{tex.setcount(#1,#2)}}
   \count100=50
   telleregister 100 inneholder \the\count100\par
   \setcount{100}{250}
   telleregister 100 inneholder nå \the\count100\par
```

Denne koden vil typografere:

```
telleregister 100 inneholder 50
telleregister 100 inneholder nå 250
```

Her bruker vi `tex.setcount()`, en av LuaTeX sine mange Lua API-funksjoner, for å *få direkte tilgang til* LuaTeX sitt interne datalagringsområde for å plassere verdien `250` i minneposisjonen som representerer telleregister `100`. Vi har i praksis *gått utenom* LuaTeX sine standard metoder for inputbehandling i TeX-motoren: å lese input, lage tokens og utføre TeX-primitive kommandoer. Men det finnes en advarende lærdom: ved å bruke LuaTeX sine Lua API-funksjoner kan kun-utvidelsesbehandlingsaktivitet *kan føre til sideeffekter*: endringer i verdier som er lagret inne i TeX-motoren, og som ellers ikke ville være mulig med rene TeX/LaTeX-kommandoer.

**Eksempel: uventede sideeffekter**

Her er et eksempel som viser *uventede* sideeffekter som kan oppstå med makroer som bruker `\directlua`. Anta at vi skriver følgende kode:

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

Å kjøre denne koden gir som utdata `12345`!

Hvordan kan det være? Vi *uttrykkelig* kalte ikke eksplisitt noen kode eller makroer for å sette den verdien i telleregister `999`. Eller gjorde vi det?

Vi definerte `\dochange` med en `\directlua` kommando som bruker `tex.setcount()` for å lagre verdien `12345` i telleregister `999`: i TeX-kode er det ekvivalenten til `\count999=12345`. Deretter brukte vi den standard TeX-primitive `\edef` for å definere makroen `\careful`—det er bruken av `\edef` som utløser den uventede sideeffekten.

`\edef` fullt utvider argumentet sitt: her oppdager den en utvidbar makro `\dochange` og utvider den. Den `\dochange` makroen bruker den utvidbare kommandoen `\directlua` som inneholder et Lua API-kall; så utvidelsen av `\dochange` fører til utvidelse av `\directlua` og det får `tex.setcount()` til å bli kalt, noe som endrer verdien i telleregister `999`.

Hvis vi definerer `\dochange` på nytt til å bruke TeX-kommandoer:

```
   Før: telleregister 999 inneholder \the\count999.\par
   \def\dochange{\count999=12345\relax}
   \edef\careful{\dochange}
   Etter: telleregister 999 inneholder \the\count999.\par
```

Å kjøre denne koden gir som utdata

```
Før: telleregister 999 inneholder 0.
Etter: telleregister 999 inneholder 0.
```

Det er tydelig at det ikke var noen effekt på `\count999`. Når `\edef` definerer `\careful` det, utvider det `\dochange` men den utvidelsen produserer bare ikke-utvidbare TeX-primitiver: de er *ikke utført* men bare *lagret* i tokenlisten som utgjør definisjonen av `\careful`.

Bare som en bonus forklarer det samme prinsippet hvorfor dette gir typografert utdata:

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

## Kort introduksjon til LuaTeX sin Lua API

Som vi har sett, `\directlua` gjør ikke bare at du kan skrive konvensjonell Lua-kode, eller en blanding av Lua- og TeX/LaTeX-kode, men den gir også tilgang til en samling ekstra Lua-funksjoner (spesifikke for LuaTeX) som du kan bruke (kalle) for å kommunisere med, eller direkte styre, de indre mekanismene i LuaTeXs typografiprogramvare. Vi har brukt flere Lua-funksjoner i denne artikkelen, `tex.print()`, `texio.write()`, `tex.setcount()` og disse, sammen med *mange* flere, er dokumentert i [LuaTeX Reference Manual](http://www.pragma-ade.com/general/manuals/luatex.pdf) der grupper av beslektede funksjoner omtales som *biblioteker*.

Du kan tenke på disse Lua-funksjonene som LuaTeXs Lua API (**Et**applikasjons- **P**rogrammerings **I**grensesnitt) som gir verktøyene til å konstruere avanserte typografi- og dokumenttekniske løsninger ved å styre typografisk oppførsel i LuaTeX ved hjelp av Lua som driver.

Som nevnt organiserer LuaTeX sitt API i et sett med funksjoner det kaller biblioteker: grupper av funksjoner som henger sammen gjennom formål eller handlinger. Hvert sett med funksjoner er utformet for å gi tilgang til et bestemt aspekt av LuaTeXs interne prosesser, datastrukturer, datalagring og typografialgoritmer. Internt er LuaTeX bygget opp av flere komponenter: programvarebiblioteker/-verktøy (for det meste skrevet i C) som ikke bare utgjør selve TeX-motoren, men også andre delsystemer, inkludert Lua, MetaPost, Kpathsea, FontForge, libpng og zlib. Disse bibliotekene er integrert for å bygge funksjonene og egenskapene til LuaTeXs kjørbare programvare, og det er gjennom Lua API at brukerne får tilgang til LuaTeXs funksjonalitet som er avledet fra integrasjonen og koordineringen av disse flere programvarekomponentene.

## Noen eksempler og fallgruver

I denne delen presenterer vi noen flere eksempler som bruker temaene, konseptene og forklaringene som er gitt i denne artikkelen.

### Bruk av tilde-tegnet (\~)

Lua-språket bruker `~` tegnet (kalt tilde) som en del av syntaksen, inkludert syntaksen for å utføre en «ikke lik»-test; for eksempel, for å teste om en variabel `x` er ikke lik `4` vi kunne skrive:

```
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
```

Hvis vi prøver å kjøre denne enkle Lua-koden via `\directlua`:

```
\directlua{
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
}
```

får vi en feil:

`[\directlua]:1: 'then' expected near '\'.`

Det er merkelig, for koden vår er korrekt: vi har brukt `'then'` og det finnes ingen `\` tegn i koden vår, så hva gikk galt? For å forstå dette må vi huske at for TeX/LaTeX, `~` er vanligvis definert som et «spesialtegn» med kategori-kode 13: såkalte aktive tegn, som er min-makroer og derfor underlagt ekspansjon. Når `\directlua` oppdager `~` tegnet *fjerner det* fra inndataene og *og erstatte det* med resultatet av ekspansjonen. Ved bruk av ren TeX inneholder den resulterende teksten (koden) som LuaTeX produserer og sender til Lua-tolkeren faktisk ikke `~` tegnet, og er:

`local x=3 if x \penalty \@M \ = 4 then print("x is not equal to 4") end`

Den `~` tegnet har blitt *fjernet* og *ekspandert* til sine bestanddeler av kommandoer — Lua-koden ovenfor følger av ren TeXs definisjon av det aktive tegnet `~`. Nå kan vi se hvorfor Lua svarer med feilen `'then' expected near '\'`— den begynner å parse denne koden, men møter ordet `\penalty` som ikke betyr noe for Lua og gir en syntaksfeil.

For å rette opp dette må `~` tegnet ha en trygg kategori-kode når `\directlua` behandler koden din; for eksempel kan vi midlertidig endre kategori-koden til `~` til 11 (bokstav) ved å sette koden inn i en gruppe:

```
\begingroup
\catcode`\~=11
\directlua{
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
}
\endgroup
```

Denne koden fungerer som forventet, og `x is not equal to 4` skrives ut til konsollen. Det finnes andre alternativer: vi kan bruke de ekspanderbare kommandoene `\noexpand` eller `\string`.

#### Ved bruk av \string⟨token⟩

Vi kan bruke `\string` på det ett-tegns `⟨token⟩` `~` som har kategori-kode 13 (aktivt tegn); `\string` konverterer `~` tegnet for å generere en tegntoken som har kategori-kode 12. Hvis vi gjør

```
\directlua{
   local x=3
   if x \string~= 4 then
   print("x is not equal to 4")
   end
}
```

produserer det Lua-koden vi trenger:

`local x=3 if x ~= 4 then tex.print("x is not equal to 4") end`

#### Ved bruk av \noexpand⟨token⟩

Vi kan bruke `\noexpand~` for å undertrykke ekspansjonen av det aktive tegnet `~`

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}
```

Den uekspanderte `~` tokenen går videre til tokenlisten som bygges opp i `\directlua` og vil bli konvertert tilbake til tekst, noe som gir fungerende Lua-kode.

### Ved bruk av #-tegnet

I Lua-språket kan `#` tegnet brukes til å finne lengden på en tabell. Men hvis vi prøver følgende kode

```
\directlua{
   local tbl = {}
   tbl[1] = "Hello"
   tbl[2] = "World"
   tex.print("Table length is "..#tbl)
}
```

kunne vi forvente at LuaTeX skulle sette

`Table length is 2`

men det gir en feil:

`\directlua]:1: attempt to get length of a number value`

Denne feilen utløses fordi `#` tegnet vanligvis har kategori-kode 6 (makroparameter) — `#` tegnet har to bruksområder i TeX/LaTeX: å angi makroparametere (`#1`, `#2`… `#9`) og erstatningsteksten i justeringsmaler (for `\halign` og `\valign`).

Når `\directlua` når det genererer tokener for å bygge tokenlisten sin, ser det `#` tegnet med kategori-kode 6 og lager en passende tegntoken for å representere det. Når tiden kommer for å konvertere den endelige tokenlisten tilbake til tekstform, får tegntokenen for # (med kategori-kode 6) en særskilt behandling: den skrives ut som *to påfølgende tegn*: `##`, noe som gir at følgende kode sendes til Lua:

`local tbl = {} tbl[1] = "Hello" tbl[2] = "World" print(##tbl)`

Ved konvertering til Lua-kode har den opprinnelige `#` blitt doblet, og det gir en feil:

`\directlua]:1: attempt to get length of a number value`

Dette problemet oppstår på grunn av TeXs syntaks, som bruker et dobbelt #-symbol `##` for å representere eller generere en enkelt `#` token; denne syntaksen brukes i makroer som definerer andre makroer som tar parametere, eller i makroer som brukes til å lage maler for `\halign` eller `\valign` tabellkonstruksjonskommandoer. Dette er ganske forvirrende, så la oss se på et eksempel.

#### Eksempel

La oss anta at vi definerer en makro `\mymacro` som tar én parameter, `#1`, men som også definerer en annen makro `\foo` som selv tar én parameter. For å skille mellom parameteren `#1` som brukes med `\mymacro` og behovet for å definere `\foo` slik at den kan bruke sin egen parameter `#1` krever TeX-syntaksen at du bruker `##1` inne i `\mymacro` for å representere parameteren som skal brukes med `\foo`:

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

Hvis du skulle skrive `\mymacro{Hey!}` ville den definere makroen `\foo` til å være

`\def\foo#1{Hey! Hello#1}`

Merk at `\mymacro`s parameter `#1` (`Hey!`) har blitt innlemmet i definisjonen av `\foo` og sekvensen `##1` har blitt konvertert til `#1` i definisjonen av `\foo`. Så vi kan bruke `\foo` slik:

`\foo{, World!}`

å sette `Hey! Hello, World!`

Vi kan løse `\directlua`sin behandling av `#` tegnet ved midlertidig å endre kategori-koden før LuaTeX behandler koden. For eksempel:

```
\begingroup
   \catcode`\#=11
   \directlua{
   local tbl = {}
   tbl[1] = "Hello"
   tbl[2] = "World"
   tex.print("Table length is "..#tbl)
}
\endgroup
```

Dette genererer Lua-koden

```
local tbl = {} tbl[1] = "Hello" tbl[2] = "World" tex.print("Table length is "..#tbl)
```

som setter resultatet vi forventet:

`Table length is 2`

### Ved bruk av %-tegnet

I TeX/LaTeX brukes `%` tegnet vanligvis til å inkludere kommentarer på én linje i koden din: for å signalisere til TeX-motoren at den skal ignorere alt fra dette punktet og fram til slutten av linjen der `%` er skrevet. Men i Lua-språket brukes `%` tegnet i noen svært nyttige strengebehandlingsfunksjoner, som `string.format(...)`, `string.gmatch(...)`, og `string.gsub(...)` der `%` tegnet spiller en viktig rolle som del av disse funksjonenes syntaks.

Når det brukes med TeX/LaTeX, `%` fungerer det som kommentartegnet fordi det er tildelt kategori-kode 14. For å få det til å oppføre seg som et vanlig tegn og slå av den vanlige TeX/LaTeX-oppførselen, må vi endre kategori-koden til noe trygt, for eksempel 12. Eksempelet `\directlua` nedenfor bruker en rekke teknikker som er diskutert tidligere i artikkelen, sammen med en som vi ennå ikke har nevnt: ``\catcode`\^^M=12``, som gjør at vi kan bruke Lua-kommentarer i koden vår; dette drøftes nedenfor.

#### Eksempel

Følgende eksempler er hentet fra [lua-users.org](http://lua-users.org/wiki/StringLibraryTutorial), tilpasset for bruk i `\directlua`.

```
\documentclass{article}
\begin{document}
\begingroup
\ttfamily
\let\\\relax
\catcode`\^^M=12 %<---we further explore this below!
\catcode`\%=12
\directlua{
   local str -- declare a local variable to hold the result

   tex.print("Using string.format():".."\\par")

   str=string.format("%s %q", "Hello", "Lua user!") -- string and quoted string
   tex.print(str.."\\par")
   str = string.format("%c%c%c", 76, 117, 97) -- char
   tex.print(str.."\\par")
   str=string.format("%e, %E", math.pi, math.pi) -- exponent
   tex.print(str.."\\par")
   str=string.format("%f", math.pi) -- float
   tex.print(str.."\\par")
   str=string.format("%g, %g", math.pi, 10^9) -- float or exponent
   tex.print(str.."\\par")
   str = string.format("%o, %x, %X", 99, 125, 125)  -- octal, hexadecimal, hexadecimal
   tex.print(str.."\\par")

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

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

   tex.print("\\vskip3mm".."Using string.gsub():".."\\par")
   str=string.gsub("banana", "(an)", "%1-") -- capture any occurrences of "an" and replace
   tex.print(str.."\\par")
}
\endgroup
\end{document}
```

Følgende skjermbilde viser det typografisk satte resultatet av koden ovenfor:

![Bruk av Lua-strengefunksjoner i \directlua](/files/831f831d1bba06018976a5a4318f3e622c4edea2)

## Hvorfor vises Lua-kode på én linje?

Som du kanskje har lagt merke til, presenteres alle de (genererte) Lua-kodefragmentene som vises i eksemplene i denne artikkelen som én enkelt tekstlinje: linjeskift som opprinnelig fantes i `\directlua` kodeutdragene følges ikke. Hvorfor er det slik? Det er fordi linjeskiftene i Lua-koden har blitt *fjernet* under LuaTeXs forbehandling i `\directlua`, noe som gjør at Lua-koden blir til én lang tekstlinje. Denne oppførselen kan spores til måten TeX-motorer håndterer linjeslutttegn på — markert med `\r` (vognretur) og `\n` (linjeskift) i programmeringslitteraturen. Nettopp hvorfor vi må bry oss om disse detaljene blir klart når vi diskuterer bruken av Luanismer for å kommentere ut deler av kode.

Når programvare skriver (lagrer) en tekstfil, avsluttes hver enkelt tekstlinje av såkalte «newline»-tegn — de faktiske newline-tegnene avhenger av programmet og operativsystemet som brukes til å skrive ut den filen. Wikipedia har en [interessant artikkel](https://en.wikipedia.org/wiki/Newline) som utforsker historien/utviklingen til newline-tegnene som brukes i dag.

I en hvilken som helst tekstfil kan de enkelte tekstlinjene avsluttes med ulike kombinasjoner av tegn, omtalt som vognretur (ASCII/Unicode-tegn 13) og/eller linjeskift (ASCII/Unicode-tegn 10), som betegnes med `\r` og `\n` henholdsvis. Fordi TeX-motorer er utformet for å være plattformuavhengige, trenger de en metode for å omgå den iboende plattformavhengige naturen til linjeslutt som brukes i tekstfiler. Naturligvis har TeX-motorer en innebygd (men konfigurerbar) metode for å håndtere linjeslutttegn.

### Hvordan TeX-motorer håndterer linjeslutt

Når LuaTeX behandler `\directlua{⟨code⟩}` leser den teksten som finnes i din `⟨kode⟩` og bruker standardmetoder i TeX-motoren for å behandle eventuelle linjeslutt som finnes i din `⟨kode⟩`. Som standard fører disse standardmetodene i TeX til at alle linjeslutttegn (vognreturer og linjeskift) fjernes og erstattes av mellomromstegn. Vi sier «som standard» fordi håndteringen av linjeslutttegn i en TeX-motor kan endres via en brukerkonfigurerbar parameter kalt `\endlinechar`. Her gir vi en kort oversikt i to steg, men flere detaljer finnes i Overleaf-artikkelen [En introduksjon til \endlinechar: Hvordan TeX leser linjer fra tekstfiler](/latex/no/dybdeartikler/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

#### Trinn 1: TeX setter inn sitt eget linjeslutttegn

Etter å ha lest en linje tekst fra inndatafilen din, fjerner TeX-motorer umiddelbart eventuelle `\r` eller `\n` tegn fra slutten av den linjen. Deretter *setter TeX-motorer inn* (legger tilbake) sitt eget linjeslutttegn på slutten av linjen. Det tegnet bestemmes av verdien til en brukerkonfigurerbar TeX-parameter kalt `\endlinechar` og det er gjennom denne mekanismen TeX-motorer kan behandle linjeslutttegn på en plattformuavhengig måte: de velger og setter linjeslutttegnet uavhengig av hva som opprinnelig sto i inndatatekstfilen.

Vanligvis bruker TeX-motorer innstillingen

`\endlinechar=13`

som er vognreturtegnet (`\r`). Likevel kan brukere alltid tilordne en annen tegnkode som verdien av `\endlinechar`— noe vi skal se senere i denne artikkelen.

Følgelig blir eventuelle linjeslutttegn som finnes i din `⟨kode⟩` som skal behandles av `\directlua{⟨code⟩}` fjernet og erstattet av ett enkelt tegn som bestemmes av selve TeX-motoren. Merk at TeX-motorer utfører denne linjesluttbehandlingen umiddelbart etter å ha lest en ny tekstlinje fra en fil og *før* behandler eventuelle tegn på den linjen (for å generere tokener). Men dette er ikke hele historien: det TeX-motoren *ikke* gjør med disse linjeslutttegnene (som den har satt inn) forklarer hvorfor Lua-koden blir til én enkelt linje.

#### Trinn 2: TeX konverterer sitt linjeslutttegn til et mellomrom

I tillegg til å sette inn sitt eget linjeslutttegn, definert av verdien til `\endlinechar`, bruker TeX-motorer også kategori-kode 5 for tegn som skal *behandles som* et linjeslutttegn. Dette gjør at TeX-motorer vanligvis arbeider med:

1. et linjeslutttegn definert av `\endlinechar`;
2. det samme tegnet *vanlig* som er tildelt kategori-kode 5.

Det er det TeX gjør med det linjeslutttegnet som forklarer vår utfordring med enkeltlinjer med Lua-kode. Når en TeX-motor behandler en inndatalinje, vil den til slutt oppdage det siste tegnet i den linjen: tegnet definert av `\endlinechar`. Vanligvis har det tegnet kategori-kode 5, noe som får TeX til å *erstatte det* med et mellomromstegn: dvs. ved linjeslutt fjerner TeX i praksis sitt linjeslutttegn og erstatter det med et mellomrom. Som en sidebemerkning bruker TeX-motorer også tegn med kategori-kode 5 til å oppdage blanke linjer og starte et nytt avsnitt, men det skal vi ikke ta opp her.

Selvfølgelig kan du, siden dette er TeX, utføre alle slags spesielle makroprogrammeringstriks ved å tilbakestille `\endlinechar` til et annet tegn, og/eller gi tegnet som er tildelt `\endlinechar` en kategori-kodeverdi du selv velger.

Hvis du vil hindre at Lua-koden blir én enkelt tekstlinje, kan du enten (midlertidig) endre verdien som er tildelt `\endlinechar` eller endre kategori-koden til den vanlige linjesluttavslutteren `\r`.

### TeXs merkelige ^^-notasjon

I de følgende seksjonene vil vi møte TeXs uvanlige `^^` notasjon, som er kjent som «den utvidede tegnmekanismen». Den ble utformet av Knuth som en måte å gjøre det enklere å skrive inn «kontrolltegn» som linjesluttavsluttere, tabulatorer og så videre. For eksempel:

* `^^J` representerer tegnkode 10 (`\n`, linjeskift);
* `^^M` representerer tegnkode 13 (`\r`, vognretur).

Tegnsekvenser som `^^M` konverteres tidlig i TeXs inndataskanningsprosess til sine tilsvarende tegnkoder, når TeX leser inn tegn for å generere de tilsvarende tegntokenene.

### Endring av tegnet som er tildelt \endlinechar

Når vi husker at vi fortsatt må forhindre ekspansjon av `~` tegnet, kan vi skrive

```
\begingroup
\endlinechar=10 % Change the end-of-line character to \n
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}% don’t want the \n appearing here
\endgroup% or a \n here
```

Innstillingen ovenfor for `\endlinechar` gjør at LuaTeX legger til tegnkode 10 (`\n`, linjeskift) på slutten av hver linje den leser inn. Vi gjør dette fordi `\n` (linjeskift) vanligvis har kategori-kode 12, noe du kan teste ved å skrive ``\the\catcode`\^^J``. Fordi `\n` ikke har kategori-kode 5, vil ikke LuaTeX konvertere det til et mellomromstegn, så det blir stående på slutten av hver linje som leses inn av LuaTeX. Dette fører til at et tegn med kode 10 blir værende på slutten av hver linje, og dermed kommer det med inn i tokenlisten som bygges opp av `\directlua` og deretter dukker opp igjen i Lua-koden når tokenlisten er konvertert til tekst. Med endringen ovenfor sendes Lua-koden til Lua-tolkeren som følgende tegnsekvens:

**\n**local x=3\*\*\n**if x \~= 4 then**\n**print("x is not equal to 4")**\n**end**\n\*\*

der **\n** notasjonen er ment å representere tegnkode 10 *inneholder* en eller annen ukjent makro `\n`. Nå vil Lua-tolkeren se linjeskift i koden, akkurat slik den opprinnelig var skrevet i `\directlua` kommandoen:

```
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
```

Forresten, merk at det aller første tegnet i Lua-kodestrengen er `\n` (før `lokale` nøkkelordet). `\n` Det

`\directlua{`

skyldes linjen `{` fordi det er et linjeskift rett etter den innledende

`\directlua{%`

### Endring av kategori-koden til \r

For å bevare linjeskift i Lua-koden vår kan vi også endre kategori-koden til `\r` til noe annet enn 5, slik at `\r` ikke lenger gjenkjennes (behandles som) et linjeslutttegn. Med denne teknikken bruker LuaTeX fortsatt `\endlinechar=13` og vil fortsette å legge til en `\r` på slutten av hver linje; men fordi `\r` ikke lenger har kategori-kode 5, vil LuaTeX ikke gjenkjenne `\r` tegnet som et linjeslutttegn: det vil ikke konvertere det til et mellomrom og sender det videre uskadd slik at det vises i Lua-koden.

Når vi husker at vi fortsatt må forhindre ekspansjon av `~` tegnet, kan vi skrive

```
\begingroup
\catcode`\^^M=12 % change category code of \r to 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}
\endgroup
```

I dette tilfellet sendes Lua-koden til Lua-tolkeren som:

**\r**local x=3\*\*\r**if x \~= 4 then**\r**print("x is not equal to 4")**\r**end**\r\*\*

der `\r` notasjonen er ment å representere tegnkode 13, ikke en ukjent makro `\r`. Som med `\endlinechar` eksempelet, vil Lua-tolkeren nå se linjeskift i koden, akkurat slik den opprinnelig var skrevet i den `\directlua` kommandoen:

```
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
```

Forresten, merk igjen at det aller første tegnet i Lua-kodestrengen er `\r` (før nøkkelordet local): dette kommer også fra linjen

`\directlua{`

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

Svaret skyldes risikoen for ved et uhell å introdusere feil som utløses av `\r` (med kategori-kode 11) som blir lagt til slutten av TeX/LaTeX-kommandoer lest fra inndatafilen vår. Ta dette eksemplet:

```
\begingroup
\catcode`\^^M=11 % change category code of \r to 11
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}
\endgroup
```

som gir en feil:

```
   ! Undefined control sequence.
   l.9 \endgroup
```

Hvordan kan det være sant, når `\endgroup` er en standard TeX-primitive kommando? Årsaken til feilen er ganske subtil: Når LuaTeX leste den siste tekstlinjen — den som inneholdt `\endgroup`— la den også til `\endlinechar` tegnet `\r` på slutten av den linjen. Nå ser LuaTeX, i minnet sitt, tegnsekvensen

`\endgroup\r`

der vi bruker `\r` for å angi tegnet med kode 13 — ikke navnet på en ukjent TeX-makro `\r`.

Da LuaTeX leste denne linjen fra tekstfilen vår, var den opprinnelige `\begingroup` fortsatt i kraft: vi befinner oss inne i en gruppe som ennå ikke er avsluttet ved å kjøre den tilsvarende `\endgroup` kommandoen — noe som ville føre til at `\r` gikk tilbake til den tidligere kategori-kodeverdien 5.

Når LuaTeX begynner å behandle (lage tokener fra) tekstlinjen `\endgroup\r` gjenkjenner den det første tegnet `\` som escape-tegnet, noe som får LuaTeX til å begynne å lete etter navnet på en kommando. For å identifisere et kommandonavn leter LuaTeX etter en sekvens av tegn med kategori-kode 11, men fordi `\r` også har kategori-kode 11, tror LuaTeX at `\r` tegnet (fortsatt med kategori-kode 11) danner *en del av en kommando* kalt `\endgroup\r` som selvfølgelig ikke finnes, så LuaTeX rapporterer en `Udefinert kontrollsekvens` feil. Derfor brukte vi kategori-kode 12 og ikke 11.

Fordi LuaTeXs feilmelding ble skrevet til konsollen, kunne vi ikke lett se/legge merke til `\r` tegnet, så det var ikke åpenbart hva som hadde forårsaket feilen.

### Hvorfor bryr vi oss om linjeslutt?

Årsaken er å gjøre det mulig å bruke Luanes kommentarmetode i koden din! Du kan bruke LuaTeXs standardmekanisme for å legge til `%` tegn for å kommentere ut enkel linjer i koden din; men Lua-språket har sine egne, svært nyttige, *flerlinjede* kommenteringsmekanismer som du kanskje vil dra nytte av.

La oss begynne med å se hva som skjer hvis vi prøver å bruke Lua-kommentarer på én linje uten å håndtere linjeskiftproblemer. Mens TeX bruker `%` tegnet for å kommentere ut enkeltlinjer med kode, bruker Lua to bindestreker: `--`.

Hva skjer hvis vi prøver å kjøre dette:

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- I'm going to output the result of this complex test
   print("x is not equal to 4")
   end
}
```

Vi får en feil:

`[\directlua]:1: 'end' expected near <eof>`

Denne feilen skyldes fraværet av linjeskift i Lua-koden som sendes til tolken, som bare ser én enkelt sammenhengende streng der kommentaren starter et stykke ut i den strengen:

```

local x=3 if x ~= 4 then -- I'm going to output the result of this complex test print("x is not equal to 4") end
```

Alt etter `**local x=3 if x ~= 4 then**` blir behandlet som kommentert ut, noe som får tolken til å se en ufullstendig bit Lua-kode, og det resulterer i feilen

`'end' expected near <eof>`.

der `<eof>` betyr slutten av filen.

Som du sikkert har gjettet, må vi rette opp dette ved å sikre at linjeskift overføres til den resulterende Lua-koden, noe vi kan oppnå ved for eksempel å endre kategori-koden til `\r` til 12:

```
\begingroup
\catcode`\^^M=12 % change category code of \r to 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Jeg skal skrive ut resultatet av denne komplekse testen
   print("x is not equal to 4")
   end
}
\endgroup
```

Nå ser Lua-tolken en streng, men den inneholder `\r` linjeskift slik de er skrevet i `\directlua` fragmentet:

**\r**local x=3\*\*\r**if x \~= 4 then**\r\*\*-- Jeg skal skrive ut resultatet av denne komplekse testen\*\*\r**tex.print("x er ikke lik 4")**\r**end**\r\*\*

Dette tilsvarer i praksis å skrive

```
   local x=3
   if x \noexpand~= 4 then
   -- Jeg skal skrive ut resultatet av denne komplekse testen
   print("x is not equal to 4")
   end
```

noe som betyr at Lua kan behandle denne koden riktig og ignorere linjen vi kommenterte ut.

**Blokkommentarer**

Lua-språket støtter også en syntaks det kaller [«blokkommentar»](https://www.lua.org/pil/1.3.html) (eller *lang kommentar*): disse starter med `--[[` og gjelder frem til den tilsvarende `]]`. Vi kan bruke denne praktiske syntaksen til å skrive kommentarer over flere linjer, eller kommentere ut deler av kode vi midlertidig vil fjerne:

```
\begingroup
\catcode`\^^M=12 % change category code of \r to 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   --[[ Jeg skal skrive ut resultatet av denne komplekse testen
   rett og slett fordi det faktisk er
   en så fantastisk konklusjon]]
   print("x is not equal to 4")
   end
}
\endgroup
```

## Til slutt

Først og fremst, gratulerer hvis du har klart å lese deg gjennom denne omfattende artikkelen! Vi har forsøkt å lage en rimelig dekkende guide til TeX-relaterte begreper og emner som gir bakgrunnen som trengs for å få mest mulig ut av LuaTeX via `\directlua` kommandoen. Vi håper å ha laget en artikkel som er opplysende og som bidrar med noe nyttig og verdifullt for Overleaf-brukermiljøet, og utover det. Som alltid setter vi stor pris på tilbakemeldinger, så ikke nøl med å [ta kontakt med oss](https://www.overleaf.com/contact) komme med kommentarer til denne artikkelen eller forslag til flere temaer du gjerne vil at vi skal skrive om.

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

### Og til slutt ... bare bruk luacode-pakken

Selv om TeX og Lua fungerer på grunnleggende ulike måter, deler disse språkene en rekke tegn som har «spesiell betydning» i hver språkkontekst — som \\, %, \~, #, ^, & — selvsagt tillegger Lua og TeX disse spesielle betydningene for *svært* ulike formål. Vår gjennomgang av problematiske tegn viser hvorfor det kan oppstå vanskeligheter og hvordan du kan løse dem; det kan imidlertid være ganske kjedelig å rette mange små Lua-kodefragmenter manuelt, så de fleste brukere foretrekker å bruke LaTeX-pakker som fjerner disse utfordringene. En slik pakke er [`luacode`](https://ctan.org/pkg/luacode?lang=en) som tilbyr en rekke funksjoner utformet for å forenkle arbeid med `\directlua`, men i det minste har du nå kanskje en bedre forståelse av problemene `luacode` den løser for deg.


---

# 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/no/dybdeartikler/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.
