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

# Eine Einführung in LuaTeX (Teil 2): \directlua verstehen

## Das Ziel dieses Artikels

Im ersten Teil dieses Artikels, [Eine Einführung in LuaTeX (Teil 1): Was ist es – und was macht es so anders?](/latex/de/ausfuhrliche-artikel/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md), haben wir LuaTeX kurz als eine äußerst vielseitige TeX-Engine vorgestellt: ein ausgefeiltes, programmierbares Satzsystem, das eine breite Palette von Werkzeugen zum Aufbau von Lösungen für Dokumentenentwicklung und -produktion bereitstellt.

In diesem abschließenden Teil werfen wir einen genauen Blick auf die wichtigste Komponente des LuaTeX-Werkzeugkastens: den `\directlua` Befehl, der das „Tor“ zur programmatischen Steuerung des Satzverhaltens von LuaTeX über die Lua-Skriptsprache bereitstellt.

Allerdings erfordert die vollständige Nutzung von LuaTeX über `\directlua` einige Hintergrundkenntnisse zu mehreren TeX-Themen: TeXs Token, Tokenlisten und Expansionsmechanismus. Das Ziel dieses Artikels ist es, diese grundlegenden TeX-Konzepte zu untersuchen und zu erklären: die TeX-bezogenen Prozesse hinter `\directlua` zu verknüpfen, um zu verstehen, wie es funktioniert, und die Grundlagen zu schaffen, auf denen Sie Ihre eigenen Satzlösungen mit LuaTeX aufbauen können.

Dieser Artikel enthält zahlreiche kurze Beispiele, um wichtige Aspekte von `\directlua`Verhalten zu demonstrieren und zu erklären, wobei bewusst zu komplexer Code vermieden wird und stattdessen kurze Codefragmente bevorzugt werden. Wo nötig, verwenden die Beispiele einfaches (rohes/plain) TeX – obwohl die meisten Menschen LaTeX (Makros) verwenden und bevorzugen, haben grundlegende TeX-Befehle den Vorteil der Einfachheit.

## Einführung in das Lua in LuaTeX

