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

# En introduktion till LuaTeX (del 2): Förstå \directlua

## Syftet med denna artikel

I den första delen av denna artikel, [En introduktion till LuaTeX (del 1): Vad är det – och vad gör det så annorlunda?](/latex/sv/fordjupade-artiklar/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md), vi gick kort igenom LuaTeX som en extremt mångsidig TeX-motor: en sofistikerad, programmerbar sättningsmotor som erbjuder ett brett utbud av verktyg för att konstruera lösningar för dokumentteknik och produktion.

I denna avslutande del tittar vi närmare på den viktigaste komponenten i LuaTeX-verktygslådan: `\\directlua` kommandot som utgör ”porten” till programmatisk styrning av LuaTeX:s sättning via skriptspråket Lua.

Men att fullt ut utnyttja LuaTeX via `\\directlua` kräver viss bakgrundskunskap om flera TeX-ämnen: TeX:s token, tokenlistor och expansionsmekanism. Syftet med denna artikel är att utforska och förklara dessa grundläggande TeX-begrepp: att sammanfoga de TeX-relaterade processer som ligger bakom `\\directlua` för att utveckla en förståelse för hur det fungerar och ge den grund som du kan bygga dina egna sättningslösningar på med LuaTeX.

Denna artikel innehåller många korta exempel för att demonstrera och förklara viktiga aspekter av `\\directlua`’s beteende, och undviker medvetet alltför komplex kod till förmån för korta kodfragment. Vid behov använder exemplen grundläggande (rå/plain) TeX—även om de flesta använder och föredrar LaTeX (makron) har grundläggande TeX-kommandon fördelen av enkelhet.

## Introduktion till Lua i LuaTeX