[Lua](https://www.lua.org/about.html) ist eine Skriptsprache, deren [Quellcode](https://www.lua.org/download.html) hochgradig portabel und leicht in Softwareanwendungen einbettbar ist und Entwicklern ermöglicht, Skriptfunktionen in ihre Programme zu integrieren. Lua wurde in [viele Anwendungen](https://en.wikipedia.org/wiki/List_of_applications_using_Lua) eingebettet und ist in der Computerspielbranche eine beliebte Wahl – vielleicht ist das bekannteste Beispiel [World of Warcraft](https://wowwiki.fandom.com/wiki/Lua_functions).

LuaTeX ist, wie der Name schon sagt, eine TeX-Engine, die die Lua-Skriptsprache einbettet und Benutzern die Möglichkeit bietet, das Satzverhalten von LuaTeX zu steuern, indem Lua-Programme (Skripte) in ihre Dokumente eingebunden werden. Zusätzlich zur direkten Steuerung von LuaTeX können Benutzer Lua auch rein als sehr leistungsfähige Programmiersprache nutzen, um Aufgaben auszuführen, die mit der TeX-Sprache äußerst schwierig zu erreichen sein könnten – was nach jeder fairen Einschätzung eine Herausforderung beim Erlernen und Beherrschen darstellt. Durch die Hinzufügung und Integration von Lua wird LuaTeX zu einer sehr vielseitigen und leistungsstarken TeX-Engine, die direkt zwei Programmiersprachen unterstützt.

### Lua und TeX in Ihrem Dokument verwenden: \directlua eingeben

Lua und TeX sind zwei *sehr unterschiedliche* Programmiersprachen: Lua liegt viel näher an dem, was die meisten Menschen als Programmiersprache ansehen, aber TeX mit seinen Kategoriecodes, Token, Makros und seinem Expansionsmechanismus ist weit entfernt von den Erfahrungen/Erwartungen der meisten Menschen an eine Sprache, in der man Programme schreibt. Wie die Geschichte gezeigt hat, hat sich die TeX-Sprache jedoch gehalten, weil sie gut in dem ist, wofür sie entworfen wurde: Satzsteuerung, auch wenn ihre Arbeitsweise etwas kryptisch ist.

Um der Herausforderung zu begegnen, die Lua- und TeX-Sprachen in einem einzigen TeX-Dokument zu mischen, führten die Entwickler von LuaTeX einen neuen Befehl namens `\directlua` ein, der der Weg ist, Lua zu verwenden – sowohl als eigenständige Programmiersprache für sich genommen als auch zur Steuerung des Satzverhaltens von LuaTeX.

Die `\directlua` Mit diesem Befehl können Benutzer Lua-Code in ihre TeX-Dokumente einbetten; dieser Code wird anschließend an den in LuaTeX integrierten Lua-Sprachinterpreter weitergeleitet. Allerdings `\directlua` ermöglicht es Ihnen auch, *kombinieren* Lua- und (La)TeX-Code zusammen innerhalb desselben `\directlua` Befehls – das bringt jedoch zusätzliche Komplexität mit sich, die auf grundlegenden Unterschieden zwischen Lua- und TeX-basierten Programmiersprachen beruht. Die zentrale Herausforderung bei der Verwendung einer Kombination aus (La)TeX- und Lua-Code besteht darin, sicherzustellen, dass diese beiden Sprachen friedlich koexistieren und sich nicht „gegenseitig in die Quere kommen“.

`\directlua` ist am besten für die Verwendung mit kürzeren Lua-Codefragmenten im Dokument geeignet, aber Sie können es auch mit umfangreicheren Lua-Programmen verwenden, wenn Sie möchten. Im Allgemeinen werden umfangreichere Lua-Programme und Lua-Codebibliotheken in externen Dateien gespeichert, die mithilfe von Lua `dofile()` Funktion innerhalb eines `\directlua` Befehls geladen werden. Aus Sicht der TeX-Verarbeitung liegt ein wesentlicher Vorteil der Verwendung externer Lua-Code-Dateien darin, dass Komplikationen vermieden werden, die aus TeXs Kategoriecode-Mechanismus entstehen – ein Thema, das in diesem Artikel ausführlich behandelt wird.

### Formellere Beschreibung von \directlua

Die [LuaTeX-Referenzhandbuch](http://www.pragma-ade.com/general/manuals/luatex.pdf) beschreibt `\directlua` wie folgt (leicht geändert):

> Um Lua-Code mit TeX-Eingabe zu verbinden, werden einige neue Primitive benötigt. Das Primitive `\directlua` wird verwendet, um Lua-Code sofort auszuführen. Die grundlegende Syntax lautet `\directlua{⟨code⟩}`. Das `⟨code⟩` wird vollständig expandiert und dann an den Lua-Interpreter übergeben. Nachdem das Lesen erfolgt ist und die Expansion auf `⟨code⟩`, wird die resultierende Tokenliste in eine Zeichenkette umgewandelt, als würde sie mit `\the\toks`.

Natürlich ist das technisch korrekt, aber vielleicht ohne Kenntnis von TeX-Prozessen niedrigerer Ebene – wie Token und Expansion – nicht so leicht zu verstehen.

## Verstehen von \directlua: Welche Themen werden wir behandeln?

In diesem Artikel werden wir einige wichtige Hintergrundthemen genauer betrachten und eine Reihe von Beispielen anbieten, die zeigen sollen, wie `\directlua` funktioniert und wo (oder warum) Sie vorsichtig sein müssen, wenn Sie TeX und Lua in Ihrem `⟨code⟩`.

Wir werden die folgenden Themen ausreichend detailliert untersuchen, um eine Grundlage für das Verständnis von `\directlua` und seiner „Vorverarbeitung“ des Codes, den Sie darin verwenden, zu schaffen:

* Kategoriecodes und TeX-Token: Text in Token und Token in Text umwandeln;
* TeXs Expansionsprozess (und das Verhindern von Expansion);
* Lua-Escape-Sequenzen/-Mechanismen für Zeichen und Zeichenketten;
* Verwendung von Kommentaren im Lua-Stil;
* eine kurze Einführung in die Lua-API von LuaTeX.

Wenn Sie verstehen, wie TeX-Engines Token erzeugen und verwenden, und ein Bewusstsein für den Expansionsmechanismus von TeX entwickeln, dann haben Sie die Grundlagen, die nötig sind, um die unglaubliche Vielseitigkeit von LuaTeXs `\directlua` Befehl zu interpretieren ist.

## Die Grundlagen: von Text zu Token und von Token zu Text

Overleaf hat mehrere Artikel veröffentlicht, die sich eingehend mit TeX-Token und verwandten Konzepten befassen, daher werden wir all dieses Material hier nicht wiederholen; stattdessen skizzieren wir die Bereiche/Themen, die für ein besseres Verständnis von `\directlua`.

Hier ist eine Liste zuvor veröffentlichter Artikel, die von Interesse sein könnten:

* [Was ist ein TeX-Token?](/latex/de/ausfuhrliche-artikel/53-what-is-a-tex-token.md)
* [Was ist eine TeX-Token-Liste?](/latex/de/ausfuhrliche-artikel/54-what-is-a-tex-token-list.md)
* [Wie funktioniert \expandafter: Eine Einführung in TeX-Token](/latex/de/ausfuhrliche-artikel/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)
* [Eine sechsteilige Reihe: Wie funktionieren TeX-Makros eigentlich?](/latex/de/weitere-themen/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### Zeichen-Token verstehen

Jedes Zeichen, das eine TeX-Engine aus einer Textdatei lesen kann, wird durch zwei numerische Werte dargestellt:

* sein *Zeichencode* (ASCII-Wert oder heute sein Unicode-Codepunkt);
* einen zweiten, auf TeX bezogenen Wert, genannt sein *Kategoriecode*.

Leser, die mehr über Kategoriecodes erfahren möchten, könnten an dieser von Overleaf veröffentlichten Einführung interessiert sein: [Also, wo fangen wir an? Mit Kategoriecodes](/latex/de/weitere-themen/19-how-tex-macros-actually-work-part-1.md#so2c-where-do-we-start3f-with-category-codes).

Wenn eine TeX-Engine beispielsweise ein Zeichen `Ein` einliest, hätte sie Zugriff auf zwei Informationen: `Ein`Zeichencode (65) und sein Kategoriecode (in der Regel 11). Sobald TeX dieses Zeichen `Ein`eingelesen hat, wird sein Kategoriecode nicht geändert, aber Benutzermakros können Änderungen des Kategoriecodes vornehmen, die sich auf alle *nachfolgenden* Zeichen `Ein` auswirken könnten, die *von TeX noch nicht gelesen wurden* . Folglich muss TeX dieses *gerade* Zeichen `Ein`, *eingelesene*, hat Kategoriecode 11. Dazu verwendet TeX das Integer-Paar (65,11), um einen weiteren Integer-Wert zu berechnen, den es ein *Zeichen-Token*nennt. Durch die Berechnung dieses Token-Werts, der an TeXs interne Verarbeitung weitergegeben wird, werden dieses spezielle `Ein` und sein Kategoriecode *miteinander verbunden*; tatsächlich *verkörpert* das Token die Daten, die TeX über dieses Zeichen wissen muss, um sie bei nachfolgenden Satzaktivitäten tiefer im TeX-Engine-Kern zu verwenden.

#### Wie werden Zeichen-Token berechnet?

Zunächst müssen wir uns daran erinnern, dass TeX-Engines Kategoriecode 13 verwenden, um sogenannte *aktive Zeichen*: Jedes Zeichen mit Kategoriecode 13 verhält sich wie ein Mini-Makro; folglich und wie wir unten sehen werden, werden Token für aktive Zeichen anders berechnet als reguläre Zeichen mit anderen Kategoriecodes wie 10, 11 oder 12.

Für *nicht aktive* Zeichen:

* ältere 8-Bit-Engines (Knuths TeX, e-TeX, pdfTeX) berechnen Zeichen-Token für *nicht aktive* Zeichen mit

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

* für LuaTeX, das mit Unicode-Zeichenwerten umgehen muss, ist die Berechnung für *nicht aktive* Zeichen ähnlich, erzeugt aber viel größere Integer-Werte:

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

Zurück zu unserem früheren Beispiel für den Buchstaben A mit Kategoriecode 11 würde LuaTeX einen Zeichen-Token-Wert von $$2^{21} \times 11 + 65 = 23068737$$. Sobald berechnet, *bindet* diesen bestimmten Buchstaben A mit einem Kategoriecode-Wert von 11. Benutzermakros können den Kategoriecode für jedes nachfolgende Zeichen A ändern, aber der Kategoriecode dieses einen Zeichens wurde durch die Umwandlung in ein Token für die Verwendung während der Verarbeitung innerhalb von LuaTeX festgelegt. LuaTeX hat die beabsichtigte Bedeutung dieses Zeichens, wie sie zum Zeitpunkt des Einlesens bestimmt wurde, bewahrt bzw. verkapselt.

TeX-Engines verwenden insgesamt [16 verschiedene Kategoriecodes](/latex/de/weitere-themen/43-table-of-tex-category-codes.md) und *jedem* dieser Kategoriecodes kann über den `\catcode` Befehl *jedem* jedes Zeichen zugewiesen werden, das die TeX-Engine lesen kann. Änderungen an Kategoriecodes werden verwendet, um die Art und Weise zu ändern, wie TeX-Engines bestimmte Zeichen in der Eingabe verarbeiten, und ermöglichen es TeX-Benutzern, Makros zu schreiben, die besondere Satzresultate oder Verhaltensweisen erzeugen.

**Aktive Zeichen**

Wie erwähnt, verwenden TeX-Engines Kategoriecode 13, um einem Zeichen eine „besondere Bedeutung“ zuzuweisen und es zu einem sogenannten *aktiven Zeichen* zu machen, das sich wie ein Mini-Makro verhält: kein vorangestelltes `\` ist erforderlich, das isolierte Zeichen reicht aufgrund seines Kategoriecodes aus, um sein makroähnliches Verhalten auszulösen.

Da sich ein aktives Zeichen wie ein Mini-Makro verhält, wird es nicht in ein *Zeichen-Token* umgewandelt, sondern in einen zweiten (Integer-)Tokentyp namens *Befehls-Token*. Diese werden wie folgt berechnet:

* für ältere 8-Bit-Engines (Knuths TeX, e-TeX, pdfTeX) werden Tokens für aktive Zeichen wie folgt berechnet:

1. einen Zwischenwert berechnen, der $$\text{curcs}$$ (**akt**uell **c**Kontroll **s**equenz) wobei $$\text{curcs} = \text{character code} + 1$$3. berechnen Sie den Token-Wert, wobei $$\text{active character token} = \text{curcs} + \text{4095}$$

* für LuaTeX ist die Berechnung etwas komplexer, weil es mit dem gesamten Bereich der Unicode-Zeichen umgehen muss, von denen jedes aktiv gemacht werden könnte:

1. den Zwischen-Integer-Wert berechnen $$\text{curcs}$$ indem eine sogenannte *Hash-Funktion* auf den in UTF-8 ausgedrückten Unicode-Codepunkt-Wert des aktiven Zeichens angewendet wird: $$\text{curcs}=\texttt{hashfunction}\text{(UTF-8 text for Unicode value of active character)}$$3. berechnen Sie den Integer-Token-Wert: $$\text{active character token} = \text{curcs} + 2^{29} - 1$$

**Beispiele**

* 8-Bit-Engines: die Token-Berechnung für das aktive Zeichen `~` (Zeichencode 126) führt zu $$\text{curcs} = 126 + 1 = 127$$, wodurch sich ein Token-Wert von $$4095 + 127 = 4222$$.
* LuaTeX: die Token-Berechnung für das aktive Zeichen `~` führt zu $$\text{curcs}=3186$$ wodurch sich ein Token-Wert von $$3186 + 2^{29} - 1 = 536874097$$. LuaTeX-Token verwenden deutlich größere Integer-Werte!

### Befehls-Token verstehen

Zusätzlich zur Verarbeitung von *einzelnen* Zeichen können TeX-Engines natürlich auch *Sequenzen* von Zeichen verarbeiten, die *Befehle* (oder genauer *Kontrollsequenzen*). Traditionell wird das `\` Zeichen verwendet, um den Beginn eines Befehls anzuzeigen, aber das ist nur eine Konvention – tatsächlich könnte stattdessen jedes Zeichen mit Kategoriecode 0 (das Escape-Zeichen) verwendet werden.

TeX-Engines erkennen zwei Arten von Befehlen, die als *Kontrollwörter* und *Kontrollsymbole*:

* **Kontrollwörter**: Befehle, die aus einem oder mehreren Zeichen konstruiert sind, die Kategoriecode 11 haben;
* **Kontrollsymbole**: Einzelzeichenbefehle, bei denen der Kategoriecode dieses Zeichens *nicht* 11 beträgt: wie zum Beispiel `\$`, `\#` oder `\\`.

**Hinweis**: Die TeX-Primitive `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` und `\toksdef` werden ebenfalls verwendet, um Kontrollsequenzen zu definieren, aber anders als bei regulären Makrodefinitionen sind die resultierenden Kontrollsequenzen (Kontrollwörter oder Kontrollsymbole) *nicht erweiterbar*—wir werden diese weiter unten genauer untersuchen.

#### Wie werden Befehls-Token berechnet?

Wie bei aktiven Zeichen verwenden TeX-Engines den zweiten Typ von Integer-Token-Wert, um Befehle darzustellen: *Befehls-Token*—denken Sie daran, dass aktive Zeichen auch Befehls-Token erzeugen, weil sie sich wie Mini-Makros verhalten.

Die von 8-Bit-Engines verwendeten Berechnungen zur Erzeugung von Befehls-Token-Integern finden Sie in diesem [Overleaf-Artikel](/latex/de/ausfuhrliche-artikel/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#how-tex-calculates-token-values). Hier fassen wir die wichtigsten Schritte bei der Berechnung von Befehls-Token für LuaTeX zusammen – die etwas anders sind, weil LuaTeX Unicode-Zeichencodes verarbeiten muss, die erheblich größer als 8-Bit-Werte sein können; dennoch folgen die Berechnungen von LuaTeX denselben allgemeinen Prinzipien wie die älteren 8-Bit-Engines.

Nachdem ein eingehender Befehl erkannt wurde, ignorieren TeX-Engines, einschließlich LuaTeX, das vorangestellte `\` Zeichen: Es wird nicht in Berechnungen von Befehls-Token-Werten verwendet, sondern dient lediglich als „Schalter“, um eine TeX-Engine zu informieren, dass sie einen Befehl verarbeiten muss. Der Befehls-Token-Wert wird unter Verwendung der Folge von (ein oder mehreren) Zeichen berechnet, die im Namen des Befehls enthalten sind – LuaTeX berechnet Befehls-Token für Kontrollsymbole und Kontrollwörter mit demselben Algorithmus:

1. den Zwischen-Integer-Wert berechnen $$\text{curcs}$$ indem eine sogenannte [Hash-Funktion](https://en.wikipedia.org/wiki/Hash_function) auf die Unicode-UTF-8-Zeichenkette, die im Befehlsnamen enthalten ist: $$\text{curcs}=\texttt{hashfunction}\text{(Unicode UTF-8 string of characters in command name)}$$3. berechnen Sie den Befehls-Token-Wert, wobei $$\text{command token} = \text{curcs} + 2^{29} - 1$$

**Beispiele**

* für den `\\` Für einen Befehl (ein Kontrollsymbol) berechnet LuaTeX $$\text{curcs}=94$$, was zu einem Token-Wert für `\\` von $$94 + 2^{29} - 1 = 536871005$$.
* für den `\vskip` Für einen Primitive-Befehl (ein Kontrollwort) berechnet LuaTeX $$\text{curcs}=3560$$, was zu einem Token-Wert für `\vskip` von $$3560 + 2^{29} -1 = 536874471$$.
* für das benutzerdefinierte Makro `\mynewmacro` (ein Kontrollwort) berechnet LuaTeX $$\text{curcs} = 2971$$, was zu einem Token-Wert für `\mynewmacro` von $$2971 + 2^{29} -1 = 536873882$$.

Sobald sie erstellt wurden, können Token zur späteren Verwendung in sogenannten *Tokenlisten* gespeichert werden, oder sie können sofort zur weiteren Verarbeitung im TeX-Engine-Kern weitergegeben werden. Die Verwendung von Integer-Werten zur Darstellung von Token funktioniert nicht nur auf allen Arten von Computerplattformen/Betriebssystemen, sondern ist auch eine sehr effiziente Methode für TeX, Daten zu speichern/verarbeiten.

### Wie eine TeX-Engine den Typ eines Tokens identifiziert (Befehl oder Zeichen)

Bei einem bestimmten Integer-Token-Wert, $$T$$kann eine TeX-Engine leicht feststellen, ob $$T$$ ein Befehl oder ein Zeichen darstellt, indem sie prüft, ob $$T$$ einen bestimmten $$\text{threshold value}$$überschreitet – $$\text{threshold value}$$ das hängt von der TeX-Engine ab. Wenn $$T \geq \text{threshold value}$$ dann $$T$$ ein Befehls-Token ist, ansonsten $$T$$ ist es ein Zeichen-Token. Der $$\text{threshold value}$$ ist $$4095$$ für 8-Bit-Engines und $$2^{29}-1$$ (536.870.911) für LuaTeX. Knuth entwarf die Methoden, die in Token-Berechnungsformeln verwendet werden, so dass seine TeX-Engine und alle nachfolgenden Engines, die auf seinem Code/seiner Architektur basieren, Token-Werte schnell und einfach prüfen können.

## Token können auseinander genommen werden (und wieder in Text umgewandelt werden)

Token (Integer) sind der Mechanismus, mit dem eine TeX-Engine alles „verkapselt“, was sie über ein Eingabeelement (Zeichen oder Befehl) aufzeichnen muss. Es gibt jedoch Zeiten, in denen eine TeX-Engine den Tokenisierungsprozess umkehren muss – um herauszufinden, was ursprünglich eingelesen wurde, um diesen Token-Wert zu erzeugen – ein einzelnes Zeichen oder eine Folge von einem oder mehreren Zeichen, die den Namen eines Befehls bilden:

* **für Zeichen-Token**: Jeder Zeichen-Token kann in seine zwei Bestandteile zerlegt werden: den Zeichencode und den entsprechenden Kategoriecode, der diesem Zeichen *zum Zeitpunkt seines ursprünglichen Einlesens*zugewiesen wurde. Wie alle TeX-Engines wird LuaTeX diese ursprüngliche Kategoriecode-Zuweisung nicht ändern, sondern sie bei weiteren internen Verarbeitungsaktivitäten verwenden.
* **für Befehls-Token:** Diese sind etwas detaillierter, aber wenn Sie sich LuaTeXs Berechnung von Befehls-Token ansehen, einschließlich Token für aktive Zeichen, sehen Sie, dass sie einem Muster folgen: $$\text{command token} = \text{curcs} + 2^{29} -1$$

wobei $$\text{curcs}$$ wird entsprechend der Art des erzeugten Befehls-Tokens berechnet: aktives Zeichen, Kontrollsymbol oder Kontrollwort. Die $$\text{curcs}$$ Variable ist ein *extrem* wichtiger Bestandteil der internen Operationen einer TeX-Engine: Bei jedem Befehls-Token-(Integer-)Wert kann LuaTeX den Wert von $$\text{curcs}$$ aus diesem Befehls-Token sehr leicht mit $$\text{curcs} = \text{token value} - (2^{29} -1)$$.

### Warum ist $$\text{curcs}$$ so wichtig?

Die interne TeX-Variable $$\text{curcs}$$ (**akt**uell **c**Kontroll **s**sequenz) ist eine äußerst wichtige Komponente der internen „unter der Haube“ ablaufenden Operationen einer TeX-Engine. Obwohl Sie sie in Ihrem Code nicht direkt verwenden oder darauf zugreifen können, $$\text{curcs}$$ spielt eine entscheidende Rolle, weil TeX-Engines den aktuellen Wert von $$\text{curcs}$$ als Index in interne Tabellen verwenden, die Daten über jeden dem Engine derzeit bekannten Befehl speichern. Diese Tabellen speichern Informationen über die aktuelle Bedeutung eines Befehls: Was tut er oder wofür steht er, und außerdem zeichnen sie die Folge von Zeichen auf, die ursprünglich zur Berechnung dieses $$\text{curcs}$$ Werts verwendet wurde. Durch Extrahieren des Werts von $$\text{curcs}$$ aus einem Befehls-Token kann eine TeX-Engine den Namen, also den menschenlesbaren Text, bestimmen, der einem beliebigen (Befehls-)Token entspricht, und so die Token-in-Text-Umwandlungen durchführen, die ein zentraler Aspekt von `\directlua`s Betrieb sind.

### Integer-Token wieder in Zeichen oder Zeichenfolgen (Befehlsnamen) umwandeln

Wir haben gesehen, dass TeX-Engines Eingabezeichen oder Zeichenfolgen in Integer-Token-Werte umwandeln, aber es gibt Gelegenheiten, in denen eine TeX-Engine den Prozess *umkehren* muss – um den menschenlesbaren Text auszugeben, der ursprünglich verwendet wurde, um diese Integer-Token-Werte zu erzeugen; zum Beispiel:

* Fehler- oder Warnmeldungen auf dem Bildschirm oder in eine `.log` Datei schreiben;
* TeX-/LaTeX-Code über den `\write` Befehl geändert werden;
* ausgeben, wenn eine Folge von Token innerhalb von `\directlua` (wie wir gleich sehen werden!) in Text umgewandelt wird

#### Zeichen-Token in Text umwandeln

Wie erwähnt, werden Token für nicht aktive Zeichen unter Verwendung des Kategoriecodes und Zeichencodes (Unicode-Werts) eines Eingabezeichens berechnet. LuaTeX verwendet die Formel:

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

Es ist eine unkomplizierte Programmieraufgabe, den Integer- $$\text{character token}$$ Wert zu zerlegen, um seinen zugehörigen Zeichencode ($$\text{Unicode value}$$) und $$\text{category code}$$.

#### Befehls-Token in Text umwandeln

Alle TeX-Engines speichern den Namen (die Folge von Zeichen) jedes Befehls, „den sie kennen“: unabhängig davon, ob dieser Befehl ein benutzerdefiniertes Makro oder ein eingebautes Primitive ist – die Speicherung der Namen von Primitive-Befehlen erfolgt beim Start der TeX-Engine, lange bevor sie beginnt, Ihren Code zu verarbeiten. Bei benutzerdefinierten Befehlen (Makros) wird der Name dieses Makros (abzüglich des vorangestellten `\`) als Teil der Makrodefinitionsprozesse innerhalb von TeX-Engines gespeichert.

Wenn eine TeX-Engine auf den menschenlesbaren Text zugreifen oder ihn ausgeben muss, aus dem ein Integer-Befehls-Token ursprünglich berechnet wurde, bestimmt sie zuerst den $$\text{curcs}$$ Wert für dieses Token; in LuaTeX, $$\text{curcs} = \text{token} - (2^{29} -1$$). Unter Verwendung des aus einem Befehls-Token extrahierten Werts von $$\text{curcs}$$ kann eine TeX-Engine auf eine interne Datenstruktur namens den *String-Pool* zugreifen, um die Folge menschenlesbarer Zeichen zu bestimmen, die ursprünglich zur Berechnung dieses bestimmten Werts für $$\text{curcs}$$ und folglich des entsprechenden Befehls-Tokens verwendet wurde.

Wie wir sehen werden, sind diese tokenverarbeitenden Aktivitäten – die Umwandlung von Zeichenfolgen in Integer-Token-Werte und die Rückumwandlung von Integer-Token-Werten in Zeichenfolgen („Ent-Tokenisierung“) – die *grundlegenden Mechanismen* die in `\directlua`.

## Tokenlisten

Wenn eine TeX-Engine Eingaben liest, Zeichen- und Befehls-Token erzeugt (und sie verarbeitet), kann sie auf bestimmte Befehle stoßen, die die Engine anweisen, die Weitergabe von Token an die weitere Verarbeitung vorübergehend zu stoppen und sie stattdessen für eine spätere Verwendung zu speichern. Das häufigste Beispiel ist die Definition eines Makros mit einem der Makrodefinitionsbefehle `\def`, `\edef`, `\gdef` oder `\xdef`—LaTeX-Befehle wie `\newcommand` sind Makros, die zusätzliche Funktionalität bereitstellen, die um Low-Level-Primitive herum aufgebaut ist, die letztlich den eigentlichen Makrodefinitionsprozess ausführen. Ein Makro kann als Name für eine bestimmte Liste gespeicherter Token betrachtet werden: eine Tokenliste.

TeX-Engines machen *umfangreichen* Gebrauch von Tokenlisten, insbesondere [temporären nur-internen Listen](/latex/de/ausfuhrliche-artikel/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) die für interne Verarbeitungszwecke verwendet werden. Jede TeX-Engine stellt auch Befehle auf Benutzerebene bereit, um Tokenlisten zu erstellen, die für später gespeichert werden, wenn der Benutzer oder die TeX-Engine selbst sie benötigt. Die Anzahl der Befehle zur Tokenlistenerstellung (eingebaute Primitive) variiert je nach TeX-Engine, aber sie haben alle einen gemeinsamen Mindestumfang, den jede Engine unterstützt, wie zum Beispiel das `\toks` Primitive.

In der Praxis ist eine Tokenliste einfach eine gespeicherte Folge von Integer-Werten:

* die Eingabe wird gelesen, um einzelne Token zu erzeugen (zu berechnen), die ein Zeichen oder einen Befehl darstellen;
* jedes Token wird dann gespeichert, wobei die Reihenfolge erhalten bleibt, in der die Token aus der Eingabe erzeugt wurden.

TeX-Engines speichern Tokenlisten unter Verwendung einer Datenstruktur namens [verkettete Liste](https://en.wikipedia.org/wiki/Linked_list) (der einfach verketteten Variante). Leser, die mehr über Tokenlisten erfahren möchten, sind eingeladen, den Overleaf-Artikel [Was ist eine TeX-Token-Liste?](/latex/de/ausfuhrliche-artikel/54-what-is-a-tex-token-list.md) zu lesen, der anhand einer Analogie die Konzepte/Ideen hinter einer Tokenliste aufbaut. Eine eingehende Untersuchung von TeXs Tokenlisten und ihrer Verwendung bei der Makroverarbeitung finden Sie in der Overleaf-Artikelserie [Wie funktionieren TeX-Makros eigentlich?](/latex/de/weitere-themen/01-a-six-part-series-how-do-tex-macros-actually-work.md)

#### Eine Tokenliste in grafischer Form

Die folgende Grafik zeigt eine von LuaTeX erzeugte Tokenliste mit entsprechenden Token-Werten, die aus der folgenden Eingabe erzeugt wurden

`Hi, \TeX! \hskip 5bp`

Wenn wir zum Beispiel `\mymacro` als `\def\mymacro{Hi, \TeX! \hskip 5bp}` die Definition von `\mymacro` würde im Speicher mithilfe einer Tokenliste wie dieser gespeichert werden:

![](/files/90871ce26397862b6bb50edff55737db79f5749a)

Die Tokenliste ist eine Folge verbundener Elemente, genannt *Knoten*, die Bezeichnung für ein kleines Paket von LuaTeX-Speicher, das jedem Element in der Liste zugewiesen wird (wie einzelne Glieder in einer Kette). Jeder Knoten enthält einen Integer-Token-Wert und die Speicheradresse des *nächsten* Knotens in der Kette und bildet so eine Datenstruktur namens [verkettete Liste](https://en.wikipedia.org/wiki/Linked_list). Der letzte Knoten markiert das Ende der Liste mit einem speziellen „Nullwert“ für den nächsten Knoten – weil es keinen gibt.

**Hinweise:**

* Der Einfachheit halber haben wir die Adresse jedes einzelnen Knotens angegeben, aber in der Praxis wird diese Daten nicht in Tokenlisten-Knoten gespeichert; nur die Adresse des *nächster Knoten* nächsten Knotens
* Die zweite Spalte in der Grafik mit dem Titel „Was jedes Token bedeutet“ zeigt eine Reihe grauer Kästchen mit Informationen über das in jedem Knoten enthaltene Token: Diese dienen nur zur Information und *werden nicht* sind kein Bestandteil der tatsächlich in der Tokenliste gespeicherten Daten.

Hier ist eine Tabelle der Token-Werte, die in der oben dargestellten Tokenliste enthalten sind:

|                    |                     |                                                                               |                |
| ------------------ | ------------------- | ----------------------------------------------------------------------------- | -------------- |
| **Eingabeelement** | **Art der Eingabe** | <p><strong>Kategoriecode</strong><br><br><strong>(falls Zeichen)</strong></p> | **Token-Wert** |
| H                  | Zeichen             | 11                                                                            | 23068744       |
| i                  | Zeichen             | 11                                                                            | 23068777       |
| ,                  | Zeichen             | 12                                                                            | 25165868       |
|                    | Zeichen             | 10                                                                            | 20971552       |
| \TeX               | Befehl (Makro)      |                                                                               | 536871539      |
| !                  | Zeichen             | 12                                                                            | 25165857       |
|                    | Zeichen             | 10                                                                            | 20971552       |
| \hskip             | Befehl (Primitive)  |                                                                               | 536874247      |
| 5                  | Zeichen             | 12                                                                            | 25165877       |
| b                  | Zeichen             | 11                                                                            | 23068770       |
| p                  | Zeichen             | 11                                                                            | 23068784       |

**Hinweis:** Unser ursprünglicher Eingabetext hat ein a nach dem `\hskip` Befehl, aber es gibt kein Token, das dieses Zeichen in der Tokenliste repräsentiert. Dieses Zeichen wurde vom Eingabescannen (Lesen) von LuaTeX absorbiert, weil es verwendet wurde, um LuaTeX’ Suche nach Zeichen zu beenden, aus denen der `\hskip` Befehl zu interpretieren ist.

## Wie \directlua wirklich funktioniert

Nachdem wir Token, Tokenlisten und die Umwandlung von Tokens in Text untersucht haben, besteht die nächste Herausforderung darin, das TeX-Engine-Konzept des Tokens zu verstehen *Expansion*.

Wie bereits erwähnt, `\directlua{⟨code⟩}` kann aufgefordert werden, zu verarbeiten `⟨code⟩` die sowohl Lua- als auch TeX/LaTeX-Code enthält, aber der eingebaute Lua-Sprachinterpreter von LuaTeX versteht TeX oder LaTeX nicht: Wie kann das also funktionieren? Wie ist es möglich, dass der `⟨code⟩` TeX/LaTeX-Anweisungen enthalten kann, ohne den Lua-Interpreter mit Befehlen, die er nicht versteht, völlig zu verwirren? Zum Beispiel verwendet der folgende `\directlua` Befehl nur TeX-Makros, aber er funktioniert:

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

Diese `\directlua` Befehl bewirkt, dass LuaTeX den Text setzt `Hello` aber warum und wie funktioniert das, da die Lua-Sprache TeX-Makros nicht versteht?

Die Antwort steckt in der früheren Beschreibung, die wir aus dem [LuaTeX-Referenzhandbuch](http://www.pragma-ade.com/general/manuals/luatex.pdf) aber wir können davon ausgehen, dass `\directlua{⟨code⟩}` funktioniert, indem LuaTeX zunächst die ... „vorverarbeitet“ `⟨code⟩` bevor irgendetwas an den Lua-Interpreter übergeben wird. Die Art dieser „Vorverarbeitung“ – also was sie wirklich bedeutet und welche Konsequenzen sie für Ihr `⟨code⟩`—ist das nächste Thema, das wir behandeln werden, um Lesern zu helfen, die die Leistungsfähigkeit und Flexibilität von `\directlua`.

### Wie LuaTeX \directlua verarbeitet: Ein erster Blick

Um unser Verständnis von `\directlua`’s „Vorverarbeitungs“-Aktivitäten können wir mit dem folgenden vereinfachten Diagramm beginnen, das einen Überblick darüber gibt, was geschieht. Der `⟨code⟩` bereitgestellt an `\directlua{⟨code⟩}` wird zunächst mit den oben besprochenen Prozessen und Berechnungen in Tokens umgewandelt; diese Folge von Tokens wird in einer Tokenliste gespeichert. Sobald diese Tokenliste erstellt ist, wird jedes Token in dieser Liste wieder in seine textuelle Darstellung umgewandelt: Der von jedem Token erzeugte Text – Zeichen-Token oder Befehls-Token – wird zusammengeführt (verkettet), um eine einzelne Zeichenkette von Code zu erzeugen, die zur Ausführung an den Lua-Interpreter weitergegeben wird.

![](/files/d4025b7e9f1bb59cbbfac122b1f0629878b9bc7e)

Aber Moment, was wäre der Sinn davon, von Text zu Tokens zu gehen und diese Tokens direkt wieder in Text umzuwandeln? Es dürfte Sie nicht überraschen zu erfahren, dass es ja einen zusätzlichen und wichtigen Prozess gibt, den wir in dieser Grafik nicht berücksichtigt haben: *Token-Expansion*. Jedes Token, das aus dem Text in Ihrem `⟨code⟩` wird einer Art „Überprüfung“ unterzogen, bei der LuaTeX einen Test anwendet, um zu sehen, ob dieses Token einen Befehl darstellt, der zu der Teilmenge gehört, die als *expandierbare Befehle*. Falls ja, filtert LuaTeX diesen Befehl heraus, indem es *das Entfernen* ihn aus Ihrem `⟨code⟩` und *und ersetzt ihn* durch das Ergebnis bzw. die Ergebnisse eines Prozesses, den TeX-Engines nennen *Token-Expansion*.

### Wie LuaTeX \directlua verarbeitet: Ein zweiter Blick (auf die Expansion)

TeXs Expansionsmechanismus ist ein Kernbestandteil aller auf TeX basierenden Satzsysteme, weil letztlich jedes von Knuths ursprünglichem Quellcode und Design von TeX abgeleitet ist (oder darauf basiert). Das Konzept der Expansion ist jedoch schwierig in knapper, aber zugänglicher Sprache zu erklären, weil Expansion in der Praxis ein Oberbegriff ist, der verwendet wird, um einen einzelnen Prozess zu beschreiben – aber einen, der eine Reihe von Ausgaben erzeugt. Diese unterschiedlichen Ergebnisse sind eine Folge der etwas eklektischen Menge an Befehlen, auf die Expansion angewendet werden kann, sodass man sagen kann, dass jeder expandierbare Befehl ein bestimmtes „Expansionsverhalten“ hat.

Als eine *erste Annäherung* zum Verständnis der Expansion können wir sagen, dass die Expansion eines Tokens (Befehls) bedeutet *das Entfernen* dieses Token (diesen Befehl) aus der aktuellen Eingabe von TeX zu entfernen und *das Ersetzen* es durch eine Folge von Tokens zu ersetzen, die aus der Ausführung dieses speziellen expandierbaren Befehls resultieren – also das ursprüngliche Token durch die Ergebnisse/Folgen seiner Expansion zu ersetzen *Verhalten*. Allerdings ist diese anfängliche „Definition“ der Expansion – im Sinne der Erzeugung neuer Tokens, die TeX lesen soll – nicht für alle expandierbaren Befehle vollständig korrekt, aber sie ist als Ausgangspunkt gut genug.

Ein einfaches Beispiel: das TeX-Primitive `\jobname` ist ein expandierbarer Befehl und sein *Expansion* ist eine Folge von Zeichen-Tokens, die den Namen der Haupt-TeX-Eingabedatei darstellen. Wenn TeX sich entscheidet, einen `\jobname` Befehl (ein Token) zu expandieren, wird er *entfernt* aus der aktuellen Eingabequelle von TeX und *ersetzt* durch die Folge von Zeichen-Tokens, die es erzeugt – die TeX dann weiter liest/verarbeitet.

Innerhalb von `\directlua`nachdem ein expandierbares Token verarbeitet (entfernt) und durch neue Tokens ersetzt wurde, wird LuaTeX diese neu eingesetzten Tokens weiter lesen – aber einige dieser neuen Tokens könnten ebenfalls expandierbar sein. Weil `\directlua` das sogenannte *Voll-Expansion*macht, wird LuaTeX diese neuen Tokens lesen und erneut den Expansionsprozess durchlaufen, um alle neuen (expandierbaren) Tokens zu expandieren (zu entfernen) – dieser Expansionsprozess läuft weiter, bis keine expandierbaren Tokens mehr übrig sind. Es gibt jedoch zwei wichtige Ausnahmen von dieser Regel „weiter expandieren“, auf die wir unten eingehen werden:

* unter Verwendung der Konstruktion `\the\toks`;
* bewusste Verhinderung (Unterdrückung) der Expansion für ein oder mehrere ausgewählte Tokens.

Wie bereits erwähnt, deckt unsere Arbeitsdefinition (erste Annäherung) zum Verständnis der Expansion nicht die gesamte Bandbreite an Expansionsverhalten ab, die von der Teilmenge der expandierbaren Befehle gezeigt wird. Einige expandierbare Befehle erzeugen zum Beispiel keine Tokens auf die Weise, wie `\jobname` es tut, aber sie können:

* Tokens aus der Eingabe „herausfiltern“: die bedingten Befehle einer TeX-Engine (`\if`, `\ifcat`, `\ifnum`, `\ifdim`, `\ifodd`, `\ifvmode`, …) sind expandierbar. Ihr Expansionsverhalten ist eine Art „Token-Filterung“ – Konditionale können verwendet werden in `\directlua`.
* Tokens in der Eingabe „jonglieren“: der [`\expandafter` Befehl](/latex/de/ausfuhrliche-artikel/03-a-six-part-article-series-on-expandafter-tex-tokens-and-expansion.md) ist expandierbar und verändert die Reihenfolge, in der zwei Tokens expandiert werden.
* Expansion verhindern: die expandierbaren Befehle `\noexpand` und `\unexpanded` unterdrücken die Expansion von Befehls-Tokens in der Eingabe.
* wandeln Zeichenfolgen in der Eingabe in Befehls-Tokens um: `\csname … \endcsname.`
* wandeln interne Größen in eine Folge von Zeichen-Tokens um: `\number` und `\the` sind expandierbare Befehle, die eine Folge von Zeichen-Tokens erzeugen, welche den Wert einer internen Größe darstellen.
* wandeln Befehls-Tokens in Zeichen-Tokens um: `\string` und `\detokenize` sind expandierbare Befehle, die ihre Argumente in eine Folge von Zeichen-Tokens mit Kategoriencode 12 umwandeln. Beachten Sie, dass `\detokenize` sich von `\string`: `\detokenize` kann mehrere Tokens verarbeiten und fügt nach der Verarbeitung von Befehls-Tokens, die aus *Kontrollwörter*erzeugt wurden, ein Leerzeichen mit Kategoriencode 10 hinzu. Tatsächlich `\detokenize` ein nachgestelltes Leerzeichen nach dem Befehlsnamen hinzufügt – einige Beispiele sehen wir später im Artikel.

#### Verfeinerung unserer „Definition“ von Expansion

Wir können unsere Definition nun verallgemeinern und sagen, dass die Expansion eines Befehls (Tokens) Folgendes umfasst *das Entfernen* dieses Befehls (Tokens) aus TeX’ aktueller Eingabequelle und *und ersetzt ihn* durch das Ergebnis der *Token-Operation(en)* ausgeführt

Im Wesentlichen bewirkt der Expansionsprozess, dass ein expandierbarer Befehl irgendeine Art von „Operation“ auf Tokens in TeX’ aktueller Eingabe ausführt, die die Anzahl oder das Verhalten der Tokens beeinflusst, die TeX anschließend lesen wird – die genaue Art dieser „Operation“ hängt davon ab, welcher Befehl expandiert wird. Alle Makros und aktiven Zeichen sind expandierbar, aber nur eine kleine Anzahl der integrierten Befehle (Primitiven) einer TeX-Engine wird als expandierbar eingestuft – die Liste der expandierbaren Befehle hängt von der TeX-Engine ab, die Sie verwenden.

Eine weitere Schwierigkeit beim Erklären/Verstehen der Expansion, und vielleicht die eigentliche Herausforderung, besteht darin, genau zu wissen *wann* eine TeX-Engine den Expansionsprozess tatsächlich ausführen wird oder nicht. Das ist ein großes und komplexes Thema, weil Expansion tief in den inneren Abläufen von TeX-Engines verankert ist: Wir haben nicht den Raum, dies über die Verwendung der Expansion in `\directlua`.

### Wie LuaTeX \directlua verarbeitet: Ein abschließender Blick

Das folgende Diagramm fasst die `\directlua` Vorverarbeitungsaktivitäten zusammen, die innerhalb der LuaTeX-Engine selbst stattfinden. In diesem Diagramm zeigen wir auch zwei niedrigstufige (interne) LuaTeX-Funktionen, die die eigentliche Arbeit erledigen: `scan_toks()` und `tokenlist_to_cstring()`. Diese Funktionen sind in der C-Sprache geschrieben und befinden sich tief im ausführbaren LuaTeX-Programm: Sie sind Teil der inneren Mechanik von LuaTeX und nicht *direktes* für Ihren TeX/LaTeX-Code zugänglich.

![](/files/87a2116199e427cfed6442305bac43df8028c453)

Die folgende Beschreibung von `\directlua ⟨code⟩`’s Vorverarbeitungsaktivität fasst das obige Diagramm zusammen.

1. Die Zeichenfolge in Ihrem ⟨code⟩ wird von `scan_toks()`verarbeitet. Ihr Zweck ist es, Ihren ⟨code⟩ Zeichen für Zeichen zu lesen, um Zeichen-Tokens und Befehls-Tokens zu erzeugen. Da dabei Tokens erstellt werden, ist der Kategoriencode, der jedem Zeichen in ⟨code⟩ zum Zeitpunkt des Einlesens zugewiesen ist, äußerst wichtig.
2. Während der `scan_toks()`Token-Verarbeitung (Erzeugung) von ... wird jeder expandierbare Befehl (jedes Token) expandiert *es sei denn,* verhindert durch Befehle wie `\protected` (Makrodefinitionen), `\noexpand`, `\unexpanded` usw. Aktive Zeichen (Kategoriencode 13) werden ebenfalls expandiert (sofern nicht verhindert).
3. Der von `scan_toks()` erzeugte Token-Strom wird zu einer langen Tokenliste aufgebaut – Tokens, die in dieser Liste enthalten sind, umfassen auch jene, die aus der auf expandierbare Befehle (wie Makros) in Ihrem ... angewandten Expansion hervorgegangen sind. `⟨code⟩`Beachten Sie auch, dass `scan_toks()` *nicht* die Ausführung eines Tokens, das einen nicht expandierbaren Befehl darstellt, auslösen oder bewirken: solche nicht expandierbaren Tokens werden einfach durchgereicht und in die zu konstruierende Tokenliste aufgenommen.
4. Sobald die Tokenliste fertiggestellt ist und alle Expansionsaktivitäten abgeschlossen sind, wird diese Tokenliste von einer anderen Funktion verarbeitet, die heißt `tokenlist_to_cstring()` welche jedes Token in der endgültigen Tokenliste wieder in seine textuelle Darstellung umwandelt. Dadurch entsteht eine Zeichenkette von Text, die der Lua-Code ist, der an den Lua-Interpreter weitergegeben wird. Für eine erfolgreiche Ausführung muss diese Zeichenkette syntaktisch korrekten Lua-Code enthalten.
5. Die Verarbeitung dieses Codes durch Lua erfolgt in zwei Schritten:
6. Der eingebaute Lua-Interpreter von LuaTeX parst und „kompiliert“ den in den vorherigen Schritten erzeugten Lua-Code. Wenn dieses Parsen/Kompilieren fehlschlägt, erzeugt der Lua-Interpreter Fehler (wie Syntaxfehler) – diese Fehler können dazu führen, dass der LuaTeX-Lauf fehlschlägt, sofern Sie nicht die Option gewählt haben, `--interaction=nonstopmode` auf der Befehlszeile.
7. Wenn das Parsen/Kompilieren erfolgreich ist, führt der Lua-Interpreter den in Schritt (5a) kompilierten Code aus.

Im Wesentlichen ist die `scan_toks()` Funktion der Kern der Vorverarbeitungsaktivitäten von LuaTeX: Ihre Hauptaufgabe besteht darin, alle expandierbaren TeX/LaTeX-Befehle im Text Ihres `⟨code⟩` und aus allem, was sie verarbeitet hat, eine Tokenliste zu konstruieren. Nochmals betonen wir, dass `scan_toks()` *nicht expandierbare Befehle nicht ausführt* (Tokens): Es *speichert* diese Tokens in der Tokenliste, die es konstruiert. Nach Abschluss wird diese Tokenliste anschließend umgewandelt *wieder in eine textuelle Darstellung* durch `tokenlist_to_cstring()`—eine Tokenliste ist ein rein TeX-spezifisches Konzept, das einem Lua-Interpreter völlig fremd ist; daher muss sie in Text umgewandelt werden, der dann zu Lua-Code wird, der an den Lua-Interpreter weitergegeben wird.

## Expansion als „Schnittstelle“ einer Programmiersprache

Man kann sich vorstellen, dass `\directlua`’s Expansionsprozess als Mechanismus oder Schnittstelle verwendet wird, um Daten/Informationen von der „TeX-Welt“ in die „Lua-Welt“ zu übertragen: also eine Methode bereitzustellen, mit der die TeX-Sprache Daten an die Lua-Sprache kommunizieren kann. Zum Beispiel kann TeX-Code wie `\number\count75` verwendet werden, um einen in Zählregister 75 gespeicherten Wert aus der „TeX-Welt“ in die ganzzahlige Variable x der „Lua-Welt“ zu übertragen:

```
\count75=1564 % Daten, die in der "TeX-Welt" existieren
\directlua{
   local x=\number\count75 \space % TeX-Daten in die "Lua-Welt" übertragen
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" and y = "..y)
}
```

Dadurch wird der Lua-Code erzeugt

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

**Hinweis**: Wir haben `<space>\space` nach `\number\count75` hinzugefügt, um sicherzustellen, dass ein Leerzeichen zwischen `1564` und `tex.print`—das ist hier nicht unbedingt erforderlich, weil Lua den Code auch dann korrekt parsen würde, wenn wir es wegließen. Das unmittelbar nachfolgende Leerzeichen `\count75` wird während des Prozesses aufgenommen, den TeX-Engines zur Suche nach numerischen Werten verwenden – hier der an `\count`. Das Leerzeichen nach `75` wird verwendet, um LuaTeX’ Suche nach der Ziffernfolge zu beenden `75` und aus der Eingabe aufgenommen. Das `\space` Makro expandiert, um das Leerzeichen bereitzustellen, das benötigt wird, um den Text `1564` und `tex.print`.

Unter Verwendung des obigen Codes wird LuaTeX setzen

`x= 1564 and y = 612.6`

Hier wird der Mechanismus der „Datenübertragung“ erreicht durch `\number`: einen expandierbaren Befehl, der in diesem Fall TeX anweist, den in `\count` Register `75` gespeicherten Wert abzurufen und aus diesem Wert (`1546`) eine Reihe von Zeichen-Tokens zu erzeugen, ein Zeichen-Token pro Ziffer, was zu einer Tokenfolge für die Ziffern `1`, `5`, `6` und `4`. Diese 4 Zeichen-Tokens werden in die Haupt-Tokenliste aufgenommen, die von `\directlua` und anschließend wieder in ihre textuelle Darstellung umgewandelt werden, wenn die Tokenliste in Text umgewandelt wird. Es ist zweifellos ein sehr umständlicher Weg von dem `\count75` im LuaTeX gespeicherten Registerwert zu Ziffern, die für Lua-Code bestimmt sind, aber letztlich funktioniert es.

**TIPP:** Wenn Sie die Ergebnisse der Expansionsaktivitäten von LuaTeX untersuchen möchten, können Sie Code wie diesen schreiben:

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

In diesem Beispiel verwenden wir die Langklammer-Methode, um eine String-Variable zu erzeugen `foo` deren Zweck es ist, die Zeichenkette des Lua-Codes zu halten, die aus der Expansion von allem zwischen `[[` und `]]`. Diese Zeichenkette wird über den Lua-Funktionsaufruf auf der Konsole ausgegeben `print(foo)`.

In Overleaf können Sie ähnliche Ergebnisse ansehen, indem Sie den Inhalt von `foo` zu `.log` Datei mit der LuaTeX-Lua-Funktion schreiben `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 in der \directlua-Tokenliste: nicht expandierbare Tokens und nicht expandierte Tokens

Wir haben festgestellt, dass `\directlua{⟨code⟩}` führt *Voll-Expansion* von Ihrem `⟨code⟩`: Es entfernt und expandiert alle expandierbaren Befehle, bis nur noch nicht expandierbare Tokens übrig sind. Die von `\directlua`’s Verarbeitung (in der `scan_toks()` Funktion) erzeugte Tokenfolge wird zu einer Tokenliste zusammengesetzt, deren einzelne Tokens wieder in Text umgewandelt werden, um an Lua weitergegeben zu werden.

Wir haben jedoch den letzten Teil dieser Geschichte noch nicht behandelt, weil wir die beiden „Klassen“ von Befehls-Tokens betrachten müssen, die in die innerhalb von ... aufgebaute Tokenliste gelangen können `\directlua`: Wir werden sie als *Kurzbefehls-Tokens* und *nicht expandierte* Tokens:

* **Kurzbefehls-Tokens**: Dieser Typ von Befehls-Token entsteht aus Steuersequenzen, die mit einem der TeX-Primitiven definiert wurden `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` und `\toksdef`. Diese primitiven Befehle werden verwendet, um Steuersequenzen zu definieren, die einen numerischen Wert darstellen – die resultierenden Steuersequenzen sind *nicht* expandierbar.
* **nicht expandierte Tokens**: Dieser Token-Typ entsteht aus Befehlen, die normalerweise expandiert würden, aber `\directlua` hat entweder:
* die ausdrückliche Anweisung erhalten *nicht* sie zu expandieren; zum Beispiel die Unterdrückung der Expansion durch die Befehle `\noexpand` oder `\unexpanded`—wir erklären gleich, wie das gemacht wird;
* eingeschleuste Tokens durch die Verarbeitung der Sequenz `\the\toks` (mehr dazu unten).

### Zwei „Gruppen“ von Tokens in einer \directlua-Tokenliste

Auf Grundlage unserer Erläuterungen können wir sagen, dass Tokens, die in der während der ersten Phase von ... konstruierten Tokenliste enthalten sind `\directlua`’s Vorverarbeitung (in der `scan_toks()` Funktion) in zwei Gruppen fallen:

1. *von Natur aus nicht expandierbar* Tokens

* jedes Token, das ein nicht-aktives *Zeichen*;
* jedes Token, das ein nicht expandierbares *Primitiv* *Befehl*;
* jedes Token, das einen *Kurzbefehl* (diese sind nicht expandierbar, siehe unten).

3. *nicht expandierte* Tokens:

* jedes Token, das einen expandierbaren Befehl repräsentiert, dessen Expansion *unterdrückt* wurde (oder vermieden) während `\directlua`’s Vorverarbeitung.

#### Kurzbefehls-Tokens: nicht expandierbare Befehle erstellen

Wie bereits erwähnt, stellen TeX-Engines eine Reihe von Primitiven (integrierten Befehlen) bereit, die verwendet werden können, um *nicht expandierbare* Steuersequenzen zu konstruieren (hier gekennzeichnet durch `⟨command⟩`). Diese Primitiven haben die Form:

* `\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⟩`

wobei `⟨numeric value⟩` ist ein für den jeweiligen Befehl geeigneter ganzzahliger Wert.

Hier werden wir kurz die Verwendung von `\chardef` überprüfen, um das Hauptmerkmal dieser Primitiven zu demonstrieren – die Erzeugung eines `⟨command⟩` das nicht expandierbar ist. Sie können ``\chardef\mydollar=`\$`` verwenden, um die Steuersequenz `\mydollar` zu erstellen und sie zu verwenden, um einen Satz zu setzen: `$`:

`I paid \mydollar30.`

Dies wird gesetzt als `I paid $30.` Die Steuersequenz `\mydollar` erstellt durch `\chardef` ist nicht expandierbar, wie wir im folgenden Beispiel sehen können:

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

Was den folgenden Text in der `.log` Datei

`I paid \mydollar 30.`

Dies zeigt `\mydollar` wurde *nicht* expandiert während `\directlua`’s Vorverarbeitung. Das nach `\mydollar` erscheinende Leerzeichen wird hinzugefügt, wenn ein Befehls-Token in seine textuelle Darstellung umgewandelt wird.

Wenn Sie `\chardef` verwenden, um eine Steuersequenz zu erstellen, führt TeX’ interne Klassifizierung dieser Steuersequenz (dieses Befehls) dazu, dass sie *nicht expandierbare* was ein sehr anderes Verhalten ist als bei Steuersequenzen, die mit einem der Makrodefinitionsbefehle definiert wurden: \def, \edef, \gdef oder \xdef. Wie oben erwähnt, prüft ... während des Prozesses des Aufbaus seiner Tokenliste `\directlua` jeden eingehenden Befehls-Token auf seine Expandierbarkeit. Wenn ein Befehls-Token nicht expandierbar ist, wird er direkt in die Tokenliste übernommen, und seine textuelle Darstellung erscheint später wieder in der Zeichenkette des Lua-Codes, die aus der Umwandlung der Tokens in der Tokenliste zurück in ihre Textform resultiert.

**Kurze Hinweise zu Plain TeX vs. LaTeX**

Historisch gesehen definierte Knuths ursprüngliches Plain TeX die gebräuchlichen Steuersymbole `\%`, `\&`, `\#` und `\$` unter Verwendung von `\chardef`—also nicht unter Verwendung eines der standardmäßigen Makrodefinitionsbefehle `\def`, `\edef`, `\gdef` oder `\xdef`verwenden. Zum Beispiel:

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

Die seltsame `` `\ `` Schreibweise ist eine TeX-Methode, um den numerischen Zeichenkodierungswert zu erhalten. Im alten Plain-TeX-Regime sind diese Steuersymbole nicht expandierbar (aufgrund von `\chardef`) aber LaTeX (oder Pakete) kann sie als *Makros* neu definieren, um erweiterte Funktionalität bereitzustellen – dadurch würden sie expandierbar, sodass Sie sich dessen bewusst sein sollten.

**Wie wirkt sich das auf \directlua aus?**

Vergleichen wir das Ergebnis des folgenden Codes, ausgeführt unter Plain TeX und LaTeX. Der Einfachheit halber schreiben wir die Ergebnisse in die `.log` Datei mithilfe der LuaTeX-Lua-API-Funktion `texio.write()`.

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

Wenn dieser Code ausgeführt wird mit **Plain TeX** erhält man die folgende Ausgabe in der `.log` Datei, die das Ergebnis eventueller Expansionen zeigt:

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

Offensichtlich wurde unter Plain TeX keines der Steuersymbole`\$`, `\#`, `\%` oder `\&` expandiert – weil sie alle erstellt wurden mit `\chardef`.

Wenn man diesen Code mit dem **LaTeX** Dokument ausführt:

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

erhält man die folgende Ausgabe in der `.log` Datei

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

Offensichtlich erzeugt die Ausführung mit LaTeX ein anderes Ergebnis als mit Plain TeX, weil unter LaTeX der Befehl `\$` expandiert wurde, was darauf hinweist, dass es sich um ein Makro handelt.

**Hinweis:** Sowohl in Plain TeX als auch in LaTeX `\directlua` wurden keines der Steuersymbole vollständig verarbeitet `\%`, `\&`, `\#` und `\$` um das entsprechende Zeichen zu erzeugen. Während des von `\directlua` durchgeführten Expansionsprozesses gelangen die Tokens, die diese Steuersymbole repräsentieren – oder in LaTeX ihre Expansion – direkt in die Haupt-Tokenliste, die aufgebaut wird.

**Hinweis:** Steuersymbole werden aus einem einzelnen Zeichen gebildet, das nicht zum Kategoriecode 11 gehört, etwa `\#`. Wenn ein Token, das ein Steuersymbol repräsentiert, wieder in seine Textdarstellung umgewandelt wird, fügen TeX-Engines nach diesem Text kein Leerzeichen ein. Diese besondere Behandlung von Steuersymbolen ist eine eingebaute Regel dafür, wie TeX-Engines arbeiten.

### Nicht expandierte Token: Expansion unterdrücken

`\directlua`Die Vorverarbeitung ist ein Beispiel dafür, dass eine TeX-Engine Expansion ausführt, Sie aber vielleicht *verhindern* die Anwendung von Expansion auf ein oder mehrere Token verhindern, die andernfalls expandiert würden. Ein weiteres Beispiel: LuaTeX (und alle TeX-Engines) führen einen Expansionsprozess aus, ähnlich dem von `\directlua`, wenn sie das `\write` Befehl:

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

\write weist eine TeX-Engine an, auszugeben `⟨material⟩`—oft mit TeX/LaTeX-Befehlen—in eine Textdatei (`file-number`); alle innerhalb von `⟨material⟩` werden, sofern nicht verhindert, vor dem Schreiben tatsächlich in diese Datei expandiert. `⟨material⟩` Wie zu erwarten, bieten TeX-Engines Befehle, um Expansion zu unterdrücken oder zu steuern:

\noexpand⟨token⟩

* `\noexpand⟨token⟩`: verhindert die Expansion des einzelnen `⟨token⟩`;
* `\unexpanded{⟨material⟩}`: verhindert die Expansion aller erweiterbaren Befehle (Token) in `⟨material⟩`. Es ist im Grunde eine Mehr-Token-Version von `\noexpand`;
* `\protected`: ein Präfix, das Makrodefinitionen vorangestellt wird und verhindert, dass dieses Makro unter bestimmten Umständen expandiert wird (etwa während `\directlua`, `\write` oder `\edef`).

Trotz irreführender Namen sind sowohl `\noexpand` und `\unexpanded` bei *expandierbare Befehle* und bieten gute Beispiele dafür, einen Expansionsprozess einer TeX-Engine als Ausführen von „Token-Operationen“ zu betrachten: Die Operation hier besteht darin, die Expansion eines oder mehrerer nachfolgender Token (Befehle) zu verhindern. Denn `\noexpand` und `\unexpanded` sind beides erweiterbare Befehle, werden sie während `\directlua`’s Vorverarbeitung entfernt und verarbeitet (ausgeführt), während es die Tokenliste aus Ihrem `⟨code⟩`.

#### \noexpand ⟨token⟩

`\noexpand ⟨token⟩` verhindert die Expansion des einzelnen `⟨token⟩`. `\noexpand` verwendet wird `\directlua` wird expandiert (aus der Eingabe entfernt) und durch die Ergebnisse seines „Expansionsverhaltens“ ersetzt. Das Ergebnis der Expansion von `\noexpand` ist die Erzeugung eines speziellen (versteckten) `⟨marker token⟩` das vor dem ursprünglichen `⟨token⟩` platziert wird, dessen Expansion unterdrückt werden soll: dieses `⟨marker token⟩` wirkt als Flagge und sagt „das nächste Token nicht expandieren“. Weil `\directlua` eine vollständige Expansion ausführt, werden alle Token, die aus dem „Expansionsverhalten“ eines erweiterbaren Befehls resultieren, erneut verarbeitet. Folglich, wenn die Expansion `\noexpand ⟨token⟩` abgeschlossen ist, geht LuaTeX zurück, um die Ergebnisse zu lesen, und sieht die Zwei-Token-Folge `⟨marker token⟩⟨token⟩` was dazu führt, dass das ursprüngliche `⟨token⟩` ungeexpandiert durch die Tokenliste läuft, die von `\directlua`.

**Beispiel**

Wenn wir schreiben

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

Der Stil `\TeX` Makro wird in seine Bestandteile expandiert, was in Plain TeX dazu führt, dass folgender Text an Lua übergeben wird (Hinweis: Lua kann diesen Code nicht verarbeiten, es ist nur ein Beispiel, um den Prozess zu veranschaulichen):

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

Wenn wir *unterdrücken* die Expansion des `\TeX` Makros mit `\noexpand`

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

wird der folgende Lua-Code erzeugt (auch hier kann Lua diesen Code nicht ausführen; es ist lediglich ein Beispiel, um zu demonstrieren `\noexpand`):

`local x= "\TeX "`

Aufgrund von `\noexpand`, `\directlua` wird nicht expandiert `\TeX` sondern lässt einfach den Tokenwert passieren, der das `\TeX` Befehl repräsentiert, und in die Tokenliste gelangt, die in der ersten Phase von `\directlua`’s Vorverarbeitung.

**Hinweis:** Das Leerzeichen nach `\TeX` wird durch die anschließende Umwandlung des von LuaTeX gelieferten `\TeX` Integer-Tokenwerts zurück in seine Textdarstellung eingeführt (innerhalb der `tokenlist_to_cstring()` Funktion).

#### \unexpanded{⟨material⟩}

`\unexpanded` ist ein erweiterbarer Befehl, der die Expansion aller Token unterdrückt, die aus `⟨material⟩`. Wie wir bemerkt haben, wird bei der Expansion einer TeX-Engine jeder erweiterbare Befehl *entfernt* aus der Eingabe entfernt und *ersetzt* durch die Ergebnisse seines „Expansionsverhaltens“ ersetzt; was bedeutet das also eigentlich für `\unexpanded`? Üblicherweise geht die TeX-Engine während *Voll-Expansion*sobald der Expansionsprozess für einen bestimmten Befehl abgeschlossen ist, dazu über, alle Token zu lesen/verarbeiten, die aus dem „Expansionsverhalten“ dieses Befehls entstehen—sie muss alle erzeugten Token weiter expandieren. Jedoch, `\unexpanded` *umgeht* jede weitere Expansion: So macht es das.

Innerhalb der TeX-Engine, `\unexpanded` Befehl wandelt zunächst die Zeichen und Befehle in `⟨material⟩` in eine temporäre Tokenliste aus *nicht expandierte* Token um. Nachdem alle Token erzeugt und in dieser temporären Tokenliste gespeichert wurden, bewirkt der `\unexpanded` Befehl, dass `\directlua` zu *überspringt* zurückzugehen, um sie zu lesen und zu verarbeiten—obwohl \directlua eine vollständige Expansion ausführt. Stattdessen gehen diese *nicht expandierte* Token direkt durch und werden in die Haupt-Tokenliste aufgenommen, die von `\directlua` (in der `scan_toks()` Funktion) aufgebaut wird. Auf diese Weise wird alles in `⟨material⟩` in Token umgewandelt, und der Expansionsprozess wird für diesen Token-Satz übersprungen. Die Arbeitsweise von `\unexpanded{⟨material⟩}` ist ähnlich wie die Verwendung von `\the\toks`, die wir weiter unten besprechen.

**Beispiel**

`\unexpanded` erzeugt Ergebnisse in einer Weise, die ähnlich ist wie `\noexpand` außer dass es die Expansion mehrerer Token verhindern kann; hier ist ein Beispiel:

```
\directlua{
   local x = "\unexpanded{\foo\bar\foobar}. Aber Lua kann diesen Code nicht verarbeiten!"
}
```

wodurch der folgende Text als Code für Lua erzeugt wird:

`local x = "\foo \bar \foobar . Aber Lua kann diesen Code nicht verarbeiten!"`

**Hinweis**: Nach jedem Befehlsnamen stehen Leerzeichen. Diese sind wiederum eine Folge von LuaTeXs anschließender Umwandlung der nicht expandierten Token `\foo`, `\bar` und `\foobar` zurück in Text innerhalb der `tokenlist_to_cstring()` Funktion.

#### \protected-Makrodefinitionen

Die `\protected` Befehl ist ein Präfix, das einer Makrodefinition vorangestellt wird, um zu verhindern, dass dieses Makro expandiert wird, wenn TeX eine expandierte Tokenliste aufbaut, wie etwa die von `\directlua`’s Vorverarbeitung.

**Beispiel**

Nehmen wir an, Sie definieren die folgenden Makros mit und ohne Verwendung des `\protected` Präfixes:

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

Wenn Sie den Lua-String-Verkettungsoperator (`..`) verwenden, um

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

`\directlua`’s Vorverarbeitung würde den folgenden Code für die Übergabe an Lua erzeugen:

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

`\macroA` ist nicht mit `\protected` definiert, daher wird es expandiert und erzeugt den ersten Teil der zu verknüpfenden Zeichenkette, aber `\macroB` ist mit `\protected` definiert, daher wurde es nicht expandiert.

Während der Vorverarbeitung erzeugte LuaTeXs `scan_toks()` Funktion ein Token für `\macroA`, erkannte, dass es sich um einen gewöhnlichen erweiterbaren Befehl handelt, und expandierte ihn: Diese Expansion erzeugt eine Folge von Zeichen-Token, ein Zeichen-Token für jedes Zeichen in `"This unprotected macro contains a string"`. Jedes Zeichen-Token wird weitergegeben und zur aufgebauten Tokenliste hinzugefügt.

Wenn `scan_toks()` erzeugt das Token für `\macroB` es bemerkt, dass dieser Befehl als `\protected` definiert wurde `\macroB` und expandiert ihn nicht: das Token, das `tokenlist_to_cstring()` repräsentiert `\macroB` geht unberührt (nicht expandiert) in die aufgebaute Tokenliste ein. Nachdem diese Tokenliste erstellt wurde, besteht der nächste Schritt der Vorverarbeitung innerhalb der `\macroB` Funktion darin, alle Token in der Tokenliste wieder in ihre Textdarstellung umzuwandeln. Das nicht expandierte Token, das `repräsentiert` wird erkannt und in seine Textdarstellung umgewandelt, wodurch der Text `\macroB` im für Lua bestimmten Code erscheint. Beachten Sie, dass Lua tatsächlich nicht `unexpected symbol near '\'`.

**Kurioses**: Das `\protected` Befehl wurde eingeführt von $$\varepsilon\text{-}\mathrm{\TeX}$$, der ersten großen Erweiterung von Knuths ursprünglicher TeX-Software, und wird von allen TeX-Engines unterstützt, deren Code-Abstammung $$\varepsilon\text{-}\mathrm{\TeX}$$.

### Nicht expandierte Token: Verwendung von \the\toks in \directlua

Das Programmierleben wäre ohne jene „Sonderfälle“, mit denen man sich auseinandersetzen muss, nicht dasselbe, und die Verwendung von `\the` in Verbindung mit `\toks` in einem `\directlua` Befehl ist ein solcher Sonderfall.

#### Kurzer Hintergrund zu \toks

Die TeX-Primitive `\toks` weist eine TeX-Engine an, einige Token für die spätere Verwendung zu speichern: Anstatt zur weiteren Verarbeitung weitergegeben zu werden, werden diese Token beiseitegelegt und in einem Speicherort abgelegt, der mit einem *Token-Register*. Zum Beispiel können wir einer TeX-Engine sagen, dass sie einige Token erzeugen und sie im Token-Register-Speicherplatz `100` unter Verwendung von

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

Hier verwendet TeX das Token-Register `100` um auf einen bekannten Speicherort innerhalb seines Speichers zuzugreifen: einen Speicherbereich, der zum Halten von Token-Listen vorgesehen ist.

Token, die alles zwischen den `{` und `}` werden erzeugt, *aber nicht expandiert*, und zu einer Tokenliste zusammengefügt—ähnlich der Tokenliste, die wir zuvor in diesem Artikel betrachtet haben. Um diese Token wiederzuverwenden, würden wir schreiben `\the\toks100` in dem `\the` (ein erweiterbarer Befehl) TeX anweist, die gespeicherten Token abzurufen und sie an der Stelle einzufügen, an der Sie `\the\toks100`. Eine andere Sicht darauf ist `\the\toks` veranlasst TeX, an dieser Stelle einige Token einzufügen.

Die `\toks` Befehl *expandiert nicht* einen der Token, den es erzeugen und speichern soll: Es wandelt einfach Zeichen und Befehle zwischen `{` und `}` in Token um und speichert sie.

#### Zurück zu \directlua

In der Erörterung der Expansion haben wir bemerkt `\directlua{⟨code⟩}` führt *Voll-Expansion* von `⟨code⟩`: alle erweiterbaren Befehle zu entfernen und sie durch das Ergebnis ihres Expansionsverhaltens zu ersetzen—und dabei fortzufahren, zu *weitere Expansion* alle Token weiterzuexpandieren, die aus der ursprünglichen Expansion eines erweiterbaren Befehls entstehen.

`\the` ist ein erweiterbarer Befehl, also `\directlua` wird es expandieren; jedoch, wenn `\the` in Verbindung mit `\toks` verwendet wird `\directlua`, wie in `\the\toks⟨token register⟩`, sind die eingefügten Token *nicht weiter expandiert*. Expansion von `\the\toks⟨token register⟩` fügt die Folge von *nicht expandierte* Token, gespeichert in `⟨token register⟩`, direkt in die Tokenliste ein, die von `\directlua`: dieses Verhalten umgeht den üblichen Prozess der vollständigen Expansion. In der Praxis passieren diese Token einfach, *nicht expandierte*, und werden in die Haupt-Tokenliste aufgenommen, die von `\directlua`—dieser Durchlaufprozess für nicht expandierte Token ähnelt in seiner Funktionsweise `\unexpanded`, wie bereits zuvor besprochen.

**Beispiel**

Nehmen wir an, wir definieren das Makro `\mymacro` als `\def\mymacro{\TeX}`. Es enthält nur ein Token für den `\TeX` Befehl (der ein Makro ist): also haben wir einen erweiterbaren Befehl `\mymacro` der ein weiteres Makro `\TeX`, das ebenfalls erweiterbar ist.

Der folgende Code führt dazu, dass Lua versucht, eine String-Variable zu erzeugen `x`:

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

Innerhalb von \\\\`directlua`wird das Token für `\mymacro` expandiert, aber das führt zu einem weiteren erweiterbaren Token, `\TeX`, das weiter expandiert wird. In Plain TeX führen diese Expansionen dazu, dass der folgende Text an Lua übergeben wird:

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

Dieser Code versucht, eine Zeichenkette zu definieren, die Text enthält, der die expandierte Version des `\TeX` Makros darstellt. Wenn Sie versuchen, dieses Beispiel auszuführen, wird Lua versuchen, diese Zeichenkette zu erzeugen, aber es wird scheitern und einen Fehler erzeugen:

`ungültige Escape-Sequenz bei ' "T\k'.`

Später in diesem Artikel werden wir die Bedeutung von „ungültige Escape-Sequenz“ untersuchen.

Vergleichen wir nun die Verwendung von `\mymacro` mit dem Platzieren des `\TeX` Tokens in einer Tokenliste, die von einem `\toks` Befehl:

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

LuaTeXs `\directlua` Verarbeitung erzeugt diese Zeichenkette für Lua:

`local x = "\TeX "`

Das Leerzeichen nach `\TeX` wird durch LuaTeXs Umwandlungsprozess von Befehlstoken in String erzeugt.

**Aber beachten Sie**: Das `\TeX` Makro hat *nicht* sich in seine Bestandteile expandiert. `\the\toks100` hat die Token im Register 100 einfügen lassen, aber das ist auch schon alles: sie sind *nicht* nicht weiter expandiert und werden in die Haupt-Tokenliste aufgenommen, die von `\directlua` (innerhalb der Funktion `scan_toks()`). Das Einfügen von Token in eine von `\toks` erzeugte Tokenliste ist eine weitere Möglichkeit, das Expandieren von Token zu verhindern.

Wenn wir dieses Beispiel ausführen, erzeugt es ebenfalls einen Fehler:

`ungültige Escape-Sequenz bei ' "\T'.`

Wir untersuchen Lua-Escape-Sequenzen später im Artikel.

## Andere Befehle/Techniken, die bei der Expansion verwendet werden

In diesem Abschnitt betrachten wir einige weitere TeX-Befehle/Methoden, die in Situationen nützlich sein können, in denen Expansion angewendet wird (etwa innerhalb von `\directlua`).

### \string ⟨token⟩

`\string` ist ein erweiterbarer Befehl, der das ⟨token⟩ in eine Reihe von Zeichen-Token umwandelt, die jeweils den Kategoriecode 12 besitzen.

Zum Beispiel, `\string\TeX` würde eine Folge von 4 Zeichen-Token erzeugen `\`, `T`, `e` und `X` wobei jedem Zeichen der Kategoriecode 12 zugewiesen wird (einschließlich des führenden `\` Zeichens).

Wenn wir schreiben

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

Der Stil `\string` Befehl wird expandiert und ergibt eine Folge von Zeichen-Token mit Kategoriecode 12. Nachdem `\string` expandiert wurde, werden die resultierenden Zeichen-Token (die jedes Zeichen in `\newcommand`) repräsentieren in die Haupt-Tokenliste aufgenommen, die von `\directlua`. Sobald `\directlua` seine Haupt-Tokenliste fertiggestellt hat, werden seine Bestandteile wieder in ihre Textdarstellung umgewandelt, wodurch folgender Code zur Weitergabe an den Lua-Interpreter entsteht:

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

Wenn dieser Code an Lua übergeben wird, `print(x)` wird die Zeichenkette `x` auf dem Bildschirm (Konsole) ausgeben. Wir haben hier allerdings ein wenig geschummelt und absichtlich ein Beispielbefehl verwendet, der mit `\n`. Wenn Sie in der Lage sind, dieses Beispiel auf einer lokalen TeX-Installation auszuführen, werden Sie feststellen, dass Lua den folgenden Text auf dem Bildschirm ausgibt:

```
   Ich werde verwenden
   ewcommand
```

Um diesen Code auf Overleaf auszuführen, können Sie LuaTeX anweisen, direkt in das `.log` Datei mithilfe der LuaTeX-Lua-API-Funktion `texio.write(*string*)`:

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

Wenn Sie die resultierende `.log` Datei untersuchen, werden Sie sehen, dass sie auch enthält

```
   Ich werde verwenden
   ewcommand
```

Diese unerwartete Ausgabe entsteht dadurch, dass Lua den `\n` am Anfang von `**\n**ewcommand` als Escape-Sequenz für das Zeilenvorschubzeichen (Zeichencode 10) interpretiert: Es nimmt an, dass Sie eine neue Textzeile beginnen wollen, die mit `ewcommand`beginnt. Wir besprechen Lua-Escape-Sequenzen später in diesem Artikel.

### \detokenize{⟨material⟩}

`\detokenize` ist in seiner Wirkung eine Mehr-Token-Version von `\string` und auch dies ist ein erweiterbarer Befehl, der alles in `⟨material⟩` in eine Folge von Zeichen-Token mit Kategoriecode 12 umwandelt—*außer* Leerzeichen (ASCII-/Unicode-Wert 32), die Kategoriecode 10 erhalten. `\detokenize` fügt außerdem ein abschließendes Leerzeichen nach Befehlsnamen ein, die *Kontrollwörter* gehört (z. B. `\foo`sind ( *Kontrollsymbole* gehört (z. B. `\#`, `\%` aber nach

### Beispiel

Selbst wenn die Makros `\foohoo`, `\foo`, `\bar` und `\foobar` nicht definiert sind, wenn Sie dies schreiben:

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

würde es den folgenden Text als Code für die Übergabe an den Lua-Interpreter erzeugen

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

Wenn Sie `\string` und `\detokenize` nicht verwenden

`und schreiben:`

`\directlua` würde `\foohoo`, erkennen, dass es sich um einen Befehl handelt, und versuchen, ihn zu expandieren; aber weil `\foohoo` nicht definiert ist, würde dies zu einem Fehler führen:

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

Da `\string` und `\detokenize` ihre Argumente in eine Folge von Zeichen-Token umwandeln, `\directlua`Der Expansionsprozess von `\foohoo`, `\foo`, `\bar`, oder `\foobar`bekommt die Gelegenheit, Token erweiterbarer Befehle zu erkennen

: Sie werden lange bevor sie Expansion auslösen können in Folgen von Zeichen-Token umgewandelt. `\string` und `\detokenize` Wie bereits erwähnt, beinhaltet die Expansion eines Befehls, ihn aus der Eingabe zu entfernen und durch das Ergebnis seines „Expansionsverhaltens“ zu ersetzen. Die Ergebnisse der Expansion (gewöhnlich Token) werden anschließend von der TeX-Engine gelesen. Hier besteht das „Expansionsverhalten“ für `\directlua` darin, Zeichen- und Befehlstoken aus der Eingabe aufzunehmen und sie in Folgen von Zeichen-Token umzuwandeln, die zunächst in einer temporären Tokenliste gespeichert werden, die `\directlua`.

Die folgende Grafik zeigt, wie `\string` das `\foohoo` Befehl in eine Folge von Zeichen-Token umwandelt und eine temporäre Tokenliste erzeugt, die anschließend von `\directlua` gelesen wird, um diese Zeichen-Token in die Haupt-Tokenliste aufzunehmen, die gerade aufgebaut wird.

![](/files/b0c21fe827afd27532895527bfdee5bddaabfa56)

Wenn `\string` oder `\detokenize` Befehle treffen in ihrem Argument auf Zeichen, z. B. `\string a` oder `\detokenize{abc}` diese Zeichen (hier mit Kategoriecode 11) erzeugen Zeichen-Token, jedoch mit Kategoriecode 12.

Hinweise:

Wenn wir zum obigen Beispiel zurückkehren:

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

wodurch der folgende Text als Code für die Übergabe an den Lua-Interpreter erzeugt wird

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

können wir Folgendes beobachten:

* `\detokenize` hat nach jedem Makronamen ein Leerzeichen eingefügt, aber `\string` tat das nicht.
* `\string` wirkt auf ein einzelnes Token.
* In der Zeichenkette `"\foohoo\foo \bar \foobar "` verwendet, um zu definieren `x` werden wir erneut auf LuaTeXs Mechanismus für Escape-Zeichen stoßen (unten beschrieben):

  * `\bar` beginnt mit `\b` was die Lua-Escape-Sequenz ist, die zur Darstellung des [Rücktaste-Zeichens](https://en.wikipedia.org/wiki/Backspace) (Zeichencode 8) verwendet wird;
  * Befehle `\foohoo`, `\foo` und `\foobar` beginnt ebenfalls mit `\f`der Lua-Escape-Sequenz, die zur Darstellung des [Formfeed-Zeichen](https://en.wikipedia.org/wiki/Page_break#Form_feed) (Zeichencode 12).

  Weil die Zeichenfolgen `\b` und `\f` innerhalb einer mit doppelten Anführungszeichen erstellten Zeichenkette verwendet werden `"..."` führen sie zu unerwünschten Ergebnissen, wenn nicht mit Lua’s sogenannter *Langklammern* Zeichenkettenmethode gegengesteuert wird: ein Thema, das wir nun zusammen mit Lua-Escape-Sequenzen besprechen können.

## Was sind „Lua-Escape-Sequenzen“?

Programmiersprachen reservieren bestimmte Zeichen für den „Sondergebrauch“ als Teil der Sprachsyntax: Praktisch sind diese Zeichen so definiert, dass sie irgendeine Form besonderer Bedeutung haben. Es gibt jedoch Zeiten, in denen man eine solche Sonderbedeutung eines Zeichens vorübergehend „abschalten“ muss, wenn man zum Beispiel möchte, dass dieses Zeichen als Teil einer längeren Zeichenkette eingebettet wird, in der sein normales Verhalten Syntaxfehler verursachen würde. Im Wesentlichen muss dieses Zeichen verarbeitet werden *ohne* so, dass seine standardmäßige Interpretation ausgelöst wird — es soll unbemerkt hindurchschlüpfen. Dazu verwenden Programmierer eine Technik namens *Escaping* bei der ein „Sonderzeichen“ durch seine sogenannte *Escape-Sequenz*.

Ein Standardbeispiel (auch von Lua unterstützt) ist die Verwendung doppelter Anführungszeichen innerhalb einer Zeichenkette, wobei man die inneren doppelten Anführungszeichen mit der Escape-Sequenz `\\\"`:

`"Wenn man sie nach LuaTeX fragte, antworteten sie: \\\"Es ist eine großartige TeX-Engine!\\\" Ich stimmte zu."`

Die Lua-Sprache bietet eine Reihe von Mechanismen zum Umgang mit Escape-Sequenzen:

* Standardsequenzen einschließlich `\n` (Zeilenumbruch), `\\r` (Wagenrücklauf), `\\` (Rückwärtsschrägstrich), `\\\"` (doppeltes Anführungszeichen), `\\t` (horizontaler Tabulator), `\\v` (vertikaler Tabulator) und `\\'` (einfaches Anführungszeichen);
* `\\xXX`, wobei `XX` ist eine Sequenz aus genau zwei hexadezimalen Ziffern;
* `\\ddd`, wobei `ddd` ist eine Sequenz von bis zu drei Dezimalziffern;
* Zum Zeitpunkt, als dieser Artikel geschrieben wurde (August 2019), verwendet die neueste Version von LuaTeX, obwohl auf Overleaf noch nicht verfügbar, Version 5.3 von Lua, die die Unterstützung für UTF-8-Escape-Sequenzen einführte: `\\u{XXX}`. Dieser Escape-Mechanismus ist für UTF-8-kodierte Unicode-Zeichen gedacht, wobei `XXX` eine Sequenz aus einer oder mehreren hexadezimalen Ziffern ist, die den Zeichencodepunkt darstellt. Beachten Sie, dass die einschließenden Klammern `{ }` obligatorisch sind.

### Steuerung von Escape-Sequenzen

Traditionell werden Zeichenketten mit doppelten Anführungszeichen definiert, wie in `"dies ist eine Zeichenkette"`; innerhalb einer solchen Zeichenkette können Sie Escape-Sequenzen verwenden: `"dies ist eine Zeichenkette.\\nIch beginne jetzt in einer neuen Zeile."`. Lua hat jedoch einen zweiten und *sehr* praktischen Mechanismus zum Definieren von Zeichenketten: seine sogenannten *Langklammern* Mechanismus, bei dem Sie eine Zeichenkette definieren, indem Sie den Text einschließen in `[[` und `]]`:

`[[Ich bin eine Langklammern-Zeichenkette]]`

Innerhalb einer mit der Langklammern-Methode erstellten Zeichenkette ist Lua’s Zeichen-Escape-Mechanismus *deaktiviert*: Escape-Sequenzen werden als normale Zeichen behandelt. Zum Beispiel wird in der Zeichenkette

`[[Ich bin eine Langklammern\\n Zeichenkette]]`

Der Stil `\n` die Escape-Sequenz nicht als einzelnes Wagenrücklaufzeichen (ASCII-Code 13), sondern als zwei normale Zeichen behandelt: `\` gefolgt von `n`.

### Warum sind Langklammern-Zeichenketten so nützlich?

Wie wir später sehen werden, bietet LuaTeX eine Reihe spezialisierter, eingebauter Lua-Funktionen, die Sie mit `\directlua` verwenden können, um das Satzverhalten von LuaTeX zu steuern. Zu diesen vielen Funktionen gehört eine namens `tex.print(*string*)` die es Ihnen erlaubt, `*string*` Material aus Lua-Code zurück an LuaTeX zum Setzen zu übergeben. Ein sehr einfaches Beispiel ist:

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

was dazu führt, dass LuaTeX `Hello, World!`

Die `*string*` verwendet in `tex.print(*string*)` kann auch Text enthalten, der TeX- und LaTeX-Befehle für LuaTeX zur Verarbeitung darstellt. TeX-/LaTeX-Befehle beginnen jedoch mit einem `\` Zeichen, was bei mit doppelten Anführungszeichen erstellten Zeichenketten problematisch ist, weil Lua versuchen würde, die Zeichenkette zu parsen, das anfängliche `\` Zeichen erkennen und es als Beginn einer Escape-Sequenz interpretieren würde. Wenn Lua versucht, die Escape-Sequenz zu verarbeiten, wird es normalerweise scheitern, weil das anfängliche `\` in Kombination mit dem ersten Zeichen vieler TeX-/LaTeX-Befehlsnamen keine gültige, Lua bekannte Escape-Sequenz bildet. Wenn man zum Beispiel eine Zeichenkette wie `"I like \\LaTeX"` verarbeiten würde, sähe Lua `\\L` und würde mit dem Fehler „ungültige Escape-Sequenz“ abbrechen, und das ist die Ursache der oben genannten Fehler.

#### Langklammern-Zeichenketten kommen zur Rettung!

Die Langklammern-Methode zum Erstellen (Definieren) von Zeichenketten ist äußerst nützlich, weil auch wenn TeX-/LaTeX-Befehle mit einem `\` Zeichen beginnen, die Langklammern-Zeichenkettenmethode den Escape-Sequenz-Mechanismus von Lua deaktiviert. Hier ist ein kurzes Beispiel, wobei wir uns daran erinnern, dass wir verhindern müssen, dass Makros expandiert werden, zum Beispiel mit `\protected` oder `\noexpand`.

Nehmen wir an, wir definieren ein `\\newtest` Makro wie dieses

`**\\protected**\\def\\newtest#1{Das Argument: #1}`

und verwenden es in `\directlua` mit der LuaTeX-Lua-API-Funktion `tex.print()`:

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

Aufgrund der Verwendung von `\protected`, wird das Makro `\\newtest` nicht expandiert, was zu folgendem an Lua übergebenen Text führt:

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

Das nach `\\newtest` und vor der öffnenden geschweiften Klammer (`{`) hinzugefügte Leerzeichen ist eine Nebenwirkung von `\directlua`Umwandlung von Befehls-Token zurück in ihre textuelle Darstellung.

Dieser Code wird an Lua übergeben, das anschließend die LuaTeX-Funktion `tex.print()` ausführt; es gibt jedoch ein Problem, das sich je nach den verwendeten Schriftarten unterschiedlich äußert. In LaTeX auf Overleaf würden Sie etwa eine Ausgabe wie diese sehen:

![](/files/2c2033e6d817a42dc1c497fba8f150a4dca0522e)

zusammen mit einer Warnung in der Protokolldatei:

```
   Fehlendes Zeichen: Es gibt kein
   (U+000A) in Schrift [lmroman10-regular]:+tlig;!
```

Im Plain TeX könnten Sie eine Ausgabe sehen, die in etwa so aussieht:

![](/files/8212eda9df03fe84b83a960c50b5d8d277dd3966)

In beiden Fällen wird das `\\newtest` Makro nicht aufgerufen und die Ausgabe ist nicht das, was wir beabsichtigt haben. Der Fehler wird durch Lua’s Escape-Zeichen-Mechanismus verursacht: Im Text `\\newtest {Hello}` beginnt der Makroname mit `\n` das Lua als Escape-Sequenz für ein Zeilenumbruchzeichen erkennt, sodass es `\n` durch das ASCII-Zeichen 10 bzw. hexadezimal 0A ersetzt. In der LaTeX-Fehlermeldung, `U+000A` ist eine Möglichkeit, den Unicode-Wert mit 4 hexadezimalen Ziffern darzustellen.

Weil das `\n` in ein Zeilenumbruch-Zeichen umgewandelt wird, sieht LuaTeX keinen Makroaufruf, sondern glaubt stattdessen, es werde aufgefordert, Text zu setzen, der mit ASCII-Zeichencode 10 beginnt:

`⟨ASCII 10⟩ewtest {Hello}`

Je nach verwendeter Schriftart kann LuaTeX das `⟨ASCII 10⟩` Zeichen vielleicht setzen, vielleicht aber auch nicht; der restliche Text wird jedoch unverändert ausgegeben, wobei die `{` und `}` als Gruppe behandelt und nicht gesetzt wird.

Plain TeX liefert ein anderes Ergebnis, weil die Standardschrift Computer Modern Roman ist, die eine seltsame Kodierung hat, die dazu führt, dass ein großes Omega gesetzt wird, wenn Zeichencode 10 auftaucht.

Um diese Probleme zu verhindern, müssen wir Langklammern-Zeichenketten verwenden, damit Lua’s Escaping-Mechanismus nicht angewendet wird. Das richtige Ergebnis wird mit

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

erzielt, was das im folgenden Screenshot gezeigte Ergebnis erzeugt:

![](/files/18b263a2472952f81522a8b6080ee06b111497af)

### Expansion und Nichtausführung nicht-expandierbarer Befehle

Bei der Besprechung von Expansion haben wir festgestellt, dass es sich um einen Prozess handelt, bei dem eine TeX-Engine *entfernt* einen expandierbaren Befehl (Token) aus dem aktuellen Eingabestrom und *ersetzt* ihn durch das bzw. die Ergebnisse, die von diesem expandierbaren Befehl erzeugt werden. Da \\\directlua *nur-expansionsbasiert* ausführt (um eine Tokenliste zu erzeugen), *nicht* kann LuaTeX seine Verarbeitung nicht weiter als bis dorthin fortsetzen. Sobald ein expandierbarer Befehl gelesen und vollständig expandiert wurde, werden die Ergebnisse dieser Expansion — die häufig nicht-expandierbare Befehle (Tokens) enthält — in die aufzubauende Tokenliste aufgenommen, bereit zur Rückumwandlung in Text, um sie an Lua weiterzugeben.

Hier wirkt ein wichtiges Prinzip: Während *nur-expansionsbasiert* von Aktivitäten, die darauf ausgelegt sind, eine Tokenliste zu erzeugen, führen TeX-Engines, einschließlich LuaTeX, *keine* nicht-expandierbaren primitiven, eingebauten TeX-Befehle aus.

Im Fall von `\directlua{⟨code⟩}`, wenn die vollständig expandierte Version Ihres `⟨code⟩` ergibt oder nicht-expandierbare TeX-/LaTeX-Befehle enthält, werden sie *an Lua weitergegeben* (als Text dargestellt).

#### Beispiel

Hier ist ein Beispiel, das zeigt, dass nicht-expandierbare Primitive während einer nur-expansionsbasierten Verarbeitung (wie etwa innerhalb von `\directlua`) nicht ausgeführt werden. Nehmen wir an, wir definieren ein Makro `\\setcountreg` es so verwenden:

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

**Hinweis**: Wir verwenden `\\relax` nach Parameter `#2` um zu verhindern, dass LuaTeX beim Lesen der Eingabe beim Suchen nach dem numerischen Wert (Argument) zum Abgleich mit Parameter `#2`.

Wenn außerhalb von `\directlua`wir später das Makro so ausführen

```
   \\setcountreg{100}{50}
   Der Wert im Zählregister 100 ist \\the\\count100.
```

würde es ausgeben

`Der Wert im Zählregister 100 ist 50.`

In diesem Kontext würde jede TeX-Engine das Makro verarbeiten `\\setcountreg`—das Makro expandieren, die Argumente bestimmen und weiterlesen *und die im Ersatztext des Makros (der Definition) enthaltenen Befehle ausführen.* (ausführen). Das Ergebnis hier ist, `50` als den im Register gespeicherten Wert `\\count100`.

Wenn jedoch eine TeX-Engine *nur-expansionsbasiert* nur-expansionsbasierte `\directlua`ausführt, wie es bei *wird sie nicht ausführen* die nicht-expandierbaren Befehle, die in der Definition des Makros enthalten sind.

Wenn wir schreiben

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

erzeugt er den folgenden Text als Code für Lua:

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

Der oben erzeugte Lua-Code zeigt, dass innerhalb von `\directlua` Der Stil `\\setcountreg` ist expandiert worden, seine Argumente wurden identifiziert und in den entsprechenden Parameter eingesetzt (`#1` und `#2`) doch es geht nicht darüber hinaus: Der nicht-expandierbare primitive TeX-Befehl `\count` wurde *nicht ausgeführt* wird `\directlua`der Expansionsverarbeitung von LuaTeX.

Wenn wir die resultierende Zeichenkette jedoch `x` *an LuaTeX zurückgeben* über `tex.print(x)` wie folgt

```
\\count100=50 % setze \\count100 auf einen Anfangswert von 50
\\def\\setcountreg#1#2{\\count#1=#2\\relax}
\directlua{
   local x = [[\\setcountreg{100}{250}]]
   tex.print(x)
}
Der im Zählregister 100 gespeicherte Wert ist \\the\\count100.
```

Nachdem `\directlua` beendet ist, wäre die Ausgabe

`Der im Zählregister 100 gespeicherte Wert ist 250.`

was zeigt, dass das Zählregister `100` nun den Wert `250`.

Der aus dem obigen Beispiel erzeugte Lua-Code lautet

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

Dieser Code definiert `x` als eine mit der Langklammern-Methode erstellte Zeichenkette, die verwendet wird, um Fehler mit fehlerhaften Escape-Sequenzen zu vermeiden. Wenn wir doppelte Anführungszeichen verwenden würden `"..."` um x zu definieren, würde die Zeichenkombination `\\c` am Anfang von `\count` einen Fehler auslösen: `ungültige Escape-Sequenz bei ' "\\c'`.

Der LuaTeX-Lua-API-Aufruf `tex.print(x)` führt dazu, dass LuaTeX die TeX-Code-Sequenz ausführt `\\count 100=250\\relax` und `\\count100` wird ein Wert von `250` zugewiesen, wie an der gesetzten Ausgabe zu sehen ist:

`Der im Zählregister 100 gespeicherte Wert ist 250.`

#### Vorsicht: Makros und die LuaTeX-Lua-API

Im obigen Beispiel haben wir gesehen, dass LuaTeX während `\directlua`Vorverarbeitung (Expansion) den Code nicht ausgeführt hat `\\count 100=250`, der den `nicht expandierbare` primitiven Befehl `\count`enthält: Um diesen Code auszuführen, mussten wir ihn *an LuaTeX zurückgeben* über `tex.print()`.

`\directlua` ist nur ein Beispiel dafür, dass LuaTeX eine nur-expansionsbasierte Verarbeitung zur Erzeugung einer Tokenliste durchführt. Es gibt andere Befehle, die ähnliche Expansionsverarbeitung und Tokenlisten-Erzeugungsaktivitäten ausführen, wie etwa `\write` und `\edef`: Auch diese Befehle führen bei ihrer Expansionsverarbeitung keine nicht-expandierbaren Primitive aus. Es ist ein allgemeines Prinzip, dass TeX-Engines beim Erzeugen einer Tokenliste während nur-expansionsbasierter Verarbeitungsaktivitäten keine nicht-expandierbaren Primitive ausführen.

**Unser Makro so umschreiben, dass es die LuaTeX-Lua-API verwendet**

Wir können das `\\setcountreg` Makro mit einer LuaTeX-Lua-API-Funktion namens `tex.setcount()`neu schreiben und so TeX-Befehle vermeiden, um den im Zählregister `100`:

```
   \\def\\setcount#1#2{\\directlua{tex.setcount(#1,#2)}}
   \\count100=50
   Zählregister 100 enthält \\the\\count100\par
   \\setcount{100}{250}
   Zählregister 100 enthält jetzt \\the\\count100\par
```

Dieser Code setzt:

```
Zählregister 100 enthält 50
Zählregister 100 enthält jetzt 250
```

Hier verwenden wir `tex.setcount()`, eine der vielen Lua-API-Funktionen von LuaTeX, um *direkten Zugriff auf* den internen Datenspeicherbereich von LuaTeX zu erhalten und den Wert `250` in den Speicherort einzutragen, der Zählregister `100`repräsentiert. Wir haben also praktisch *umgangen* LuaTeX’s standardmäßige Methoden zur Eingabeverarbeitung der TeX-Engine: Eingabe lesen, Token erzeugen und TeX-Primitive ausführen. Es gibt jedoch eine Warnung: Durch die Verwendung von LuaTeX’s Lua-API-Funktionen können Aktivitäten der nur-expansionsbasierten Verarbeitung *zu Nebenwirkungen führen*: Änderungen an Werten, die innerhalb der TeX-Engine gespeichert sind und mit reinen TeX-/LaTeX-Befehlen sonst nicht möglich wären.

**Beispiel: unerwartete Nebenwirkungen**

Hier ist ein Beispiel, um *unerwartete* Nebenwirkungen zu demonstrieren, die bei Makros mit `\directlua`auftreten können. Nehmen wir an, wir schreiben den folgenden Code:

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

Wenn man diesen Code ausführt, wird gesetzt: `12345`!

Wie kann das sein? Wir haben nicht *explizit* irgendeinen Code oder Makros aufgerufen, um diesen Wert in das Zählregister `999`zu setzen. Oder doch?

Wir haben `\\dochange` durch eine `\directlua` Befehl definiert, der `tex.setcount()` verwendet, um den Wert `12345` in Zählregister `999`zu speichern: im TeX-Code ist es das Äquivalent von `\\count999=12345`. Dann haben wir das standardmäßige TeX-Primitive `\edef` verwendet, um das Makro `\\careful`zu definieren — es ist die Verwendung von `\edef` , die die unerwartete Nebenwirkung auslöst.

`\edef` expandiert sein Argument vollständig: Hier erkennt es ein expandierbares Makro `\\dochange` und expandiert es. Das `\\dochange` Makro verwendet den expandierbaren Befehl `\directlua` , der einen Lua-API-Aufruf enthält; also führt die Expansion von `\\dochange` zu einer Expansion von `\directlua` und das bewirkt, dass `tex.setcount()` aufgerufen wird, wodurch der Wert in Zählregister `999`.

Wenn wir `\\dochange` neu definieren, um TeX-Befehle zu verwenden:

```
   Vorher: Zählregister 999 enthält \\the\\count999.\par
   \\def\\dochange{\\count999=12345\\relax}
   \\edef\\careful{\\dochange}
   Nachher: Zählregister 999 enthält \\the\\count999.\par
```

wenn man diesen Code ausführt, wird gesetzt

```
Vorher: Zählregister 999 enthält 0.
Nachher: Zählregister 999 enthält 0.
```

Offensichtlich hatte das keinen Einfluss auf `\\count999`. Wenn `\edef` definiert `\\careful` expandiert es `\\dochange` aber diese Expansion erzeugt nur nicht-expandierbare TeX-Primitive: sie werden *nicht ausgeführt* sondern lediglich *gespeichert* in der Tokenliste, die die Definition von `\\careful`.

Nur der Vollständigkeit halber erklärt dasselbe Prinzip, warum dies gesetzte Ausgabe erzeugt:

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

## Kurze Einführung in LuaTeXs Lua-API

Wie wir gesehen haben, `\directlua` ermöglicht Ihnen nicht nur, herkömmlichen Lua-Code oder eine Mischung aus Lua- und TeX-/LaTeX-Code zu schreiben, sondern bietet auch Zugriff auf eine Reihe zusätzlicher Lua-Funktionen (speziell für LuaTeX), die Sie verwenden (aufrufen) können, um mit dem inneren Funktionieren der Satzsoftware LuaTeX zu kommunizieren oder es direkt zu steuern. Wir haben in diesem Artikel mehrere Lua-Funktionen verwendet, `tex.print()`, `texio.write()`, `tex.setcount()` und diese sind zusammen mit *vielen* weiteren dokumentiert in [dem LuaTeX Reference Manual](http://www.pragma-ade.com/general/manuals/luatex.pdf) in dem Gruppen verwandter Funktionen als *Bibliotheken*.

Sie können sich diese Lua-Funktionen als LuaTeXs Lua-API vorstellen (**Ein**pplication **P**rogramming **I**nterface), die die Werkzeuge bereitstellt, um ausgefeilte Satz- und Dokumenten-Engineering-Lösungen zu konstruieren, indem das Satzverhalten von LuaTeX mithilfe von Lua als Treiber gesteuert wird.

Wie erwähnt, organisiert LuaTeX seine API in eine Menge von Funktionen, die es Bibliotheken nennt: Gruppen von Funktionen, die durch ihren Zweck oder ihre Aktionen miteinander verbunden sind. Jede Funktionsmenge ist darauf ausgelegt, Zugang zu einem bestimmten Aspekt von LuaTeX’s internen Prozessen, Datenstrukturen, Datenspeicherung und Satzalgorithmen zu bieten. Intern ist LuaTeX aus mehreren Komponenten aufgebaut: Softwarebibliotheken/-werkzeugen (größtenteils in C geschrieben), die nicht nur die TeX-Engine selbst umfassen, sondern auch andere Subsysteme einschließlich Lua, MetaPost, Kpathsea, FontForge, libpng und zlib. Diese Bibliotheken sind integriert, um die Funktionen und Fähigkeiten der ausführbaren LuaTeX-Software aufzubauen, und über die Lua-API erhalten Benutzer Zugriff auf die Funktionalität von LuaTeX, die aus der Integration und Koordination dieser mehreren Softwarekomponenten resultiert.

## Einige Beispiele und Fallstricke

In diesem Abschnitt präsentieren wir einige weitere Beispiele, die die in diesem Artikel dargestellten Themen, Konzepte und Erklärungen nutzen.

### Verwendung des Tilde-Zeichens (\~)

Die Lua-Sprache verwendet das `~` Zeichen (Tilde genannt) als Teil ihrer Syntax, einschließlich ihrer Syntax für einen „ungleich“-Test; zum Beispiel, um zu prüfen, ob eine Variable `x` ungleich `4` wir könnten schreiben:

```
   local x=3
   wenn x ~= 4 dann
   print("x ist nicht gleich 4")
   end
```

Wenn wir versuchen, diesen einfachen Lua-Code über `\directlua`:

```
\directlua{
   local x=3
   wenn x ~= 4 dann
   print("x ist nicht gleich 4")
   end
}
```

erhalten wir einen Fehler:

`[\directlua]:1: 'then' erwartet nahe '\'.`

Das ist seltsam, weil unser Code korrekt ist: Wir haben `'then'` und es gibt kein `\` Zeichen in unserem Code, also was ist schiefgelaufen? Um das zu verstehen, müssen wir uns daran erinnern, dass für TeX/LaTeX, `~` gewöhnlich als „Sonderzeichen“ mit Kategoriecode 13 definiert ist: sogenannte aktive Zeichen, die Mini-Makros sind und daher der Expansion unterliegen. Wenn `\directlua` erkennt das `~` Zeichen, wird es von *ersetzt* aus der Eingabe entfernt und *und ersetzt ihn* mit dem Ergebnis seiner Expansion. Wenn man Plain TeX verwendet, enthält der resultierende Text (Code), den LuaTeX erzeugt und an den Lua-Interpreter übergibt, das `~` Zeichen tatsächlich nicht und lautet:

`local x=3 if x \penalty \@M \ = 4 then print("x ist nicht gleich 4") end`

Die `~` Zeichen ist *entfernt* und *expandiert* zu seinen Bestandteilen – der obige Lua-Code ergibt sich aus der Definition des aktiven Zeichens in Plain TeX `~`. Jetzt können wir sehen, warum Lua mit dem Fehler `'then' erwartet nahe '\'`antwortet – es beginnt, diesen Code zu parsen, stößt aber auf das Wort `\penalty` das für Lua nichts bedeutet und einen Syntaxfehler erzeugt.

Um das zu beheben, muss das `~` Zeichen zum Zeitpunkt, `\directlua` LuaTeX `~` vorübergehend auf 11 (Buchstabe) setzen, indem wir den Code in eine Gruppe einschließen:

```
\begingroup
\catcode`\~=11
\directlua{
   local x=3
   wenn x ~= 4 dann
   print("x ist nicht gleich 4")
   end
}
\endgroup
```

Dieser Code funktioniert wie erwartet und `x ist nicht gleich 4` wird auf der Konsole ausgegeben. Es gibt noch andere Optionen: Wir können die erweiterbaren Befehle `\noexpand` oder `\string`.

#### Verwendung von \string⟨token⟩

Wir können `\string` auf das einzelne `⟨token⟩` `~` Zeichen `\string` das `~` anwenden, um einen Zeichen-Token zu erzeugen, der Kategoriecode 12 hat. Wenn wir

```
\directlua{
   local x=3
   if x \string~= 4 then
   print("x ist nicht gleich 4")
   end
}
```

erzeugt es den Lua-Code, den wir benötigen:

`local x=3 if x ~= 4 then tex.print("x ist nicht gleich 4") end`

#### Verwendung von \noexpand⟨token⟩

Wir können `\noexpand~` verwenden, um die Expansion des aktiven Zeichens zu unterdrücken `~`

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x ist nicht gleich 4")
   end
}
```

Das nicht expandierte `~` Token gelangt in die Tokenliste, die in `\directlua` aufgebaut wird, und wird wieder in Text umgewandelt, wodurch funktionierender Lua-Code entsteht.

### Verwendung des #-Zeichens

Innerhalb der Sprache Lua kann das `#` Zeichen verwendet werden, um die Länge einer Tabelle zu ermitteln. Wenn wir jedoch den folgenden Code ausprobieren

```
\directlua{
   local tbl = {}
   tbl[1] = "Hallo"
   tbl[2] = "Welt"
   tex.print("Tabellenlänge ist "..#tbl)
}
```

könnten wir erwarten, dass LuaTeX

`Tabellenlänge ist 2`

ausgibt, aber es erzeugt einen Fehler:

`\directlua]:1: Versuch, die Länge eines Zahlenwerts zu ermitteln`

Dieser Fehler wird ausgelöst, weil das `#` Zeichen normalerweise Kategoriecode 6 (Makroparameter) hat – das `#` Zeichen hat in TeX/LaTeX zwei Verwendungen: um Makroparameter anzugeben (`#1`, `#2`… `#9`) und den Ersetzungstext in Ausrichtungsvorlagen (für `\halign` und `\valign`).

Wenn `\directlua` erzeugt Tokens, um seine Tokenliste aufzubauen, sieht es das `#` Zeichen mit Kategoriecode 6 und erzeugt einen passenden Zeichen-Token, um es darzustellen. Wenn es an der Zeit ist, die endgültige Tokenliste wieder in Textform umzuwandeln, erhält der Zeichen-Token für # (mit Kategoriecode 6) eine Sonderbehandlung: Er wird ausgegeben als *zwei aufeinanderfolgende Zeichen*: `##`, wodurch folgender Code an Lua übergeben wird:

`local tbl = {} tbl[1] = "Hallo" tbl[2] = "Welt" print(##tbl)`

Bei der Umwandlung in Lua-Code wurde das ursprüngliche `#` verdoppelt und das erzeugt einen Fehler:

`\directlua]:1: Versuch, die Länge eines Zahlenwerts zu ermitteln`

Dieses Problem entsteht aufgrund der TeX-Syntax, die ein doppeltes Rautenzeichen verwendet `##` um einen einzelnen `#` Token darzustellen oder zu erzeugen; diese Syntax wird in Makros verwendet, die andere Makros definieren, die Parameter annehmen, oder in Makros, die Vorlagen für die `\halign` oder `\valign` Tabellenerzeugungsbefehle erstellen. Das ist ziemlich verwirrend, also sehen wir uns ein Beispiel an.

#### Beispiel

Nehmen wir an, wir definieren ein Makro `\mymacro` das einen einzelnen Parameter annimmt, `#1`, aber es definiert auch ein zweites Makro `\foo` das selbst einen einzelnen Parameter annimmt. Um zwischen dem Parameter zu unterscheiden `#1` verwendet mit `\mymacro` und der Notwendigkeit, `\foo` zu definieren, um seinen eigenen Parameter zu verwenden `#1` verlangt die TeX-Syntax, dass man `##1` innerhalb von `\mymacro` verwendet, um den Parameter darzustellen, der mit `\foo`:

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

Wenn Sie schreiben würden `\mymacro{Hey!}` würde es das Makro `\foo` als

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

Beachten Sie, dass der `\mymacro`Parameter `#1` (`Hey!`) wurde in die Definition von `\foo` und die Folge `##1` wurde zu `#1` in der Definition von `\foo`. So können wir `\foo` es so verwenden:

`\foo{, Welt!}`

um zu setzen `Hey! Hallo, Welt!`

Wir können `\directlua`die Behandlung des `#` Zeichens durch TeX vorübergehend ändern, indem wir seinen Kategoriecode vor der Verarbeitung des Codes durch LuaTeX ändern. Zum Beispiel:

```
\begingroup
   \catcode`\#=11
   \directlua{
   local tbl = {}
   tbl[1] = "Hallo"
   tbl[2] = "Welt"
   tex.print("Tabellenlänge ist "..#tbl)
}
\endgroup
```

Dadurch wird der Lua-Code erzeugt

```
local tbl = {} tbl[1] = "Hallo" tbl[2] = "Welt" tex.print("Tabellenlänge ist "..#tbl)
```

wodurch das von uns erwartete Ergebnis gesetzt wird:

`Tabellenlänge ist 2`

### Verwendung des %-Zeichens

Innerhalb von TeX/LaTeX wird das `%` Zeichen typischerweise verwendet, um einzeilige Kommentare in Ihrem Code einzufügen: um der TeX-Engine mitzuteilen, dass sie alles von diesem Punkt an bis zum Ende der Zeile ignorieren soll, in der das `%` geschrieben ist. Innerhalb der Lua-Sprache wird das `%` Zeichen jedoch in einigen sehr nützlichen Zeichenkettenverarbeitungsfunktionen verwendet, wie etwa `string.format(...)`, `string.gmatch(...)`, und `string.gsub(...)` in denen das `%` Zeichen eine wichtige Rolle als Teil der Syntax dieser Funktionen spielt.

Wenn es mit TeX/LaTeX verwendet wird, `%` fungiert als Kommentarzeichen, weil ihm Kategoriecode 14 zugewiesen ist. Damit es sich wie ein normales Zeichen verhält und das übliche TeX/LaTeX-Verhalten ausgeschaltet wird, müssen wir seinen Kategoriecode auf etwas Sicheres wie 12 ändern. Das `\directlua` Beispiel unten verwendet eine Reihe von Techniken, die im Artikel zuvor besprochen wurden, zusammen mit einer, die wir noch nicht erwähnt haben: ``\catcode`\^^M=12``, wodurch wir Lua-Kommentare in unserem Code verwenden können; das wird unten besprochen.

#### Beispiel

Die folgenden Beispiele sind von [lua-users.org](http://lua-users.org/wiki/StringLibraryTutorial), entsprechend für die Verwendung innerhalb von `\directlua`.

```
\documentclass{article}
\begin{document}
\begingroup
\ttfamily
\let\\\relax
\catcode`\^^M=12 %<---wir untersuchen dies weiter unten genauer!
\catcode`\%=12
\directlua{
   local str -- lokale Variable deklarieren, um das Ergebnis zu halten

   tex.print("Verwendung von string.format():".."\\par")

   str=string.format("%s %q", "Hallo", "Lua-Benutzer!") -- Zeichenkette und zitierte Zeichenkette
   tex.print(str.."\\par")
   str = string.format("%c%c%c", 76, 117, 97) -- Zeichen
   tex.print(str.."\\par")
   str=string.format("%e, %E", math.pi, math.pi) -- Exponent
   tex.print(str.."\\par")
   str=string.format("%f", math.pi) -- Fließkommazahl
   tex.print(str.."\\par")
   str=string.format("%g, %g", math.pi, 10^9) -- Fließkommazahl oder Exponent
   tex.print(str.."\\par")
   str = string.format("%o, %x, %X", 99, 125, 125)  -- Oktal, Hexadezimal, Hexadezimal
   tex.print(str.."\\par")

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

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

   tex.print("\\vskip3mm".."Verwendung von string.gsub():".."\\par")
   str=string.gsub("banana", "(an)", "%1-") -- alle Vorkommen von "an" erfassen und ersetzen
   tex.print(str.."\\par")
}
\endgroup
\end{document}
```

Der folgende Screenshot zeigt das gesetzte Ergebnis des obigen Codes:

![Verwendung von Lua-Zeichenkettenfunktionen in \directlua](/files/3700c2e6e01837d5bc6ac6d0d9403598bcf498b2)

## Warum wird Lua-Code in einer einzigen Zeile angezeigt?

Wie Ihnen vielleicht aufgefallen ist, werden alle (erzeugten) Lua-Codefragmente, die in den Beispielen dieses Artikels gezeigt werden, als eine einzige Textzeile dargestellt: Zeilenumbrüche, die ursprünglich in den `\directlua` Code-Snippets vorhanden waren, werden nicht übernommen. Warum ist das so? Das liegt daran, dass Zeilenumbrüche im Lua-Code während der Vorverarbeitung durch LuaTeX *entfernt wurden* während der Vorverarbeitung von LuaTeX innerhalb `\directlua`, wodurch der Lua-Code zu einer langen Textzeile wird. Dieses Verhalten lässt sich auf die Art und Weise zurückführen, wie TeX-Engines mit Zeilenendzeichen umgehen – bezeichnet durch `\\r` (Wagenrücklauf) und `\n` (Zeilenvorschub) in der Programmliteratur. Warum wir uns um diese feinen Details kümmern müssen, wird klar, wenn wir die Verwendung von Luanes Mechanismen zum Auskommentieren von Codeabschnitten besprechen.

Wenn Software eine Textdatei schreibt (speichert), wird jede einzelne Textzeile mit sogenannten „Newline“-Zeichen beendet – die tatsächlichen Newline-Zeichen hängen von der Anwendung und dem Betriebssystem ab, mit dem diese Datei geschrieben wird. Wikipedia hat einen [interessanten Artikel](https://en.wikipedia.org/wiki/Newline) der die Geschichte/Evolution der heute verwendeten Newline-Zeichen untersucht.

Bei jeder beliebigen Textdatei können ihre einzelnen Textzeilen durch verschiedene Kombinationen von Zeichen beendet werden, die als Wagenrücklauf (ASCII/Unicode-Zeichen 13) und/oder Zeilenvorschub (ASCII/Unicode-Zeichen 10) bezeichnet werden, die mit `\\r` und `\n` bzw. bezeichnet werden. Weil TeX-Engines plattformunabhängig konzipiert sind, benötigen sie eine Methode, um die von Natur aus plattformabhängige Art der Zeilenenden in Textdateien zu umgehen. Natürlich haben TeX-Engines eine eingebaute (aber konfigurierbare) Methode zum Umgang mit Zeilenendzeichen.

### Wie TeX-Engines mit Zeilenenden umgehen

Wenn LuaTeX `\directlua{⟨code⟩}` verarbeitet, `⟨code⟩` liest es den in Ihrer `⟨code⟩`enthaltenen Text und wendet die standardmäßigen Methoden der TeX-Engine an, um alle in Ihrer `\endlinechar`gesteuert werden kann. Hier geben wir einen kurzen zweistufigen Überblick, weitere Details finden Sie jedoch im Overleaf-Artikel [Eine Einführung in \endlinechar: Wie TeX Zeilen aus Textdateien liest](/latex/de/ausfuhrliche-artikel/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

#### Schritt 1: TeX fügt sein eigenes Zeilenendzeichen ein

Nachdem TeX-Engines eine Textzeile aus Ihrer Eingabedatei gelesen haben, entfernen sie sofort alle `\\r` oder `\n` Zeichen vom Ende dieser Zeile. Anschließend *fügen* (wieder) hinzu `\endlinechar` and die eigene Zeilenendzeichen an das Ende dieser Zeile. Dieses Zeichen wird durch den Wert eines benutzerkonfigurierbaren TeX-Parameters bestimmt, der

Typischerweise verwenden TeX-Engines die Einstellung

`\endlinechar=13`

was dem Wagenrücklaufzeichen entspricht (`\\r`). Allerdings können Benutzer immer einen anderen Zeichencode als Wert von `\endlinechar`zuweisen – wie wir später in diesem Artikel sehen werden.

Folglich werden alle Zeilenendzeichen, die in Ihrer `⟨code⟩` enthalten sind, von `\directlua{⟨code⟩}` zu verarbeiten *bevor* herausgelöscht und durch ein einzelnes Zeichen ersetzt, das von der TeX-Engine selbst bestimmt wird. Beachten Sie, dass TeX-Engines diese Zeilenendverarbeitung unmittelbar nach dem Einlesen einer neuen Textzeile aus einer Datei durchführen und *nicht* die Zeichen in dieser Zeile verarbeiten (um Tokens zu erzeugen). Dies ist jedoch nicht das Ende der Geschichte: Was die TeX-Engine

#### Schritt 2: TeX wandelt sein Zeilenendzeichen in ein Leerzeichen um

Zusätzlich zum Einfügen ihres eigenen Zeilenendzeichens, definiert durch den Wert von `\endlinechar`verwenden TeX-Engines auch Kategoriecode 5 für Zeichen, die als *behandelt werden sollen,* ein Zeilenendzeichen. Dies führt dazu, dass TeX-Engines normalerweise mit:

1. ein durch `\endlinechar`;
2. definiertes Zeilenendzeichen *normalerweise* demselben Zeichen

Es ist das, was TeX mit diesem Zeilenendzeichen macht, das unser Rätsel hinsichtlich der einzelnen Lua-Codezeilen erklärt. Wenn eine TeX-Engine eine Eingabezeile verarbeitet, wird sie schließlich das letzte Zeichen in dieser Zeile erkennen: das durch `\endlinechar`definierte Zeichen. Gewöhnlich hat dieses Zeichen Kategoriecode 5, wodurch TeX es *es ersetzen* durch ein Leerzeichen: D. h. am Zeilenende entfernt TeX effektiv sein Zeilenendzeichen und ersetzt es durch ein Leerzeichen. Nebenbei bemerkt verwenden TeX-Engines Zeichen mit Kategoriecode 5 auch, um Leerzeilen zu erkennen und einen neuen Absatz zu beginnen, aber darauf gehen wir hier nicht ein.

Natürlich können Sie bei TeX allerlei spezielle Makro-Programmiertricks anwenden, indem Sie den `\endlinechar` auf ein anderes Zeichen neu setzen und/oder dem Zeichen, das `\endlinechar` zugewiesen ist, einen Kategoriecodewert Ihrer Wahl geben.

Wenn Sie verhindern möchten, dass Lua-Code zu einer einzigen Textzeile wird, können Sie entweder den für `\endlinechar` zugewiesenen Wert (vorübergehend) ändern `\\r`.

### TeXs bizarre ^^-Notation

In den folgenden Abschnitten werden wir TeXs ungewöhnliche `^^` Notation begegnen, die als „erweiterter Zeichenmechanismus“ bekannt ist. Sie wurde von Knuth entwickelt, um das Eingeben von „Steuerzeichen“ wie Zeilenendzeichen, Tabulatoren und so weiter zu erleichtern. Zum Beispiel:

* `^^J` stellt Zeichencode 10 dar (`\n`, Zeilenvorschub);
* `^^M` stellt Zeichencode 13 dar (`\\r`, Wagenrücklauf).

Zeichenfolgen wie `^^M` werden früh im Eingabescansprozess von TeX in ihre entsprechenden Zeichencodes umgewandelt, wenn TeX Eingabezeichen liest, um die entsprechenden Zeichen-Token zu erzeugen.

### Ändern des dem \endlinechar zugewiesenen Zeichens

Wenn man sich daran erinnert, dass wir weiterhin die Expansion des `~` Zeichens verhindern müssen, können wir schreiben

```
\begingroup
\endlinechar=10 % ändere das Zeilenendzeichen zu \n
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x ist nicht gleich 4")
   end
}% hier soll kein \n erscheinen
\endgroup% oder ein \n hier
```

Die obige Einstellung für `\endlinechar` bewirkt, dass LuaTeX Zeichencode 10 (`\n`, Zeilenvorschub) an das Ende jeder Zeile anhängt, die es einliest. Wir tun dies, weil `\n` (Zeilenvorschub) normalerweise Kategoriecode 12 hat, was man testen kann mit ``\the\catcode`\^^J``. Weil `\n` nicht Kategoriecode 5 hat, wird LuaTeX es nicht in ein Leerzeichen umwandeln, sodass es am Ende jeder von LuaTeX eingelesenen Zeile erhalten bleibt. Dadurch bleibt ein Zeichen mit Code 10 am Ende jeder Zeile erhalten und gelangt so in die Tokenliste, die von `\directlua` aufgebaut wird, und erscheint anschließend wieder im Lua-Code, sobald die Tokenliste in Text umgewandelt wird. Mit der obigen Änderung wird der Lua-Code dem Lua-Interpreter als folgende Zeichenfolge übergeben:

**\n**local x=3\*\*\n**wenn x \~= 4 dann**\n**print("x ist nicht gleich 4")**\n**end**\n\*\*

wobei die **\n** Notation dazu dient, Zeichencode 10 darzustellen *nicht* ein unbekanntes Makro `\n`. Nun sieht der Lua-Interpreter Zeilenumbrüche im Code, genau so, wie er ursprünglich in der `\directlua` Befehl:

```
   local x=3
   wenn x ~= 4 dann
   print("x ist nicht gleich 4")
   end
```

Übrigens, beachten Sie, dass das allererste Zeichen in der Lua-Codezeichenkette `\n` ist (vor dem `lokalen` Schlüsselwort). Das `\n` entsteht aus der Zeile

`\directlua{`

weil direkt nach dem öffnenden `{` ein Zeilenumbruch steht und dieser ebenfalls erhalten bleibt. Um dies zu verhindern, können Sie schreiben

`\directlua{%`

### Ändern des Kategoriecodes von \r

Um Zeilenumbrüche in unserem Lua-Code beizubehalten, können wir auch den Kategoriecode von `\\r` auf etwas anderes als 5 ändern, so dass `\\r` nicht länger als Zeilenendzeichen erkannt (behandelt) wird. Mit dieser Technik verwendet LuaTeX weiterhin `\endlinechar=13` und wird weiterhin ein `\\r` an das Ende jeder Zeile anhängen; jedoch weil `\\r` nicht länger Kategoriecode 5 hat, wird LuaTeX das `\\r` Zeichen nicht als Zeilenende erkennen: Es wird es nicht in ein Leerzeichen umwandeln und es unversehrt weiterreichen, sodass es im Lua-Code erscheint.

Wenn man sich daran erinnert, dass wir weiterhin die Expansion des `~` Zeichens verhindern müssen, können wir schreiben

```
\begingroup
\catcode`\^^M=12 % Kategoriecode von \r auf 12 ändern
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x ist nicht gleich 4")
   end
}
\endgroup
```

In diesem Fall wird der Lua-Code dem Lua-Interpreter als folgende Zeichenfolge übergeben:

**\\\r**local x=3\*\*\r**wenn x \~= 4 dann**\\\r**print("x ist nicht gleich 4")**\\\r**end**\r\*\*

wobei die `\\r` Notation soll Zeichencode 13 darstellen, nicht irgendein unbekanntes Makro `\\r`. Wie beim `\endlinechar` Beispiel wird der Lua-Interpreter nun Zeilenumbrüche im Code sehen, genau wie sie ursprünglich in der `\directlua` Befehl:

```
   local x=3
   wenn x ~= 4 dann
   print("x ist nicht gleich 4")
   end
```

Übrigens, beachten Sie wieder, dass das allererste Zeichen in der Lua-Codezeichenkette `\\r` ist (vor dem lokalen Schlüsselwort): Auch das entsteht aus der Zeile

`\directlua{`

#### Warum hat \r Kategoriecode 12, aber nicht Kategoriecode 11 verwendet?

Die Antwort liegt im Risiko, versehentlich Fehler einzuführen, die durch `\\r` (mit Kategoriecode 11) am Ende von TeX/LaTeX-Befehlen ausgelöst werden, die aus unserer Eingabedatei gelesen werden. Nehmen wir dieses Beispiel:

```
\begingroup
\catcode`\^^M=11 % Kategoriecode von \r auf 11 ändern
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x ist nicht gleich 4")
   end
}
\endgroup
```

was einen Fehler erzeugt:

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

Wie kann das wahr sein, wenn `\endgroup` ein standardmäßiger TeX-Primitive-Befehl ist? Die Ursache des Fehlers ist recht subtil: Als LuaTeX die letzte Textzeile las – die mit `\endgroup`– fügte es auch das `\endlinechar` Zeichen `\\r` an das Ende dieser Zeile an. Jetzt sieht LuaTeX in seinem Speicher die Zeichenfolge

`\endgroup\r`

wobei wir `\\r` verwenden, um das Zeichen mit Code 13 anzugeben – nicht den Namen eines unbekannten TeX-Makros `\\r`.

Zu dem Zeitpunkt, als LuaTeX diese Zeile aus unserer Textdatei las, ist das ursprüngliche `\begingroup` noch wirksam: Wir befinden uns innerhalb einer Gruppe, die noch nicht durch Ausführen des passenden `\endgroup` Befehls geschlossen wurde – was dazu führen würde, dass `\\r` wieder auf seinen vorherigen Kategoriecodewert 5 zurückgesetzt würde.

Wenn LuaTeX beginnt, die Zeile `\endgroup\r` zu verarbeiten (Tokens zu erzeugen), erkennt es das erste Zeichen `\` als Escape-Zeichen, das LuaTeX dazu veranlasst, nach dem Namen eines Befehls zu suchen. Um einen Befehlsnamen zu identifizieren, sucht LuaTeX nach einer Folge von Zeichen mit Kategoriecode 11, aber weil `\\r` ebenfalls Kategoriecode 11 hat, denkt LuaTeX, dass das `\\r` Zeichen (immer noch mit Kategoriecode 11) bildet *Teil eines Befehls* namens `\endgroup\r` was es natürlich nicht gibt, also meldet LuaTeX einen `Undefinierte Steuersequenz` Fehler. Deshalb haben wir Kategoriecode 12 und nicht 11 verwendet.

Weil die Fehlermeldung von LuaTeX auf die Konsole geschrieben wurde, konnten wir das `\\r` Zeichen nicht leicht sehen/bemerken, sodass nicht offensichtlich war, was den Fehler verursacht hatte.

### Warum beschäftigen wir uns mit Zeilenenden?

Der Grund ist, um die Verwendung von Luas Kommentiermethode in Ihrem Code zu ermöglichen! Sie können LuaTeXs Standardmechanismus verwenden, um `%` Zeichen hinzuzufügen, um einzelne Zeilen in Ihrem Code auszukommentieren; allerdings hat die Lua-Sprache ihre eigenen, sehr nützlichen, *mehrzeiligen* Kommentiermechanismen, deren Vorteile Sie vielleicht nutzen möchten.

Lassen Sie uns damit beginnen zu sehen, was passiert, wenn wir versuchen, einzeilige Kommentare der Lua-Sprache zu verwenden, ohne die Zeilenumbruch-Probleme anzugehen. Während TeX das `%` Zeichen verwendet, um einzelne Codezeilen auszukommentieren, verwendet Lua einen doppelten Bindestrich: `--`.

Was passiert, wenn wir versuchen, das auszuführen:

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Ich werde das Ergebnis dieses komplexen Tests ausgeben
   print("x ist nicht gleich 4")
   end
}
```

Wir erhalten einen Fehler:

`[\directlua]:1: 'end' erwartet nahe <eof>`

Dieser Fehler wird durch das Fehlen von Zeilenumbrüchen im an den Interpreter übergebenen Lua-Code verursacht, der nur eine einzige fortlaufende Zeichenkette sieht, in der der Kommentar mitten in dieser Zeichenkette beginnt:

```

local x=3 if x ~= 4 then -- Ich werde das Ergebnis dieses komplexen Tests ausgeben print("x ist nicht gleich 4") end
```

Alles nach `**local x=3 if x ~= 4 then**` wird als auskommentiert behandelt, wodurch der Interpreter einen unvollständigen Lua-Code-Abschnitt sieht, was zum Fehler

`'end' erwartet nahe <eof>`.

wobei `<eof>` bedeutet Dateiende.

Wie Sie vermutlich schon vermutet haben, müssen wir dies beheben, indem wir sicherstellen, dass Zeilenumbrüche bis in den resultierenden Lua-Code übertragen werden; das können wir zum Beispiel erreichen, indem wir den Kategoriecode von `\\r` auf 12:

```
\begingroup
\catcode`\^^M=12 % Kategoriecode von \r auf 12 ändern
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Ich werde das Ergebnis dieses komplexen Tests ausgeben
   print("x ist nicht gleich 4")
   end
}
\endgroup
```

Jetzt sieht der Lua-Interpreter einen String, aber er enthält `\\r` Zeilenumbrüche, wie sie in dem `\directlua` Fragment:

**\\\r**local x=3\*\*\r**wenn x \~= 4 dann**\r\*\*-- Ich werde das Ergebnis dieses komplexen Tests ausgeben\*\*\r**tex.print("x ist nicht gleich 4")**\\\r**end**\r\*\*

Das entspricht im Grunde dem Schreiben von

```
   local x=3
   if x \noexpand~= 4 then
   -- Ich werde das Ergebnis dieses komplexen Tests ausgeben
   print("x ist nicht gleich 4")
   end
```

was bedeutet, dass Lua diesen Code korrekt verarbeiten und die auskommentierte Zeile ignorieren kann.

**Blockkommentare**

Die Lua-Sprache unterstützt auch eine Syntax, die sie [„Blockkommentar“](https://www.lua.org/pil/1.3.html) (oder *langen Kommentar*): diese beginnen mit `--[[` und gelten bis zum entsprechenden `]]`. Wir können diese praktische Syntax verwenden, um mehrzeilige Kommentare zu schreiben oder Codeabschnitte auszukommentieren, die wir vorübergehend entfernen möchten:

```
\begingroup
\catcode`\^^M=12 % Kategoriecode von \r auf 12 ändern
\directlua{
   local x=3
   if x \noexpand~= 4 then
   --[[ Ich werde das Ergebnis dieses komplexen Tests ausgeben
   einfach weil es wirklich
   ein so erstaunliches Ergebnis ist]]
   print("x ist nicht gleich 4")
   end
}
\endgroup
```

## Abschließend

Zunächst einmal herzlichen Glückwunsch, wenn Sie es geschafft haben, diesen umfangreichen Artikel bis zum Ende zu lesen! Wir haben versucht, einen einigermaßen umfassenden Leitfaden zu TeX-bezogenen Konzepten und Themen zu erstellen, der den notwendigen Hintergrund vermittelt, um über den `\directlua` Befehl das Beste aus LuaTeX herauszuholen. Wir hoffen, einen Artikel verfasst zu haben, der lehrreich ist und der Overleaf-Nutzercommunity und darüber hinaus etwas Nützliches und Wertvolles bietet. Wie immer freuen wir uns über Rückmeldungen, also zögern Sie bitte nicht, [uns zu kontaktieren](https://www.overleaf.com/contact) uns mit Kommentaren zu diesem Artikel oder Vorschlägen zu weiteren Themen zu kontaktieren, über die wir schreiben sollen.

Viel $$\text{Lua}\mathrm{\TeX}\text{-ing!}$$ von Graham Douglas und dem Overleaf-Team.

### Und schließlich ... verwenden Sie einfach das Paket luacode

Obwohl TeX und Lua grundlegend unterschiedlich arbeiten, haben diese Sprachen eine Reihe von Zeichen gemeinsam, die im Kontext jeder Sprache „besondere Bedeutungen“ haben — etwa \\\\, %, \~, #, ^, & — natürlich weisen Lua und TeX diesen Sonderbedeutungen für *sehr* unterschiedliche Zwecke. Unsere Untersuchung problematischer Zeichen zeigt, warum Schwierigkeiten entstehen können und wie Sie sie beheben können; allerdings könnte es ziemlich mühsam sein, viele kleine Lua-Codefragmente manuell zu korrigieren, daher bevorzugen die meisten Nutzer LaTeX-Pakete, die diese Herausforderungen beseitigen. Ein solches Paket ist [`luacode`](https://ctan.org/pkg/luacode?lang=en) das eine Reihe von Funktionen bereitstellt, die die Arbeit mit `\directlua`, aber zumindest haben Sie jetzt vielleicht ein besseres Verständnis der Probleme `luacode` für Sie löst.


---

# 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/de/ausfuhrliche-artikel/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.