[Lua](https://www.lua.org/about.html) är ett skriptspråk vars [källkod](https://www.lua.org/download.html) är mycket portabel och enkel att bädda in i programvaruapplikationer, vilket gör det möjligt för utvecklare att lägga till skriptfunktioner i sina program. Lua har bäddats in i [många applikationer](https://en.wikipedia.org/wiki/List_of_applications_using_Lua) och är ett populärt val inom mjukvaru- och spelindustrin—kanske är det mest kända exemplet [World of Warcraft](https://wowwiki.fandom.com/wiki/Lua_functions).

LuaTeX, som namnet antyder, är en TeX-motor som bäddar in skriptspråket Lua, vilket ger användarna möjlighet att styra LuaTeX:s sättningsbeteende genom att inkludera Lua-program (skript) i sina dokument. Utöver direkt styrning av LuaTeX kan användarna utnyttja Lua enbart som ett mycket kapabelt programmeringsspråk för att utföra uppgifter som kan vara extremt svåra att åstadkomma med TeX-språket—vilket, enligt varje rimlig bedömning, är en utmaning att lära sig och bemästra. Genom tillägget och integreringen av Lua blir LuaTeX en mycket mångsidig och kraftfull TeX-motor som direkt stöder två programmeringsspråk.

### Använd Lua och TeX i ditt dokument: skriv \\\directlua

Lua och TeX är två *mycket olika* programmeringsspråk: Lua ligger mycket närmare det som de flesta uppfattar som ett programmeringsspråk, men TeX, med sina kategorikoder, token, makron och expansionsmekanism, ligger långt ifrån de flesta människors erfarenheter/förväntningar på ett språk att skriva program i. Historien har dock visat att TeX-språket har bestått eftersom det är bra på det som det skapades för: att styra sättning, även om dess arbetssätt är något gåtfullt.

För att hantera utmaningen med att blanda språken Lua och TeX i ett och samma TeX-dokument introducerade LuaTeX:s utvecklare ett nytt kommando som kallas `\\directlua` som är vägen till att använda Lua—både som ett fristående programmeringsspråk i sig självt och för att styra LuaTeX:s sättningsbeteende.

Den `\\directlua` kommandot låter användare bädda in Lua-kod i sina TeX-dokument; den koden skickas därefter vidare till LuaTeX:s inbyggda Lua-språktolk. Men `\\directlua` gör det också möjligt för dig att *kombinera* Lua- och (La)TeX-kod tillsammans, inom samma `\\directlua` kommando—även om det inför ytterligare komplexitet på grund av grundläggande skillnader mellan Lua- och TeX-baserade programmeringsspråk. Den viktigaste utmaningen när man använder en kombination av (La)TeX- och Lua-kod är att se till att dessa två språk samexisterar fredligt och inte ”kommer i vägen för varandra”.

`\\directlua` är bäst lämpat för användning med kortare Lua-kodfragment i dokumentet, men du kan använda det med mer omfattande Lua-program om du vill. Generellt sparas mer omfattande Lua-program och Lua-kodbibliotek i externa filer som kan laddas med Lua:s `dofile()` funktion i ett `\\directlua` kommando. Ur TeX-bearbetningssynpunkt är en betydande fördel med att använda externa Lua-kodfiler att man undviker komplikationer som uppstår från TeX:s kategorikodsmekanism—ett ämne som utforskas fullt ut i denna artikel.

### Mer formell beskrivning av \\\directlua

Den [LuaTeX:s referensmanual](http://www.pragma-ade.com/general/manuals/luatex.pdf) beskriver `\\directlua` på följande sätt (något modifierat):

> För att sammanfoga Lua-kod med TeX-inmatning behövs några nya primitiver. Primitiven `\\directlua` används för att omedelbart exekvera Lua-kod. Den grundläggande syntaxen är `\\directlua{⟨code⟩}`. Paketet `⟨code⟩` expanderas fullständigt och matas sedan in i Lua-tolken. Efter att läsning och expansion har tillämpats på `⟨code⟩`, konverteras den resulterande tokenlistan till en sträng som om den visades med `\\the\\toks`.

Detta är förstås tekniskt korrekt men kanske inte så lätt att förstå utan viss kunskap om TeX-processer på lägre nivå—såsom token och expansion.

## Förstå \\\directlua: Vilka ämnen kommer vi att gå igenom?

I denna artikel ska vi titta närmare på några viktiga bakgrundsämnen och erbjuda ett antal exempel som är utformade för att demonstrera hur `\\directlua` fungerar och var (eller varför) du behöver vara försiktig när du kombinerar TeX och Lua i din `⟨code⟩`.

Vi kommer att utforska följande ämnen i tillräcklig detalj för att ge en grund för att förstå `\\directlua` och dess ”förbearbetning” av koden du använder i det:

* kategorikoder och TeX-token: konvertering av text till token och token till text;
* TeX:s expansionsprocess (och hur man förhindrar expansion);
* Lua:s escape-sekvenser/-mekanismer för tecken och strängar;
* användning av Lua-stilkommentarer;
* en kort introduktion till LuaTeX:s Lua-API.

Om du förstår hur TeX-motorer skapar och använder token och blir medveten om TeX:s expansionsmekanism har du den grund som behövs för att låsa upp den otroliga mångsidigheten hos LuaTeX:s `\\directlua` kommandot.

## Grunderna: från text till token och från token till text

Overleaf har publicerat flera artiklar som ger en fördjupad titt på TeX-token och närliggande begrepp, så vi kommer inte att upprepa allt det materialet här; i stället kommer vi att skissera de områden/ämnen som är relevanta för att utveckla en bättre förståelse av `\\directlua`.

Här är en lista över tidigare publicerade artiklar som kan vara av intresse:

* [Vad är en TeX-token?](/latex/sv/fordjupade-artiklar/53-what-is-a-tex-token.md)
* [Vad är en TeX-tokenlista?](/latex/sv/fordjupade-artiklar/54-what-is-a-tex-token-list.md)
* [Hur fungerar \\\expandafter: En introduktion till TeX-token](/latex/sv/fordjupade-artiklar/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)
* [En serie i sex delar: Hur fungerar TeX-makron egentligen?](/latex/sv/fler-amnen/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### Förstå teckentoken

Varje tecken som en TeX-motor kan läsa från en textfil representeras av två numeriska värden:

* dess *teckenkod* (ASCII-värde eller, i dag, dess Unicode-kodpunkt);
* ett andra, TeX-centrerat, värde som kallas dess *kategorikod*.

Läsare som vill veta mer om kategorikoder kan vara intresserade av att läsa denna introduktion publicerad av Overleaf: [Så var börjar vi? Med kategorikoder](/latex/sv/fler-amnen/19-how-tex-macros-actually-work-part-1.md#so2c-where-do-we-start3f-with-category-codes).

Till exempel, om en TeX-motor läser in ett tecken `Ett` har den tillgång till två informationsbitar: `Ett`s teckenkod (65) och dess kategorikod (vanligen 11). När TeX väl har matat in det tecknet `Ett`, kommer dess kategorikod inte att ändras, men användarmakron kan göra ändringar i kategorikod som kan påverka alla *efterföljande* tecknet `Ett` som *ännu inte har lästs* av TeX. Följaktligen behöver TeX registrera att *detta* tecknet `Ett`, *nyss inlästa*, har kategorikod 11. För att göra det använder TeX heltalsparet (65,11) för att beräkna ett annat heltalsvärde som det kallar en *teckentoken*. Genom att beräkna det tokenvärdet, som skickas vidare till TeX:s interna bearbetning, blir just det `Ett` och dess kategorikod *bundna samman*; i praktiken *inkapslar* de data som TeX behöver känna till om det tecknet för användning i eventuella efterföljande sättningsaktiviteter djupare inne i TeX-motorn.

#### Hur beräknas teckentoken?

För det första behöver vi komma ihåg att TeX-motorer använder kategorikod 13 för att skapa så kallade *aktiva tecken*: varje tecken med kategorikod 13 beter sig som ett minimakro; därför, och som vi ska se nedan, beräknas token för aktiva tecken annorlunda än för vanliga tecken med andra kategorikoder såsom 10, 11 eller 12.

För *icke-aktiva* tecken:

* äldre 8-bitarsmotorer (Knuths TeX, e-TeX, pdfTeX) beräknar teckentoken för *icke-aktiva* tecken med

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

* för LuaTeX, som måste hantera Unicode-teckenvärden, är beräkningen för *icke-aktiva* tecken liknande men ger mycket större heltalsvärden:

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

Om vi går tillbaka till vårt tidigare exempel med bokstaven A med kategorikod 11 skulle LuaTeX beräkna ett teckentokenvärde på $$2^{21} \times 11 + 65 = 23068737$$. *binder* det specifika tecknet A till värdet 11 för kategorikoden. Användarmakron kan ändra kategorikoden för varje efterföljande tecken A, men detta teckens kategorikod har låsts genom att omvandlas till en token för användning när det passerar genom LuaTeX:s inre arbete. LuaTeX har bevarat, eller inkapslat, den avsedda betydelsen hos det tecknet såsom den bestämdes vid inläsningstillfället.

TeX-motorer använder totalt [16 olika kategorikoder](/latex/sv/fler-amnen/43-table-of-tex-category-codes.md) och *varje* av dessa kategorikoder kan tilldelas, via `\\catcode` kommandot, till *varje* tecken som TeX-motorn är kapabel att läsa. Ändringar av kategorikoder används för att ändra sättet TeX-motorer bearbetar särskilda tecken i indata, vilket gör det möjligt för TeX-användare att skriva makron som ger särskilda sättningsresultat eller beteenden.

**Aktiva tecken**

Som nämnts använder TeX-motorer kategorikod 13 för att ge ett tecken en ”speciell betydelse”, vilket gör det till ett så kallat *aktivt tecken* som beter sig som ett minimakro: ingen inledande `\` krävs, det isolerade tecknet räcker, tack vare sin kategorikod, för att utlösa dess makrolika beteende.

Eftersom ett aktivt tecken fungerar som ett minimakro omvandlas det inte till en *teckentoken* utan till en andra (heltals-)tokenstyp som kallas en *kommandotoken*. Dessa beräknas enligt följande:

* för äldre 8-bitarsmotorer (Knuths TeX, e-TeX, pdfTeX) beräknas token för aktiva tecken via:

1. beräkna ett mellanliggande värde som kallas $$\text{curcs}$$ (**cur**rent **c**ontrol **s**equence) där $$\text{curcs} = \text{character code} + 1$$3. beräkna tokenvärdet där $$\text{active character token} = \text{curcs} + \text{4095}$$

* för LuaTeX är beräkningen lite mer komplex eftersom den måste hantera hela spannet av Unicode-tecken, som alla kan göras aktiva:

1. beräkna det mellanliggande heltalsvärdet $$\text{curcs}$$ genom att tillämpa en så kallad *hashfunktion* på det aktiva tecknets Unicode-kodpunktsvärde uttryckt i UTF-8: $$\text{curcs}=\texttt{hashfunction}\text{(UTF-8 text for Unicode value of active character)}$$3. beräkna det heltalsbaserade tokenvärdet: $$\text{active character token} = \text{curcs} + 2^{29} - 1$$

**Exempel**

* 8-bitarsmotorer: tokenberäkningen för det aktiva tecknet `~` (teckenkod 126) resulterar i $$\text{curcs} = 126 + 1 = 127$$, vilket ger ett tokenvärde på $$4095 + 127 = 4222$$.
* LuaTeX: tokenberäkningen för det aktiva tecknet `~` resulterar i $$\text{curcs}=3186$$ vilket ger ett tokenvärde på $$3186 + 2^{29} - 1 = 536874097$$. LuaTeX-token använder mycket större heltalsvärden!

### Förstå kommandotoken

Utöver att bearbeta *enskilda* tecken kan TeX-motorer naturligtvis bearbeta *sekvenser* av tecken som kallas *kommandon* (eller, mer korrekt, *kontrollsekvenser*). Enligt tradition används `\` tecknet för att signalera början av ett kommando, men det är bara en konvention—i själva verket skulle vilket tecken som helst med kategorikod 0 (escape-tecknet) kunna användas i stället.

TeX-motorer känner igen två typer av kommandon som kallas *kontrollord* och *kontrollsymboler*:

* **kontrollord**: kommandon som konstrueras av ett eller flera tecken som har kategorikod 11;
* **kontrollsymboler**: enteckenskommandon där det tecknets kategorikod *inte* 11: till exempel `\\$`, `\#` eller `\\`.

**Obs**: TeX-primitiverna `\\chardef`, `\\mathchardef`, `\\countdef`, `\\dimendef`, `\\skipdef`, `\\muskipdef` och `\\toksdef` används också för att definiera kontrollsekvenser, men till skillnad från vanliga makrodefinitioner är de resulterande kontrollsekvenserna (kontrollord eller kontrollsymboler) *inte expanderbara*—vi kommer att utforska dessa mer i detalj nedan.

#### Hur beräknas kommandotoken?

Precis som för aktiva tecken använder TeX-motorer den andra typen av heltals-tokenvärde för att representera kommandon: *kommandotoken*—kom ihåg att aktiva tecken också genererar kommandotoken eftersom de beter sig som minimakron.

Beräkningarna som används av 8-bitarsmotorer för att skapa heltal för kommandotoken finns i denna [Overleaf-artikel](/latex/sv/fordjupade-artiklar/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#how-tex-calculates-token-values). Här sammanfattar vi de viktigaste stegen i beräkningen av kommandotoken för LuaTeX—som är något annorlunda eftersom LuaTeX måste bearbeta Unicode-teckenkodsvärden som kan vara avsevärt större än 8-bitarsvärden; dock följer LuaTeX:s beräkningar samma allmänna principer som används av äldre 8-bitarsmotorer.

När TeX-motorer, inklusive LuaTeX, har upptäckt ett inkommande kommando, ignorerar de det inledande `\` tecknet: det används inte i beräkningar av kommandotokenvärden utan fungerar bara som en ”omkopplare” för att informera en TeX-motor om att den behöver bearbeta ett kommando. Kommandotokenvärdet beräknas med hjälp av sekvensen av (ett eller flera) tecken som finns i kommandots namn—LuaTeX beräknar kommandotoken för kontrollsymboler och kontrollord med samma algoritm:

1. beräkna det mellanliggande heltalsvärdet $$\text{curcs}$$ genom att tillämpa en så kallad [hashfunktion](https://en.wikipedia.org/wiki/Hash_function) på den Unicode UTF-8-sträng av tecken som finns i kommandots namn: $$\text{curcs}=\texttt{hashfunction}\text{(Unicode UTF-8 string of characters in command name)}$$3. beräkna kommandotokenvärdet där $$\text{command token} = \text{curcs} + 2^{29} - 1$$

**Exempel**

* för `\\` kommandot (en kontrollsymbol) beräknar LuaTeX $$\text{curcs}=94$$, vilket ger ett tokenvärde för `\\` för $$94 + 2^{29} - 1 = 536871005$$.
* för `\\vskip` primitivkommandot (ett kontrollord) beräknar LuaTeX $$\text{curcs}=3560$$, vilket ger ett tokenvärde för `\\vskip` för $$3560 + 2^{29} -1 = 536874471$$.
* för det användardefinierade makrot `\\mynewmacro` (ett kontrollord) beräknar LuaTeX $$\text{curcs} = 2971$$, vilket ger ett tokenvärde för `\\mynewmacro` för $$2971 + 2^{29} -1 = 536873882$$.

När de väl har skapats kan token lagras för senare användning via så kallade *tokenlistor* eller så kan de omedelbart skickas vidare för fortsatt bearbetning inne i TeX-motorn. Att använda heltalsvärden för att representera token fungerar inte bara över alla typer av datorplattformar/operativsystem utan är också ett mycket effektivt sätt för TeX att lagra/bearbeta data.

### Hur en TeX-motor identifierar tokenstypen (kommando eller tecken)

Givet ett visst heltals-tokenvärde, $$T$$kan en TeX-motor enkelt avgöra om $$T$$ representerar ett kommando eller ett tecken genom att testa om $$T$$ överskrider ett visst $$\text{threshold value}$$—det $$\text{threshold value}$$ beror på TeX-motorn. Om $$T \geq \text{threshold value}$$ så $$T$$ är ett kommandotoken, annars $$T$$ är det en teckentoken. Det $$\text{threshold value}$$ är $$4095$$ för 8-bitarsmotorer och $$2^{29}-1$$ (536 870 911) för LuaTeX. Knuth utformade metoderna som används i formler för tokenberäkning så att hans TeX-motor, och alla senare motorer som bygger på hans kod/arkitektur, snabbt och enkelt kan testa tokenvärden.

## Token kan delas upp (och konverteras tillbaka till text)

Token (heltal) är den mekanism genom vilken en TeX-motor ”inkapslar” allt den behöver registrera om ett inmatningsobjekt (tecken eller kommando). Det finns dock tillfällen då en TeX-motor behöver vända tokeniseringsprocessen—för att ta reda på vad som ursprungligen lästes in för att skapa det tokenvärdet—ett enskilt tecken eller en sekvens av ett eller flera tecken som bildar namnet på ett kommando:

* **för teckentoken**: Varje teckentoken kan delas upp i sina två beståndsdelar: teckenkoden och motsvarande kategorikod som tilldelades det tecknet *vid den tidpunkt då det ursprungligen lästes in*. Liksom alla TeX-motorer kommer LuaTeX inte att ändra den ursprungliga tilldelningen av kategorikod, utan kommer att använda den under fortsatt intern bearbetning.
* **för kommandotoken:** Dessa är något mer detaljerade, men om man tittar på LuaTeX:s beräkning av kommandotoken, inklusive token för aktiva tecken, ser man att de följer ett mönster: $$\text{command token} = \text{curcs} + 2^{29} -1$$

där $$\text{curcs}$$ beräknas enligt vilken typ av kommandotoken som genereras: aktivt tecken, kontrollsymbol eller kontrollord. Det $$\text{curcs}$$ variabeln är en *extremt* viktig komponent i en TeX-motors interna arbete: givet vilket kommandotokenvärde som helst kan LuaTeX mycket enkelt extrahera värdet av $$\text{curcs}$$ från det kommandotokenet med hjälp av $$\text{curcs} = \text{token value} - (2^{29} -1)$$.

### Varför är $$\text{curcs}$$ så viktigt?

Den interna TeX-variabeln $$\text{curcs}$$ (**cur**rent **c**ontrol **s**equence) är en ytterst viktig komponent i en TeX-motors inre ”under huven”-operationer. Även om du inte kommer att, och inte kan, använda eller komma åt den direkt i din kod, $$\text{curcs}$$ spelar den en avgörande roll eftersom TeX-motorer använder det aktuella värdet av $$\text{curcs}$$ som ett index i interna tabeller som lagrar data om varje kommando som för närvarande är känt av motorn. Dessa tabeller lagrar information om ett kommandos aktuella betydelse: vad gör det eller vad representerar det, och dessutom registrerar de den sekvens av tecken som ursprungligen användes för att beräkna det $$\text{curcs}$$ värdet. Genom att extrahera värdet av $$\text{curcs}$$ från ett kommandotoken kan en TeX-motor fastställa namnet, dvs. den mänskligt läsbara texten, som motsvarar vilken (kommando)token som helst, vilket gör att den kan utföra token-till-text-konverteringar som är en viktig del av `\\directlua`’s funktion.

### Konvertera heltals-token tillbaka till tecken eller teckensekvenser (kommandonamn)

Vi har sett att TeX-motorer konverterar inmatade tecken eller teckensekvenser till tokenvärden i heltal, men det finns tillfällen då en TeX-motor behöver *vända* den processen—för att mata ut den mänskligt läsbara text som ursprungligen användes för att skapa dessa tokenvärden i heltal; till exempel:

* skriva fel- eller varningsmeddelanden till skärmen eller `.log` fil;
* mata ut TeX-/LaTeX-kod till en textfil via `\\write` kommandot;
* vid konvertering av en tokensekvens till text inom `\\directlua` (som vi snart ska se!)

#### Konvertera teckentoken till text

Som nämnts beräknas token för icke-aktiva tecken med hjälp av ett inmatat teckens kategorikod och teckenkod (Unicode-värde). LuaTeX använder formeln:

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

Det är en enkel programmeringsuppgift att dela upp heltals $$\text{character token}$$ värdet för att få fram dess beståndsdel teckenkod ($$\text{Unicode value}$$) $$\text{category code}$$.

#### Konvertera kommandotoken till text

Alla TeX-motorer lagrar namnet (sekvensen av tecken) för varje kommando de ”känner till”: oavsett om det kommandot är ett användardefinierat makro eller en inbyggd primitiv—lagringen av primitivkommandons namn sker när TeX-motorn startar, långt innan den börjar bearbeta din kod. För användardefinierade kommandon (makron) lagras namnet på makrot (minus det inledande `\`) lagras som en del av makrodefinitionsprocesserna i TeX-motorer.

När en TeX-motor behöver komma åt eller mata ut den mänskligt läsbara text från vilken ett heltalsbaserat kommandotoken ursprungligen beräknades, kommer den först att fastställa $$\text{curcs}$$ värdet för den tokenen; i LuaTeX, $$\text{curcs} = \text{token} - (2^{29} -1$$). Med hjälp av värdet av $$\text{curcs}$$ som extraherats ur ett kommandotoken kan en TeX-motor komma åt en intern datastruktur som kallas *strängpoolen* för att fastställa sekvensen av mänskligt läsbara tecken som ursprungligen användes för att beräkna just det värdet för $$\text{curcs}$$ och därmed det motsvarande kommandotoken.

Som vi ska se är dessa tokenbearbetningsaktiviteter—att konvertera teckensekvenser till tokenvärden i heltal och att konvertera tokenvärden i heltal tillbaka till teckensekvenser (”de-tokenisering”)—de *grundläggande mekanismerna* som används i `\\directlua`.

## Tokenlistor

När en TeX-motor läser indata, genererar tecken- och kommandotoken (och bearbetar dem), kan den stöta på vissa kommandon som instruerar motorn att tillfälligt sluta skicka token vidare för fortsatt bearbetning men i stället lagra dem för senare användning. Det vanligaste exemplet är att definiera ett makro med hjälp av ett av makrodefinitionskommandona `\def`, `\edef`, `\gdef` eller `\xdef`—LaTeX-kommandon som `\\newcommand` är makron som tillhandahåller ytterligare funktionalitet uppbyggd kring primitiva lågnivåkommandon som i slutändan utför den faktiska makrodefinitionsprocessen. Ett makro kan betraktas som namnet på en viss lista av lagrade token: en tokenlista.

TeX-motorer gör *omfattande* användning av tokenlistor, särskilt [tillfälliga interna listor](/latex/sv/fordjupade-artiklar/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) som används för intern bearbetning. Varje TeX-motor tillhandahåller också användarkommandon för att skapa tokenlistor som lagras för när användaren, eller TeX-motorn själv, behöver dem. Antalet kommandon för att skapa tokenlistor (inbyggda primitiver) varierar beroende på TeX-motor men de delar alla en kärnuppsättning av det minimum som stöds av varje motor, till exempel `\toks` primitiv.

I praktiken är en tokenlista bara en lagrad sekvens av heltalsvärden:

* indatan läses för att generera (beräkna) enskilda token, som representerar ett tecken eller kommando;
* varje token lagras sedan, vilket bevarar den ordning i vilken token genererades från indatan.

TeX-motorer lagrar tokenlistor med hjälp av en datastruktur som kallas en [länkad lista](https://en.wikipedia.org/wiki/Linked_list) (av den enkel-länkade varianten). Läsare som vill veta mer om tokenlistor uppmanas att läsa Overleaf-artikeln [Vad är en TeX-tokenlista?](/latex/sv/fordjupade-artiklar/54-what-is-a-tex-token-list.md) som använder en analogi för att konstruera begreppen/idéerna bakom en tokenlista. En djupgående genomgång av TeX:s tokenlistor och hur de används i makrobearbetning finns i Overleafs artikelserie [Hur fungerar TeX-makron egentligen?](/latex/sv/fler-amnen/01-a-six-part-series-how-do-tex-macros-actually-work.md)

#### En tokenlista i grafisk form

Följande grafik visar en LuaTeX-genererad tokenlista med motsvarande tokenvärden som skapats från följande indata

`Hi, \\TeX! \\hskip 5bp`

Till exempel, om vi definierar `\\mymacro` som `\\def\\mymacro{Hi, \\TeX! \\hskip 5bp}` definitionen av `\\mymacro` skulle lagras i minnet med hjälp av en tokenlista som denna:

![](/files/2d9e19dd454e069c2831417b50ce720fd6ed3f5a)

Tokenlistan är en sekvens av länkade objekt som kallas *noder*, namnet på ett litet minnesblock i LuaTeX som allokeras för att hålla varje objekt i listan (som enskilda länkar i en kedja). Varje nod innehåller ett heltals-tokenvärde och minnesadress för *nästa* nod i kedjan, vilket bildar en datastruktur som kallas en [länkad lista](https://en.wikipedia.org/wiki/Linked_list). Den sista noden anger slutet på listan med ett särskilt ”nollvärde” för nästa nod—eftersom det inte finns någon.

**Anmärkningar:**

* För enkelhets skull har vi inkluderat adressen för varje enskild nod, men i praktiken lagras inte den datan i tokenlistnoderna; endast adressen för *nästa nod* krävs för att bygga TeX-motorns tokenlistor.
* Den andra kolumnen i grafiken med titeln ”Vad varje token betyder” visar en serie grå rutor som innehåller information om token i varje nod: dessa är enbart för information och *blir inte* utgör inte en del av den faktiska data som lagras i tokenlistan.

Här är en tabell över tokenvärdena som finns i tokenlistan som avbildas ovan:

|                  |                     |                                                                         |                |
| ---------------- | ------------------- | ----------------------------------------------------------------------- | -------------- |
| **Indataobjekt** | **Typ av indata**   | <p><strong>Kategorikod</strong><br><br><strong>(om tecken)</strong></p> | **Tokenvärde** |
| H                | tecknet             | 11                                                                      | 23068744       |
| i                | tecknet             | 11                                                                      | 23068777       |
| ,                | tecknet             | 12                                                                      | 25165868       |
|                  | tecknet             | 10                                                                      | 20971552       |
| \\\TeX           | kommando (makro)    |                                                                         | 536871539      |
| !                | tecknet             | 12                                                                      | 25165857       |
|                  | tecknet             | 10                                                                      | 20971552       |
| \hskip           | kommando (primitiv) |                                                                         | 536874247      |
| 5                | tecknet             | 12                                                                      | 25165877       |
| b                | tecknet             | 11                                                                      | 23068770       |
| p                | tecknet             | 11                                                                      | 23068784       |

**Obs:** Vår ursprungliga inmatningstext har a efter `\hskip` kommandot men det finns ingen token som representerar det tecknet i tokenlistan. Det tecknet absorberades av LuaTeX:s inläsningsprocess eftersom det användes för att avsluta LuaTeX:s sökning efter tecken som utgör `\hskip` kommandot.

## Hur \\\directlua verkligen fungerar

Nu när vi har utforskat tokens, tokenlistor och att konvertera tokens till text, är nästa utmaning att förstå TeX-motorns begrepp token *expansion*.

Som nämnts, `\\directlua{⟨code⟩}` kan ombes att bearbeta `⟨code⟩` som innehåller både Lua- och TeX/LaTeX-kod men LuaTeX:s inbyggda Lua-tolk förstår inte TeX eller LaTeX: så hur kan detta fungera? Hur är det möjligt för `⟨code⟩` att innehålla TeX/LaTeX-instruktioner utan att grundligt förvirra Lua-tolken med kommandon som den inte förstår? Till exempel använder följande `\\directlua` kommandot bara TeX-makron, men det fungerar:

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

Denna `\\directlua` kommandot resulterar i att LuaTeX sätter `Hello` men varför och hur fungerar detta eftersom Lua-språket inte förstår TeX-makron?

Svaret finns i den tidigare beskrivning vi lånade från [LuaTeX:s referensmanual](http://www.pragma-ade.com/general/manuals/luatex.pdf) men vi kan betrakta att `\\directlua{⟨code⟩}` fungerar genom att LuaTeX först ”förbehandlar” den `⟨code⟩` innan något skickas till Lua-tolken. Vad denna ”förbehandling” innebär — dvs. vad det egentligen betyder och vilka konsekvenserna blir för din `⟨code⟩`—är nästa ämne vi kommer att ta upp för att hjälpa läsare som vill dra nytta av kraften och flexibiliteten hos `\\directlua`.

### Hur LuaTeX bearbetar \directlua: en första titt

För att bygga vidare på vår förståelse av `\\directlua`s ”förbehandlings”-aktiviteter kan vi börja med följande förenklade diagram som ger en översikt över vad som händer.  `⟨code⟩` som ges till `\\directlua{⟨code⟩}` omvandlas först till tokens med hjälp av de processer och beräkningar som diskuterats ovan; den sekvensen av tokens lagras i en tokenlista. När tokenlistan har byggts omvandlas varje token i listan tillbaka till sin textuella representation: texten som produceras av varje token—tecken-token eller kommando-token—sammanfogas (konkateneras) för att skapa en enda kodsträng som skickas vidare till Lua-tolken för körning.

![](/files/ee89600a0d3df020315ab687a426d95ba4ef40ac)

Men vänta, vad vore poängen med att gå från text till tokens och sedan konvertera dessa tokens direkt tillbaka till text? Du blir kanske inte förvånad över att få veta att ja, det finns en extra och avgörande process som vi inte har tagit med i denna bild: *tokenexpansion*. Varje token som produceras från texten i din `⟨code⟩` genomgår en typ av ”granskning” där LuaTeX gör ett test för att se om den tokenen representerar ett kommando som tillhör delmängden som kallas *expanderbara kommandon*. Om så är fallet filtrerar LuaTeX bort det kommandot genom att *att ta bort* det från din `⟨code⟩` och *ersätta det* med resultatet av en process som TeX-motorer kallar *tokenexpansion*.

### Hur LuaTeX bearbetar \directlua: en andra titt (på expansion)

TeX:s expansionsmekanism är en kärnkomponent i alla TeX-baserade sättningsmotorer eftersom var och en i slutändan härstammar från (eller är baserad på) Knuths ursprungliga källkod och design för TeX. Begreppet expansion är dock svårt att förklara i ett kortfattat men ändå tillgängligt språk eftersom expansion i praktiken är en ”paraplyterm” som används för att beskriva en enda process — men en som producerar en rad olika utfall. Dessa varierande resultat är en följd av den ganska brokiga uppsättning kommandon som expansion kan tillämpas på, så du kan betrakta att varje expanderbart kommando har ett visst ”expansionsbeteende”.

Som en *första approximation* för att förstå expansion kan vi säga att expansion av en token (kommando) betyder *att ta bort* att ta bort det kommandot (tokenen) från TeX:s aktuella indata och *att ersätta* ersätta det med en sekvens av tokens som resultat av att köra just det expanderbara kommandot — vilket ersätter den ursprungliga tokenen med resultaten/konsekvenserna av dess expansion *beteendet*. Dock är denna inledande ”definition” av expansion — i termer av att generera nya tokens för TeX att läsa — inte helt korrekt för alla expanderbara kommandon, men den duger som utgångspunkt.

Som ett enkelt exempel: TeX-primitiven `\jobname` är ett expanderbart kommando och dess *expansion* är en sekvens av tecken-tokens som representerar namnet på den huvudsakliga TeX-indatafilen. Om TeX beslutar att expandera ett `\jobname` kommando (token) så *tas bort* från TeX:s aktuella indatakälla och *ersätts* med den sekvens av tecken-tokens som det genererar — vilken TeX sedan fortsätter att läsa/bearbeta.

Inom `\\directlua`, efter att en expanderbar token har bearbetats (tagits bort) och ersatts med nya tokens, kommer LuaTeX att fortsätta läsa de nya tokens som det just har lagt på plats — men några av de nya tokens kan också vara expanderbara. Eftersom `\\directlua` utför så kallad *full expansion*, kommer LuaTeX att läsa dessa nya tokens och, ännu en gång, gå igenom expansionsprocessen för att expandera (ta bort) alla nya (expanderbara) tokens — denna expansionsprocess fortsätter tills inga expanderbara tokens återstår. Det finns dock två viktiga undantag från denna regel om att ”fortsätta expandera”, och båda tar vi upp nedan:

* genom att använda konstruktionen `\\the\\toks`;
* avsiktlig förhindran (undertryckning) av expansion för en eller flera utvalda tokens.

Som nämnts täcker vår arbetsdefinition (första approximation) för att förstå expansion inte hela spektrumet av expansionsbeteenden som demonstreras av delmängden expanderbara kommandon. Till exempel genererar vissa expanderbara kommandon inte tokens på det sätt som `\jobname` gör, men de kan istället:

* ”filtrera” tokens från indata: en TeX-motors villkorskommandon (`\if`, `\ifcat`, `\ifnum`, `\ifdim`, `\ifodd`, `\ifvmode`, …) är expanderbara. Deras expansionsbeteende är en typ av ”tokenfiltrering” — villkorskommandon kan användas i `\\directlua`.
* ”jonglera” med tokens i indata:  [`\expandafter` kommandot](/latex/sv/fordjupade-artiklar/03-a-six-part-article-series-on-expandafter-tex-tokens-and-expansion.md) är expanderbart och ändrar ordningen i vilken två tokens expanderas.
* förhindra expansion: de expanderbara kommandona `\noexpand` och `\unexpanded` undertrycker expansion av kommandotokens i indata.
* konvertera teckensekvenser i indata till kommandotokens: `\csname … \endcsname.`
* konvertera interna värden till en sekvens av tecken-tokens: `\number` och `\the` är expanderbara kommandon som genererar en sekvens av tecken-tokens som representerar värdet av ett internt värde.
* konvertera kommandotokens till tecken-tokens: `\string` och `\detokenize` är expanderbara kommandon som konverterar sina argument till en sekvens av tecken-tokens med kategorikod 12. Observera att `\detokenize` skiljer sig från `\string`: `\detokenize` kan bearbeta flera tokens och infogar ett blankstegstecken, med kategorikod 10, efter att ha bearbetat kommandotokens som skapats från *kontrollord*. I praktiken `\detokenize` lägger till ett avslutande blankstegstecken efter kommandonamnet — vi kommer att se några exempel senare i artikeln.

#### Förfining av vår ”definition” av expansion

Vi kan nu generalisera vår definition och säga att expansion av ett kommando (en token) innebär *borttagning* av det kommandot (tokenen) från TeX:s aktuella indatakälla och *ersätta det* med resultatet av *tokenoperation(er)* som utförs av det kommandot. I huvudsak får expansionsprocessen ett expanderbart kommando att utföra någon typ av ”operation” på tokens i TeX:s aktuella indata, vilket påverkar antalet eller beteendet hos de tokens som TeX därefter kommer att läsa — den exakta karaktären hos den ”operationen” beror på vilket kommando som expanderas. Alla makron och aktiva tecken är expanderbara, men endast ett litet antal av en TeX-motors inbyggda kommandon (primitiver) klassificeras som expanderbara — listan över expanderbara kommandon beror på vilken TeX-motor du använder.

Varje ny TeX-motor ärver de primitiva kommandon som är inbyggda i dess förälder(er) — de tidigare generationernas TeX-motor(er) från vilka den härleddes — och några av dessa ärvda primitiver kommer att vara expanderbara. Naturligtvis kan en ny TeX-motor välja att inte implementera några av de primitiva kommandon som finns i de tidigare motorerna eller att ändra deras beteende för att passa den nya motorns behov. Dessutom implementerar nya TeX-motorer vanligtvis ytterligare primitiver för att ge stöd åt sin egen förbättrade funktionalitet — några av dessa kan också vara expanderbara. Följaktligen kommer antalet expanderbara kommandon som du har tillgång till att variera beroende på vilken TeX-motor du använder — LuaTeX har en ganska stor samling av dem.

En annan svårighet med att förklara/förstå expansion, och kanske den verkliga utmaningen, är att exakt veta *när* en TeX-motor faktiskt kommer, eller inte kommer, att utföra expansionsprocessen. Det är ett stort och komplext ämne eftersom expansion är djupt inbäddad i TeX-motorernas inre funktioner: vi har inte utrymme att behandla detta i detalj utöver användningen av expansion i `\\directlua`.

### Hur LuaTeX bearbetar \directlua: en avslutande titt

Följande diagram sammanfattar de `\\directlua` förbehandlingsaktiviteter som äger rum inne i själva LuaTeX-motorn. I detta diagram visar vi också två lågnivå-interna LuaTeX-funktioner som faktiskt gör arbetet: `scan_toks()` och `tokenlist_to_cstring()`. Dessa funktioner är skrivna i språket C och finns djupt inne i den körbara LuaTeX-programvaran: de är en del av LuaTeX:s inre maskineri och inte *direkt* åtkomliga för din TeX/LaTeX-kod.

![](/files/976111671fec2207e2137bb2a54984212180653a)

Följande beskrivning av `\directlua ⟨code⟩`s förbehandlingsaktivitet sammanfattar diagrammet ovan.

1. Teckensekvensen i din ⟨code⟩ bearbetas av `scan_toks()`. Dess syfte är att läsa din ⟨code⟩ tecken för tecken för att generera tecken-tokens och kommandotokens. Eftersom den skapar tokens är kategorikoden som tilldelas varje tecken i ⟨code⟩, vid tidpunkten då det läses in, oerhört viktig.
2. Under `scan_toks()`s tokenbearbetning (generering) expanderas varje expanderbart kommando (token) *om inte* förhindras via kommandon som `\protected` (makrodefinitioner), `\noexpand`, `\unexpanded` osv. Aktiva tecken (kategorikod 13) expanderas också (om det inte förhindras).
3. Tokenströmmen som skapas av `scan_toks()` byggs in i en lång tokenlista — tokens som finns i den listan inkluderar sådana som producerats från expansion som tillämpats på expanderbara kommandon (såsom makron) som finns i din `⟨code⟩`. Observera också att `scan_toks()` *gör inte* utlöser eller orsakar körning av någon token som representerar ett icke-expanderbart kommando: sådana icke-expanderbara tokens skickas helt enkelt vidare för att införlivas i den tokenlista som byggs upp.
4. När tokenlistan är färdig och all expansionsaktivitet är avslutad bearbetas den tokenlistan av en annan funktion som kallas `tokenlist_to_cstring()` som konverterar varje token i den slutliga tokenlistan tillbaka till sin textuella representation. Detta genererar en textsträng som är Lua-koden som ska skickas vidare till Lua-tolken. För att körningen ska lyckas måste den strängen innehålla syntaktiskt korrekt Lua-kod.
5. Luas bearbetning av den koden sker i två steg:
6. LuaTeX:s inbyggda Lua-tolk parserar och ”kompilerar” Lua-koden som genererats i de föregående stegen. Om denna parsning/kompilering misslyckas kommer Lua-tolken att generera fel (såsom syntaxfel) — dessa fel kan göra att LuaTeX-körningen misslyckas om du inte valde att använda `--interaction=nonstopmode` på kommandoraden.
7. Om parsningen/kompileringen lyckas exekverar Lua-tolken koden som kompilerades i steg (5a).

I huvudsak är `scan_toks()` funktionen kärnan i LuaTeX:s förbearbetningsaktiviteter: dess huvuduppgift är att expandera alla expanderbara TeX/LaTeX-kommandon som finns i texten i din `⟨code⟩` och konstruera en tokenlista av allt den har bearbetat. Återigen betonar vi att `scan_toks()` *kör inte icke-expanderbara kommandon* (tokens): den bara *lagrar* de tokens i den tokenlista den konstruerar. När den är färdig konverteras tokenlistan därefter *tillbaka till en textuell representation* av `tokenlist_to_cstring()`—en tokenlista är ett begrepp som bara hör till TeX och är helt främmande för en Lua-tolk, vilket förklarar behovet av att konvertera den till text, så att den blir Lua-kod som kan skickas vidare till Lua-tolken.

## Expansion som ett ”gränssnitt” i ett programspråk

Du kan tänka dig att `\\directlua`s expansionsprocess används som en mekanism eller ett gränssnitt för att föra data/information från ”TeX-världen” över till ”Lua-världen”: ett sätt för TeX-språket att kommunicera data till Lua-språket. Till exempel kan TeX-kod som `\number\count75` användas för att överföra ett värde i ”TeX-världen” som lagrats i räknarregister 75 till heltalsvariabeln x i ”Lua-världen”:

```
\count75=1564  % Data existing in the "TeX World"
\directlua{
   local x=\number\count75 \space  % Transfer TeX data to the "Lua World"
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" and y = "..y)
}
```

Detta genererar Lua-koden

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

**Obs**: Vi lade till `<space>\space` efter `\number\count75` för att säkerställa att ett blankstegstecken bevarades mellan `1564` och `tex.print`—det är inte strikt nödvändigt här eftersom Lua fortfarande skulle tolka koden korrekt om vi utelämnade det. Blankstegstecknet som följer direkt efter `\count75` absorberas under den process som TeX-motorer använder för att leta efter numeriska värden — här värdet som skickas till `\count`. Blankstegstecknet efter `75` används för att avsluta LuaTeX:s sökning efter siffersekvensen `75` och absorberas från indata.  `\space` makrot expanderar för att tillhandahålla blankstegstecknet som behövs för att separera texten `1564` och `tex.print`.

Om du använder koden ovan kommer LuaTeX att sätta

`x= 1564 and y = 612.6`

Här uppnås mekanismen för att ”föra över data” genom `\number`: ett expanderbart kommando som i detta fall instruerar TeX att hämta värdet som lagras i `\count` register `75` och från det värdet (`1546`) generera en serie tecken-tokens, en tecken-token för varje siffra, vilket resulterar i en tokensekvens för siffrorna `1`, `5`, `6` och `4`. Dessa fyra tecken-tokens införlivas i den huvudsakliga tokenlistan som byggs upp av `\\directlua` och konverteras därefter tillbaka till sin textuella representation när tokenlistan konverteras till text. Det är utan tvekan en mycket omständlig väg från `\count75` registervärdet som lagras i LuaTeX till siffror avsedda för Lua-kod, men i slutändan fungerar det.

**TIPS:** Om du vill inspektera resultaten av LuaTeX:s expansionsaktiviteter kan du skriva kod som denna:

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

I det här exemplet använder vi metoden med långa hakparenteser för att skapa en strängvariabel `foo` vars syfte är att hålla strängen med Lua-kod som genereras från expansionen av allt mellan `[[` och `]]`. Den strängen skrivs ut till konsolen via funktionsanropet `print(foo)`.

I Overleaf kan du se liknande resultat genom att skriva innehållet i `foo` till `.log` filen med LuaTeX:s Lua-funktion `texio.write()`:

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

## Tokens i \directlua-tokenlistan: icke-expanderbara tokens och oexpanderade tokens

Vi har noterat att `\\directlua{⟨code⟩}` utför *full expansion* av din `⟨code⟩`: den tar bort och expanderar alla expanderbara kommandon tills endast icke-expanderbara tokens återstår. Sekvensen av tokens som skapas av `\\directlua`s bearbetning (i `scan_toks()` funktionen) länkas samman för att bilda en tokenlista vars enskilda tokens kommer att konverteras tillbaka till text för att skickas vidare till Lua.

Vi har dock ännu inte behandlat den sista delen av denna historia eftersom vi behöver överväga de två ”klasserna” av kommandotoken som kan ta sig igenom till tokenlistan som byggs upp inom `\\directlua`: vi kommer att kalla dem *snabbkommando-tokens* och *oexpanderade* tokens:

* **snabbkommando-tokens**: Denna typ av kommandotoken uppstår från kontrollsekvenser som definieras med hjälp av en av TeX-primitiverna `\\chardef`, `\\mathchardef`, `\\countdef`, `\\dimendef`, `\\skipdef`, `\\muskipdef` och `\\toksdef`. Dessa primitiva kommandon används för att definiera kontrollsekvenser som representerar ett numeriskt värde — de resulterande kontrollsekvenserna är *inte* expanderbara.
* **oexpanderade tokens**: Denna tokentyp uppstår från kommandon som normalt skulle expanderas men `\\directlua` har antingen:
* uttryckligen blivit instruerade *inte* att expandera dem; till exempel undertryckning av expansion med kommandona `\noexpand` eller `\unexpanded`—vi förklarar snart hur detta görs;
* injicerat tokens genom att bearbeta sekvensen `\\the\\toks` (mer om det nedan).

### Två ”grupper” av token i en \directlua-tokenlista

Baserat på våra diskussioner kan vi säga att tokens som finns i tokenlistan som byggs upp under det första skedet av `\\directlua`s förbearbetning (i `scan_toks()` funktionen) faller i två grupper:

1. *i sig icke-expanderbara* tokens

* varje token som representerar ett icke-aktivt *tecknet*;
* varje token som representerar en icke-expanderbar *primitiv* *kommandot*;
* varje token som representerar en *snabbkommando* (dessa är inte expanderbara, se nedan).

3. *oexpanderade* tokens:

* varje token som representerar ett expanderbart kommando vars expansion var *undertryckt* (eller undvikits) under `\\directlua`s förbearbetning.

#### Tokens för snabbkommandon: att skapa icke-expanderbara kommandon

Som nämnts tillhandahåller TeX-motorer en uppsättning primitiver (inbyggda kommandon) som kan användas för att konstruera *icke-expanderbara* kontrollsekvenser (angivna här med `⟨command⟩`). Dessa primitiver har formen:

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

där `⟨numeric value⟩` är något heltalsvärde som passar för varje kommando.

Här går vi kort igenom användningen av `\\chardef` för att demonstrera den viktigaste egenskapen hos dessa primitiver — att producera en `⟨command⟩` som är icke-expanderbar. Du kan använda ``\chardef\mydollar=`\$`` för att skapa kontrollsekvensen `\mydollar` och använda den för att sätta en `$`:

`I paid \mydollar30.`

Detta kommer att sätta `I paid $30.` Kontrollsekvensen `\mydollar` skapad av `\\chardef` är inte expanderbar, vilket vi kan se av följande exempel:

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

Vilket producerar följande text i `.log` fil

`I paid \mydollar 30.`

Detta visar `\mydollar` var *inte* expanderad under `\\directlua`s förbearbetning. Blanksteget som visas efter `\mydollar` läggs till när en kommandotoken konverteras till sin representation som text.

När du använder `\\chardef` för att skapa en kontrollsekvens leder TeX:s interna klassificering av den kontrollsekvensen (kommandot) till att den blir *icke-expanderbara* vilket är ett mycket annorlunda beteende jämfört med kontrollsekvenser som definieras med ett av makrodefinitionskommandona: \def, \edef, \gdef eller \xdef. Som nämnts ovan granskar `\\directlua` varje inkommande kommandotoken för att kontrollera om den är expanderbar. Om en kommandotoken inte är expanderbar passerar den rakt igenom till tokenlistan och dess textrepresentation kommer senare att dyka upp igen i den sträng av Lua-kod som uppstår när tokens i tokenlistan konverteras tillbaka till sin textform.

**Korta anteckningar om plain TeX kontra LaTeX**

Historiskt definierade Knuths ursprungliga plain TeX de vanligt använda kontrollsymbolerna `\%`, `\&`, `\#` och `\\$` med hjälp av `\\chardef`—inte med hjälp av ett av standardkommandona för makrodefinition `\def`, `\edef`, `\gdef` eller `\xdef`. För exempel:

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

Den märkliga `` `\ `` syntaxen är en TeX-metod för att få fram det numeriska teckenkodsvärdet. I det gamla plain TeX-systemet är dessa kontrollsymboler inte expanderbara (på grund av `\\chardef`) men LaTeX (eller paket) kan omdefiniera dem som *makron* för att ge utökad funktionalitet — vilket skulle göra dem expanderbara, så det kan vara bra att vara medveten om detta.

**Hur påverkar detta \directlua?**

Låt oss jämföra resultatet av följande kod som körs under plain TeX och LaTeX. För enkelhets skull skriver vi resultaten till `.log` filen med LuaTeX:s Lua-API-funktion `texio.write()`.

```
\directlua{
   local x=[[\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.]]
   texio.write(x)
}
```

Om denna kod körs med **plain TeX** får man följande utdata i `.log` filen, som visar resultatet av eventuella expansioner:

```
\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.
```

Tydligt nog expanderades ingen av kontrollsymbolerna under plain TeX`\\$`, `\#`, `\%` eller `\&` —eftersom de alla skapas med `\\chardef`.

Om denna kod körs med **LaTeX** dokumentet:

```
\documentclass{article}
\begin{document}
   \directlua{local x=[[\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.]] texio.write(x)}
\end{document}
```

får man följande utdata i `.log` fil

```
\protect \TU\textdollar 150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.
```

Tydligt nog ger körning med LaTeX ett annat resultat än plain TeX eftersom kommandot under LaTeX `\\$` har expanderats, vilket visar att det är ett makro.

**Obs:** Både i plain TeX och LaTeX `\\directlua` bearbetades inga av kontrollsymbolerna fullständigt `\%`, `\&`, `\#` och `\\$` för att generera motsvarande tecken. Under expansionsprocessen som utförs av `\\directlua` passerar tokens som representerar dessa kontrollsymboler — eller, för LaTeX, deras expansion — rakt igenom till den huvudsakliga tokenlista som byggs upp.

**Obs:** Kontrollsymboler bildas av ett enda tecken som inte har kategorikod 11, till exempel `\#`. När en token som representerar en kontrollsymbol konverteras tillbaka till sin textuella representation infogar TeX-motorer inte något blankstegstecken efter den texten. Denna särskilda behandling av kontrollsymboler är en inbyggd regel för hur TeX-motorer fungerar.

### Oexpanderade tokens: att undertrycka expansion

`\\directlua`’s förbearbetning är ett exempel där en TeX-motor utför expansion men du kanske vill *förhindra* att expansion tillämpas på en eller flera tokens som annars skulle expanderas. Som ännu ett exempel utför LuaTeX (och alla TeX-motorer) en expansionsprocess, liknande den hos `\\directlua`, när de bearbetar `\\write` kommandot:

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

\write instruerar en TeX-motor att skriva ut `⟨material⟩`—ofta innehållande TeX/LaTeX-kommandon— till en textfil (`filnummer`); alla expanderbara kommandon inom `⟨material⟩` kommer, om de inte förhindras, att expanderas innan `⟨material⟩` det faktiskt skrivs till den filen.

Som du kanske väntar dig tillhandahåller TeX-motorer kommandon för att undertrycka eller kontrollera expansion:

* `\noexpand⟨token⟩`: förhindrar expansion av den enskilda `⟨token⟩`;
* `\unexpanded{⟨material⟩}`: förhindrar expansion av alla expanderbara kommandon (tokens) i `⟨material⟩`. Det är i praktiken en flertokensversion av `\noexpand`;
* `\protected`: ett prefix som läggs till makrodefinitioner och som förhindrar expansion av det makrot under vissa omständigheter (t.ex. under `\\directlua`, `\\write` eller `\edef`).

Trots namn som antyder något annat är både `\noexpand` och `\unexpanded` är *expanderbara kommandon* och ger bra exempel på att se en TeX-motors expansionsprocess som utförande av ”tokenoperationer”: operationen här är att förhindra expansion av en eller flera efterföljande tokens (kommandon). Eftersom `\noexpand` och `\unexpanded` är båda expanderbara kommandon tas de bort och bearbetas (exekveras) under `\\directlua`’s förbearbetning när den konstruerar tokenlistan från din `⟨code⟩`.

#### \noexpand ⟨token⟩

`\noexpand ⟨token⟩` förhindrar expansion av den enskilda `⟨token⟩`. `\noexpand` inom `\\directlua` kommer att expanderas (tas bort från indata) och ersättas av resultaten av dess ”expansionsbeteende”. Resultatet av att expandera `\noexpand` är att skapa en särskild (dold) `⟨marker token⟩` som placeras framför den ursprungliga `⟨token⟩` vars expansion ska undertryckas: den `⟨marker token⟩` fungerar som en flagga som säger ”expandera inte nästa token”. Eftersom `\\directlua` utför full expansion kommer den att bearbeta om alla tokens som blir resultatet av ett expanderbart kommandos ”expansionsbeteende”. Följaktligen, när expansionen av `\noexpand ⟨token⟩` är klar går LuaTeX tillbaka för att läsa resultaten och ser tvåtoken-sekvensen `⟨marker token⟩⟨token⟩` vilket gör att den ursprungliga `⟨token⟩` passerar igenom, oexpanderad, in i tokenlistan som konstrueras av `\\directlua`.

**Exempel**

Om vi skriver

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

den `\\TeX` makrot expanderas till sina beståndsdelstokens, vilket i plain TeX kommer att resultera i att följande text skickas till Lua (observera: Lua kan inte bearbeta denna kod, det är bara ett exempel för att demonstrera processen):

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

Om vi *undertrycker* expansionen av den `\\TeX` makrot med `\noexpand`

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

skapas följande Lua-kod (igen, Lua kan inte köra denna kod; det är helt enkelt ett exempel för att demonstrera `\noexpand`):

`local x= "\TeX "`

På grund av `\noexpand`, `\\directlua` kommer inte att expandera `\\TeX` utan helt enkelt tillåta tokenvärdet som representerar `\\TeX` kommandot att passera igenom oskadat in i tokenlistan som byggs under det första steget av `\\directlua`s förbearbetning.

**Obs:** Blankstecknet som visas efter `\\TeX` införs genom LuaTeX:s efterföljande omvandling av det `\\TeX` heltalstokenvärdet tillbaka till dess textuella representation (inom `tokenlist_to_cstring()` funktionen).

#### \unexpanded{⟨material⟩}

`\unexpanded` är ett expanderbart kommando som undertrycker expansion av alla tokens som bildas av `⟨material⟩`. Som vi har noterat, när en TeX-motor utför expansion tas alla expanderbara kommandon *tas bort* bort från indata och *ersätts* ersätts av resultaten av dess ”expansionsbeteende”; så vad betyder det egentligen för `\unexpanded`? Vanligtvis, under *full expansion*, när expansionsprocessen för ett visst kommando har slutförts går TeX-motorn vidare och läser/bearbetar alla tokens som uppstår från det kommandots ”expansionsbeteende” — den behöver ytterligare expandera alla tokens som skapats. Men `\unexpanded` *går förbi* all ytterligare expansion: så här gör den det.

Inuti TeX-motorn `\unexpanded` omvandlar kommandot först tecknen och kommandona i `⟨material⟩` till en tillfällig tokenlista bestående av *oexpanderade* tokens. När alla tokens har skapats och lagrats i den tillfälliga tokenlistan får `\unexpanded` kommandot `\\directlua` till *hoppa över* att gå tillbaka för att läsa och bearbeta dem — trots att \directlua utför full expansion. I stället *oexpanderade* passerar dessa tokens rakt igenom och blir införlivade i den huvudsakliga tokenlista som byggs av `\\directlua` (i `scan_toks()` funktionen). På detta sätt omvandlas allt i `⟨material⟩` till tokens och expansionsprocessen hoppas över för den uppsättningen tokens. Operationen hos `\unexpanded{⟨material⟩}` liknar användningen av `\\the\\toks`, som vi diskuterar nedan.

**Exempel**

`\unexpanded` ger resultat på ett sätt som liknar `\noexpand` utom att det kan förhindra expansion av flera tokens; här är ett exempel:

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

vilket ger följande text som kod för Lua:

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

**Obs**: Det finns blanksteg efter varje kommandonamn. Dessa är återigen en konsekvens av LuaTeX:s efterföljande omvandling av de oexpanderade tokens `\foo`, `\bar` och `\foobar` till text inom `tokenlist_to_cstring()` funktionen.

#### \protected-makrodefinitioner

Den `\protected` kommandot är ett prefix som tillämpas på en makrodefinition för att förhindra att det makrot expanderas när TeX bygger en expanderad tokenlista, såsom tokenlistan som byggs av `\\directlua`s förbearbetning.

**Exempel**

Anta att du definierar följande makron med och utan att använda `\protected` prefixet:

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

Om du använder Lunas operator för strängkonkatenering (`..`) för att skriva

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

`\\directlua`’s förbearbetning skulle ge följande kod att skicka till Lua:

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

`\macroA` är inte definierad med `\protected` så den expanderas och producerar den första delen av strängen som ska konkatenras, men `\macroB` är definierad med `\protected` så den har inte expanderats.

Under förbearbetningen skapade LuaTeX:s `scan_toks()` funktion en token för `\macroA`, kände igen att det var ett vanligt expanderbart kommando och expanderade det: den expansionen producerar en sekvens av teckentokens, en teckentoken för varje tecken i `"This unprotected macro contains a string"`. Varje teckentoken skickas vidare och läggs till tokenlistan som byggs.

När `scan_toks()` skapar tokenen för `\macroB` märker den att kommandot definierades som `\protected` och expanderar det inte: tokenen som representerar `\macroB` passerar igenom orörd (oexpanderad) in i tokenlistan som byggs. När tokenlistan har byggts är nästa steg i förbearbetningen, inom `tokenlist_to_cstring()` funktionen, att omvandla alla tokens i tokenlistan tillbaka till deras textuella representation. Den oexpanderade token som representerar `\macroB` identifieras och omvandlas till sin textrepresentation, vilket resulterar i texten `\macroB` som visas i koden avsedd för Lua. Observera att Lua faktiskt inte kan sammanfoga `"This unprotected macro contains a string"..\macroB` för att producera den slutliga strängen eftersom `\macroB` inte har någon betydelse i Lunas syntax, vilket ger felet `unexpected symbol near '\'`.

**Kuriosa**: Paketet `\protected` kommandot introducerades av $$\varepsilon\text{-}\mathrm{\TeX}$$den första stora utökningen av Knuths ursprungliga TeX-programvara, och stöds av alla TeX-motorer vars kodsläkt inkluderar $$\varepsilon\text{-}\mathrm{\TeX}$$.

### Oexpanderade tokens: att använda \the\toks i \directlua

Livet inom programmering skulle inte vara detsamma utan dessa ”specialfall” att hantera, och användningen av `\the` i kombination med `\toks` i en `\\directlua` kommando är ett sådant specialfall.

#### Kort bakgrund om \toks

TeX-primitiven `\toks` instruerar en TeX-motor att spara vissa tokens för senare användning: i stället för att skickas vidare för ytterligare bearbetning läggs dessa tokens åt sidan och lagras på en minnesplats som anges med en *tokenregister*. Till exempel kan vi säga åt en TeX-motor att skapa vissa tokens och lagra dem på tokenregisterplatsen `100` med hjälp av

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

Här använder TeX tokenregister `100` för att komma åt en känd plats i sitt minne: ett lagringsutrymme avsett för att hålla tokenlistor.

Tokens som representerar allt mellan `{` och `}` skapas, *men expanderas inte*, och kedjas samman i en tokenlista — liknande tokenlistan vi undersökte tidigare i den här artikeln. För att återanvända dessa tokens skulle vi skriva `\the\toks100` där `\the` (ett expanderbart kommando) instruerar TeX att hämta de lagrade tokens och infoga dem på platsen där du skrev `\the\toks100`. Ett annat sätt att se det är `\\the\\toks` får TeX att infoga vissa tokens på den platsen.

Den `\toks` kommandot *expanderar inte* någon av de tokens det ombeds skapa och spara: det omvandlar helt enkelt tecken och kommandon mellan `{` och `}` till tokens och lagrar dem.

#### Tillbaka till \directlua

I diskussionen om expansion noterade vi `\\directlua{⟨code⟩}` utför *full expansion* för `⟨code⟩`: att ta bort alla expanderbara kommandon och ersätta dem med resultatet av deras expansionsbeteende — och fortsätta att *ytterligare expandera* alla tokens som uppstår från den initiala expansionen av ett expanderbart kommando.

`\the` är ett expanderbart kommando så `\\directlua` kommer att expandera det; men när `\the` används i kombination med `\toks` inom `\\directlua`, som i `\the\toks⟨token register⟩`, de infogade tokensen är *inte ytterligare expanderade*. Expansion av `\the\toks⟨token register⟩` infogar sekvensen av *oexpanderade* tokens, lagrade i `⟨token register⟩`, direkt in i tokenlistan som konstrueras av `\\directlua`: detta beteende går förbi den vanliga processen för full expansion. I praktiken passerar dessa tokens igenom, *oexpanderade*för att bli införlivade i den huvudsakliga tokenlistan som konstrueras av `\\directlua`—denna genomsläppsprocess för oexpanderade tokens liknar i funktion `\unexpanded`, som diskuterats tidigare.

**Exempel**

Anta att vi definierar makrot `\\mymacro` som `\def\mymacro{\TeX}`. Det innehåller bara en token för `\\TeX` kommandot (som är ett makro): alltså har vi ett expanderbart kommando `\\mymacro` som innehåller ett annat makro `\\TeX`, som också är expanderbart.

Följande kod kommer att få Lua att försöka skapa en strängvariabel `x`:

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

Inuti \\`directlua`, tokenen för `\\mymacro` expanderas men det resulterar i en annan expanderbar token, `\\TeX`som expanderas ytterligare. I plain TeX resulterar dessa expansioner i följande text som skickas till Lua:

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

Denna kod försöker definiera en sträng som innehåller text som representerar den expanderade versionen av `\\TeX` makrot. Om du försöker köra detta exempel kommer Lua att försöka konstruera den strängen men det kommer att misslyckas och ge ett fel:

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

Senare i artikeln kommer vi att utforska innebörden av ”ogiltig escape-sekvens”.

Låt oss nu jämföra användningen av `\\mymacro` med att placera `\\TeX` tokenen i en tokenlista som genereras av en `\toks` kommandot:

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

LuaTeX:s `\\directlua` bearbetning kommer att generera denna textsträng för Lua:

`local x = "\TeX "`

Blankstecknet efter `\\TeX` genereras av LuaTeX:s omvandlingsprocess från kommandotoken till sträng.

**Men observera**: Paketet `\\TeX` makrot har *inte* expanderats till sina beståndsdelstokens. `\the\toks100` orsakade att tokens som lagrats i register 100 infogades, men det var allt: de är *inte* inte ytterligare expanderade och blir införlivade i den huvudsakliga tokenlistan som byggs av `\\directlua` (inom funktionen `scan_toks()`). Att lägga tokens i en tokenlista skapad av `\toks` är ännu ett sätt att förhindra att tokens expanderas.

Om vi kör detta exempel ger det också ett fel:

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

Vi utforskar Lua:s escape-sekvenser senare i artikeln.

## Andra kommandon/tekniker som används i expansion

I det här avsnittet tittar vi på några ytterligare TeX-kommandon/metoder som kan vara användbara i situationer där expansion tillämpas (såsom inom `\\directlua`).

### \string ⟨token⟩

`\string` är ett expanderbart kommando som omvandlar ⟨token⟩ till en serie teckentokens, var och en med kategorikod 12.

Till exempel, `\string\TeX` skulle producera en serie av fyra teckentokens `\`, `T`, `e` och `X` där varje tecken tilldelas kategorikod 12 (inklusive det inledande `\` tecknet).

Om vi skriver

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

den `\string` kommandot kommer att expanderas, vilket resulterar i en sekvens av teckentokens med kategorikod 12. Efter `\string` har expanderats kommer de resulterande teckentokensen (som representerar varje tecken i `\\newcommand`) att införlivas i den huvudsakliga tokenlistan som konstrueras av `\\directlua`. När `\\directlua` har avslutat konstruktionen av sin huvudsakliga tokenlista omvandlas dess beståndsdelstokens tillbaka till sin textuella representation, vilket ger följande kod att skicka vidare till Lua-tolken:

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

När denna kod skickas till Lua, `print(x)` kommer att skriva ut strängen `x` på skärmen (konsolen). Vi har dock varit lite listiga och medvetet använt ett exempelkommando som börjar med `\n`. Om du kan köra detta exempel i en lokal TeX-installation kommer du att märka att Lua skriver följande text på skärmen:

```
   Jag kommer att använda
   ewcommand
```

För att köra denna kod på Overleaf kan du instruera LuaTeX att skriva direkt till `.log` filen med LuaTeX:s Lua-API-funktion `texio.write(*string*)`:

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

Om du granskar den resulterande `.log` filen kommer du att se att den också innehåller

```
   Jag kommer att använda
   ewcommand
```

Detta oväntade resultat beror på att Lua tolkar `\n` i början av `**\n**ewcommand` som escape-sekvensen för radmatningstecknet (teckenkod 10): den antar att du vill börja en ny rad text som börjar med `ewcommand`. Vi diskuterar Lua:s escape-sekvenser senare i artikeln.

### \detokenize{⟨material⟩}

`\detokenize` är i sina effekter en flertokensversion av `\string` och det är också ett expanderbart kommando som omvandlar allt i `⟨material⟩` till en sekvens av teckentokens med kategorikod 12—*utom* blankstegstecken (ASCII/Unicode-värde 32) som får kategorikod 10. `\detokenize` infogar också ett avslutande blankstegstecken efter kommandonamn som är *kontrollord* (t.ex., `\foo`) men inget blankstegstecken infogas efter *kontrollsymboler* (t.ex., `\#`, `\%` osv.).

### Exempel

Även om makrona `\foohoo`, `\foo`, `\bar` och `\foobar` inte är definierade, om du skriver detta:

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

skulle det ge följande text som kod att skicka till Lua-tolken

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

Om du inte använder `\string` och `\detokenize` och skriver:

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

`\\directlua` skulle bearbeta `\foohoo`, känna igen att det är ett kommando och försöka expandera det; men eftersom `\foohoo` är inte definierat skulle det resultera i ett fel:

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

Eftersom `\string` och `\detokenize` omvandla sina argument till en serie teckentokens, `\\directlua`’s expansionsprocess får faktiskt möjlighet att upptäcka expanderbara kommandotokens `\foohoo`, `\foo`, `\bar`, eller `\foobar`: de omvandlas till sekvenser av teckentokens långt innan de kan utlösa expansion.

Som noterats tidigare innebär expansion av ett kommando att det tas bort från indata och ersätts av resultatet av dess ”expansionsbeteende”. Resultaten av expansionen (vanligtvis tokens) läses därefter av TeX-motorn. Här är ”expansionsbeteendet” för `\string` och `\detokenize` är att absorbera tecken- och kommandotokens från indata och omvandla dem till sekvenser av teckentokens, initialt lagrade i en tillfällig tokenlista, som `\\directlua` därefter läser. Dessa teckentokens införlivas i den huvudsakliga tokenlistan som konstrueras av `\\directlua`.

Följande grafik visar hur `\string` omvandlar `\foohoo` kommandot till en sekvens av teckentokens, vilket producerar en tillfällig tokenlista som därefter läses av `\\directlua` för att införliva dessa teckentokens i den huvudsakliga tokenlistan som konstrueras.

![](/files/0d4aab0aed99665c9883a9aa476f625f6c3aac7d)

Om `\string` eller `\detokenize` stöter på tecken i sitt argument, t.ex. `\string a` eller `\detokenize{abc}` producerar dessa tecken (här med kategorikod 11) teckentokens men med kategorikod 12.

Anmärkningar:

Om vi återgår till exemplet ovan:

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

vilket ger följande text som kod att skicka till Lua-tolken

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

kan vi observera följande:

* `\detokenize` har infogat ett blankstegstecken efter varje makronamn men `\string` inte gjort det.
* `\string` verkar på en enda token.
* I strängen `"\foohoo\foo \bar \foobar "` som används för att definiera `x` kommer vi återigen att stöta på Lunas mekanism för escape-tecken (diskuteras nedan):

  * `\bar` börjar med `\b` som är Lua:s escape-sekvens som används för att representera [bakstegstecknet](https://en.wikipedia.org/wiki/Backspace) (teckenkod 8);
  * kommandon `\foohoo`, `\foo` och `\foobar` alla börjar med `\f`, den Lua escape-sekvens som används för att representera [sidmatningstecknet](https://en.wikipedia.org/wiki/Page_break#Form_feed) (teckenkod 12).

  Eftersom teckensekvenserna `\b` och `\f` används i en sträng som skapas med dubbla citattecken `"..."` de kommer att ge oönskade resultat om inte åtgärder vidtas för att förhindra detta med hjälp av Luas så kallade *långa hakparenteser* strängmetoden: ett ämne som vi nu kan diskutera tillsammans med Lua escape-sekvenser.

## Vad är “Lua escape-sekvenser”?

Programmeringsspråk reserverar vissa tecken för “särskild användning” som en del av språkets syntax: i praktiken definieras dessa tecken så att de har någon form av särskild betydelse. Det finns dock tillfällen då du tillfälligt behöver “stänga av” ett sådant teckens särskilda betydelse om du till exempel vill att tecknet ska bäddas in som en del av en längre sträng där dess normala beteende skulle orsaka syntaxfel. I huvudsak måste det tecknet behandlas *utan* så att dess vanliga tolkning inte utlöses — det ska slinka igenom obemärkt. För att göra detta använder programmerare en teknik som kallas *escaping* där ett “specialtecken” representeras av dess så kallade *escape-sekvens*.

Ett standardexempel (som också stöds av Lua) är att använda dubbla citattecken inne i en sträng, där du maskerar de inre dubbla citattecknen med escape-sekvensen `\"`:

`"När de tillfrågades om LuaTeX svarade de: \"Det är en fantastisk TeX-motor!\" Jag höll med."`

Lua-språket tillhandahåller ett antal mekanismer för att arbeta med escape-sekvenser:

* standardsekvenser inklusive `\n` (ny rad), `\r` (vagnretur), `\\` (omvänt snedstreck), `\"` (dubbelt citattecken), `\t` (horisontell tabulator), `\v` (vertikal tabulator) och `\'` (enkelt citattecken);
* `\xXX`, där `XX` är en sekvens av exakt två hexadecimala siffror;
* `\ddd`, där `ddd` är en sekvens av upp till tre decimaler;
* vid tiden då denna artikel skrevs (augusti 2019) använder den senaste versionen av LuaTeX, även om den ännu inte var tillgänglig på Overleaf, version 5.3 av Lua, som introducerade stöd för UTF-8 escape-sekvenser: `\u{XXX}`. Denna escape-mekanism är för UTF-8-kodade Unicode-tecken där `XXX` är en sekvens av en eller flera hexadecimala siffror som representerar teckenets kodpunkt. Observera att de omgivande hakparenteserna `{ }` är obligatoriska.

### Att styra escape-sekvenser

Traditionellt definieras strängar med dubbla citattecken, som i `"detta är en sträng"`; i en sådan sträng kan du använda escape-sekvenser: `"detta är en sträng.\nJag börjar nu på en ny rad."`. Men Lua har en andra och *mycket* bekväm mekanism för att definiera strängar: dess så kallade *långa hakparenteser* mekanism, där du definierar en sträng genom att innesluta texten i `[[` och `]]`:

`[[Jag är en sträng med långa hakparenteser]]`

Inuti en sträng som skapas med metoden med långa hakparenteser är Lua:s tecken-escape-mekanism *avstängd*: escape-sekvenser behandlas som vanliga tecken. Till exempel, i strängen

`[[Jag är en sträng med långa hakparenteser\n string]]`

den `\n` escape-sekvensen behandlas inte som det enskilda vagnreturtecknet (ASCII-kod 13) utan som två vanliga tecken: `\` följt av `n`.

### Varför är strängar med långa hakparenteser så användbara?

Som vi senare ska utforska tillhandahåller LuaTeX en uppsättning specialiserade inbyggda Lua-funktioner som du kan använda med `\\directlua` för att styra LuaTeX:s sätt att sätta text. Bland dessa många funktioner finns en som kallas `tex.print(*string*)` som gör att du kan skicka `*string*` material från Lua-kod tillbaka till LuaTeX för sättning. Ett mycket enkelt exempel är:

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

vilket gör att LuaTeX sätter `Hello, World!`

Den `*string*` används i `tex.print(*string*)` kan också inkludera text som representerar TeX- och LaTeX-kommandon som LuaTeX ska bearbeta. TeX/LaTeX-kommandon börjar dock med ett `\` tecken, vilket är problematiskt med strängar som skapas med dubbla citattecken eftersom Lua då skulle försöka tolka strängen, upptäcka det inledande `\` tecknet och tolka det som början på en escape-sekvens. När Lua försöker behandla escape-sekvensen misslyckas det vanligtvis eftersom det inledande `\` kombinerat med det första tecknet i många TeX/LaTeX-kommandonamn inte bildar en giltig escape-sekvens som Lua känner igen. Till exempel, när en sträng som `"Jag gillar \LaTeX"` skulle Lua se `\L` och misslyckas med felet “ogiltig escape-sekvens”, och detta är orsaken till felen som nämns ovan.

#### Strängar med långa hakparenteser kommer till undsättning!

Metoden med långa hakparenteser för att skapa (definiera) strängar är extremt användbar eftersom även om TeX/LaTeX-kommandon börjar med ett `\` tecken, så inaktiverar strängmetoden med långa hakparenteser Lua:s mekanism för escape-sekvenser. Här är ett kort exempel, med tanke på att vi behöver förhindra att makron expanderas med till exempel `\protected` eller `\noexpand`.

Anta att vi definierar ett `\newtest` makro så här

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

och använder det i `\\directlua` med LuaTeX:s Lua API-funktion `tex.print()`:

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

På grund av användningen av `\protected`, expanderas inte makrot `\newtest` vilket leder till följande text som skickas till Lua:

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

Mellanslagstecknet som läggs till efter `\newtest` och före den öppnande klammern (`{`) är en sidoeffekt av `\\directlua`s konvertering av kommandotoken tillbaka till deras textuella representation.

Denna kod skickas till Lua som därefter kör LuaTeX-funktionen `tex.print()` men det finns ett problem som yttrar sig på sätt som beror på vilka typsnitt du använder. I LaTeX på Overleaf skulle du se ett utfall som detta:

![](/files/1b8e4901208587963df7ad3e280900a669d40872)

tillsammans med en varning i loggfilen:

```
   Missing character: There is no
   (U+000A) in font [lmroman10-regular]:+tlig;!
```

I vanlig TeX kan du få ett utfall som ungefär ser ut så här:

![](/files/73ba6cc8b7c63be58650489082de137d8965460c)

I båda fallen `\newtest` kallas inte makrot och utdata blir inte som vi tänkt oss. Felet orsakas av Lua:s mekanism för escape-tecken: i texten `\newtest {Hello}` börjar makronamnet med `\n` vilket Lua känner igen som escape-sekvensen för ett radmatningstecken och därför ersätter `\n` med ASCII-tecknet 10, eller i hex 0A. I LaTeX-felmeddelandet, `U+000A` är ett sätt att representera Unicode-värdet med 4 hexadecimala siffror.

Eftersom `\n` konverteras till radmatningstecknet ser LuaTeX inte ett makroanrop utan tror istället att det ombeds att sätta text som börjar med ASCII-teckenkod 10:

`⟨ASCII 10⟩ewtest {Hello}`

Beroende på vilket typsnitt som används kan LuaTeX eventuellt, eller eventuellt inte, kunna sätta `⟨ASCII 10⟩` tecknet men den återstående texten skrivs ut som den är med `{` och `}` behandlat som en grupp och inte utskrivet.

Vanlig TeX ger ett annat resultat eftersom standardtypsnittet är Computer Modern Roman, som har en märklig kodning som gör att en versal omega sätts när teckenkod 10 påträffas.

För att förhindra dessa problem måste vi använda strängar med långa hakparenteser för att hindra Lua:s escape-mekanism från att tillämpas. Det korrekta resultatet fås med

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

vilket ger resultatet som visas i följande skärmbild:

![](/files/56bf10d4b79daed8b080d8e36338581109283d00)

### Expansion och icke-körning av icke-expanderbara kommandon

När vi diskuterade expansion noterade vi att det är en process där en TeX-motor *tar bort* ett expanderbart kommando (token) från den aktuella inmatningen och *ersätter* det med resultatet som produceras av det expanderbara kommandot. Eftersom \directlua utför *endast-expansion* aktiviteter (för att generera en tokenlista), *gör inte* inte ta LuaTeX:s behandling längre än så. När ett expanderbart kommando har lästs in och expanderats fullt ut kommer resultaten av den expansionen — som ofta inkluderar icke-expanderbara kommandon (token) — att införlivas i den tokenlista som byggs upp, redo att konverteras tillbaka till text för att skickas vidare till Lua.

Det finns en viktig princip i spel här: under *endast-expansion* aktiviteter som syftar till att skapa en tokenlista utför TeX-motorer, inklusive LuaTeX, *inte* några icke-expanderbara primitiva, inbyggda TeX-kommandon.

I fallet med `\\directlua{⟨code⟩}`, om den fullt expanderade versionen av din `⟨code⟩` producerar, eller innehåller icke-expanderbara TeX/LaTeX-kommandon så *kommer de att skickas vidare till Lua* (representerade som text).

#### Exempel

Här är ett exempel som visar att icke-expanderbara primitiva inte körs under processer som bara är expansion (såsom inom `\\directlua`). Anta att vi definierar ett makro `\setcountreg` så här:

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

**Obs**: Vi använder `\relax` efter parameter `#2` för att förhindra att LuaTeX går för långt när det skannar inmatningen i sin sökning efter det numeriska värdet (argumentet) som ska matcha parameter `#2`.

Om vi, utanför `\\directlua`, senare kör makrot så här

```
   \setcountreg{100}{50}
   Värdet i räknarregister 100 är \the\count100.
```

det skulle ge ut

`Värdet i räknarregister 100 är 50.`

I detta sammanhang skulle vilken TeX-motor som helst behandla makrot `\setcountreg`—expandera makrot, bestämma argumenten och fortsätta att läsa *och utföra åtgärder* (köra) kommandon som finns i makrots ersättningstext (definition). Resultatet här blir att tilldela `50` som det värde som lagras i register `\count100`.

Men när en TeX-motor utför *endast-expansion* aktiviteter, som den gör med `\\directlua`, *kommer den inte att köra* de icke-expanderbara kommandon som finns i makrots definition.

Om vi skriver

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

den ger följande text som kod för Lua:

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

Lua-koden som genererats ovan visar att inom `\\directlua` den `\setcountreg` har expanderats, dess argument har identifierats och satts in i rätt parameter (`#1` och `#2`) men den går inte längre än så: det icke-expanderbara primitiva TeX-kommandot `\count` var *inte körs* under `\\directlua`s expansionsbearbetning.

Men LuaTeX kommer att köra TeX-koden om vi skickar den resulterande strängen `x` *tillbaka till LuaTeX* via `tex.print(x)` så här

```
\count100=50 % sätt \count100 till ett startvärde på 50
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{250}]]
   tex.print(x)
}
Värdet som lagras i räknarregister 100 är \the\count100.
```

Efter att `\\directlua` har avslutats skulle utdata vara

`Värdet som lagras i räknarregister 100 är 250.`

vilket visar att räknarregister `100` nu faktiskt innehåller värdet `250`.

Lua-koden som genereras från exemplet ovan är

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

Denna kod definierar `x` som en sträng skapad med metoden med långa hakparenteser, som används för att undvika fel med felaktiga escape-sekvenser. Om vi använde dubbla citattecken `"..."` för att definiera x, skulle teckenkombinationen `\c` i början av `\count` utlösa ett fel: `invalid escape sequence near ' "\c'`.

LuaTeX:s Lua API-anrop `tex.print(x)` resulterar i att LuaTeX kör TeX-kodsekvensen `\count 100=250\relax` och `\count100` tilldelas värdet `250` som man kan se i det satta resultatet:

`Värdet som lagras i räknarregister 100 är 250.`

#### Varning: makron och LuaTeX:s Lua API

I exemplet ovan såg vi att under `\\directlua`s förbearbetning (expansion) körde LuaTeX inte koden `\count 100=250`, som innehåller `icke-expanderbara` det primitiva kommandot `\count`: för att köra (utföra) den koden var vi tvungna att *skicka den tillbaka till LuaTeX* via `tex.print()`.

`\\directlua` är bara ett exempel på när LuaTeX utför en endast-expansion-bearbetning för att konstruera en tokenlista. Det finns andra kommandon som utför liknande expansionsbearbetning och aktiviteter för att generera tokenlistor, såsom `\\write` och `\edef`: dessa kommandon kör inte heller icke-expanderbara primitiva under sin expansionsbearbetning. Det är en allmän princip att TeX-motorer inte kör icke-expanderbara primitiva när de konstruerar en tokenlista under aktiviteter som endast består av expansion-bearbetning.

**Omskriva vårt makro för att använda LuaTeX:s Lua API**

Vi kan skriva om `\setcountreg` makrot med hjälp av en LuaTeX Lua API-funktion som kallas `tex.setcount()`, och därmed undvika TeX-kommandon för att ändra värdet som lagras i räknarregister `100`:

```
   \def\setcount#1#2{\directlua{tex.setcount(#1,#2)}}
   \count100=50
   räknarregister 100 innehåller \the\count100\par
   \setcount{100}{250}
   räknarregister 100 innehåller nu \the\count100\par
```

Denna kod kommer att sätta:

```
räknarregister 100 innehåller 50
räknarregister 100 innehåller nu 250
```

Här använder vi `tex.setcount()`, en av LuaTeX:s många Lua API-funktioner, för att *direkt komma åt* LuaTeX:s interna datalagringsområde för att placera värdet `250` i minnesplatsen som representerar räknarregister `100`. Vi har i praktiken *gått förbi* LuaTeX:s vanliga inmatningsbearbetningsmetoder i TeX-motorn: läsa inmatning, skapa token och köra TeX:s primitiva kommandon. Men här finns en varningshistoria: genom att använda LuaTeX:s Lua API-funktioner kan aktiviteter som endast består av expansion *leda till sidoeffekter*: ändringar av värden som lagras inne i TeX-motorn och som annars inte skulle vara möjliga med enbart TeX/LaTeX-kommandon.

**Exempel: oväntade sidoeffekter**

Här är ett exempel som visar *oväntade* sidoeffekter som kan uppstå med makron som använder `\\directlua`. Anta att vi skriver följande kod:

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

När denna kod körs sätts `12345`!

Hur kan det vara möjligt? Vi gjorde inte *uttryckligen* någon kod eller något makro för att lägga det värdet i räknarregister `999`. Eller gjorde vi?

Vi definierade `\dochange` med en `\\directlua` kommando som använder `tex.setcount()` för att lagra värdet `12345` i räknarregister `999`: i TeX-kod är det motsvarigheten till `\count999=12345`. Sedan använde vi den vanliga TeX-primitiven `\edef` för att definiera makrot `\careful`—det är användningen av `\edef` som utlöser den oväntade sidoeffekten.

`\edef` expanderar dess argument fullständigt: här upptäcker den ett expanderbart makro `\dochange` och expanderar det. Det `\dochange` makrot använder det expanderbara kommandot `\\directlua` som innehåller ett Lua API-anrop; så expansionen av `\dochange` resulterar i expansion av `\\directlua` och det gör att `tex.setcount()` anropas, vilket ändrar värdet i räknarregister `999`.

Om vi omdefinierar `\dochange` så att det använder TeX-kommandon:

```
   Före: räknarregister 999 innehåller \the\count999.\par
   \def\dochange{\count999=12345\relax}
   \edef\careful{\dochange}
   Efter: räknarregister 999 innehåller \the\count999.\par
```

när denna kod körs sätts

```
Före: räknarregister 999 innehåller 0.
Efter: räknarregister 999 innehåller 0.
```

Tydligt nog fanns det ingen effekt på `\count999`. När `\edef` definierar `\careful` expanderar det `\dochange` men den expansionen producerar endast icke-expanderbara TeX-primitiver: de *inte körs* men helt enkelt *lagras* i tokenlistan som utgör definitionen av `\careful`.

För säkerhets skull förklarar samma princip varför detta ger satt utdata:

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

## Kort introduktion till LuaTeX:s Lua API

Som vi har sett, `\\directlua` gör det inte bara möjligt att skriva vanlig Lua-kod, eller en blandning av Lua- och TeX/LaTeX-kod, utan ger också tillgång till en uppsättning ytterligare Lua-funktioner (specifika för LuaTeX) som du kan använda (anropa) för att kommunicera med, eller direkt styra, de inre funktionerna i sättningsprogramvaran LuaTeX. Vi har använt flera Lua-funktioner i den här artikeln, `tex.print()`, `texio.write()`, `tex.setcount()` och dessa, tillsammans med *många* fler, dokumenteras i [LuaTeX Reference Manual](http://www.pragma-ade.com/general/manuals/luatex.pdf) där grupper av relaterade funktioner kallas *bibliotek*.

Du kan tänka på dessa Lua-funktioner som LuaTeX:s Lua API (**Ett**pplication **P**rogramming **I**nterface) som tillhandahåller verktygen för att konstruera avancerade lösningar för sättning och dokumentteknik genom att styra LuaTeX:s sättningsbeteende med Lua som drivkraft.

Som nämnts organiserar LuaTeX sitt API i uppsättningar av funktioner som det kallar bibliotek: grupper av funktioner som hänger samman genom sitt syfte eller sina åtgärder. Varje uppsättning funktioner är utformad för att ge tillgång till en viss aspekt av LuaTeX:s interna processer, datastrukturer, datalagring och sättningsalgoritmer. Internt är LuaTeX uppbyggt av flera komponenter: programvarubibliotek/verktyg (främst skrivna i C) som inte bara utgör själva TeX-motorn utan även andra delsystem inklusive Lua, MetaPost, Kpathsea, FontForge, libpng och zlib. Dessa bibliotek är integrerade för att bygga funktionerna hos den körbara LuaTeX-programvaran, och det är genom Lua API som användarna får tillgång till LuaTeX:s funktionalitet, härledd från dess integration och samordning av dessa flera programvarukomponenter.

## Några exempel och fallgropar

I detta avsnitt presenterar vi några ytterligare exempel som använder de ämnen, begrepp och förklaringar som ges i den här artikeln.

### Att använda tilde-tecknet (\~)

Lua-språket använder `~` tecknet (kallas tilde) som en del av sin syntax, inklusive sin syntax för att utföra ett “inte lika med”-test; till exempel, för att testa om en variabel `x` inte är lika med `4` kan vi skriva:

```
   local x=3
   om x ~= 4 då
   print("x är inte lika med 4")
   end
```

Om vi försöker köra denna enkla Lua-kod via `\\directlua`:

```
\directlua{
   local x=3
   om x ~= 4 då
   print("x är inte lika med 4")
   end
}
```

får vi ett fel:

`[\directlua]:1: 'then' förväntades nära '\'.`

Det är märkligt eftersom vår kod är korrekt: vi har använt `'then'` och det finns inget `\` tecken i vår kod, så vad gick fel? För att förstå detta måste vi komma ihåg att, för TeX/LaTeX, `~` är vanligtvis definierat som ett “specialtecken” med kategori kod 13: så kallade aktiva tecken som är minikmakron och därför föremål för expansion. När `\\directlua` detekterar `~` tecknet expanderas det av *genom att ta bort det* bort från indata och *ersätta det* med resultatet av dess expansion. Med vanlig TeX producerar den resulterande texten (koden) som LuaTeX skapar och skickar vidare till Lua-tolken faktiskt inte `~` tecknet, och är:

`local x=3 if x \penalty \@M \ = 4 then print("x är inte lika med 4") end`

Den `~` tecknet har *tas bort* och *expanderats* till sina beståndsdelande kommandon—Lua-koden ovan är ett resultat av vanlig TeX:s definition av det aktiva tecknet `~`. Nu kan vi se varför Lua svarar med felet `'then' förväntades nära '\'`—den börjar tolka denna kod men stöter på ordet `\penalty` som inte betyder något för Lua och genererar ett syntaxfel.

För att rätta till detta behöver `~` tecknet ha en säker kategori kod vid den tidpunkt `\\directlua` bearbetar din kod; till exempel kan vi tillfälligt ändra kategori koden för `~` till 11 (bokstav) genom att innesluta koden i en grupp:

```
\begingroup
\catcode`\~=11
\directlua{
   local x=3
   om x ~= 4 då
   print("x är inte lika med 4")
   end
}
\endgroup
```

Denna kod fungerar som förväntat och `x är inte lika med 4` skrivs ut till konsolen. Det finns andra alternativ: vi kan använda de expanderbara kommandona `\noexpand` eller `\string`.

#### Med \string⟨token⟩

Vi kan tillämpa `\string` på det enkla `⟨token⟩` `~` vilket har kategori kod 13 (aktivt tecken); `\string` omvandlar `~` tecknet för att generera en teckentoken som har kategori kod 12. Om vi gör

```
\directlua{
   local x=3
   if x \string~= 4 then
   print("x är inte lika med 4")
   end
}
```

så producerar den den Lua-kod vi behöver:

`local x=3 if x ~= 4 then tex.print("x är inte lika med 4") end`

#### Med \noexpand⟨token⟩

Vi kan använda `\noexpand~` för att undertrycka expansionen av det aktiva tecknet `~`

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x är inte lika med 4")
   end
}
```

Det oexpanderade `~` token passerar vidare till tokenlistan som byggs i `\\directlua` och kommer att konverteras tillbaka till text, vilket ger fungerande Lua-kod.

### Med #-tecknet

Inom Lua-språket kan `#` tecknet användas för att få längden på en tabell. Men om vi försöker följande kod

```
\directlua{
   local tbl = {}
   tbl[1] = "Hej"
   tbl[2] = "Världen"
   tex.print("Tabellängden är "..#tbl)
}
```

vi kanske förväntar oss att LuaTeX sätter

`Tabellängden är 2`

men det genererar ett fel:

`\directlua]:1: försök att ta längden på ett numeriskt värde`

Detta fel utlöses eftersom `#` tecknet vanligtvis har kategori kod 6 (makroparameter)— `#` tecknet har två användningar i TeX/LaTeX: för att ange makroparametrar (`#1`, `#2`… `#9`) och ersättningstexten i justeringsmallar (för `\halign` och `\valign`).

När `\\directlua` genererar token för att bygga sin tokenlista ser det `#` tecknet med kategori kod 6 och skapar en lämplig teckentoken för att representera det. När det är dags att konvertera den slutliga tokenlistan tillbaka till textform får teckentokenen för # (med kategori kod 6) en särskild behandling: den skrivs ut som *två efterföljande tecken*: `##`, vilket resulterar i att följande kod skickas till Lua:

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

Vid konvertering till Lua-kod har det ursprungliga `#` har fördubblats och det genererar ett fel:

`\directlua]:1: försök att ta längden på ett numeriskt värde`

Detta problem uppstår på grund av TeX:s syntax som använder ett dubbelt hashtecken `##` för att representera eller generera ett enda `#` token; denna syntax används i makron som definierar andra makron som tar parametrar, eller i makron som används för att skapa mallar för `\halign` eller `\valign` tabellkonstruktionskommandon. Detta är ganska förvirrande så låt oss titta på ett exempel.

#### Exempel

Anta att vi definierar ett makro `\\mymacro` som tar en enda parameter, `#1`, men det definierar också ett andra makro `\foo` som i sin tur tar en enda parameter. För att skilja mellan parametern `#1` som används med `\\mymacro` och behovet av att definiera `\foo` för att använda sin egen parameter `#1` kräver TeX:s syntax att du använder `##1` inuti `\\mymacro` för att representera parametern som ska användas med `\foo`:

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

Om du skulle skriva `\mymacro{Hey!}` skulle det definiera makrot `\foo` att vara

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

Observera att `\\mymacro`parametern `#1` (`Hej!`) har införlivats i definitionen av `\foo` och sekvensen `##1` har konverterats till `#1` i definitionen av `\foo`. Så vi kan använda `\foo` så här:

`\foo{, World!}`

att sätta `Hej! Hej, världen!`

Vi kan lösa `\\directlua`s behandling av `#` tecknet genom att tillfälligt ändra dess kategori kod innan LuaTeX bearbetar koden. Till exempel:

```
\begingroup
   \catcode`\#=11
   \directlua{
   local tbl = {}
   tbl[1] = "Hej"
   tbl[2] = "Världen"
   tex.print("Tabellängden är "..#tbl)
}
\endgroup
```

Detta genererar Lua-koden

```
local tbl = {} tbl[1] = "Hej" tbl[2] = "Världen" tex.print("Tabellängden är "..#tbl)
```

vilket ger det förväntade resultatet:

`Tabellängden är 2`

### Med %-tecknet

Inom TeX/LaTeX används `%` tecknet vanligtvis för att inkludera kommentarer på en rad i din kod: för att signalera till TeX-motorn att den ska ignorera allt från den punkten till slutet av raden där `%` är skrivet. Men inom Lua-språket används `%` tecknet i vissa mycket användbara strängbehandlingsfunktioner, såsom `string.format(...)`, `string.gmatch(...)`, och `string.gsub(...)` i vilka `%` tecknet spelar en viktig roll som en del av dessa funktions syntax.

När den används med TeX/LaTeX, `%` fungerar `\\directlua` som kommentartecken eftersom det tilldelats kategori kod 14. För att få det att bete sig som ett vanligt tecken, och stänga av dess vanliga TeX/LaTeX-beteende, behöver vi ändra dess kategori kod till något säkert, till exempel 12. Den ``\catcode`\^^M=12 %<---vi utforskar detta vidare nedan!``, vilket låter oss använda Lua-kommentarer i vår kod; detta diskuteras nedan.

#### Exempel

Följande exempel är lånade från [lua-users.org](http://lua-users.org/wiki/StringLibraryTutorial), med lämpliga ändringar för användning inom `\\directlua`.

```
\documentclass{article}
\begin{document}
\begingroup
\ttfamily
\let\\\relax
\catcode`\^^M=12 %<---vi utforskar detta vidare nedan!
\catcode`\%=12
\directlua{
   local str -- deklarera en lokal variabel för att hålla resultatet

   tex.print("Använder string.format():".."\\par")

   str=string.format("%s %q", "Hej", "Lua-användare!") -- sträng och citerad sträng
   tex.print(str.."\\par")
   str = string.format("%c%c%c", 76, 117, 97) -- tecken
   tex.print(str.."\\par")
   str=string.format("%e, %E", math.pi, math.pi) -- exponent
   tex.print(str.."\\par")
   str=string.format("%f", math.pi) -- flyttal
   tex.print(str.."\\par")
   str=string.format("%g, %g", math.pi, 10^9) -- flyttal eller exponent
   tex.print(str.."\\par")
   str = string.format("%o, %x, %X", 99, 125, 125)  -- oktal, hexadecimalt, hexadecimalt
   tex.print(str.."\\par")

   tex.print("\\vskip3mm".."Använder string.gmatch():".."\\par")

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

   tex.print("\\vskip3mm".."Använder string.gsub():".."\\par")
   str=string.gsub("banan", "(an)", "%1-") -- fånga alla förekomster av "an" och ersätt
   tex.print(str.."\\par")
}
\endgroup
\end{document}
```

Följande skärmbild visar det typograferade resultatet av koden ovan:

![Användning av Lua-strängfunktioner i \directlua](/files/4efc1c05c346a25309e6602a513311de9152d00a)

## Varför visas Lua-koden på en enda rad?

Som du kanske har märkt presenteras alla de (genererade) Lua-kodfragment som visas i exemplen i denna artikel som en enda textrad: radbrytningar som ursprungligen fanns i `\\directlua` kodsnuttarna följs inte. Varför är det så? Det beror på att radbrytningarna i Lua-koden har *tagits bort* under LuaTeX:s förbearbetning inom `\\directlua`, vilket gör att Lua-koden blir en lång textrad. Det beteendet kan spåras till hur TeX-motorer hanterar tecken för radslut—betecknade med `\r` (vagnretur) och `\n` (radmatning) i programmeringslitteraturen. Precis varför vi behöver oroa oss för dessa detaljer blir tydligt när vi diskuterar att använda Luals mekanismer för att kommentera bort kodavsnitt.

När programvara skriver (sparar) en textfil avslutas varje enskild textrad med så kallade “newline”-tecken—de faktiska newline-tecknen beror på vilken applikation och vilket operativsystem som används för att skriva ut den filen. Wikipedia har en [intressant artikel](https://en.wikipedia.org/wiki/Newline) som utforskar historien/utvecklingen av de newline-tecken som används i dag.

Givet vilken textfil som helst kan dess enskilda textrader avslutas med olika kombinationer av tecken, kallade vagnretur (ASCII/Unicode-tecken 13) och/eller radmatning (ASCII/Unicode-tecken 10), som betecknas med `\r` och `\n` respektive. Eftersom TeX-motorer är utformade för att vara plattformsoberoende behöver de en metod för att kringgå den i grunden plattformsberoende naturen hos radslut i textfiler. Naturligtvis har TeX-motorer en inbyggd (men konfigurerbar) metod för att hantera radslutstecken.

### Hur TeX-motorer hanterar radslut

När LuaTeX bearbetar `\\directlua{⟨code⟩}` läser den texten som finns i din `⟨code⟩` och tillämpar standardmetoder för TeX-motorer för att bearbeta eventuella radslut som finns i din `⟨code⟩`. Som standard gör dessa standardmetoder för TeX att alla radslutstecken (vagnreturer och radmatningar) tas bort och ersätts med blanktecken. Vi säger “som standard” eftersom en TeX-motors hantering av radslutstecken kan ändras via en användarkonfigurerbar parameter som kallas `\endlinechar`. Här ger vi en kort tvåstegsöversikt, men ytterligare detaljer finns i Overleaf-artikeln [En introduktion till \endlinechar: Hur TeX läser rader från textfiler](/latex/sv/fordjupade-artiklar/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

#### Steg 1: TeX infogar sitt eget radslutstecken

Efter att ha läst en textrad från din inmatningsfil tar TeX-motorer omedelbart bort alla `\r` eller `\n` tecken från slutet av den raden. Därefter, TeX-motorer *infogar* (lägger tillbaka) sitt eget radslutstecken i slutet av den raden. Det tecknet bestäms av värdet på en användarkonfigurerbar TeX-parameter som kallas `\endlinechar` och det är genom denna mekanism som TeX-motorer kan bearbeta radslutstecken på ett plattformsoberoende sätt: de väljer och ställer in radslutstecknet oavsett vad som ursprungligen fanns i inmatningstextfilen.

Vanligtvis använder TeX-motorer inställningen

`\endlinechar=13`

vilket är vagnreturstecknet (`\r`). Men användare kan alltid tilldela en annan teckenkod som värde för `\endlinechar`—vilket vi kommer att se senare i artikeln.

Följaktligen kommer alla radslutstecken som finns i din `⟨code⟩` att bearbetas av `\\directlua{⟨code⟩}` tas bort och ersättas av ett enda tecken som bestäms av TeX-motorn själv. Observera att TeX-motorer utför denna bearbetning av radslut omedelbart efter att ha läst in en ny textrad från en fil och *innan* bearbetning av eventuella tecken på den raden (för att generera token). Men detta är inte slutet på historien: vad TeX-motorn *gör* gör med dessa radslutstecken (den har infogat) förklarar varför Lua-koden blir en enda rad.

#### Steg 2: TeX konverterar sitt radslutstecken till ett blanktecken

Förutom att infoga sitt eget radslutstecken, definierat av värdet på `\endlinechar`, använder TeX-motorer också kategori kod 5 för tecken som ska *behandlas som* ett radslutstecken. Detta resulterar i att TeX-motorer vanligtvis arbetar med:

1. ett radslutstecken definierat av `\endlinechar`;
2. att samma tecken *vanligtvis* tilldelats kategori kod 5.

Det är vad TeX gör med det radslutstecknet som förklarar vårt dilemma kring enstaka rader av Lua-kod. När en TeX-motor bearbetar en inmatningsrad kommer den så småningom att upptäcka det sista tecknet på den raden: tecknet definierat av `\endlinechar`. Vanligtvis har det tecknet kategori kod 5 vilket får TeX att *ersätta det* med ett blanktecken: dvs. i slutet av raderna tar TeX i praktiken bort sitt radslutstecken och ersätter det med ett blanktecken. Som en sidoanteckning använder TeX-motorer också tecken med kategori kod 5 för att upptäcka tomma rader och starta ett nytt stycke, men det tar vi inte upp här.

Naturligtvis, i TeX kan du utföra alla möjliga specialprogrammeringstrick genom att återställa `\endlinechar` till något annat tecken, och/eller ge tecknet som tilldelats `\endlinechar` ett kategori kodvärde som du själv väljer.

Om du vill förhindra att Lua-kod blir en enda textrad kan du antingen (tillfälligt) ändra värdet som tilldelats `\endlinechar` eller ändra kategori koden för den vanliga radslutsavslutaren `\r`.

### TeX:s bisarra ^^-notation

I de följande avsnitten kommer vi att stöta på TeX:s ovanliga `^^` notation, som är känd som den “utökade teckenmekanismen”. Den utformades av Knuth som ett sätt att underlätta inmatning av “kontrolltecken” såsom radslutsavslutare, tabulatorer och så vidare. Till exempel:

* `^^J` representerar teckenkod 10 (`\n`, radmatning);
* `^^M` representerar teckenkod 13 (`\r`, vagnretur).

Teckensekvenser som `^^M` omvandlas tidigt i TeX:s inmatningsavläsningsprocess till sina motsvarande teckenkoder, när TeX läser inmatningstecken för att generera motsvarande teckentoken.

### Ändra tecknet som tilldelats \endlinechar

Kom ihåg att vi fortfarande måste förhindra expansion av `~` tecknet, kan vi skriva

```
\begingroup
\endlinechar=10 % Ändra radslutstecknet till \n
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x är inte lika med 4")
   end
}% vi vill inte att \n ska visas här
\endgroup% eller en \n här
```

Den ovanstående inställningen för `\endlinechar` gör att LuaTeX lägger till teckenkod 10 (`\n`, radmatning) i slutet av varje rad den läser in. Vi gör detta eftersom `\n` (radmatning) vanligtvis har kategori kod 12, vilket du kan testa genom att skriva ``\the\catcode`\^^J``. Eftersom `\n` har inte kategori kod 5 kommer LuaTeX inte att konvertera det till ett blanktecken så det förblir i slutet av varje rad som läses in av LuaTeX. Detta resulterar i att ett tecken med kod 10 blir kvar i slutet av varje rad, och därmed tar sig igenom in i tokenlistan som byggs av `\\directlua` och därefter återkommer i Lua-koden när tokenlistan konverteras till text. Med ändringen ovan skickas Lua-koden till Lua-tolken som följande teckensekvens:

**\n**local x=3\*\*\n**om x \~= 4 då**\n**print("x är inte lika med 4")**\n**end**\n\*\*

där **\n** notationen är avsedd att representera teckenkod 10 *inte* något okänt makro `\n`. Nu kommer Lua-tolken att se radbrytningar i koden, exakt som den ursprungligen skrevs i `\\directlua` kommandot:

```
   local x=3
   om x ~= 4 då
   print("x är inte lika med 4")
   end
```

För övrigt, notera att det allra första tecknet i Lua-kodsträngen är `\n` (före `lokala` nyckelordet). Det `\n` uppstår från raden

`\directlua{`

eftersom det finns en radbrytning direkt efter den öppnande `{` och även detta bevaras. För att förhindra det kan du skriva

`\directlua{%`

### Ändra kategori koden för \r

För att behålla radbrytningar i vår Lua-kod kan vi också ändra kategori koden för `\r` till något annat än 5, så att `\r` inte längre känns igen (behandlas som) ett radslutstecken. Med denna teknik använder LuaTeX fortfarande `\endlinechar=13` och fortsätter att lägga till en `\r` i slutet av varje rad; men eftersom `\r` inte längre har kategori kod 5 kommer LuaTeX inte att känna igen `\r` tecknet som ett radslut: det kommer inte att konvertera det till ett blanktecken och skickar det oskadat vidare så att det dyker upp i Lua-koden.

Kom ihåg att vi fortfarande måste förhindra expansion av `~` tecknet, kan vi skriva

```
\begingroup
\catcode`\^^M=12 % ändra kategori koden för \r till 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x är inte lika med 4")
   end
}
\endgroup
```

I detta fall skickas Lua-koden till Lua-tolken som:

**\r**local x=3\*\*\r**om x \~= 4 då**\r**print("x är inte lika med 4")**\r**end**\r\*\*

där `\r` notationen är avsedd att representera teckenkod 13 inte något okänt makro `\r`. Som med `\endlinechar` exemplet kommer Lua-tolken nu att se radbrytningar i koden, exakt som den ursprungligen skrevs i `\\directlua` kommandot:

```
   local x=3
   om x ~= 4 då
   print("x är inte lika med 4")
   end
```

För övrigt, notera återigen att det allra första tecknet i Lua-kodsträngen är `\r` (före det lokala nyckelordet): även detta uppstår från raden

`\directlua{`

#### Varför användes \r kategori kod 12 men inte kategori kod 11?

Svaret beror på risken för att oavsiktligt införa fel som utlöses av `\r` (med kategori kod 11) som läggs till i slutet av TeX/LaTeX-kommandon som läses från vår inmatningsfil. Ta detta exempel:

```
\begingroup
\catcode`\^^M=11 % ändra kategori koden för \r till 11
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x är inte lika med 4")
   end
}
\endgroup
```

vilket genererar ett fel:

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

Hur kan det vara sant eftersom `\endgroup` är ett standard TeX-primitivkommando? Orsaken till felet är ganska subtil: När LuaTeX läste den sista textraden—den som innehöll `\endgroup`—lade den också till `\endlinechar` tecknet `\r` till slutet av den raden. Nu, inne i sitt minne, ser LuaTeX teckensekvensen

`\endgroup\r`

där vi använder `\r` för att ange tecknet med kod 13—inte namnet på något okänt TeX-makro `\r`.

Vid den tidpunkt då LuaTeX läste denna rad från vår textfil är det ursprungliga `\begingroup` fortfarande aktivt: vi befinner oss i en grupp som ännu inte har avslutats genom att exekvera det matchande `\endgroup` kommandot—vilket skulle få `\r` att återgå till sitt tidigare kategori kodvärde 5.

När LuaTeX börjar bearbeta (skapa token) från textraden `\endgroup\r` känner den igen det första tecknet `\` som escape-tecknet vilket får LuaTeX att börja leta efter namnet på ett kommando. För att identifiera ett kommandonamn letar LuaTeX efter en sekvens av tecken med kategori kod 11 men eftersom `\r` också har kategori kod 11 tror LuaTeX att `\r` tecknet (fortfarande med kategori kod 11) bildar *del av ett kommando* kallat `\endgroup\r` som naturligtvis inte finns så LuaTeX rapporterar ett `Odefinierad kontrollsekvens` fel. Det är därför vi använde kategori kod 12 och inte 11.

Eftersom LuaTeX:s felmeddelande skrevs till konsolen kunde vi inte lätt se/uppmärksamma `\r` tecknet så det var inte självklart vad som hade orsakat felet.

### Varför oroar vi oss för radslut?

Anledningen är att möjliggöra användning av Luals kommentarsmetod i din kod! Du kan använda LuaTeX:s standardmekanism att lägga till `%` tecken för att kommentera bort enstaka rader i din kod; dock har Lua-språket sina egna, mycket användbara, *flera-radiga* kommenteringsmekanismer som du kanske vill dra nytta av.

Låt oss börja med att se vad som händer om vi försöker använda Lua-språkets kommentarer på en rad utan att ta itu med radbrytningsproblem. Medan TeX använder `%` tecknet för att kommentera bort enstaka kodrader, använder Lua ett dubbelt bindestreck: `--`.

Vad händer om vi försöker köra detta:

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Jag ska skriva ut resultatet av detta komplexa test
   print("x är inte lika med 4")
   end
}
```

Vi får ett fel:

`[\directlua]:1: 'end' förväntades nära <eof>`

Detta fel orsakas av avsaknaden av radbrytningar i Lua-koden som skickas till tolken, vilken bara ser en enda sammanhängande sträng där kommentaren börjar mitt i den strängen:

```

local x=3 if x ~= 4 then -- Jag ska skriva ut resultatet av detta komplexa test print("x är inte lika med 4") end
```

Allt efter `**local x=3 if x ~= 4 then**` betraktas som kommenterat bort vilket gör att tolken ser en ofullständig bit av Lua-kod, vilket resulterar i felet

`'end' förväntades nära <eof>`.

där `<eof>` betyder filslut.

Som du säkert har gissat måste vi åtgärda detta genom att se till att radbrytningar överförs till den resulterande Lua-koden, vilket vi till exempel kan åstadkomma genom att ändra kategori koden för `\r` till 12:

```
\begingroup
\catcode`\^^M=12 % ändra kategori koden för \r till 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Jag kommer att skriva ut resultatet av detta komplexa test
   print("x är inte lika med 4")
   end
}
\endgroup
```

Nu ser Lua-tolken en sträng men den innehåller `\r` radbrytningar som de skrivs i `\\directlua` fragmentet:

**\r**local x=3\*\*\r**om x \~= 4 då**\r\*\*-- Jag kommer att skriva ut resultatet av detta komplexa test\*\*\r**tex.print("x är inte lika med 4")**\r**end**\r\*\*

Detta är i praktiken likvärdigt med att skriva

```
   local x=3
   if x \noexpand~= 4 then
   -- Jag kommer att skriva ut resultatet av detta komplexa test
   print("x är inte lika med 4")
   end
```

vilket betyder att Lua kan bearbeta denna kod korrekt och ignorera raden vi kommenterade bort.

**Blockkommentarer**

Lua-språket stöder också en syntax som det kallar [”blockkommentar”](https://www.lua.org/pil/1.3.html) (eller *lång kommentar*): dessa börjar med `--[[` och gäller i praktiken tills motsvarande `]]`. Vi kan använda denna praktiska syntax för att skriva kommentarer över flera rader, eller kommentera ut delar av kod som vi tillfälligt vill ta bort:

```
\begingroup
\catcode`\^^M=12 % ändra kategori koden för \r till 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   --[[ Jag kommer att skriva ut resultatet av detta komplexa test
   helt enkelt därför att det verkligen är
   en så fantastisk slutsats]]
   print("x är inte lika med 4")
   end
}
\endgroup
```

## Sammanfattningsvis

För det första, grattis om du har lyckats läsa igenom denna omfattande artikel! Vi har försökt ta fram en någorlunda heltäckande guide till TeX-relaterade begrepp och ämnen som ger den bakgrund som behövs för att få ut mesta möjliga av LuaTeX via `\\directlua` kommandot. Det är vår förhoppning att vi har producerat en artikel som är pedagogisk och bidrar med något användbart och värdefullt till Overleafs användargemenskap, och bortom den. Som alltid tar vi gärna emot feedback, så tveka inte att [kontakta oss](https://www.overleaf.com/contact) med kommentarer om den här artikeln eller förslag på fler ämnen du skulle vilja att vi skriver om.

Glad $$\text{Lua}\mathrm{\TeX}\text{-ing!}$$ från Graham Douglas och Overleaf-teamet.

### Och till sist... använd bara paketet luacode

Även om TeX och Lua fungerar på fundamentalt olika sätt, delar dessa språk ett antal tecken som har ”specialbetydelser” inom ramen för varje språk—såsom \\\\, %, \~, #, ^, &—tilldelar naturligtvis Lua och TeX dessa specialbetydelser för *mycket* olika syften. Vår genomgång av problematiska tecken visar varför svårigheter kan uppstå och hur du kan lösa dem; men det kan vara ganska tidskrävande att manuellt rätta många små Lua-kodfragment, så de flesta användare föredrar att använda LaTeX-paket som tar bort dessa utmaningar. Ett sådant paket är [`luacode`](https://ctan.org/pkg/luacode?lang=en) som erbjuder en uppsättning funktioner utformade för att förenkla arbetet med `\\directlua`, men åtminstone har du nu kanske en bättre förståelse för de problem `luacode` som det löser åt dig.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/sv/fordjupade-artiklar/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.
