> 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/el/se-vathos-arthra/09-an-introduction-to-luatex-part-2-understanding-directlua.md).

# Μια εισαγωγή στο LuaTeX (Μέρος 2): Κατανόηση του \directlua

## Ο στόχος αυτού του άρθρου

Στο πρώτο μέρος αυτού του άρθρου, [Εισαγωγή στο LuaTeX (Μέρος 1): Τι είναι — και τι το κάνει τόσο διαφορετικό;](/latex/el/se-vathos-arthra/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md), εξετάσαμε συνοπτικά το LuaTeX ως μια εξαιρετικά ευέλικτη μηχανή TeX: ένα εξελιγμένο, προγραμματιζόμενο σύστημα στοιχειοθεσίας, που παρέχει ένα ευρύ φάσμα εργαλείων για τη δημιουργία λύσεων μηχανικής και παραγωγής εγγράφων.

Σε αυτή την καταληκτική συνέχεια, εξετάζουμε προσεκτικά το πιο ζωτικό συστατικό της εργαλειοθήκης του LuaTeX: την `\directlua` εντολή που παρέχει την «πύλη» για τον προγραμματιστικό έλεγχο της στοιχειοθεσίας του LuaTeX μέσω της γλώσσας σεναρίων Lua.

Ωστόσο, η πλήρης αξιοποίηση του LuaTeX μέσω της `\directlua` απαιτεί κάποιες βασικές γνώσεις σε αρκετά θέματα TeX: τα διακριτικά (tokens) του TeX, τις λίστες διακριτικών και τον μηχανισμό επέκτασης. Στόχος αυτού του άρθρου είναι να διερευνήσει και να εξηγήσει αυτές τις θεμελιώδεις έννοιες του TeX: συνθέτοντας τις διεργασίες που σχετίζονται με το TeX πίσω από το `\directlua` για να αναπτύξετε κατανόηση του πώς λειτουργεί και να αποκτήσετε τα θεμέλια πάνω στα οποία θα χτίσετε τις δικές σας λύσεις στοιχειοθεσίας χρησιμοποιώντας το LuaTeX.

Αυτό το άρθρο περιλαμβάνει πολυάριθμα σύντομα παραδείγματα για να δείξει και να εξηγήσει βασικές πτυχές του `\directlua`της συμπεριφοράς του, αποφεύγοντας σκόπιμα υπερβολικά σύνθετο κώδικα υπέρ σύντομων αποσπασμάτων κώδικα. Όπου χρειάζεται, τα παραδείγματα χρησιμοποιούν βασικό (raw/plain) TeX—αν και οι περισσότεροι χρησιμοποιούν και προτιμούν τη LaTeX (μακροεντολές), οι βασικές εντολές TeX έχουν το πλεονέκτημα της απλότητας.

## Εισαγωγή στη Lua στο LuaTeX

[Η Lua](https://www.lua.org/about.html) είναι μια γλώσσα σεναρίων της οποίας ο [πηγαίος κώδικας](https://www.lua.org/download.html) είναι ιδιαίτερα φορητός και εύκολος στην ενσωμάτωση σε εφαρμογές λογισμικού, επιτρέποντας στους προγραμματιστές να ενσωματώνουν δυνατότητες scripting στα προγράμματά τους. Η Lua έχει ενσωματωθεί σε [πολλές εφαρμογές](https://en.wikipedia.org/wiki/List_of_applications_using_Lua) και αποτελεί δημοφιλή επιλογή στον κλάδο των βιντεοπαιχνιδιών—ίσως το πιο γνωστό παράδειγμα είναι το [World of Warcraft](https://wowwiki.fandom.com/wiki/Lua_functions).

Το LuaTeX, όπως υποδηλώνει το όνομά του, είναι μια μηχανή TeX που ενσωματώνει τη γλώσσα σεναρίων Lua, παρέχοντας στους χρήστες τη δυνατότητα να ελέγχουν τη συμπεριφορά στοιχειοθεσίας του LuaTeX μέσω της ενσωμάτωσης προγραμμάτων Lua (σεναρίων) στα έγγραφά τους. Εκτός από τον άμεσο έλεγχο του LuaTeX, οι χρήστες μπορούν να αξιοποιήσουν τη Lua καθαρά ως μια ιδιαίτερα ικανή γλώσσα προγραμματισμού για να εκτελούν εργασίες που θα μπορούσαν να είναι εξαιρετικά δύσκολο να επιτευχθούν χρησιμοποιώντας τη γλώσσα TeX — η οποία, με κάθε δίκαιη εκτίμηση, είναι πρόκληση να τη μάθει και να την κατακτήσει κανείς. Με την προσθήκη και ενσωμάτωση της Lua, το LuaTeX γίνεται μια πολύ ευέλικτη και ισχυρή μηχανή TeX που υποστηρίζει άμεσα δύο γλώσσες προγραμματισμού.

### Χρήση της Lua και του TeX στο έγγραφό σας: εισαγάγετε \directlua

Η Lua και το TeX είναι δύο *πολύ διαφορετικές* γλώσσες προγραμματισμού: η Lua είναι πολύ πιο κοντά σε αυτό που οι περισσότεροι θεωρούν ως γλώσσα προγραμματισμού, αλλά το TeX, με τους κωδικούς κατηγορίας, τα tokens, τις μακροεντολές και τον μηχανισμό επέκτασης, απέχει πολύ από τις εμπειρίες/προσδοκίες των περισσότερων ανθρώπων για μια γλώσσα στην οποία γράφονται προγράμματα. Ωστόσο, όπως έδειξε η ιστορία, η γλώσσα TeX έχει αντέξει στον χρόνο επειδή είναι καλή σε αυτό για το οποίο σχεδιάστηκε: τον έλεγχο της στοιχειοθεσίας, ακόμη κι αν ο τρόπος λειτουργίας της είναι κάπως ερμητικός.

Για να αντιμετωπιστεί η πρόκληση της ανάμειξης των γλωσσών Lua και TeX σε ένα μόνο έγγραφο TeX, οι προγραμματιστές του LuaTeX εισήγαγαν μια νέα εντολή με το όνομα `\directlua` η οποία αποτελεί τη διαδρομή για τη χρήση της Lua — τόσο ως αυτόνομης γλώσσας προγραμματισμού καθαυτής όσο και για τον έλεγχο της συμπεριφοράς στοιχειοθεσίας του LuaTeX.

Η `\directlua` \directlua επιτρέπει στους χρήστες να ενσωματώνουν κώδικα Lua στα έγγραφα TeX τους· αυτός ο κώδικας στη συνέχεια παραδίδεται στον ενσωματωμένο διερμηνέα της γλώσσας Lua του LuaTeX. Ωστόσο, `\directlua` επίσης σας επιτρέπει να *συνδυάσετε* κώδικα Lua και (La)TeX μαζί, μέσα στην ίδια `\directlua` εντολή—αν και αυτό εισάγει πρόσθετες πολυπλοκότητες λόγω των θεμελιωδών διαφορών στις γλώσσες προγραμματισμού που βασίζονται στη Lua και στο TeX. Η βασική πρόκληση κατά τη χρήση συνδυασμού κώδικα (La)TeX και Lua είναι να διασφαλιστεί ότι οι δύο γλώσσες συνυπάρχουν αρμονικά και δεν «παρεμβαίνουν η μία στην άλλη».

`\directlua` είναι πιο κατάλληλη για χρήση με μικρότερα αποσπάσματα κώδικα Lua μέσα στο έγγραφο, αλλά μπορείτε να τη χρησιμοποιήσετε και με εκτενέστερα προγράμματα Lua, αν το επιθυμείτε. Γενικά, πιο εκτενή προγράμματα Lua και βιβλιοθήκες κώδικα Lua αποθηκεύονται σε εξωτερικά αρχεία, τα οποία μπορούν να φορτωθούν χρησιμοποιώντας τη συνάρτηση της Lua `dofile()` μέσα σε μια `\directlua` εντολή. Από την άποψη της επεξεργασίας TeX, ένα σημαντικό πλεονέκτημα της χρήσης εξωτερικών αρχείων κώδικα Lua είναι η αποφυγή επιπλοκών που προκύπτουν από τον μηχανισμό κωδικών κατηγορίας του TeX—ένα θέμα που εξετάζεται πλήρως σε αυτό το άρθρο.

### Πιο επίσημη περιγραφή της \directlua

Η [Εγχειρίδιο Αναφοράς LuaTeX](http://www.pragma-ade.com/general/manuals/luatex.pdf) περιγράφει `\directlua` ως εξής (ελαφρώς τροποποιημένο):

> Για να συγχωνευτεί ο κώδικας Lua με την είσοδο TeX, χρειάζονται μερικά νέα πρωτογενή στοιχεία. Η πρωτογενής εντολή `\directlua` χρησιμοποιείται για την άμεση εκτέλεση κώδικα Lua. Η βασική σύνταξη είναι `\directlua{⟨code⟩}`. Το `⟨code⟩` αναπτύσσεται πλήρως και στη συνέχεια τροφοδοτείται στον διερμηνέα Lua. Αφού γίνει η ανάγνωση και εφαρμοστεί η επέκταση στο `⟨code⟩`, η προκύπτουσα λίστα διακριτικών μετατρέπεται σε συμβολοσειρά σαν να εμφανιζόταν με τη χρήση του `\the\toks`.

Φυσικά αυτό είναι τεχνικά ακριβές αλλά, ίσως, όχι τόσο εύκολο να κατανοηθεί χωρίς κάποιες γνώσεις των διαδικασιών TeX χαμηλότερου επιπέδου—όπως τα tokens και η επέκταση.

## Κατανόηση της \directlua: Ποια θέματα θα καλύψουμε;

Σε αυτό το άρθρο θα εξετάσουμε πιο προσεκτικά ορισμένα βασικά θέματα υποβάθρου και θα προσφέρουμε αρκετά παραδείγματα σχεδιασμένα να δείξουν πώς `\directlua` λειτουργεί και πού (ή γιατί) πρέπει να είστε προσεκτικοί όταν συνδυάζετε TeX και Lua στο `⟨code⟩`.

Θα εξερευνήσουμε τα ακόλουθα θέματα με επαρκή λεπτομέρεια ώστε να θέσουμε τα θεμέλια για την κατανόηση του `\directlua` και της «προεπεξεργασίας» του κώδικα που χρησιμοποιείτε μέσα σε αυτό:

* κωδικοί κατηγορίας και tokens του TeX: μετατροπή κειμένου σε tokens και tokens σε κείμενο·
* η διαδικασία επέκτασης του TeX (και η αποτροπή της επέκτασης)·
* μηχανισμοί/ακολουθίες διαφυγής της Lua για χαρακτήρες και συμβολοσειρές·
* χρήση σχολίων τύπου Lua·
* μια σύντομη εισαγωγή στο Lua API του LuaTeX.

Αν κατανοήσετε πώς οι μηχανές TeX δημιουργούν και χρησιμοποιούν tokens και αναπτύξετε επίγνωση του μηχανισμού επέκτασης του TeX, τότε θα έχετε τα απαραίτητα θεμέλια για να ξεκλειδώσετε την απίστευτη ευελιξία της `\directlua` εντολή.

## Τα θεμέλια: από το κείμενο στα tokens και από τα tokens στο κείμενο

Το Overleaf έχει δημοσιεύσει αρκετά άρθρα που εξετάζουν σε βάθος τα tokens του TeX και συναφείς έννοιες, οπότε δεν θα επαναλάβουμε εδώ όλο εκείνο το υλικό· αντ' αυτού, θα περιγράψουμε συνοπτικά εκείνες τις περιοχές/θέματα που σχετίζονται με την καλύτερη κατανόηση του `\directlua`.

Ακολουθεί μια λίστα προηγουμένως δημοσιευμένων άρθρων που μπορεί να σας ενδιαφέρουν:

* [Τι είναι ένα token του TeX;](/latex/el/se-vathos-arthra/53-what-is-a-tex-token.md)
* [Τι είναι μια λίστα tokens του TeX;](/latex/el/se-vathos-arthra/54-what-is-a-tex-token-list.md)
* [Πώς λειτουργεί το \expandafter: Μια εισαγωγή στα tokens του TeX](/latex/el/se-vathos-arthra/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)
* [Μια σειρά έξι μερών: Πώς λειτουργούν πραγματικά οι μακροεντολές TeX;](/latex/el/perissotera-themata/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### Κατανόηση των χαρακτηρικών tokens

Κάθε χαρακτήρας που μπορεί να διαβάσει μια μηχανή TeX από ένα αρχείο κειμένου αναπαρίσταται από δύο αριθμητικές τιμές:

* τον *κωδικό χαρακτήρα* (τιμή ASCII ή, σήμερα, το σημείο κώδικα Unicode)·
* μια δεύτερη, επικεντρωμένη στο TeX, τιμή που ονομάζεται *κωδικός κατηγορίας*.

Οι αναγνώστες που θα ήθελαν να μάθουν περισσότερα για τους κωδικούς κατηγορίας ίσως ενδιαφερθούν να διαβάσουν αυτή την εισαγωγή που δημοσίευσε το Overleaf: [Από πού λοιπόν ξεκινάμε; Από τους κωδικούς κατηγορίας](/latex/el/perissotera-themata/19-how-tex-macros-actually-work-part-1.md#so2c-where-do-we-start3f-with-category-codes).

Για παράδειγμα, αν μια μηχανή TeX διαβάσει έναν χαρακτήρα `Ένα` θα έχει πρόσβαση σε δύο πληροφορίες: `Ένα`τον κωδικό χαρακτήρα του (65) και τον κωδικό κατηγορίας του (συνήθως 11). Μόλις το TeX εισαγάγει αυτόν τον χαρακτήρα `Ένα`, ο κωδικός κατηγορίας του δεν θα αλλάξει, αλλά οι μακροεντολές του χρήστη μπορούν να κάνουν αλλαγές στους κωδικούς κατηγορίας που θα μπορούσαν να επηρεάσουν οποιονδήποτε *μεταγενέστερο* χαρακτήρα `Ένα` που *δεν έχει ακόμη διαβαστεί* από το TeX. Κατά συνέπεια, το TeX πρέπει να καταγράψει ότι *αυτός* χαρακτήρα `Ένα`, *που μόλις διαβάστηκε*, έχει κωδικό κατηγορίας 11. Για να το κάνει αυτό, το TeX χρησιμοποιεί το ζεύγος ακεραίων (65,11) για να υπολογίσει μια άλλη ακέραια τιμή την οποία ονομάζει *χαρακτηρικό token*. Υπολογίζοντας αυτή την τιμή token, η οποία μεταβιβάζεται στην εσωτερική επεξεργασία του TeX, ο συγκεκριμένος `Ένα` και ο κωδικός κατηγορίας του είναι *δεμένα μεταξύ τους*· ουσιαστικά, αυτό το χαρακτηρικό token *ενθυλακώνει* τα δεδομένα που το TeX πρέπει να γνωρίζει για αυτόν τον χαρακτήρα για χρήση σε οποιεσδήποτε επόμενες δραστηριότητες στοιχειοθεσίας βαθύτερα μέσα στη μηχανή TeX.

#### Πώς υπολογίζονται τα χαρακτηρικά tokens;

Πρώτον, πρέπει να θυμόμαστε ότι οι μηχανές TeX χρησιμοποιούν τον κωδικό κατηγορίας 13 για τη δημιουργία των λεγόμενων *ενεργών χαρακτήρων*: οποιοσδήποτε χαρακτήρας με κωδικό κατηγορίας 13 συμπεριφέρεται σαν μικρο-μακροεντολή· κατά συνέπεια, και όπως θα δούμε παρακάτω, τα tokens για ενεργούς χαρακτήρες υπολογίζονται διαφορετικά από τους κανονικούς χαρακτήρες με άλλους κωδικούς κατηγορίας όπως 10, 11 ή 12.

Για *μη ενεργοί* χαρακτήρες:

* οι παλαιότερες 8-bit μηχανές (το TeX του Knuth, e-TeX, pdfTeX) υπολογίζουν τα χαρακτηρικά tokens για *μη ενεργοί* χαρακτήρες χρησιμοποιώντας

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

* για το LuaTeX, το οποίο πρέπει να χειρίζεται τιμές χαρακτήρων Unicode, ο υπολογισμός για *μη ενεργοί* χαρακτήρες είναι παρόμοιος αλλά παράγει πολύ μεγαλύτερες ακέραιες τιμές:

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

Επιστρέφοντας στο προηγούμενο παράδειγμά μας για το γράμμα A με κωδικό κατηγορίας 11, το LuaTeX θα υπολόγιζε μια τιμή χαρακτηρικού token ίση με $$2^{21} \times 11 + 65 = 23068737$$. Μόλις υπολογιστεί, αυτή η τιμή χαρακτηρικού token *δεσμεύει* τον συγκεκριμένο χαρακτήρα A σε μια τιμή κωδικού κατηγορίας 11. Οι μακροεντολές του χρήστη μπορεί να αλλάξουν τον κωδικό κατηγορίας για οποιονδήποτε επόμενο χαρακτήρα A, αλλά ο κωδικός κατηγορίας αυτού έχει σταθεροποιηθεί με τη μετατροπή του σε token για χρήση καθώς περνά μέσα από τα εσωτερικά του LuaTeX. Το LuaTeX έχει διατηρήσει, ή ενθυλακώσει, την επιδιωκόμενη σημασία αυτού του χαρακτήρα όπως καθορίστηκε τη στιγμή που διαβάστηκε.

Οι μηχανές TeX χρησιμοποιούν συνολικά [16 διαφορετικούς κωδικούς κατηγορίας](/latex/el/perissotera-themata/43-table-of-tex-category-codes.md) και *οποιοσδήποτε* από αυτούς τους κωδικούς κατηγορίας μπορεί να αποδοθεί, μέσω της `\catcode` εντολής, σε *οποιοσδήποτε* χαρακτήρα που η μηχανή TeX είναι σε θέση να διαβάσει. Οι αλλαγές στους κωδικούς κατηγορίας χρησιμοποιούνται για να τροποποιήσουν τον τρόπο με τον οποίο οι μηχανές TeX επεξεργάζονται συγκεκριμένους χαρακτήρες στην είσοδο, επιτρέποντας στους χρήστες TeX να γράφουν μακροεντολές που παράγουν ειδικά αποτελέσματα ή συμπεριφορές στοιχειοθεσίας.

**Ενεργοί χαρακτήρες**

Όπως σημειώθηκε, οι μηχανές TeX χρησιμοποιούν τον κωδικό κατηγορίας 13 για να αποδώσουν μια «ειδική σημασία» σε έναν χαρακτήρα, καθιστώντας τον έτσι λεγόμενο *ενεργό χαρακτήρα* ο οποίος συμπεριφέρεται σαν μικρο-μακροεντολή: δεν απαιτείται προηγούμενο `\` \\, ο απομονωμένος χαρακτήρας, λόγω του κωδικού κατηγορίας του, αρκεί για να ενεργοποιήσει τη συμπεριφορά του σαν μακροεντολή.

Επειδή ένας ενεργός χαρακτήρας λειτουργεί σαν μικρο-μακροεντολή, δεν μετατρέπεται σε ένα *χαρακτηρικό token* αλλά σε έναν δεύτερο τύπο token (ακέραιο) που ονομάζεται *token εντολής*. Αυτά υπολογίζονται ως εξής:

* για παλαιότερες 8-bit μηχανές (το TeX του Knuth, e-TeX, pdfTeX) τα tokens για ενεργούς χαρακτήρες υπολογίζονται μέσω:

1. υπολογίστε μια ενδιάμεση τιμή που ονομάζεται $$\text{curcs}$$ (**τρέχ**ουσα **c**ελέγχ **ος**ακολουθία) όπου $$\text{curcs} = \text{character code} + 1$$3. υπολογίστε την τιμή του token όπου $$\text{active character token} = \text{curcs} + \text{4095}$$

* για το LuaTeX ο υπολογισμός είναι λίγο πιο σύνθετος επειδή πρέπει να χειριστεί το πλήρες φάσμα των χαρακτήρων Unicode, οποιοσδήποτε από τους οποίους θα μπορούσε να καταστεί ενεργός:

1. υπολογίστε την ενδιάμεση ακέραια τιμή $$\text{curcs}$$ εφαρμόζοντας μια λεγόμενη *συνάρτηση κατακερματισμού* στην τιμή του σημείου κώδικα Unicode του ενεργού χαρακτήρα όπως εκφράζεται σε UTF-8: $$\text{curcs}=\texttt{hashfunction}\text{(UTF-8 text for Unicode value of active character)}$$3. υπολογίστε την ακέραια τιμή του token: $$\text{active character token} = \text{curcs} + 2^{29} - 1$$

**Παραδείγματα**

* 8-bit μηχανές: ο υπολογισμός του token για τον ενεργό χαρακτήρα `~` (κωδικός χαρακτήρα 126) καταλήγει σε $$\text{curcs} = 126 + 1 = 127$$, δίνοντας τιμή token ίση με $$4095 + 127 = 4222$$.
* LuaTeX: ο υπολογισμός του token για τον ενεργό χαρακτήρα `~` καταλήγει σε $$\text{curcs}=3186$$ δίνοντας τιμή token ίση με $$3186 + 2^{29} - 1 = 536874097$$. Τα tokens του LuaTeX χρησιμοποιούν πολύ μεγαλύτερες ακέραιες τιμές!

### Κατανόηση των tokens εντολών

Εκτός από την επεξεργασία *μεμονωμένων* χαρακτήρων, οι μηχανές TeX μπορούν, φυσικά, να επεξεργάζονται *ακολουθίες* χαρακτήρων που ονομάζονται *εντολές* (ή, πιο σωστά, *ακολουθίες ελέγχου*). Από παράδοση, ο `\` χαρακτήρας χρησιμοποιείται για να σηματοδοτήσει την έναρξη μιας εντολής, αλλά αυτό είναι απλώς μια σύμβαση—στην πραγματικότητα, οποιοσδήποτε χαρακτήρας με κωδικό κατηγορίας 0 (ο χαρακτήρας διαφυγής) θα μπορούσε να χρησιμοποιηθεί αντί γι' αυτό.

Οι μηχανές TeX αναγνωρίζουν δύο τύπους εντολών που είναι γνωστοί ως *λέξεις ελέγχου* και *σύμβολα ελέγχου*:

* **λέξεις ελέγχου**: εντολές που αποτελούνται από έναν ή περισσότερους χαρακτήρες με κωδικό κατηγορίας 11·
* **σύμβολα ελέγχου**: εντολές μονού χαρακτήρα, όπου ο κωδικός κατηγορίας αυτού του χαρακτήρα *δεν* 11: όπως `\$`, `\#` ή `\\`.

**Σημείωση**: Τα πρωτογενή στοιχεία TeX `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` και `\toksdef` χρησιμοποιούνται επίσης για τον ορισμό ακολουθιών ελέγχου, αλλά, σε αντίθεση με τους συνηθισμένους ορισμούς μακροεντολών, οι προκύπτουσες ακολουθίες ελέγχου (λέξεις ελέγχου ή σύμβολα ελέγχου) *δεν είναι επεκτάσιμες*—θα τις εξετάσουμε πιο αναλυτικά παρακάτω.

#### Πώς υπολογίζονται τα tokens εντολών;

Όπως και οι ενεργοί χαρακτήρες, οι μηχανές TeX χρησιμοποιούν τον δεύτερο τύπο ακέραιας τιμής token για να αναπαραστήσουν εντολές: *tokens εντολών*—θυμηθείτε ότι οι ενεργοί χαρακτήρες παράγουν επίσης tokens εντολών επειδή συμπεριφέρονται σαν μικρο-μακροεντολές.

Οι υπολογισμοί που χρησιμοποιούν οι 8-bit μηχανές για τη δημιουργία ακεραίων token εντολών μπορούν να βρεθούν σε αυτό το [άρθρο του Overleaf](/latex/el/se-vathos-arthra/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#how-tex-calculates-token-values). Εδώ, θα συνοψίσουμε τα βασικά βήματα στους υπολογισμούς των tokens εντολών για το LuaTeX—τα οποία είναι λίγο διαφορετικά επειδή το LuaTeX πρέπει να επεξεργάζεται τιμές Unicode χαρακτήρων που μπορεί να είναι σημαντικά μεγαλύτερες από 8-bit τιμές· ωστόσο, οι υπολογισμοί του LuaTeX ακολουθούν τις ίδιες γενικές αρχές που χρησιμοποιούνται από παλαιότερες 8-bit μηχανές.

Αφού ανιχνεύσουν μια εισερχόμενη εντολή, οι μηχανές TeX, συμπεριλαμβανομένου του LuaTeX, αγνοούν τον αρχικό `\` χαρακτήρα: δεν χρησιμοποιείται στους υπολογισμούς των τιμών token εντολών αλλά απλώς λειτουργεί ως «διακόπτης» για να ενημερώσει μια μηχανή TeX ότι πρέπει να επεξεργαστεί μια εντολή. Η τιμή token της εντολής υπολογίζεται χρησιμοποιώντας την ακολουθία χαρακτήρων (1 ή περισσότερων) που υπάρχουν στο όνομα της εντολής—το LuaTeX υπολογίζει tokens εντολών για σύμβολα ελέγχου και λέξεις ελέγχου χρησιμοποιώντας τον ίδιο αλγόριθμο:

1. υπολογίστε την ενδιάμεση ακέραια τιμή $$\text{curcs}$$ εφαρμόζοντας μια λεγόμενη [συνάρτηση κατακερματισμού](https://en.wikipedia.org/wiki/Hash_function) στη συμβολοσειρά χαρακτήρων Unicode UTF-8 που περιέχεται στο όνομα της εντολής: $$\text{curcs}=\texttt{hashfunction}\text{(Unicode UTF-8 string of characters in command name)}$$3. υπολογίστε την τιμή του token της εντολής όπου $$\text{command token} = \text{curcs} + 2^{29} - 1$$

**Παραδείγματα**

* για το `\\` εντολή (σύμβολο ελέγχου), το LuaTeX υπολογίζει $$\text{curcs}=94$$, με αποτέλεσμα μια τιμή token για το `\\` του $$94 + 2^{29} - 1 = 536871005$$.
* για το `\vskip` πρωτογενούς εντολής (λέξη ελέγχου) το LuaTeX υπολογίζει $$\text{curcs}=3560$$, με αποτέλεσμα μια τιμή token για το `\vskip` του $$3560 + 2^{29} -1 = 536874471$$.
* για τη μακροεντολή που ορίζεται από τον χρήστη `\mynewmacro` (λέξη ελέγχου) το LuaTeX υπολογίζει $$\text{curcs} = 2971$$, με αποτέλεσμα μια τιμή token για το `\mynewmacro` του $$2971 + 2^{29} -1 = 536873882$$.

Μόλις δημιουργηθούν, τα tokens μπορούν να αποθηκευτούν για μελλοντική χρήση μέσω των λεγόμενων *λιστών tokens* ή μπορούν να μεταβιβαστούν αμέσως για περαιτέρω επεξεργασία μέσα στη μηχανή TeX. Η χρήση ακέραιων τιμών για την αναπαράσταση tokens όχι μόνο λειτουργεί σε όλους τους τύπους υπολογιστικών πλατφορμών/λειτουργικών συστημάτων, αλλά είναι επίσης ένας πολύ αποδοτικός τρόπος για το TeX να αποθηκεύει/επεξεργάζεται δεδομένα.

### Πώς μια μηχανή TeX αναγνωρίζει τον τύπο του token (εντολή ή χαρακτήρας)

Δεδομένης μιας συγκεκριμένης ακέραιης τιμής token, $$T$$, μια μηχανή TeX μπορεί εύκολα να καθορίσει αν $$T$$ αναπαριστά μια εντολή ή έναν χαρακτήρα ελέγχοντας αν $$T$$ υπερβαίνει ένα συγκεκριμένο $$\text{threshold value}$$—αυτό $$\text{threshold value}$$ εξαρτάται από τη μηχανή TeX. Αν $$T \geq \text{threshold value}$$ τότε $$T$$ είναι token εντολής, διαφορετικά $$T$$ είναι χαρακτηρικό token. Η $$\text{threshold value}$$ είναι $$4095$$ για 8-bit μηχανές και $$2^{29}-1$$ (536.870.911) για το LuaTeX. Ο Knuth σχεδίασε τις μεθόδους που χρησιμοποιούνται στους τύπους υπολογισμού tokens έτσι ώστε η μηχανή TeX του, και όλες οι επόμενες μηχανές που βασίζονται στον κώδικα/αρχιτεκτονική του, να μπορούν να ελέγχουν γρήγορα και εύκολα τις τιμές token.

## Τα tokens μπορούν να διασπαστούν (και να μετατραπούν ξανά σε κείμενο)

Τα tokens (ακέραιοι) είναι ο μηχανισμός μέσω του οποίου μια μηχανή TeX «ενθυλακώνει» όλα όσα χρειάζεται να καταγράψει για ένα στοιχείο εισόδου (χαρακτήρα ή εντολή). Ωστόσο, υπάρχουν στιγμές που μια μηχανή TeX χρειάζεται να αντιστρέψει τη διαδικασία tokenization—για να διαπιστώσει τι είχε αρχικά διαβαστεί ώστε να παραχθεί αυτή η τιμή token—έναν μεμονωμένο χαρακτήρα ή μια ακολουθία ενός ή περισσότερων χαρακτήρων που σχηματίζουν το όνομα μιας εντολής:

* **για χαρακτηρικά tokens**: Κάθε χαρακτηρικό token μπορεί να διασπαστεί στα δύο συνιστώντα μέρη του: τον κωδικό χαρακτήρα και τον αντίστοιχο κωδικό κατηγορίας που αποδόθηκε σε αυτόν τον χαρακτήρα *τη στιγμή που διαβάστηκε αρχικά*. Όπως όλες οι μηχανές TeX, το LuaTeX δεν θα αλλάξει αυτή την αρχική ανάθεση κωδικού κατηγορίας, αλλά θα την αξιοποιήσει κατά τις περαιτέρω εσωτερικές δραστηριότητες επεξεργασίας.
* **για tokens εντολών:** Αυτά είναι λίγο πιο λεπτομερή, αλλά αν κοιτάξετε τον υπολογισμό των tokens εντολών στο LuaTeX, συμπεριλαμβανομένων των tokens για ενεργούς χαρακτήρες, θα δείτε ότι ακολουθούν ένα μοτίβο: $$\text{command token} = \text{curcs} + 2^{29} -1$$

όπου $$\text{curcs}$$ υπολογίζεται σύμφωνα με τον τύπο του token εντολής που παράγεται: ενεργός χαρακτήρας, σύμβολο ελέγχου ή λέξη ελέγχου. Η $$\text{curcs}$$ μεταβλητή είναι ένα *εξαιρετικά* σημαντικό συστατικό των εσωτερικών λειτουργιών μιας μηχανής TeX: δεδομένης οποιασδήποτε ακέραιης τιμής token εντολής, το LuaTeX μπορεί πολύ εύκολα να εξαγάγει την τιμή του $$\text{curcs}$$ από αυτό το token εντολής χρησιμοποιώντας $$\text{curcs} = \text{token value} - (2^{29} -1)$$.

### Γιατί είναι $$\text{curcs}$$ τόσο σημαντικό;

Η εσωτερική μεταβλητή του TeX $$\text{curcs}$$ (**τρέχ**ουσα **c**ελέγχ **ος**ακολουθίας) είναι ένα εξαιρετικά σημαντικό συστατικό των εσωτερικών «κάτω από το καπό» λειτουργιών μιας μηχανής TeX. Αν και δεν θα χρησιμοποιήσετε, ούτε μπορείτε, να το χρησιμοποιήσετε ή να έχετε πρόσβαση σε αυτό άμεσα στον κώδικά σας, $$\text{curcs}$$ διαδραματίζει καθοριστικό ρόλο επειδή οι μηχανές TeX χρησιμοποιούν την τρέχουσα τιμή του $$\text{curcs}$$ ως δείκτη σε εσωτερικούς πίνακες που αποθηκεύουν δεδομένα για κάθε εντολή που είναι επί του παρόντος γνωστή στη μηχανή. Αυτοί οι πίνακες αποθηκεύουν πληροφορίες για την τρέχουσα σημασία μιας εντολής: τι κάνει ή τι αναπαριστά και, επιπλέον, καταγράφουν την ακολουθία χαρακτήρων που χρησιμοποιήθηκε αρχικά για να υπολογιστεί αυτή η $$\text{curcs}$$ τιμή. Εξάγοντας την τιμή του $$\text{curcs}$$ από ένα token εντολής, μια μηχανή TeX είναι σε θέση να προσδιορίσει το όνομα, δηλαδή το αναγνώσιμο από άνθρωπο κείμενο, που αντιστοιχεί σε οποιοδήποτε token (εντολής), επιτρέποντάς της να εκτελεί τις μετατροπές από token σε κείμενο που αποτελούν βασική πτυχή της `\directlua`λειτουργίας του.

### Μετατροπή ακέραιων tokens πίσω σε χαρακτήρες ή ακολουθίες χαρακτήρων (ονόματα εντολών)

Είδαμε ότι οι μηχανές TeX μετατρέπουν τους χαρακτήρες εισόδου ή τις ακολουθίες χαρακτήρων σε ακέραιες τιμές token, αλλά υπάρχουν περιπτώσεις όπου μια μηχανή TeX χρειάζεται να *αντιστρέψει* αυτή τη διαδικασία—για να εξαγάγει το αναγνώσιμο από άνθρωπο κείμενο που χρησιμοποιήθηκε αρχικά για τη δημιουργία αυτών των ακέραιων τιμών token· για παράδειγμα:

* εγγραφή μηνυμάτων σφάλματος ή προειδοποίησης στην οθόνη ή `.log` αρχείο;
* εξαγωγή κώδικα TeX/LaTeX σε αρχείο κειμένου μέσω της `\write` εντολή;
* κατά τη μετατροπή μιας ακολουθίας tokens σε κείμενο μέσα στο `\directlua` (όπως θα δούμε σύντομα!)

#### Μετατροπή χαρακτηρικών tokens σε κείμενο

Όπως σημειώθηκε, τα tokens για μη ενεργούς χαρακτήρες υπολογίζονται χρησιμοποιώντας τον κωδικό κατηγορίας και τον κωδικό χαρακτήρα (τιμή Unicode) του χαρακτήρα εισόδου. Το LuaTeX χρησιμοποιεί τον τύπο:

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

Είναι μια απλή προγραμματιστική εργασία να διασπαστεί ο ακέραιος $$\text{character token}$$ ώστε να εξαχθεί ο συνιστών κωδικός χαρακτήρα ($$\text{Unicode value}$$) και $$\text{category code}$$.

#### Μετατροπή tokens εντολών σε κείμενο

Όλες οι μηχανές TeX αποθηκεύουν το όνομα (ακολουθία χαρακτήρων) κάθε εντολής που «γνωρίζουν»: είτε αυτή η εντολή είναι μακροεντολή ορισμένη από τον χρήστη είτε ενσωματωμένο πρωτογενές στοιχείο—η αποθήκευση των ονομάτων των πρωτογενών εντολών πραγματοποιείται όταν η μηχανή TeX ξεκινά, πολύ πριν αρχίσει να επεξεργάζεται τον κώδικά σας. Για εντολές ορισμένες από τον χρήστη (μακροεντολές), το όνομα αυτής της μακροεντολής (χωρίς το αρχικό `\`) αποθηκεύεται ως μέρος των διεργασιών ορισμού μακροεντολών μέσα στις μηχανές TeX.

Όταν μια μηχανή TeX χρειάζεται να προσπελάσει ή να εξαγάγει το αναγνώσιμο από άνθρωπο κείμενο από το οποίο υπολογίστηκε αρχικά ένα ακέραιο token εντολής, θα προσδιορίσει πρώτα την $$\text{curcs}$$ τιμή για αυτό το token· στο LuaTeX, $$\text{curcs} = \text{token} - (2^{29} -1$$). Χρησιμοποιώντας την τιμή του $$\text{curcs}$$ που εξάγεται από ένα token εντολής, μια μηχανή TeX μπορεί να προσπελάσει μια εσωτερική δομή δεδομένων που ονομάζεται *δεξαμενή συμβολοσειρών* για να προσδιορίσει την ακολουθία αναγνώσιμων από άνθρωπο χαρακτήρων που χρησιμοποιήθηκε αρχικά για τον υπολογισμό αυτής της συγκεκριμένης τιμής για το $$\text{curcs}$$ και, κατά συνέπεια, του αντίστοιχου token εντολής.

Όπως θα δούμε, αυτές οι δραστηριότητες επεξεργασίας tokens—η μετατροπή ακολουθιών χαρακτήρων σε ακέραιες τιμές token και η μετατροπή ακέραιων τιμών token πίσω σε ακολουθίες χαρακτήρων («απο-tokenization»)—είναι οι *θεμελιώδεις μηχανισμοί* που χρησιμοποιούνται μέσα στο `\directlua`.

## Λίστες tokens

Καθώς μια μηχανή TeX διαβάζει είσοδο, παράγοντας χαρακτηρικά και εντολ- tokens (και επεξεργαζόμενη αυτά), μπορεί να συναντήσει ορισμένες εντολές που της δίνουν οδηγίες να σταματήσει προσωρινά να προωθεί τα tokens για περαιτέρω επεξεργασία αλλά, αντίθετα, να τα αποθηκεύσει για μελλοντική χρήση. Το πιο συνηθισμένο παράδειγμα είναι ο ορισμός μιας μακροεντολής χρησιμοποιώντας μία από τις εντολές ορισμού μακροεντολών `\def`, `\edef`, `\gdef` ή `\xdef`—εντολές LaTeX όπως `\newcommand` είναι μακροεντολές που παρέχουν πρόσθετη λειτουργικότητα χτισμένη γύρω από πρωτογενή στοιχεία χαμηλού επιπέδου, τα οποία τελικά εκτελούν την πραγματική διαδικασία ορισμού μακροεντολών. Μια μακροεντολή μπορεί να θεωρηθεί ως το όνομα που δίνεται σε μια συγκεκριμένη λίστα αποθηκευμένων tokens: μια λίστα tokens.

Οι μηχανές TeX κάνουν *εκτεταμένη* χρήση λιστών tokens, ιδιαίτερα [προσωρινών εσωτερικών λιστών μόνο](/latex/el/se-vathos-arthra/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) για εσωτερικούς σκοπούς επεξεργασίας. Κάθε μηχανή TeX παρέχει επίσης εντολές επιπέδου χρήστη για τη δημιουργία λιστών tokens που αποθηκεύονται για όταν τις χρειάζεται ο χρήστης ή η ίδια η μηχανή TeX. Ο αριθμός των εντολών δημιουργίας λιστών token (ενσωματωμένα πρωτογενή στοιχεία) ποικίλλει ανάλογα με τη μηχανή TeX, αλλά όλες μοιράζονται ένα βασικό ελάχιστο σύνολο που υποστηρίζεται από κάθε μηχανή, όπως η `\toks` πρωτογενής εντολή.

Στην πράξη, μια λίστα tokens είναι απλώς μια αποθηκευμένη ακολουθία ακέραιων τιμών:

* η είσοδος διαβάζεται για να παραχθούν (υπολογιστούν) μεμονωμένα tokens, που αναπαριστούν έναν χαρακτήρα ή μια εντολή·
* κάθε token στη συνέχεια αποθηκεύεται, διατηρώντας τη σειρά με την οποία τα tokens δημιουργήθηκαν από την είσοδο.

Οι μηχανές TeX αποθηκεύουν λίστες tokens χρησιμοποιώντας μια δομή δεδομένων που ονομάζεται [συνδεδεμένη λίστα](https://en.wikipedia.org/wiki/Linked_list) (της μονής διασύνδεσης). Οι αναγνώστες που επιθυμούν να μάθουν περισσότερα για τις λίστες tokens προσκαλούνται να διαβάσουν το άρθρο του Overleaf [Τι είναι μια λίστα tokens του TeX;](/latex/el/se-vathos-arthra/54-what-is-a-tex-token-list.md) το οποίο χρησιμοποιεί μια αναλογία για να οικοδομήσει τις έννοιες/ιδέες πίσω από μια λίστα tokens. Μια σε βάθος διερεύνηση των λιστών tokens του TeX και του πώς χρησιμοποιούνται στην επεξεργασία μακροεντολών, μπορεί να βρεθεί στη σειρά άρθρων του Overleaf [Πώς λειτουργούν πραγματικά οι μακροεντολές TeX;](/latex/el/perissotera-themata/01-a-six-part-series-how-do-tex-macros-actually-work.md)

#### Μια λίστα tokens σε γραφική μορφή

Το ακόλουθο γραφικό δείχνει μια λίστα tokens που δημιουργήθηκε από το LuaTeX με τις αντίστοιχες τιμές token που παράγονται από την ακόλουθη είσοδο

`Hi, \TeX! \hskip 5bp`

Για παράδειγμα, αν ορίσουμε `\mymacro` ως `\def\mymacro{Hi, \TeX! \hskip 5bp}` ο ορισμός του `\mymacro` θα αποθηκευόταν στη μνήμη χρησιμοποιώντας μια λίστα tokens όπως αυτή:

![](/files/68cfd1efa31c4033c0045e8a291f1fab8abac64b)

Η λίστα tokens είναι μια ακολουθία συνδεδεμένων στοιχείων που ονομάζονται *κόμβων*, το όνομα που δίνεται σε ένα μικρό τμήμα της μνήμης του LuaTeX που έχει δεσμευτεί για να κρατά κάθε στοιχείο της λίστας (όπως οι μεμονωμένοι κρίκοι μιας αλυσίδας). Κάθε κόμβος περιέχει μια ακέραια τιμή token και τη διεύθυνση μνήμης του *επόμενου* κόμβου στην αλυσίδα, σχηματίζοντας μια δομή δεδομένων που ονομάζεται [συνδεδεμένη λίστα](https://en.wikipedia.org/wiki/Linked_list). Ο τελευταίος κόμβος υποδεικνύει το τέλος της λίστας χρησιμοποιώντας μια ειδική «τιμή null» για τον επόμενο κόμβο—επειδή δεν υπάρχει επόμενος.

**Σημειώσεις:**

* Για λόγους ευκολίας, έχουμε συμπεριλάβει τη διεύθυνση κάθε μεμονωμένου κόμβου, αλλά στην πράξη αυτά τα δεδομένα δεν αποθηκεύονται μέσα στους κόμβους της λίστας tokens· μόνο η διεύθυνση του *επόμενος κόμβος* απαιτείται για τη δημιουργία λιστών tokens της μηχανής TeX.
* Η δεύτερη στήλη στο γραφικό με τίτλο «Τι σημαίνει κάθε token» δείχνει μια σειρά από γκρι πλαίσια που περιέχουν πληροφορίες για το token που περιέχεται σε κάθε κόμβο: αυτά είναι καθαρά πληροφοριακά και *δεν* δεν αποτελούν μέρος των πραγματικών δεδομένων που αποθηκεύονται στη λίστα tokens.

Ακολουθεί ένας πίνακας με τις τιμές token που περιέχονται στη λίστα tokens που απεικονίζεται παραπάνω:

|                      |                      |                                                                                          |                |
| -------------------- | -------------------- | ---------------------------------------------------------------------------------------- | -------------- |
| **Στοιχείο εισόδου** | **Τύπος εισόδου**    | <p><strong>Κωδικός κατηγορίας</strong><br><br><strong>(αν είναι χαρακτήρας)</strong></p> | **Τιμή token** |
| H                    | χαρακτήρα            | 11                                                                                       | 23068744       |
| i                    | χαρακτήρα            | 11                                                                                       | 23068777       |
| ,                    | χαρακτήρα            | 12                                                                                       | 25165868       |
|                      | χαρακτήρα            | 10                                                                                       | 20971552       |
| \TeX                 | εντολή (μακροεντολή) |                                                                                          | 536871539      |
| !                    | χαρακτήρα            | 12                                                                                       | 25165857       |
|                      | χαρακτήρα            | 10                                                                                       | 20971552       |
| \hskip               | εντολή (πρωτογενής)  |                                                                                          | 536874247      |
| 5                    | χαρακτήρα            | 12                                                                                       | 25165877       |
| b                    | χαρακτήρα            | 11                                                                                       | 23068770       |
| σ                    | χαρακτήρα            | 11                                                                                       | 23068784       |

**Σημείωση:** Το αρχικό κείμενο εισόδου μας έχει ένα α μετά την `\hskip` εντολή, αλλά δεν υπάρχει token που να αναπαριστά αυτόν τον χαρακτήρα στη λίστα tokens. Αυτός ο χαρακτήρας απορροφήθηκε από τη διαδικασία σάρωσης εισόδου (ανάγνωσης) του LuaTeX επειδή χρησιμοποιήθηκε για να τερματίσει την αναζήτηση του LuaTeX για χαρακτήρες που αποτελούν το `\hskip` εντολή.

## Πώς λειτουργεί πραγματικά το \directlua

Τώρα που εξερευνήσαμε τα tokens, τις λίστες tokens και τη μετατροπή tokens σε κείμενο, η επόμενη πρόκληση είναι να κατανοήσουμε τη σύλληψη του TeX engine για το token *επέκταση*.

Όπως σημειώθηκε, `\directlua{⟨code⟩}` μπορεί να ζητηθεί να επεξεργαστεί `⟨code⟩` που περιέχει τόσο κώδικα Lua όσο και TeX/LaTeX, αλλά ο ενσωματωμένος διερμηνέας της γλώσσας Lua του LuaTeX δεν καταλαβαίνει TeX ή LaTeX: πώς μπορεί λοιπόν αυτό να λειτουργεί; Πώς είναι δυνατόν το `⟨code⟩` να περιέχει οδηγίες TeX/LaTeX χωρίς να μπερδεύει εντελώς τον διερμηνέα Lua με εντολές που δεν καταλαβαίνει; Για παράδειγμα, η ακόλουθη `\directlua` εντολή χρησιμοποιεί μόνο μακροεντολές TeX, αλλά λειτουργεί:

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

Αυτό το `\directlua` εντολή έχει ως αποτέλεσμα το σελιδοθέτημα του LuaTeX `Hello` αλλά γιατί και πώς λειτουργεί αυτό, αφού η γλώσσα Lua δεν καταλαβαίνει μακροεντολές TeX;

Η απάντηση περιέχεται στην προηγούμενη περιγραφή που δανειστήκαμε από το [Εγχειρίδιο Αναφοράς LuaTeX](http://www.pragma-ade.com/general/manuals/luatex.pdf) αλλά μπορούμε να θεωρήσουμε ότι `\directlua{⟨code⟩}` λειτουργεί επειδή το LuaTeX αρχικά «προεπεξεργάζεται» το `⟨code⟩` πριν σταλεί οτιδήποτε στον διερμηνέα Lua. Η φύση αυτής της «προεπεξεργασίας»—δηλαδή τι πραγματικά σημαίνει και ποιες είναι οι συνέπειές της για το `⟨code⟩`—είναι το επόμενο θέμα που θα εξετάσουμε για να βοηθήσουμε τους αναγνώστες που ενδιαφέρονται να αξιοποιήσουν τη δύναμη και την ευελιξία του `\directlua`.

### Πώς το LuaTeX επεξεργάζεται το \directlua: Μια πρώτη ματιά

Για να εμβαθύνουμε στην κατανόησή μας του `\directlua`των δραστηριοτήτων «προεπεξεργασίας» του μπορούμε να ξεκινήσουμε με το ακόλουθο απλοποιημένο διάγραμμα που δίνει μια επισκόπηση του τι συμβαίνει. Το `⟨code⟩` παρέχεται στο `\directlua{⟨code⟩}` αρχικά μετατρέπεται σε tokens χρησιμοποιώντας τις διαδικασίες και τους υπολογισμούς που συζητήθηκαν παραπάνω· αυτή η ακολουθία tokens αποθηκεύεται σε μια λίστα tokens. Μόλις δημιουργηθεί αυτή η λίστα tokens, κάθε token σε αυτήν τη λίστα μετατρέπεται ξανά στην κειμενική του αναπαράσταση: το κείμενο που παράγεται από κάθε token—token χαρακτήρα ή token εντολής—συνδυάζεται (συγκολλάται) για να δημιουργηθεί μια ενιαία συμβολοσειρά κώδικα που δίνεται στον διερμηνέα Lua για εκτέλεση.

![](/files/8316d7995f8bd31bc3266ff2537c19f90e43239b)

Μα περιμένετε, ποιο θα ήταν το νόημα να περάσουμε από κείμενο σε tokens και να μετατρέψουμε αυτά τα tokens κατευθείαν πίσω σε κείμενο; Δεν θα σας εξέπληττε να μάθετε ότι, ναι, υπάρχει μια επιπλέον και ζωτική διαδικασία που δεν έχουμε συμπεριλάβει σε αυτό το γραφικό: *επέκταση των tokens*. Κάθε token που παράγεται από το κείμενο στο `⟨code⟩` υποβάλλεται σε ένα είδος «επιθεώρησης», κατά το οποίο το LuaTeX εφαρμόζει ένα τεστ για να δει αν αυτό το token αντιπροσωπεύει μια εντολή που ανήκει στο υποσύνολο γνωστό ως *εντολές που μπορούν να επεκταθούν*. Αν ναι, το LuaTeX φιλτράρει αυτή την εντολή με το να *την αφαίρεση* από το `⟨code⟩` και *αντικαθιστώντας το* με το/τα αποτέλεσμα/α ενός διαδικασίας που οι μηχανές TeX ονομάζουν *επέκταση των tokens*.

### Πώς το LuaTeX επεξεργάζεται το \directlua: Μια δεύτερη ματιά (στην επέκταση)

Ο μηχανισμός επέκτασης του TeX είναι ένα βασικό συστατικό όλων των μηχανών στοιχειοθεσίας που βασίζονται στο TeX, επειδή, τελικά, καθεμία τους προέρχεται από (ή βασίζεται στο) τον αρχικό πηγαίο κώδικα και τον σχεδιασμό του TeX του Knuth. Ωστόσο, η έννοια της επέκτασης είναι δύσκολο να εξηγηθεί με σύντομη αλλά προσιτή γλώσσα, επειδή, στην πράξη, η επέκταση είναι ένας «ομπρελοειδής» όρος που χρησιμοποιείται για να περιγράψει μια ενιαία διαδικασία—αλλά μία που παράγει μια σειρά από αποτελέσματα. Αυτά τα ποικίλα αποτελέσματα είναι συνέπεια του κάπως εκλεκτικού συνόλου εντολών στις οποίες μπορεί να εφαρμοστεί η επέκταση, οπότε μπορείτε να θεωρήσετε ότι κάθε επεκτάσιμη εντολή έχει μια ορισμένη «συμπεριφορά επέκτασης».

Ως *πρώτη προσέγγιση* για την κατανόηση της επέκτασης μπορούμε να πούμε ότι η επέκταση ενός token (εντολής) σημαίνει *την αφαίρεση* την αφαίρεση αυτής της εντολής (token) από την τρέχουσα είσοδο του TeX και *την αντικατάστασή* την αντικατάστασή της με μια ακολουθία tokens που προκύπτει από την εκτέλεση της συγκεκριμένης επεκτάσιμης εντολής—αντικαθιστώντας το αρχικό token με τα αποτελέσματα/τις συνέπειες της επέκτασής του *συμπεριφοράς*. Ωστόσο, αυτός ο αρχικός «ορισμός» της επέκτασης—με όρους παραγωγής νέων tokens για να τα διαβάσει το TeX—δεν είναι απολύτως ακριβής για όλες τις επεκτάσιμες εντολές, αλλά είναι αρκετά καλός ως αφετηρία.

Για να δώσουμε ένα απλό παράδειγμα: το πρωτόγονο TeX `\jobname` είναι επεκτάσιμη εντολή και το *επέκταση* της είναι μια ακολουθία tokens χαρακτήρων που αντιπροσωπεύουν το όνομα του κύριου αρχείου εισόδου TeX. Αν το TeX αποφασίσει να επεκτείνει μια `\jobname` εντολή (token) αυτή *αφαιρείται* από την τρέχουσα πηγή εισόδου του TeX και *αντικαθίσταται* από την ακολουθία tokens χαρακτήρων που δημιουργεί—την οποία το TeX στη συνέχεια προχωρά να διαβάσει/επεξεργαστεί.

Μέσα στο `\directlua`, αφού ένα επεκτάσιμο token επεξεργαστεί (αφαιρεθεί) και αντικατασταθεί από νέα tokens, το LuaTeX θα συνεχίσει να διαβάζει αυτά τα νέα tokens που μόλις έθεσε στη θέση του—αλλά μερικά από αυτά τα νέα tokens μπορεί επίσης να είναι επεκτάσιμα. Επειδή `\directlua` εκτελεί το λεγόμενο *πλήρη επέκταση*, το LuaTeX θα διαβάσει αυτά τα νέα tokens και, για άλλη μια φορά, θα περάσει από τη διαδικασία επέκτασης για να επεκτείνει (αφαιρέσει) οποιαδήποτε νέα (επεκτάσιμα) tokens—αυτή η διαδικασία επέκτασης συνεχίζεται μέχρι να μην απομένουν tokens που μπορούν να επεκταθούν. Ωστόσο, υπάρχουν δύο σημαντικές εξαιρέσεις σε αυτόν τον κανόνα «συνέχισε να επεκτείνεις», τις οποίες θα συζητήσουμε παρακάτω:

* χρησιμοποιώντας την κατασκευή `\the\toks`;
* σκόπιμη αποτροπή (καταστολή) της επέκτασης για ένα ή περισσότερα επιλεγμένα tokens.

Όπως σημειώθηκε, ο λειτουργικός μας ορισμός (πρώτη προσέγγιση) για την κατανόηση της επέκτασης δεν καλύπτει το πλήρες εύρος των συμπεριφορών επέκτασης που επιδεικνύει το υποσύνολο των επεκτάσιμων εντολών. Για παράδειγμα, ορισμένες επεκτάσιμες εντολές δεν παράγουν tokens με τον τρόπο που το `\jobname` το κάνει, αλλά μπορεί να:

* να «φιλτράρουν» tokens από την είσοδο: οι συνθήκες μιας μηχανής TeX (`\if`, `\ifcat`, `\ifnum`, `\ifdim`, `\ifodd`, `\ifvmode`, …) είναι επεκτάσιμες. Η συμπεριφορά επέκτασής τους είναι ένα είδος «φιλτραρίσματος tokens»—οι συνθήκες μπορούν να χρησιμοποιηθούν σε `\directlua`.
* να «ανακατεύουν» tokens στην είσοδο: το [`\expandafter` εντολή](/latex/el/se-vathos-arthra/03-a-six-part-article-series-on-expandafter-tex-tokens-and-expansion.md) είναι επεκτάσιμο και αλλάζει τη σειρά με την οποία δύο tokens επεκτείνονται.
* να αποτρέπουν την επέκταση: οι επεκτάσιμες εντολές `\noexpand` και `\unexpanded` καταστέλλουν την επέκταση των tokens εντολής στην είσοδο.
* να μετατρέπουν ακολουθίες χαρακτήρων στην είσοδο σε tokens εντολών: `\csname … \endcsname.`
* να μετατρέπουν εσωτερικές ποσότητες σε μια ακολουθία tokens χαρακτήρων: `\number` και `\the` είναι επεκτάσιμες εντολές που παράγουν μια ακολουθία tokens χαρακτήρων που αντιπροσωπεύουν την τιμή μιας εσωτερικής ποσότητας.
* να μετατρέπουν tokens εντολής σε tokens χαρακτήρων: `\string` και `\detokenize` είναι επεκτάσιμες εντολές που μετατρέπουν τα ορίσματά τους σε μια ακολουθία tokens χαρακτήρων με κωδικό κατηγορίας 12. Σημειώστε ότι `\detokenize` διαφέρει από το `\string`: `\detokenize` μπορεί να επεξεργαστεί πολλαπλά tokens και εισάγει έναν χαρακτήρα κενού, με κωδικό κατηγορίας 10, μετά την επεξεργασία tokens εντολής που δημιουργήθηκαν από το *λέξεις ελέγχου*. Στην πράξη, `\detokenize` προσθέτει έναν τελικό χαρακτήρα κενού μετά το όνομα της εντολής—θα δούμε μερικά παραδείγματα αργότερα στο άρθρο.

#### Βελτιώνοντας τον «ορισμό» μας για την επέκταση

Μπορούμε τώρα να γενικεύσουμε τον ορισμό μας λέγοντας ότι η επέκταση μιας εντολής (token) περιλαμβάνει *την αφαίρεση* αυτής της εντολής (token) από την τρέχουσα πηγή εισόδου του TeX και *αντικαθιστώντας το* την αντικατάστασή της με το αποτέλεσμα της *λειτουργίας tokens* που εκτελείται από αυτή την εντολή. Στην ουσία, η διαδικασία επέκτασης κάνει μια επεκτάσιμη εντολή να εκτελεί κάποιο είδος «λειτουργίας» πάνω σε tokens στην τρέχουσα είσοδο του TeX, η οποία επηρεάζει τον αριθμό ή τη συμπεριφορά των tokens που θα διαβάσει στη συνέχεια το TeX—η ακριβής φύση αυτής της «λειτουργίας» εξαρτάται από το ποια εντολή επεκτείνεται. Όλες οι μακροεντολές και οι ενεργοί χαρακτήρες είναι επεκτάσιμοι, αλλά μόνο ένας μικρός αριθμός των ενσωματωμένων εντολών (πρωτόγονων εντολών) μιας μηχανής TeX ταξινομούνται ως επεκτάσιμες—η λίστα των επεκτάσιμων εντολών εξαρτάται από τη μηχανή TeX που χρησιμοποιείτε.

Κάθε νέα μηχανή TeX κληρονομεί τις πρωτόγονες εντολές που είναι ενσωματωμένες στους προγόνους της—τη/τις μηχανή/ές TeX προηγούμενης γενιάς από τις οποίες προήλθε—και ορισμένες από αυτές τις κληρονομημένες πρωτόγονες εντολές θα είναι επεκτάσιμες. Φυσικά, μια νέα μηχανή TeX μπορεί να επιλέξει να μην υλοποιήσει ορισμένες από τις πρωτόγονες εντολές που περιέχονται στις προηγούμενες μηχανές ή να τροποποιήσει τη συμπεριφορά τους ώστε να ταιριάζει στις ανάγκες της νέας μηχανής. Επιπλέον, οι νέες μηχανές TeX συνήθως υλοποιούν πρόσθετες πρωτόγονες εντολές για να παρέχουν υποστήριξη για τη δική τους βελτιωμένη λειτουργικότητα—κάποιες από αυτές μπορεί επίσης να είναι επεκτάσιμες. Κατά συνέπεια, ο αριθμός των επεκτάσιμων εντολών που έχετε στη διάθεσή σας θα διαφέρει ανάλογα με τη μηχανή TeX που χρησιμοποιείτε—το LuaTeX διαθέτει αρκετές από αυτές.

Μια άλλη δυσκολία στην εξήγηση/κατανόηση της επέκτασης, και ίσως η πραγματική πρόκληση, είναι να γνωρίζουμε ακριβώς *πότε* μια μηχανή TeX πρόκειται, ή δεν πρόκειται, στην πραγματικότητα να εκτελέσει τη διαδικασία επέκτασης. Αυτό είναι ένα μεγάλο και σύνθετο θέμα, επειδή η επέκταση είναι βαθιά ενσωματωμένη σε όλη την εσωτερική λειτουργία των μηχανών TeX: δεν έχουμε χώρο να το εξετάσουμε με καμία λεπτομέρεια πέρα από τη χρήση της επέκτασης στο `\directlua`.

### Πώς το LuaTeX επεξεργάζεται το \directlua: Μια τελευταία ματιά

Το ακόλουθο διάγραμμα συνοψίζει τις `\directlua` δραστηριότητες προεπεξεργασίας που λαμβάνουν χώρα μέσα στην ίδια τη μηχανή LuaTeX. Σε αυτό το διάγραμμα δείχνουμε επίσης δύο χαμηλού επιπέδου (εσωτερικές) συναρτήσεις LuaTeX που κάνουν στην πραγματικότητα τη δουλειά: `scan_toks()` και `tokenlist_to_cstring()`. Αυτές οι συναρτήσεις είναι γραμμένες στη γλώσσα C και βρίσκονται βαθιά μέσα στο εκτελέσιμο λογισμικό LuaTeX: αποτελούν μέρος του εσωτερικού μηχανισμού του LuaTeX και δεν είναι *άμεσα* προσβάσιμες από τον κώδικα TeX/LaTeX σας.

![](/files/6e8a7b7c4949edd7d2435be6fcf8a3ee182cf75c)

Η ακόλουθη περιγραφή του `\directlua ⟨code⟩`της δραστηριότητας προεπεξεργασίας συνοψίζει το παραπάνω διάγραμμα.

1. Η ακολουθία χαρακτήρων στο ⟨code⟩ σας επεξεργάζεται από το `scan_toks()`. Σκοπός του είναι να διαβάσει το ⟨code⟩ σας χαρακτήρα προς χαρακτήρα για να δημιουργήσει tokens χαρακτήρων και tokens εντολών. Επειδή δημιουργεί tokens, ο κωδικός κατηγορίας που αντιστοιχίζεται σε κάθε χαρακτήρα στο ⟨code⟩, τη στιγμή που διαβάζεται, είναι εξαιρετικά σημαντικός.
2. Κατά τη διάρκεια της επεξεργασίας (δημιουργίας) tokens του `scan_toks()`κάθε επεκτάσιμη εντολή (token) επεκτείνεται *εκτός αν* αποτρέπεται μέσω εντολών όπως `\protected` (ορισμοί μακροεντολών), `\noexpand`, `\unexpanded` κ.λπ. Οι ενεργοί χαρακτήρες (κωδικός κατηγορίας 13) επίσης επεκτείνονται (εκτός αν αποτραπεί).
3. Η ροή των tokens που δημιουργείται από το `scan_toks()` ενσωματώνεται σε μια ενιαία μεγάλη λίστα tokens—τα tokens που υπάρχουν σε αυτή τη λίστα περιλαμβάνουν εκείνα που παράχθηκαν από την εφαρμογή επέκτασης σε επεκτάσιμες εντολές (όπως οι μακροεντολές) που υπάρχουν στο `⟨code⟩`. Σημειώστε επίσης ότι `scan_toks()` *δεν* ενεργοποιεί ή προκαλεί την εκτέλεση οποιουδήποτε token που αντιπροσωπεύει μη επεκτάσιμη εντολή: τέτοια μη επεκτάσιμα tokens απλώς περνούν μέσα και ενσωματώνονται στη λίστα tokens που κατασκευάζεται.
4. Μόλις η λίστα tokens ολοκληρωθεί και όλη η δραστηριότητα επέκτασης τελειώσει, αυτή η λίστα tokens επεξεργάζεται από μια άλλη συνάρτηση που ονομάζεται `tokenlist_to_cstring()` η οποία μετατρέπει κάθε token στην τελική λίστα tokens ξανά στην κειμενική του αναπαράσταση. Αυτό δημιουργεί μια συμβολοσειρά κειμένου που είναι ο κώδικας Lua που θα δοθεί στον διερμηνέα Lua. Για επιτυχή εκτέλεση, αυτή η συμβολοσειρά πρέπει να περιέχει συντακτικά σωστό κώδικα Lua.
5. Η επεξεργασία του Lua αυτού του κώδικα λαμβάνει χώρα σε δύο βήματα:
6. Ο ενσωματωμένος διερμηνέας Lua του LuaTeX αναλύει και «μεταγλωττίζει» τον κώδικα Lua που δημιουργήθηκε στα προηγούμενα βήματα. Αν αυτή η ανάλυση/μεταγλώττιση αποτύχει, ο διερμηνέας Lua θα δημιουργήσει σφάλματα (όπως σφάλματα σύνταξης)—αυτά τα σφάλματα μπορούν να προκαλέσουν αποτυχία της εκτέλεσης του LuaTeX, εκτός αν επιλέξατε να χρησιμοποιήσετε `--interaction=nonstopmode` στη γραμμή εντολών.
7. Αν η ανάλυση/μεταγλώττιση επιτύχει, ο διερμηνέας Lua εκτελεί τον κώδικα που μεταγλωττίστηκε στο βήμα (5a).

Στην ουσία, η `scan_toks()` συνάρτηση είναι ο πυρήνας των δραστηριοτήτων προεπεξεργασίας του LuaTeX: το κύριο έργο της είναι να επεκτείνει όλες τις επεκτάσιμες εντολές TeX/LaTeX που περιέχονται στο κείμενο του `⟨code⟩` και να κατασκευάσει μια λίστα tokens από ό,τι έχει επεξεργαστεί. Και πάλι, τονίζουμε ότι `scan_toks()` *δεν εκτελεί μη επεκτάσιμες εντολές* (tokens): απλώς *αποθηκεύει* αυτά τα tokens στη λίστα tokens που κατασκευάζει. Μόλις ολοκληρωθεί, αυτή η λίστα tokens στη συνέχεια μετατρέπεται *πίσω σε κειμενική αναπαράσταση* από το `tokenlist_to_cstring()`—μια λίστα tokens είναι μια έννοια αποκλειστικά του TeX, εντελώς ξένη σε έναν διερμηνέα Lua, εξ ου και η ανάγκη να μετατραπεί σε κείμενο, ώστε να γίνει κώδικας Lua για να περαστεί στον διερμηνέα Lua.

## Η επέκταση ως «διεπαφή» γλώσσας προγραμματισμού

Μπορείτε να θεωρήσετε το `\directlua`της διαδικασίας επέκτασης να χρησιμοποιείται ως μηχανισμό, ή διεπαφή, για τη μεταβίβαση δεδομένων/πληροφοριών από τον «Κόσμο του TeX» στον «Κόσμο του Lua»: παρέχοντας μια μέθοδο ώστε η γλώσσα TeX να επικοινωνεί δεδομένα στη γλώσσα Lua. Για παράδειγμα, κώδικας TeX όπως `\number\count75` μπορεί να χρησιμοποιηθεί για τη μεταφορά μιας τιμής από τον «Κόσμο του TeX» που είναι αποθηκευμένη στον καταχωρητή μετρητή 75 προς τη μεταβλητή ακέραιου x του «Κόσμου του Lua»:

```
\count75=1564 % Δεδομένα που υπάρχουν στον "Κόσμο του TeX"
\directlua{
   local x=\number\count75 \space % Μεταφορά δεδομένων TeX στον "Κόσμο του Lua"
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" και y = "..y)
}
```

Αυτό δημιουργεί τον κώδικα Lua

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

**Σημείωση**: Προσθέσαμε `<space>\space` μετά το `\number\count75` για να διασφαλίσουμε ότι διατηρήθηκε ένας χαρακτήρας κενού μεταξύ του `1564` και `tex.print`—αυτό δεν είναι αυστηρά απαραίτητο εδώ, επειδή η Lua θα αναλύσει σωστά τον κώδικα ακόμη κι αν το παραλείψουμε. Ο χαρακτήρας κενού αμέσως μετά το `\count75` απορροφάται κατά τη διαδικασία που χρησιμοποιούν οι μηχανές TeX για να αναζητήσουν αριθμητικές τιμές—εδώ, η τιμή που δίνεται στο `\count`. Ο χαρακτήρας κενού μετά το `75` χρησιμοποιείται για να τερματίσει την αναζήτηση του LuaTeX για ακολουθία ψηφίων `75` και απορροφάται από την είσοδο. Το `\space` μακροεντολή επεκτείνεται για να παρέχει τον χαρακτήρα κενού που χρειάζεται για να διαχωρίσει το κείμενο `1564` και `tex.print`.

Χρησιμοποιώντας τον παραπάνω κώδικα το LuaTeX θα στοιχειοθετήσει

`x= 1564 και y = 612.6`

Εδώ, ο μηχανισμός «μεταβίβασης δεδομένων» επιτυγχάνεται με το `\number`: μια επεκτάσιμη εντολή η οποία, σε αυτή την περίπτωση, δίνει εντολή στο TeX να ανακτήσει την τιμή που είναι αποθηκευμένη στο `\count` register `75` και από αυτή την τιμή (`1546`) να δημιουργήσει μια σειρά από tokens χαρακτήρων, ένα token χαρακτήρα για κάθε ψηφίο, με αποτέλεσμα μια ακολουθία tokens για τα ψηφία `1`, `5`, `6` και `4`. Αυτά τα 4 tokens χαρακτήρων ενσωματώνονται στη βασική λίστα tokens που κατασκευάζεται από το `\directlua` και στη συνέχεια μετατρέπονται ξανά στην κειμενική τους αναπαράσταση όταν η λίστα tokens μετατρέπεται σε κείμενο. Είναι αναμφίβολα μια πολύ έμμεση διαδρομή από την `\count75` τιμή του καταχωρητή που είναι αποθηκευμένη μέσα στο LuaTeX, στα ψηφία που προορίζονται για κώδικα Lua, αλλά, τελικά, λειτουργεί.

**ΣΥΜΒΟΥΛΗ:** Αν θέλετε να επιθεωρήσετε τα αποτελέσματα των δραστηριοτήτων επέκτασης του LuaTeX, μπορείτε να γράψετε κώδικα όπως αυτός:

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

Σε αυτό το παράδειγμα χρησιμοποιούμε τη μέθοδο των μακριών αγκυλών για να δημιουργήσουμε μια μεταβλητή συμβολοσειράς `foo` ο σκοπός της οποίας είναι να κρατήσει τη συμβολοσειρά κώδικα Lua που δημιουργείται από την επέκταση όλων όσων βρίσκονται μεταξύ `[[` και `]]`. Αυτή η συμβολοσειρά τυπώνεται στην κονσόλα μέσω της κλήσης της συνάρτησης Lua `print(foo)`.

Στο Overleaf μπορείτε να δείτε παρόμοια αποτελέσματα γράφοντας τα περιεχόμενα του `foo` στο `.log` αρχείου χρησιμοποιώντας τη συνάρτηση Lua του LuaTeX `texio.write()`:

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

## Tokens στη λίστα tokens του \directlua: μη επεκτάσιμα tokens και μη επεκταμένα tokens

Έχουμε σημειώσει ότι `\directlua{⟨code⟩}` εκτελεί *πλήρη επέκταση* του `⟨code⟩`: αφαιρεί και επεκτείνει όλες τις επεκτάσιμες εντολές μέχρι να μείνουν μόνο μη επεκτάσιμα tokens. Η ακολουθία tokens που δημιουργείται από την επεξεργασία του `\directlua`του (στη συνάρτηση `scan_toks()` ) συνδέονται μεταξύ τους για να σχηματίσουν μια λίστα tokens της οποίας τα επιμέρους tokens θα μετατραπούν ξανά σε κείμενο για να περαστούν στο Lua.

Ωστόσο, δεν έχουμε ακόμη αντιμετωπίσει το τελευταίο μέρος αυτής της ιστορίας, επειδή χρειάζεται να εξετάσουμε τις δύο «τάξεις» token εντολής που μπορούν να φτάσουν μέχρι τη λίστα tokens που κατασκευάζεται μέσα στο `\directlua`: θα τα αναφερόμαστε ως *σύντομα tokens εντολών* και *μη επεκταμένα* tokens:

* **σύντομα tokens εντολών**: Αυτός ο τύπος token εντολής προκύπτει από ακολουθίες ελέγχου που ορίζονται χρησιμοποιώντας ένα από τα πρωτόγονα TeX `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` και `\toksdef`. Αυτές οι πρωτόγονες εντολές χρησιμοποιούνται για να ορίσουν ακολουθίες ελέγχου που αντιπροσωπεύουν μια αριθμητική τιμή—οι προκύπτουσες ακολουθίες ελέγχου είναι *όχι* επεκτάσιμες.
* **μη επεκταμένα tokens**: Αυτός ο τύπος token προκύπτει από εντολές που κανονικά θα επεκτείνονταν αλλά `\directlua` έχει είτε:
* δοθεί ρητή εντολή *όχι* να τις επεκτείνει· για παράδειγμα, καταστολή της επέκτασης από τις εντολές `\noexpand` ή `\unexpanded`—θα εξηγήσουμε σύντομα πώς γίνεται αυτό·
* tokens που έχουν εισαχθεί με την επεξεργασία της ακολουθίας `\the\toks` (περισσότερα γι' αυτό παρακάτω).

### Δύο «ομάδες» token σε μια λίστα tokens του \directlua

Με βάση τις συζητήσεις μας, μπορούμε να πούμε ότι τα tokens που περιέχονται στη λίστα tokens που κατασκευάζεται κατά το πρώτο στάδιο της `\directlua`της προεπεξεργασίας του `scan_toks()` συνάρτησης εμπίπτουν σε δύο ομάδες:

1. *εγγενώς μη επεκτάσιμα* tokens

* οποιοδήποτε token που αντιπροσωπεύει μη ενεργό *χαρακτήρα*;
* οποιοδήποτε token που αντιπροσωπεύει μη επεκτάσιμη *πρωτόγονη* *εντολή*;
* οποιοδήποτε token που αντιπροσωπεύει μια *σύντομη εντολή* (αυτές δεν είναι επεκτάσιμες, βλ. παρακάτω).

3. *μη επεκταμένα* tokens:

* οποιοδήποτε token που αντιπροσωπεύει μια επεκτάσιμη εντολή της οποίας η επέκταση ήταν *κατασταλμένη* (ή αποφεύχθηκε) κατά την `\directlua`προεπεξεργασία του

#### Tokens σύντομων εντολών: δημιουργία μη επεκτάσιμων εντολών

Όπως σημειώθηκε, οι μηχανές TeX παρέχουν ένα σύνολο πρωτόγονων εντολών (ενσωματωμένων εντολών) που μπορούν να χρησιμοποιηθούν για τη δημιουργία *μη επεκτάσιμων* ακολουθιών ελέγχου (που υποδεικνύονται εδώ με `⟨command⟩`). Αυτές οι πρωτόγονες παίρνουν τη μορφή:

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

όπου `⟨numeric value⟩` είναι κάποια ακέραια τιμή κατάλληλη για κάθε εντολή.

Εδώ, θα επανεξετάσουμε σύντομα τη χρήση του `\chardef` για να δείξουμε το βασικό χαρακτηριστικό αυτών των πρωτόγονων εντολών—την παραγωγή μιας `⟨command⟩` που δεν είναι επεκτάσιμη. Μπορείτε να χρησιμοποιήσετε ``\chardef\mydollar=`\$`` για να δημιουργήσετε την ακολουθία ελέγχου `\mydollar` και να τη χρησιμοποιήσετε για να στοιχειοθετήσετε ένα `$`:

`Πλήρωσα \mydollar30.`

Αυτό θα στοιχειοθετήσει `Πλήρωσα $30.` Η ακολουθία ελέγχου `\mydollar` που δημιουργείται από το `\chardef` δεν είναι επεκτάσιμη, όπως βλέπουμε από το ακόλουθο παράδειγμα:

```
\chardef\mydollar=`\$
\directlua{
   local x =[[Πλήρωσα \mydollar30.]]
   texio.write(x)
}
```

Το οποίο παράγει το ακόλουθο κείμενο στο `.log` αρχείο

`Πλήρωσα \mydollar 30.`

Αυτό δείχνει `\mydollar` ήταν *όχι* επεκτάθηκε κατά την `\directlua`της προεπεξεργασίας του `\mydollar` Το διάστημα που εμφανίζεται μετά το

Όταν χρησιμοποιείτε `\chardef` για να δημιουργήσετε μια ακολουθία ελέγχου, η εσωτερική ταξινόμηση του TeX για αυτή την ακολουθία ελέγχου (εντολή) έχει ως αποτέλεσμα να είναι *μη επεκτάσιμων* το οποίο είναι πολύ διαφορετική συμπεριφορά σε σύγκριση με ακολουθίες ελέγχου που ορίζονται από μία από τις εντολές ορισμού μακροεντολών: \def, \edef, \gdef ή \xdef. Όπως σημειώθηκε παραπάνω, κατά τη διαδικασία κατασκευής της λίστας tokens του `\directlua` εξετάζει κάθε εισερχόμενο token εντολής για να ελέγξει αν είναι επεκτάσιμο. Αν ένα token εντολής δεν είναι επεκτάσιμο, περνάει κατευθείαν στη λίστα tokens και η κειμενική του αναπαράσταση θα επανεμφανιστεί αργότερα στη συμβολοσειρά του κώδικα Lua που προκύπτει από τη μετατροπή των tokens της λίστας tokens ξανά στην κειμενική τους μορφή.

**Σύντομες σημειώσεις για το plain TeX έναντι του LaTeX**

Ιστορικά, το αρχικό plain TeX του Knuth όρισε τα κοινώς χρησιμοποιούμενα σύμβολα ελέγχου `\%`, `\&`, `\#` και `\$` χρησιμοποιώντας `\chardef`—όχι χρησιμοποιώντας μία από τις τυπικές εντολές ορισμού μακροεντολών `\def`, `\edef`, `\gdef` ή `\xdef`. Για παράδειγμα:

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

Η παράξενη `` `\ `` σύνταξη είναι μια μέθοδος του TeX για να πάρει την αριθμητική τιμή του κωδικού χαρακτήρα. Στο παλιό καθεστώς του plain TeX, αυτά τα σύμβολα ελέγχου δεν είναι επεκτάσιμα (λόγω του `\chardef`) αλλά το LaTeX (ή πακέτα) μπορεί να τα επαναορίσει ως *μακροεντολές* για να παρέχει βελτιωμένη λειτουργικότητα—κάτι που θα τα καθιστούσε επεκτάσιμα, οπότε ίσως χρειαστεί να το γνωρίζετε.

**Πώς επηρεάζει αυτό το \directlua;**

Ας συγκρίνουμε το αποτέλεσμα του ακόλουθου κώδικα όταν εκτελείται υπό plain TeX και LaTeX. Για απλότητα θα γράψουμε τα αποτελέσματα στο `.log` αρχείο χρησιμοποιώντας τη συνάρτηση Lua API του LuaTeX `texio.write()`.

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

Εκτελώντας αυτόν τον κώδικα χρησιμοποιώντας **plain TeX** παράγει το ακόλουθο αποτέλεσμα στο `.log` αρχείο, δείχνοντας το αποτέλεσμα τυχόν επεκτάσεων:

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

Προφανώς, υπό plain TeX κανένα από τα σύμβολα ελέγχου`\$`, `\#`, `\%` ή `\&` δεν επεκτάθηκε—επειδή όλα δημιουργούνται χρησιμοποιώντας `\chardef`.

Εκτελώντας αυτόν τον κώδικα χρησιμοποιώντας το **LaTeX** έγγραφο:

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

παράγει το ακόλουθο αποτέλεσμα στο `.log` αρχείο

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

Προφανώς, η εκτέλεση του LaTeX παράγει διαφορετικό αποτέλεσμα από το plain TeX επειδή υπό το LaTeX η εντολή `\$` έχει επεκταθεί, υποδεικνύοντας ότι είναι μακροεντολή.

**Σημείωση:** Και στο plain TeX και στο LaTeX `\directlua` δεν επεξεργάστηκε πλήρως κανένα από τα σύμβολα ελέγχου `\%`, `\&`, `\#` και `\$` για να δημιουργήσει τον αντίστοιχο χαρακτήρα. Κατά τη διαδικασία επέκτασης που εκτελείται από το `\directlua` τα tokens που αντιπροσωπεύουν αυτά τα σύμβολα ελέγχου—ή, για το LaTeX, η επέκτασή τους—περνούν κατευθείαν στη βασική λίστα tokens που κατασκευάζεται.

**Σημείωση:** Τα σύμβολα ελέγχου σχηματίζονται από έναν μόνο χαρακτήρα που δεν ανήκει στον κωδικό κατηγορίας 11, όπως `\#`. Όταν ένα token που αντιπροσωπεύει ένα σύμβολο ελέγχου μετατρέπεται ξανά στην κειμενική του αναπαράσταση, οι μηχανές TeX δεν εισάγουν χαρακτήρα κενού μετά από αυτό το κείμενο. Αυτή η ειδική μεταχείριση των συμβόλων ελέγχου είναι ένας ενσωματωμένος κανόνας για τον τρόπο λειτουργίας των μηχανών TeX.

### Μη επεκταμένα tokens: καταστολή της επέκτασης

`\directlua`Η προεπεξεργασία του είναι ένα παράδειγμα όπου μια μηχανή TeX εκτελεί επέκταση, αλλά ίσως να θέλετε να *αποτρέψετε* την εφαρμογή της επέκτασης σε ένα ή περισσότερα διακριτικά που διαφορετικά θα επεκτείνονταν. Ως άλλο παράδειγμα, το LuaTeX (και όλες οι μηχανές TeX) εκτελούν μια διαδικασία επέκτασης, παρόμοια με εκείνη του `\directlua`, όταν επεξεργάζονται το `\write` εντολή:

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

\write δίνει εντολή σε μια μηχανή TeX να εξαγάγει `⟨material⟩`—συχνά περιέχοντας εντολές TeX/LaTeX— σε ένα αρχείο κειμένου (`file-number`); οποιεσδήποτε επεκτάσιμες εντολές μέσα στο `⟨material⟩` θα, εκτός αν αποτραπεί, επεκταθούν πριν `⟨material⟩` γραφούν πραγματικά σε αυτό το αρχείο.

Όπως ίσως θα περιμένατε, οι μηχανές TeX παρέχουν εντολές για την καταστολή ή τον έλεγχο της επέκτασης:

* `\noexpand⟨token⟩`: αποτρέπει την επέκταση του μεμονωμένου `⟨token⟩`;
* `\unexpanded{⟨material⟩}`: αποτρέπει την επέκταση όλων των επεκτάσιμων εντολών (διακριτικών) στο `⟨material⟩`. Στην ουσία, είναι μια εκδοχή πολλαπλών διακριτικών του `\noexpand`;
* `\protected`: ένα πρόθεμα που προστίθεται στους ορισμούς μακροεντολών και αποτρέπει την επέκταση εκείνης της μακροεντολής σε ορισμένες περιστάσεις (όπως κατά τη διάρκεια `\directlua`, `\write` ή `\edef`).

Παρά τα ονόματα που υποδηλώνουν το αντίθετο, και τα δύο `\noexpand` και `\unexpanded` είστε *εντολές που μπορούν να επεκταθούν* και αποτελούν καλά παραδείγματα του να βλέπουμε τη διαδικασία επέκτασης μιας μηχανής TeX ως εκτέλεση «πράξεων πάνω σε διακριτικά»: η πράξη εδώ είναι η αποτροπή της επέκτασης ενός ή περισσότερων επόμενων διακριτικών (εντολών). Επειδή `\noexpand` και `\unexpanded` και τα δύο είναι επεκτάσιμες εντολές, αφαιρούνται και επεξεργάζονται (εκτελούνται) κατά τη `\directlua`προεπεξεργασία του, καθώς κατασκευάζει τη λίστα διακριτικών από το `⟨code⟩`.

#### \noexpand ⟨token⟩

`\noexpand ⟨token⟩` αποτρέπει την επέκταση του μεμονωμένου `⟨token⟩`. `\noexpand` μέσα σε `\directlua` θα επεκταθεί (θα αφαιρεθεί από την είσοδο) και θα αντικατασταθεί από τα αποτελέσματα της «συμπεριφοράς επέκτασής» του. Το αποτέλεσμα της επέκτασης του `\noexpand` είναι η δημιουργία ενός ειδικού (κρυφού) `⟨marker token⟩` που τοποθετείται μπροστά από το αρχικό `⟨token⟩` του οποίου η επέκταση πρόκειται να κατασταλεί: αυτό `⟨marker token⟩` λειτουργεί ως σημαία που λέει «μην επεκτείνεις το επόμενο διακριτικό». Επειδή `\directlua` εκτελεί πλήρη επέκταση, θα επανεπεξεργαστεί οποιαδήποτε διακριτικά προκύπτουν από τη «συμπεριφορά επέκτασης» μιας επεκτάσιμης εντολής. Κατά συνέπεια, όταν η επέκταση του `\noexpand ⟨token⟩` ολοκληρωθεί, το LuaTeX επιστρέφει για να διαβάσει τα αποτελέσματα και βλέπει την ακολουθία δύο διακριτικών `⟨marker token⟩⟨token⟩` η οποία προκαλεί το αρχικό `⟨token⟩` να περάσει, χωρίς επέκταση, στη λίστα διακριτικών που κατασκευάζεται από το `\directlua`.

**Παράδειγμα**

Αν γράψουμε

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

το `\TeX` μακροεντολή επεκτείνεται στα συστατικά της διακριτικά τα οποία, στο plain TeX, θα οδηγήσουν στην παρακάτω κειμενική μορφή που θα περάσει στη Lua (σημείωση: η Lua δεν μπορεί να επεξεργαστεί αυτόν τον κώδικα, είναι απλώς ένα παράδειγμα για να επιδείξει τη διαδικασία):

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

Αν *καταστείλουμε* την επέκταση της `\TeX` μακροεντολής χρησιμοποιώντας `\noexpand`

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

ο παρακάτω κώδικας Lua παράγεται (και πάλι, η Lua δεν μπορεί να εκτελέσει αυτόν τον κώδικα· είναι απλώς ένα παράδειγμα για να δείξει `\noexpand`):

`local x= "\TeX "`

Λόγω του `\noexpand`, `\directlua` δεν θα επεκτείνει `\TeX` αλλά απλώς θα επιτρέψει στη τιμή του διακριτικού που αντιπροσωπεύει την `\TeX` εντολή να περάσει ανέπαφη, στη λίστα διακριτικών που κατασκευάζεται κατά το πρώτο στάδιο της `\directlua`προεπεξεργασία του

**Σημείωση:** Ο χαρακτήρας κενού που εμφανίζεται μετά το `\TeX` εισάγεται από τη μεταγενέστερη μετατροπή του LuaTeX του `\TeX` ακέραιου διακριτικού nalue πίσω στην κειμενική του αναπαράσταση (μέσα στη `tokenlist_to_cstring()` συνάρτηση).

#### \unexpanded{⟨material⟩}

`\unexpanded` είναι επεκτάσιμη εντολή που καταστέλλει την επέκταση όλων των διακριτικών που σχηματίζονται από το `⟨material⟩`. Όπως έχουμε σημειώσει, όταν μια μηχανή TeX εκτελεί επέκταση, οποιαδήποτε επεκτάσιμη εντολή *αφαιρείται* αφαιρείται από την είσοδο και *αντικαθίσταται* αντικαθίσταται από τα αποτελέσματα της «συμπεριφοράς επέκτασής» της· τι σημαίνει όμως αυτό στην πράξη για `\unexpanded`; Συνήθως, κατά τη διάρκεια *πλήρη επέκταση*, μόλις ολοκληρωθεί η διαδικασία επέκτασης για μια συγκεκριμένη εντολή, η μηχανή TeX συνεχίζει να διαβάζει/επεξεργάζεται οποιαδήποτε διακριτικά προκύπτουν από τη «συμπεριφορά επέκτασης» της εντολής αυτής—πρέπει να επεκτείνει περαιτέρω τα διακριτικά που παράχθηκαν. Ωστόσο, `\unexpanded` *παρακάμπτει* οποιαδήποτε περαιτέρω επέκταση: να πώς το κάνει.

Μέσα στη μηχανή TeX, η `\unexpanded` συνάρτηση πρώτα μετατρέπει τους χαρακτήρες και τις εντολές στο `⟨material⟩` σε μια προσωρινή λίστα διακριτικών που αποτελείται από *μη επεκταμένα* διακριτικά. Αφού δημιουργηθούν και αποθηκευτούν όλα τα διακριτικά σε εκείνη την προσωρινή λίστα διακριτικών, η `\unexpanded` εντολή προκαλεί την `\directlua` σε *παράλειψη* του να επιστρέψει για να τα διαβάσει και να τα επεξεργαστεί—παρόλο που το \directlua εκτελεί πλήρη επέκταση. Αντίθετα, εκείνα τα *μη επεκταμένα* διακριτικά περνούν απευθείας και ενσωματώνονται στην κύρια λίστα διακριτικών που κατασκευάζεται από το `\directlua` (στη `scan_toks()` συνάρτηση). Με αυτόν τον τρόπο, τα πάντα στο `⟨material⟩` μετατρέπονται σε διακριτικά και η διαδικασία επέκτασης παραλείπεται για εκείνο το σύνολο διακριτικών. Η λειτουργία του `\unexpanded{⟨material⟩}` είναι παρόμοια με τη χρήση του `\the\toks`, το οποίο συζητούμε παρακάτω.

**Παράδειγμα**

`\unexpanded` παράγει αποτελέσματα με τρόπο παρόμοιο με το `\noexpand` εκτός από το ότι μπορεί να αποτρέψει την επέκταση πολλών διακριτικών· εδώ είναι ένα παράδειγμα:

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

που παράγει το ακόλουθο κείμενο ως κώδικα για τη Lua:

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

**Σημείωση**: Υπάρχουν χαρακτήρες κενού μετά από κάθε όνομα εντολής. Και αυτό είναι και πάλι συνέπεια της μεταγενέστερης μετατροπής από το LuaTeX των μη επεκταμένων διακριτικών `\foo`, `\bar` και `\foobar` πίσω σε κείμενο μέσα στη `tokenlist_to_cstring()` συνάρτηση.

#### \protected ορισμοί μακροεντολών

Η `\protected` η εντολή είναι ένα πρόθεμα που εφαρμόζεται σε έναν ορισμό μακροεντολής για να αποτρέψει την επέκταση εκείνης της μακροεντολής όταν το TeX κατασκευάζει μια επεκταμένη λίστα διακριτικών, όπως η λίστα διακριτικών που κατασκευάζεται από το `\directlua`προεπεξεργασία του

**Παράδειγμα**

Ας υποθέσουμε ότι ορίζετε τις ακόλουθες μακροεντολές με και χωρίς τη χρήση του `\protected` προθέματος:

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

Αν χρησιμοποιήσετε τον τελεστή συνένωσης συμβολοσειρών της Lua (`..`) για να γράψετε

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

`\directlua`η προεπεξεργασία του θα παρήγαγε τον ακόλουθο κώδικα για πέρασμα στη Lua:

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

`\macroA` δεν έχει οριστεί με τη χρήση του `\protected` οπότε επεκτείνεται, παράγοντας το πρώτο μέρος της συμβολοσειράς που θα συνενωθεί, αλλά `\macroB` έχει οριστεί με τη χρήση του `\protected` οπότε δεν έχει επεκταθεί.

Κατά την προεπεξεργασία, η `scan_toks()` συνάρτηση δημιούργησε ένα διακριτικό για το `\macroA`, αναγνώρισε ότι ήταν μια συνηθισμένη επεκτάσιμη εντολή και την επεκτάθηκε: εκείνη η επέκταση παράγει μια ακολουθία διακριτικών χαρακτήρων, ένα διακριτικό χαρακτήρα για κάθε χαρακτήρα στο `"This unprotected macro contains a string"`. Κάθε διακριτικό χαρακτήρα μεταβιβάζεται και προστίθεται στη λίστα διακριτικών που κατασκευάζεται.

Όταν `scan_toks()` δημιουργεί το διακριτικό για το `\macroB` παρατηρεί ότι εκείνη η εντολή είχε οριστεί ως `\protected` και δεν την επεκτείνει: το διακριτικό που αντιπροσωπεύει το `\macroB` περνά ανέπαφο (χωρίς επέκταση) στη λίστα διακριτικών που κατασκευάζεται. Αφού κατασκευαστεί εκείνη η λίστα διακριτικών, το επόμενο στάδιο της προεπεξεργασίας, μέσα στη `tokenlist_to_cstring()` συνάρτηση, είναι να μετατρέψει όλα τα διακριτικά της λίστας διακριτικών πίσω στην κειμενική τους αναπαράσταση. Το μη επεκταμένο διακριτικό που αντιπροσωπεύει το `\macroB` ανιχνεύεται και μετατρέπεται στην κειμενική του αναπαράσταση, με αποτέλεσμα το κείμενο `\macroB` να εμφανίζεται στον κώδικα που προορίζεται για τη Lua. Σημειώστε ότι η Lua στην πραγματικότητα δεν μπορεί να συνενώσει `"This unprotected macro contains a string"..\macroB` για να παράγει την τελική συμβολοσειρά επειδή `\macroB` δεν έχει νόημα στη σύνταξη της Lua, με αποτέλεσμα το σφάλμα `unexpected symbol near '\'`.

**Πληροφοριακά**: Το `\protected` η εντολή εισήχθη από το $$\varepsilon\text{-}\mathrm{\TeX}$$, την πρώτη σημαντική επέκταση του αρχικού λογισμικού TeX του Knuth, και υποστηρίζεται από όλες τις μηχανές TeX των οποίων η καταγωγή κώδικα περιλαμβάνει το $$\varepsilon\text{-}\mathrm{\TeX}$$.

### Μη επεκταμένα διακριτικά: Χρήση του \the\toks στο \directlua

Η ζωή στον προγραμματισμό δεν θα ήταν η ίδια χωρίς εκείνες τις «ειδικές περιπτώσεις» που πρέπει να αντιμετωπίζουμε και η χρήση του `\the` σε συνδυασμό με `\toks` σε μια `\directlua` εντολή είναι μία τέτοια ειδική περίπτωση.

#### Σύντομο υπόβαθρο για το \toks

Η πρωτόγονη εντολή του TeX `\toks` δίνει εντολή σε μια μηχανή TeX να αποθηκεύσει κάποια διακριτικά για χρήση αργότερα: αντί να μεταβιβαστούν για περαιτέρω επεξεργασία, αυτά τα διακριτικά παραμερίζονται και αποθηκεύονται σε μια θέση μνήμης που ορίζεται χρησιμοποιώντας ένα *μητρώο διακριτικών*. Για παράδειγμα, μπορούμε να πούμε σε μια μηχανή TeX να δημιουργήσει κάποια διακριτικά και να τα αποθηκεύσει στη θέση μητρώου διακριτικών `100` χρησιμοποιώντας

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

Εδώ, το TeX χρησιμοποιεί το μητρώο διακριτικών `100` για να αποκτήσει πρόσβαση σε μια γνωστή θέση μέσα στη μνήμη του: μια περιοχή αποθήκευσης που προορίζεται για τη φύλαξη λιστών διακριτικών.

Τα διακριτικά που αντιπροσωπεύουν οτιδήποτε ανάμεσα στο `{` και `}` δημιουργούνται, *αλλά δεν επεκτείνονται*, και συνδέονται σε μια λίστα διακριτικών—παρόμοια με τη λίστα διακριτικών που εξετάσαμε νωρίτερα σε αυτό το άρθρο. Για να επαναχρησιμοποιήσουμε εκείνα τα διακριτικά, θα γράφαμε `\the\toks100` όπου `\the` (μια επεκτάσιμη εντολή) δίνει εντολή στο TeX να ανακτήσει τα αποθηκευμένα διακριτικά και να τα εισαγάγει στη θέση όπου γράψατε `\the\toks100`. Ένας άλλος τρόπος να το σκεφτείτε είναι ότι το `\the\toks` προκαλεί το TeX να εισαγάγει κάποια διακριτικά σε εκείνη τη θέση.

Η `\toks` εντολή *δεν επεκτείνει* κανένα από τα διακριτικά που του ζητείται να δημιουργήσει και να αποθηκεύσει: απλώς μετατρέπει χαρακτήρες και εντολές ανάμεσα στο `{` και `}` σε διακριτικά και τα αποθηκεύει.

#### Πίσω στο \directlua

Στη συζήτηση για την επέκταση σημειώσαμε `\directlua{⟨code⟩}` εκτελεί *πλήρη επέκταση* του `⟨code⟩`: την αφαίρεση όλων των επεκτάσιμων εντολών και την αντικατάστασή τους με το αποτέλεσμα της συμπεριφοράς επέκτασής τους—συνεχίζοντας να *επεκτείνει περαιτέρω* οποιαδήποτε διακριτικά προκύπτουν από την αρχική επέκταση μιας επεκτάσιμης εντολής.

`\the` είναι επεκτάσιμη εντολή, οπότε το `\directlua` θα το επεκτείνει· ωστόσο, όταν `\the` χρησιμοποιείται σε συνδυασμό με το `\toks` μέσα σε `\directlua`, όπως στο `\the\toks⟨token register⟩`, τα εισαγόμενα διακριτικά *δεν επεκτείνονται περαιτέρω*. Η επέκταση του `\the\toks⟨token register⟩` εισάγει την ακολουθία των *μη επεκταμένα* διακριτικών, αποθηκευμένων στο `⟨token register⟩`, απευθείας στη λίστα διακριτικών που κατασκευάζεται από το `\directlua`: αυτή η συμπεριφορά παρακάμπτει τη συνήθη διαδικασία πλήρους επέκτασης. Στην πράξη, αυτά τα διακριτικά περνούν, *μη επεκταμένα*, για να ενσωματωθούν στην κύρια λίστα διακριτικών που κατασκευάζεται από το `\directlua`—αυτή η διαδικασία διέλευσης για μη επεκταμένα διακριτικά είναι παρόμοια στη λειτουργία με `\unexpanded`, όπως συζητήθηκε νωρίτερα.

**Παράδειγμα**

Ας υποθέσουμε ότι ορίζουμε τη μακροεντολή `\mymacro` ως `\def\mymacro{\TeX}`. Περιέχει μόνο ένα διακριτικό για την `\TeX` εντολή (η οποία είναι μακροεντολή): άρα έχουμε μια επεκτάσιμη εντολή `\mymacro` που περιέχει μια άλλη μακροεντολή `\TeX`, η οποία είναι επίσης επεκτάσιμη.

Ο ακόλουθος κώδικας θα έχει ως αποτέλεσμα η Lua να προσπαθήσει να δημιουργήσει μια μεταβλητή συμβολοσειράς `x`:

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

Μέσα στο \\`directlua`, το διακριτικό για το `\mymacro` επεκτείνεται, αλλά αυτό καταλήγει σε ένα άλλο επεκτάσιμο διακριτικό, `\TeX`, το οποίο επεκτείνεται περαιτέρω. Στο plain TeX, αυτές οι επεκτάσεις καταλήγουν στο ακόλουθο κείμενο που περνά στη Lua:

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

Αυτός ο κώδικας προσπαθεί να ορίσει μια συμβολοσειρά που περιέχει κείμενο το οποίο αντιπροσωπεύει την επεκταμένη έκδοση της `\TeX` μακροεντολής. Αν προσπαθήσετε να εκτελέσετε αυτό το παράδειγμα, η Lua θα επιχειρήσει να κατασκευάσει εκείνη τη συμβολοσειρά αλλά θα αποτύχει, δημιουργώντας ένα σφάλμα:

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

Αργότερα σε αυτό το άρθρο θα εξερευνήσουμε το νόημα της «μη έγκυρης ακολουθίας διαφυγής».

Ας αντιπαραβάλουμε τώρα τη χρήση του `\mymacro` με την τοποθέτηση του `\TeX` διακριτικού μέσα σε μια λίστα διακριτικών που παράγεται από ένα `\toks` εντολή:

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

του LuaTeX η `\directlua` επεξεργασία θα παράγει αυτή τη συμβολοσειρά κειμένου για τη Lua:

`local x = "\TeX "`

Ο χαρακτήρας κενού μετά το `\TeX` παράγεται από τη διαδικασία μετατροπής εντολής-διακριτικού-σε-συμβολοσειρά του LuaTeX.

**Αλλά σημειώστε ότι η**: Το `\TeX` μακροεντολή έχει *όχι* επεκταθεί στα συστατικά της διακριτικά. `\the\toks100` προκάλεσε την εισαγωγή των διακριτικών που είναι αποθηκευμένα στο μητρώο 100, αλλά αυτό είναι όλο: αυτά *όχι* δεν επεκτείνονται περαιτέρω και ενσωματώνονται στην κύρια λίστα διακριτικών που κατασκευάζεται από το `\directlua` (μέσα στη συνάρτηση `scan_toks()`). Η τοποθέτηση διακριτικών σε μια λίστα διακριτικών που δημιουργείται από `\toks` είναι ακόμη ένας τρόπος για να αποτρέψουμε την επέκταση των διακριτικών.

Αν εκτελέσουμε αυτό το παράδειγμα, παράγει κι αυτό σφάλμα:

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

Εξετάζουμε αργότερα στο άρθρο τις ακολουθίες διαφυγής της Lua.

## Άλλες εντολές/τεχνικές που χρησιμοποιούνται στην επέκταση

Σε αυτή την ενότητα εξετάζουμε μερικές επιπλέον εντολές/μεθόδους του TeX που μπορεί να είναι χρήσιμες σε καταστάσεις όπου εφαρμόζεται επέκταση (όπως μέσα στο `\directlua`).

### \string ⟨token⟩

`\string` είναι μια επεκτάσιμη εντολή που μετατρέπει το ⟨token⟩ σε μια σειρά διακριτικών χαρακτήρων, καθένα με κωδικό κατηγορίας 12.

Για παράδειγμα, `\string\TeX` θα παρήγαγε μια σειρά από 4 διακριτικά χαρακτήρων `\`, `T`, `e` και `X` όπου σε κάθε χαρακτήρα αποδίδεται κωδικός κατηγορίας 12 (συμπεριλαμβανομένου του αρχικού `\` χαρακτήρα).

Αν γράψουμε

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

το `\string` η εντολή θα επεκταθεί, με αποτέλεσμα μια ακολουθία διακριτικών χαρακτήρων με κωδικό κατηγορίας 12. Αφού `\string` επεκταθεί, τα προκύπτοντα διακριτικά χαρακτήρων (που αντιπροσωπεύουν κάθε χαρακτήρα στο `\newcommand`) θα ενσωματωθούν στην κύρια λίστα διακριτικών που κατασκευάζεται από το `\directlua`. Μόλις το `\directlua` ολοκληρώσει την κατασκευή της κύριας λίστας διακριτικών του, τα συστατικά του διακριτικά μετατρέπονται πίσω στην κειμενική τους αναπαράσταση, κάτι που παράγει τον ακόλουθο κώδικα για μετάδοση στον διερμηνευτή Lua:

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

Όταν αυτός ο κώδικας περάσει στη Lua, `print(x)` θα εμφανίσει τη συμβολοσειρά `x` στην οθόνη (κονσόλα). Ωστόσο, ήμασταν λίγο πονηροί και χρησιμοποιήσαμε σκόπιμα ένα παράδειγμα εντολής που ξεκινά με `\n`. Αν μπορείτε να εκτελέσετε αυτό το παράδειγμα σε τοπική εγκατάσταση TeX, θα παρατηρήσετε ότι η Lua εκτυπώνει το ακόλουθο κείμενο στην οθόνη:

```
   I will use
   ewcommand
```

Για να εκτελέσετε αυτόν τον κώδικα στο Overleaf μπορείτε να δώσετε εντολή στο LuaTeX να γράψει απευθείας στο `.log` αρχείο χρησιμοποιώντας τη συνάρτηση Lua API του LuaTeX `texio.write(*string*)`:

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

Αν εξετάσετε το παραγόμενο `.log` αρχείο, θα δείτε ότι περιέχει επίσης

```
   I will use
   ewcommand
```

Αυτή η απροσδόκητη έξοδος οφείλεται στο ότι η Lua ερμηνεύει το `\n` στην αρχή του `**\n**ewcommand` ως ακολουθία διαφυγής για τον χαρακτήρα αλλαγής γραμμής (κωδικός χαρακτήρα 10): υποθέτει ότι θέλετε να ξεκινήσετε μια νέα γραμμή κειμένου που αρχίζει με `ewcommand`. Συζητούμε τις ακολουθίες διαφυγής της Lua αργότερα σε αυτό το άρθρο.

### \detokenize{⟨material⟩}

`\detokenize` είναι, ως προς τα αποτελέσματά του, μια εκδοχή πολλαπλών διακριτικών του `\string` και είναι επίσης μια επεκτάσιμη εντολή που μετατρέπει τα πάντα στο `⟨material⟩` σε μια ακολουθία διακριτικών χαρακτήρων με κωδικό κατηγορίας 12—*εκτός* τους χαρακτήρες κενού (τιμή ASCII/Unicode 32) οι οποίοι παίρνουν κωδικό κατηγορίας 10. `\detokenize` επίσης εισάγει έναν τελικό χαρακτήρα κενού μετά από ονόματα εντολών που είναι *λέξεις ελέγχου* (π.χ., `\foo`) αλλά κανένας χαρακτήρας κενού δεν εισάγεται μετά το *σύμβολα ελέγχου* (π.χ., `\#`, `\%` κτλ.).

### Παράδειγμα

Ακόμη κι αν οι μακροεντολές `\foohoo`, `\foo`, `\bar` και `\foobar` δεν είναι ορισμένες, αν γράψετε αυτό:

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

θα παρήγαγε το ακόλουθο κείμενο ως κώδικα για πέρασμα στον διερμηνευτή Lua

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

Αν δεν χρησιμοποιήσετε `\string` και `\detokenize` και γράψετε:

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

`\directlua` θα επεξεργαζόταν το `\foohoo`, θα αναγνώριζε ότι είναι εντολή και θα προσπαθούσε να την επεκτείνει· αλλά επειδή `\foohoo` δεν είναι ορισμένη, θα οδηγούσε σε σφάλμα:

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

Επειδή `\string` και `\detokenize` μετατρέπουν τα ορίσματά τους σε μια σειρά διακριτικών χαρακτήρων, `\directlua`η διαδικασία επέκτασής του έχει την ευκαιρία να εντοπίσει επεκτάσιμα διακριτικά εντολών `\foohoo`, `\foo`, `\bar`, ή `\foobar`: μετατρέπονται σε ακολουθίες διακριτικών χαρακτήρων πολύ πριν μπορέσουν να προκαλέσουν επέκταση.

Όπως σημειώθηκε προηγουμένως, η επέκταση μιας εντολής περιλαμβάνει την αφαίρεσή της από την είσοδο και την αντικατάστασή της με το αποτέλεσμα της «συμπεριφοράς επέκτασής» της. Τα αποτελέσματα της επέκτασης (συνήθως διακριτικά) στη συνέχεια διαβάζονται από τη μηχανή TeX. Εδώ, η «συμπεριφορά επέκτασης» για το `\string` και `\detokenize` είναι να απορροφά διακριτικά χαρακτήρων και εντολών από την είσοδο και να τα μετατρέπει σε ακολουθίες διακριτικών χαρακτήρων, που αρχικά αποθηκεύονται σε μια προσωρινή λίστα διακριτικών, την οποία `\directlua` διαβάζει στη συνέχεια. Αυτά τα διακριτικά χαρακτήρων ενσωματώνονται στην κύρια λίστα διακριτικών που κατασκευάζεται από το `\directlua`.

Το ακόλουθο γραφικό απεικονίζει πώς `\string` μετατρέπει το `\foohoo` διακριτικό της εντολής σε μια ακολουθία διακριτικών χαρακτήρων, παράγοντας μια προσωρινή λίστα διακριτικών που στη συνέχεια διαβάζεται από το `\directlua` για να ενσωματώσει εκείνα τα διακριτικά χαρακτήρων στην κύρια λίστα διακριτικών που κατασκευάζεται.

![](/files/8318cd43cfdaf55cba2d0ba08b7ddc8e964f5de1)

Αν `\string` ή `\detokenize` συναντούν χαρακτήρες στο όρισμά τους π.χ., `\string a` ή `\detokenize{abc}` εκείνοι οι χαρακτήρες (εδώ, με κωδικό κατηγορίας 11) παράγουν διακριτικά χαρακτήρων αλλά με κωδικό κατηγορίας 12.

Σημειώσεις:

Αν επιστρέψουμε στο παραπάνω παράδειγμα:

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

το οποίο παράγει το ακόλουθο κείμενο ως κώδικα για πέρασμα στον διερμηνευτή Lua

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

μπορούμε να παρατηρήσουμε τα εξής:

* `\detokenize` έχει εισαγάγει έναν χαρακτήρα κενού μετά από κάθε όνομα μακροεντολής, αλλά `\string` δεν το έκανε.
* `\string` ενεργεί πάνω σε ένα μόνο διακριτικό.
* Στη συμβολοσειρά `"\foohoo\foo \bar \foobar "` που χρησιμοποιήθηκε για να οριστεί το `x` θα συναντήσουμε και πάλι τον μηχανισμό του χαρακτήρα διαφυγής της Lua (που συζητείται παρακάτω):

  * `\bar` ξεκινά με `\b` που είναι η ακολουθία διαφυγής της Lua που χρησιμοποιείται για να αναπαραστήσει τον [χαρακτήρα backspace](https://en.wikipedia.org/wiki/Backspace) (κωδικός χαρακτήρα 8);
  * εντολές `\foohoo`, `\foo` και `\foobar` όλα ξεκινούν με `\f`, την ακολουθία διαφυγής της Lua που χρησιμοποιείται για να αναπαραστήσει τον [χαρακτήρα formfeed](https://en.wikipedia.org/wiki/Page_break#Form_feed) (κωδικός χαρακτήρα 12).

  Επειδή οι ακολουθίες χαρακτήρων `\b` και `\f` χρησιμοποιούνται μέσα σε μια συμβολοσειρά που δημιουργείται με διπλά εισαγωγικά `"..."` θα παράγουν ανεπιθύμητα αποτελέσματα εκτός αν ληφθούν μέτρα για να αποτραπεί αυτό χρησιμοποιώντας τα λεγόμενα του Lua *μακριά αγκύλια* μέθοδο συμβολοσειράς: ένα θέμα που μπορούμε τώρα να συζητήσουμε μαζί με τις ακολουθίες διαφυγής του Lua.

## Τι είναι οι «ακολουθίες διαφυγής του Lua»;

Οι γλώσσες προγραμματισμού κρατούν ορισμένους χαρακτήρες για «ειδική χρήση» ως μέρος της σύνταξης της γλώσσας: στην πράξη, αυτοί οι χαρακτήρες ορίζονται ώστε να έχουν κάποια μορφή ειδικής σημασίας. Ωστόσο, υπάρχουν φορές που χρειάζεται να «απενεργοποιήσετε» προσωρινά αυτή την ειδική σημασία ενός χαρακτήρα, αν, για παράδειγμα, θέλετε ο χαρακτήρας αυτός να ενσωματωθεί ως μέρος μιας μεγαλύτερης συμβολοσειράς όπου η τυπική του συμπεριφορά θα προκαλούσε συντακτικά σφάλματα. Ουσιαστικά, ο χαρακτήρας αυτός πρέπει να επεξεργαστεί *χωρίς* ώστε να περάσει χωρίς να γίνει αντιληπτό, χωρίς να ενεργοποιηθεί η τυπική ερμηνεία του. Για να γίνει αυτό, οι προγραμματιστές χρησιμοποιούν μια τεχνική που ονομάζεται *διαφυγή* στην οποία ένας «ειδικός χαρακτήρας» αναπαρίσταται από τη λεγόμενη *ακολουθία διαφυγής*.

Ένα τυπικό παράδειγμα (υποστηρίζεται επίσης από το Lua) είναι η χρήση διπλών εισαγωγικών μέσα σε μια συμβολοσειρά, όπου διαφεύγετε τα εσωτερικά διπλά εισαγωγικά χρησιμοποιώντας την ακολουθία διαφυγής `\\"`:

`«Όταν ρωτήθηκαν για το LuaTeX απάντησαν: \\\"Είναι μια καταπληκτική μηχανή TeX!\\\" Συμφώνησα.»`

Η γλώσσα Lua παρέχει διάφορους μηχανισμούς για την εργασία με ακολουθίες διαφυγής:

* τυπικές ακολουθίες, μεταξύ των οποίων `\n` (νέα γραμμή), `\\r` (επιστροφή δρομέα), `\\` (αντίστροφη κάθετος), `\\"` (διπλό εισαγωγικό), `\\t` (οριζόντια στηλοθέτηση), `\\v` (κάθετη στηλοθέτηση) και `\\'` (μονό εισαγωγικό);
* `\\xXX`, όπου `XX` είναι μια ακολουθία ακριβώς δύο δεκαεξαδικών ψηφίων;
* `\\ddd`, όπου `ddd` είναι μια ακολουθία έως τριών δεκαδικών ψηφίων;
* τη στιγμή που γράφτηκε αυτό το άρθρο (Αύγουστος 2019) η πιο πρόσφατη έκδοση του LuaTeX, αν και δεν ήταν ακόμη διαθέσιμη στο Overleaf, χρησιμοποιεί την έκδοση 5.3 του Lua, η οποία εισήγαγε υποστήριξη για ακολουθίες διαφυγής UTF-8: `\\u{XXX}`. Αυτός ο μηχανισμός διαφυγής αφορά χαρακτήρες Unicode κωδικοποιημένους σε UTF-8, όπου `XXX` είναι μια ακολουθία ενός ή περισσότερων δεκαεξαδικών ψηφίων που αναπαριστούν τον κωδικό σημείο του χαρακτήρα. Σημειώστε ότι τα περικλείοντα αγκύλια `{ }` είναι υποχρεωτικά.

### Έλεγχος των ακολουθιών διαφυγής

Παραδοσιακά, οι συμβολοσειρές ορίζονται χρησιμοποιώντας διπλά εισαγωγικά όπως στο `"αυτή είναι μια συμβολοσειρά"`; μέσα σε μια τέτοια συμβολοσειρά μπορείτε να χρησιμοποιήσετε ακολουθίες διαφυγής: `"αυτή είναι μια συμβολοσειρά.\\nΘα ξεκινήσω τώρα σε νέα γραμμή."`. Ωστόσο, το Lua έχει έναν δεύτερο και *πολύ* βολικό μηχανισμό για τον ορισμό συμβολοσειρών: τα λεγόμενα *μακριά αγκύλια* μηχανισμό, στον οποίο ορίζετε μια συμβολοσειρά περικλείοντας το κείμενο σε `[[` και `]]`:

`[[Είμαι μια συμβολοσειρά με μακριά αγκύλια]]`

Μέσα σε μια συμβολοσειρά που δημιουργείται με τη μέθοδο των μακριών αγκυλών, ο μηχανισμός διαφυγής χαρακτήρων του Lua *απενεργοποιείται*: οι ακολουθίες διαφυγής αντιμετωπίζονται ως κανονικοί χαρακτήρες. Για παράδειγμα, στη συμβολοσειρά

`[[Είμαι μια συμβολοσειρά με μακριά αγκύλια\\n συμβολοσειρά]]`

το `\n` η ακολουθία διαφυγής δεν αντιμετωπίζεται ως ο μονός χαρακτήρας επιστροφής δρομέα (κωδικός ASCII 13) αλλά ως δύο κανονικοί χαρακτήρες: `\` ακολουθούμενος από `n`.

### Γιατί οι συμβολοσειρές με μακριά αγκύλια είναι τόσο χρήσιμες;

Όπως θα εξετάσουμε αργότερα, το LuaTeX παρέχει μια σειρά εξειδικευμένων, ενσωματωμένων συναρτήσεων Lua που μπορείτε να χρησιμοποιήσετε με `\directlua` για να ελέγξετε τη στοιχειοθετική συμπεριφορά του LuaTeX. Ανάμεσα σε αυτές τις πολλές συναρτήσεις υπάρχει μία που ονομάζεται `tex.print(*string*)` που σας επιτρέπει να περάσετε `*string*` υλικό από κώδικα Lua πίσω στο LuaTeX για στοιχειοθεσία. Ένα πολύ απλό παράδειγμα είναι:

`\\directlua{tex.print("Γεια σου, Κόσμε!")}`

το οποίο θα κάνει το LuaTeX να στοιχειοθετήσει `Γεια σου, Κόσμε!`

Η `*string*` χρησιμοποιείται στο `tex.print(*string*)` μπορεί επίσης να περιλαμβάνει κείμενο που αναπαριστά εντολές TeX και LaTeX για επεξεργασία από το LuaTeX. Ωστόσο, οι εντολές TeX/LaTeX ξεκινούν με έναν `\` χαρακτήρα, ο οποίος είναι προβληματικός με συμβολοσειρές που δημιουργούνται με διπλά εισαγωγικά επειδή το Lua θα προσπαθήσει να αναλύσει τη συμβολοσειρά, να εντοπίσει το αρχικό `\` χαρακτήρα και να τον ερμηνεύσει ως την αρχή μιας ακολουθίας διαφυγής. Όταν το Lua προσπαθεί να επεξεργαστεί την ακολουθία διαφυγής συνήθως αποτυγχάνει επειδή το αρχικό `\` σε συνδυασμό με τον πρώτο χαρακτήρα σε πολλά ονόματα εντολών TeX/LaTeX δεν σχηματίζει μια έγκυρη ακολουθία διαφυγής γνωστή στο Lua. Για παράδειγμα, κατά την επεξεργασία μιας συμβολοσειράς όπως `"Μου αρέσει \\LaTeX"` το Lua θα έβλεπε `\\L` και θα αποτύγχανε με το σφάλμα «μη έγκυρη ακολουθία διαφυγής», και αυτή είναι η αιτία των σφαλμάτων που σημειώθηκαν παραπάνω.

#### Οι συμβολοσειρές με μακριά αγκύλια έρχονται να σώσουν την κατάσταση!

Η μέθοδος δημιουργίας (ορισμού) συμβολοσειρών με μακριά αγκύλια είναι εξαιρετικά χρήσιμη επειδή, παρόλο που οι εντολές TeX/LaTeX ξεκινούν με έναν `\` χαρακτήρα, η μέθοδος συμβολοσειράς με μακριά αγκύλια απενεργοποιεί (σβήνει) τον μηχανισμό ακολουθιών διαφυγής του Lua. Ακολουθεί ένα σύντομο παράδειγμα, θυμηθείτε ότι πρέπει να αποτρέψουμε την ανάπτυξη μακροεντολών χρησιμοποιώντας, για παράδειγμα, `\protected` ή `\noexpand`.

Ας υποθέσουμε ότι ορίζουμε μια `\\newtest` μακροεντολή όπως αυτή

`**\\protected**\\def\\newtest#1{Το όρισμα: #1}`

και να τη χρησιμοποιήσουμε στο `\directlua` με τη συνάρτηση Lua API του LuaTeX `tex.print()`:

```
\directlua{
   tex.print("\\newtest{Γεια}")
}
```

Λόγω της χρήσης του `\protected`, η μακροεντολή `\\newtest` δεν αναπτύσσεται, με αποτέλεσμα το ακόλουθο κείμενο να περνά στο Lua:

`tex.print("\\newtest {Γεια}")`

Ο χαρακτήρας κενού που προστίθεται μετά το `\\newtest` και πριν από την ανοιχτή αγκύλη (`{`) είναι παρενέργεια της μετατροπής των εντολοσήμων από το `\directlua`πίσω στην κειμενική τους αναπαράσταση.

Αυτός ο κώδικας περνά στο Lua, το οποίο στη συνέχεια εκτελεί τη συνάρτηση LuaTeX `tex.print()` αλλά υπάρχει ένα πρόβλημα που εκδηλώνεται με τρόπους που εξαρτώνται από τις γραμματοσειρές που χρησιμοποιείτε. Στο LaTeX στο Overleaf θα βλέπατε έξοδο όπως αυτή:

![](/files/0c5084386d447c3b038507a788861c87f3633de5)

μαζί με μια προειδοποίηση στο αρχείο καταγραφής:

```
   Λείπει χαρακτήρας: Δεν υπάρχει
   (U+000A) στη γραμματοσειρά [lmroman10-regular]:+tlig;!
```

Στο απλό TeX ίσως βλέπατε έξοδο που μοιάζει κάπως έτσι:

![](/files/446663c3809d7de358acf009ee3f477c163b2e99)

Και στις δύο περιπτώσεις το `\\newtest` μακροεντολή δεν καλείται και η έξοδος δεν είναι αυτή που θέλαμε. Το σφάλμα προκαλείται από τον μηχανισμό χαρακτήρων διαφυγής του Lua: στο κείμενο `\\newtest {Γεια}` το όνομα της μακροεντολής ξεκινά με `\n` τον οποίο το Lua αναγνωρίζει ως ακολουθία διαφυγής για χαρακτήρα αλλαγής γραμμής, οπότε τον αντικαθιστά `\n` με τον χαρακτήρα ASCII 10, ή δεκαεξαδικά 0A. Στο μήνυμα σφάλματος της LaTeX, `U+000A` είναι ένας τρόπος να αναπαραστήσουμε την τιμή Unicode χρησιμοποιώντας 4 δεκαεξαδικά ψηφία.

Επειδή το `\n` μετατρέπεται στον χαρακτήρα αλλαγής γραμμής, το LuaTeX δεν βλέπει κλήση μακροεντολής αλλά αντίθετα θεωρεί ότι του ζητείται να στοιχειοθετήσει κάποιο κείμενο που ξεκινά με τον κωδικό χαρακτήρα ASCII 10:

`⟨ASCII 10⟩ewtest {Γεια}`

Ανάλογα με τη γραμματοσειρά που χρησιμοποιείται, το LuaTeX μπορεί ή μπορεί να μην μπορεί να στοιχειοθετήσει τον `⟨ASCII 10⟩` χαρακτήρα, αλλά το υπόλοιπο κείμενο εξάγεται ως έχει με το `{` και `}` να αντιμετωπίζεται ως ομάδα και να μην εκτυπώνεται.

Το απλό TeX δίνει διαφορετικό αποτέλεσμα επειδή η προεπιλεγμένη γραμματοσειρά είναι η Computer Modern Roman, η οποία έχει μια παράξενη κωδικοποίηση που έχει ως αποτέλεσμα να στοιχειοθετείται ένα κεφαλαίο Ωμέγα όταν εμφανίζεται ο κωδικός χαρακτήρα 10.

Για να αποφευχθούν αυτά τα προβλήματα πρέπει να χρησιμοποιήσουμε συμβολοσειρές με μακριά αγκύλια ώστε να μην εφαρμόζεται ο μηχανισμός διαφυγής του Lua. Το σωστό αποτέλεσμα παράγεται με

`\\directlua{tex.print([[\\newtest{Γεια}]])}`

το οποίο παράγει το αποτέλεσμα που φαίνεται στο ακόλουθο στιγμιότυπο οθόνης:

![](/files/c87df8c09d2343f670ef563e0a4f5e72983a402f)

### Ανάπτυξη και μη εκτέλεση μη επεκτάσιμων εντολών

Όταν συζητούσαμε για την ανάπτυξη σημειώσαμε ότι πρόκειται για μια διαδικασία κατά την οποία μια μηχανή TeX *αφαιρεί* μια επεκτάσιμη εντολή (token) από το τρέχον είσοδο και *την αντικαθιστά* με το αποτέλεσμα/αποτελέσματα που παράγονται από εκείνη την επεκτάσιμη εντολή. Επειδή το \\\directlua εκτελεί *μόνο ανάπτυξη* δραστηριότητες (για τη δημιουργία μιας λίστας tokens), δεν *δεν* προχωρήσει την επεξεργασία του LuaTeX πέρα από αυτό. Μόλις διαβαστεί μια επεκτάσιμη εντολή και αναπτυχθεί πλήρως, τα αποτελέσματα εκείνης της ανάπτυξης—τα οποία συχνά περιλαμβάνουν μη επεκτάσιμες εντολές (tokens)—ενσωματώνονται στη λίστα tokens που κατασκευάζεται, έτοιμα για μετατροπή πίσω σε κείμενο ώστε να σταλούν στο Lua.

Υπάρχει μια σημαντική αρχή εδώ: κατά τη διάρκεια *μόνο ανάπτυξη* δραστηριοτήτων που έχουν σχεδιαστεί για να παράγουν μια λίστα tokens, οι μηχανές TeX, συμπεριλαμβανομένου του LuaTeX, *δεν εκτελούν* καμία μη επεκτάσιμη πρωταρχική, ενσωματωμένη εντολή TeX.

Στην περίπτωση του `\directlua{⟨code⟩}`, αν η πλήρως ανεπτυγμένη έκδοση του `⟨code⟩` παράγει ή περιέχει μη επεκτάσιμες εντολές TeX/LaTeX, αυτές *θα περαστούν στο Lua* (ως κείμενο).

#### Παράδειγμα

Ακολουθεί ένα παράδειγμα για να δείξουμε ότι οι μη επεκτάσιμες πρωταρχικές εντολές δεν εκτελούνται κατά την επεξεργασία μόνο ανάπτυξης (όπως μέσα στο `\directlua`). Ας υποθέσουμε ότι ορίζουμε μια μακροεντολή `\\setcountreg` ως εξής:

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

**Σημείωση**: Χρησιμοποιούμε `\\relax` μετά την παράμετρο `#2` για να αποτρέψουμε το LuaTeX από το να υπερβεί όταν σαρώνει την είσοδο στην αναζήτησή του για την αριθμητική τιμή (όρισμα) που θα αντιστοιχιστεί στην παράμετρο `#2`.

Αν, εκτός του `\directlua`, αργότερα εκτελέσουμε τη μακροεντολή έτσι

```
   \\setcountreg{100}{50}
   Η τιμή στο καταχωρητή μετρητή 100 είναι \\the\\count100.
```

θα έδινε ως έξοδο

`Η τιμή στο καταχωρητή μετρητή 100 είναι 50.`

Σε αυτό το πλαίσιο, οποιαδήποτε μηχανή TeX θα επεξεργαζόταν τη μακροεντολή `\\setcountreg`—θα ανέπτυσσε τη μακροεντολή, θα καθόριζε τα ορίσματα και θα συνέχιζε να διαβάζει *και να εκτελεί* (να εκτελεί) τις εντολές που περιέχονται στο κείμενο αντικατάστασης (ορισμό) της μακροεντολής. Το αποτέλεσμα εδώ είναι να ανατεθεί `50` ως η τιμή που αποθηκεύεται στον καταχωρητή `\\count100`.

Ωστόσο, όταν μια μηχανή TeX εκτελεί *μόνο ανάπτυξη* δραστηριότητες, όπως συμβαίνει με το `\directlua`, δεν *θα εκτελέσει* τις μη επεκτάσιμες εντολές που περιέχονται στον ορισμό της μακροεντολής.

Αν γράψουμε

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

παράγει το ακόλουθο κείμενο ως κώδικα για το Lua:

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

Ο κώδικας Lua που παράχθηκε παραπάνω δείχνει ότι μέσα στο `\directlua` το `\\setcountreg` έχει αναπτυχθεί, τα ορίσματά του έχουν εντοπιστεί και αντικατασταθεί στην κατάλληλη παράμετρο (`#1` και `#2`) αλλά δεν προχωρά πέρα από αυτό: η μη επεκτάσιμη πρωταρχική εντολή TeX `\count` ήταν *δεν εκτελείται* κατά την επεξεργασία ανάπτυξης μόνο του `\directlua`του LuaTeX.

Ωστόσο, το LuaTeX θα εκτελέσει τον κώδικα TeX αν περάσουμε την προκύπτουσα συμβολοσειρά `x` *πίσω στο LuaTeX* μέσω `tex.print(x)` όπως εδώ

```
\\count100=50 % ορισμός του \\count100 σε αρχική τιμή 50
\\def\\setcountreg#1#2{\\count#1=#2\\relax}
\directlua{
   local x = [[\\setcountreg{100}{250}]]
   tex.print(x)
}
Η τιμή που αποθηκεύεται στον καταχωρητή μετρητή 100 είναι \\the\\count100.
```

Αφού `\directlua` έχει ολοκληρωθεί, η έξοδος θα ήταν

`Η τιμή που αποθηκεύεται στον καταχωρητή μετρητή 100 είναι 250.`

δείχνοντας ότι ο καταχωρητής μετρητή `100` πλέον περιέχει την τιμή `250`.

Ο κώδικας Lua που παράχθηκε από το παραπάνω παράδειγμα είναι

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

Αυτός ο κώδικας ορίζει `x` να είναι μια συμβολοσειρά που δημιουργείται με τη μέθοδο των μακριών αγκυλών, η οποία χρησιμοποιείται για να αποφευχθούν σφάλματα με λανθασμένες ακολουθίες διαφυγής. Αν χρησιμοποιούσαμε διπλά εισαγωγικά `"..."` για να ορίσουμε το x, ο συνδυασμός χαρακτήρων `\\c` στην αρχή του `\count` θα προκαλούσε σφάλμα: `μη έγκυρη ακολουθία διαφυγής κοντά στο ' "\\c'`.

Η κλήση Lua API του LuaTeX `tex.print(x)` έχει ως αποτέλεσμα το LuaTeX να εκτελέσει τη σειρά κώδικα TeX `\\count 100=250\\relax` και `\\count100` ανατίθεται τιμή `250` όπως φαίνεται από το στοιχειοθετημένο αποτέλεσμα:

`Η τιμή που αποθηκεύεται στον καταχωρητή μετρητή 100 είναι 250.`

#### Προσοχή: μακροεντολές και το LuaTeX Lua API

Στο παραπάνω παράδειγμα είδαμε ότι κατά την `\directlua`προεπεξεργασία (ανάπτυξη) του LuaTeX δεν εκτέλεσε τον κώδικα `\\count 100=250`, ο οποίος περιέχει την `μη επεκτάσιμων` πρωταρχική εντολή `\count`: για να εκτελέσουμε (να τρέξουμε) αυτόν τον κώδικα έπρεπε να τον *τον περάσουμε πίσω στο LuaTeX* μέσω `tex.print()`.

`\directlua` είναι μόνο ένα παράδειγμα όπου το LuaTeX εκτελεί επεξεργασία μόνο ανάπτυξης για να κατασκευάσει μια λίστα tokens. Υπάρχουν και άλλες εντολές που εκτελούν παρόμοια επεξεργασία ανάπτυξης και δραστηριότητες δημιουργίας λίστας tokens, όπως `\write` και `\edef`: οι εντολές αυτές επίσης δεν εκτελούν μη επεκτάσιμες πρωταρχικές εντολές κατά την επεξεργασία ανάπτυξής τους. Γενική αρχή είναι ότι οι μηχανές TeX δεν εκτελούν μη επεκτάσιμες πρωταρχικές εντολές όταν κατασκευάζουν μια λίστα tokens κατά τις δραστηριότητες επεξεργασίας μόνο ανάπτυξης.

**Αναδιατύπωση της μακροεντολής μας για να χρησιμοποιεί το LuaTeX Lua API**

Μπορούμε να ξαναγράψουμε τη `\\setcountreg` μακροεντολή χρησιμοποιώντας μια συνάρτηση Lua API του LuaTeX που ονομάζεται `tex.setcount()`, αποφεύγοντας έτσι εντολές TeX για να αλλάξουμε την τιμή που αποθηκεύεται στον καταχωρητή μετρητή `100`:

```
   \\def\\setcount#1#2{\\directlua{tex.setcount(#1,#2)}}
   \\count100=50
   ο καταχωρητής μετρητή 100 περιέχει \\the\\count100\\par
   \\setcount{100}{250}
   ο καταχωρητής μετρητή 100 περιέχει τώρα \\the\\count100\\par
```

Αυτός ο κώδικας θα στοιχειοθετήσει:

```
ο καταχωρητής μετρητή 100 περιέχει 50
ο καταχωρητής μετρητή 100 περιέχει τώρα 250
```

Εδώ χρησιμοποιούμε `tex.setcount()`, μία από τις πολλές συναρτήσεις Lua API του LuaTeX, για να *έχουμε άμεση πρόσβαση* στην εσωτερική περιοχή αποθήκευσης δεδομένων του LuaTeX ώστε να τοποθετήσουμε την τιμή `250` στην τοποθεσία μνήμης που αντιπροσωπεύει τον καταχωρητή μετρητή `100`. Στην ουσία, έχουμε *παρακάμψει* τις τυπικές μεθόδους επεξεργασίας εισόδου της μηχανής TeX του LuaTeX: ανάγνωση εισόδου, δημιουργία tokens και εκτέλεση πρωταρχικών εντολών TeX. Ωστόσο, υπάρχει μια προειδοποιητική ιστορία: με τη χρήση των συναρτήσεων Lua API του LuaTeX, η δραστηριότητα επεξεργασίας μόνο ανάπτυξης *μπορεί να οδηγήσει σε παρενέργειες*: αλλαγές στις τιμές που αποθηκεύονται μέσα στη μηχανή TeX, οι οποίες διαφορετικά δεν θα ήταν δυνατές με καθαρά TeX/LaTeX εντολές.

**Παράδειγμα: απροσδόκητες παρενέργειες**

Ακολουθεί ένα παράδειγμα για να δείξουμε *απροσδόκητες* παρενέργειες που μπορεί να προκύψουν με μακροεντολές που χρησιμοποιούν `\directlua`. Ας υποθέσουμε ότι γράφουμε τον ακόλουθο κώδικα:

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

Εκτελώντας αυτόν τον κώδικα στοιχειοθετείται `12345`!

Πώς γίνεται αυτό; Δεν *ρητά* καλέσαμε κανέναν κώδικα ή μακροεντολές για να βάλουμε αυτή την τιμή στον καταχωρητή μετρητή `999`. Ή μήπως το κάναμε;

Ορίσαμε `\\dochange` με ένα `\directlua` εντολή που χρησιμοποιεί `tex.setcount()` για να αποθηκεύσει την τιμή `12345` στον καταχωρητή μετρητή `999`: στον κώδικα TeX είναι το ισοδύναμο του `\\count999=12345`. Στη συνέχεια χρησιμοποιήσαμε την τυπική πρωταρχική εντολή TeX `\edef` για να ορίσουμε τη μακροεντολή `\\careful`—είναι η χρήση του `\edef` που ενεργοποιεί την απροσδόκητη παρενέργεια.

`\edef` αναπτύσσει πλήρως το όρισμά της: εδώ, εντοπίζει μια επεκτάσιμη μακροεντολή `\\dochange` και την αναπτύσσει. Η `\\dochange` μακροεντολή χρησιμοποιεί την επεκτάσιμη εντολή `\directlua` η οποία περιέχει μια κλήση Lua API· έτσι η ανάπτυξη του `\\dochange` έχει ως αποτέλεσμα την ανάπτυξη του `\directlua` και αυτό προκαλεί `tex.setcount()` να κληθεί, πράγμα που αλλάζει την τιμή στον καταχωρητή μετρητή `999`.

Αν ξαναορίσουμε το `\\dochange` να χρησιμοποιεί εντολές TeX:

```
   Πριν: ο καταχωρητής μετρητή 999 περιέχει \\the\\count999.\\par
   \\def\\dochange{\\count999=12345\\relax}
   \\edef\\careful{\\dochange}
   Μετά: ο καταχωρητής μετρητή 999 περιέχει \\the\\count999.\\par
```

εκτελώντας αυτόν τον κώδικα στοιχειοθετείται

```
Πριν: ο καταχωρητής μετρητή 999 περιέχει 0.
Μετά: ο καταχωρητής μετρητή 999 περιέχει 0.
```

Σαφώς, δεν υπήρξε καμία επίδραση στο `\\count999`. Όταν `\edef` ορίζει `\\careful` το αναπτύσσει `\\dochange` αλλά αυτή η ανάπτυξη παράγει μόνο μη αναπτύξιμες πρωταρχικές εντολές TeX: δεν *δεν εκτελείται* αλλά απλώς *αποθηκεύονται* στη λίστα tokens που αποτελεί τον ορισμό του `\\careful`.

Για καλό και για κακό, η ίδια αρχή εξηγεί γιατί αυτό παράγει στοιχειοθετημένη έξοδο:

```
\\def\\dochange{\\directlua{tex.print("Γεια")}}
\\edef\\careful{\\dochange}
```

## Σύντομη εισαγωγή στο Lua API του LuaTeX

Όπως είδαμε, `\directlua` όχι μόνο σας επιτρέπει να γράφετε συμβατικό κώδικα Lua, ή ένα μείγμα κώδικα Lua και TeX/LaTeX, αλλά παρέχει επίσης πρόσβαση σε μια σειρά πρόσθετων συναρτήσεων Lua (ειδικών για το LuaTeX) που μπορείτε να χρησιμοποιήσετε (να καλέσετε) για να επικοινωνήσετε με ή να ελέγξετε άμεσα τον εσωτερικό μηχανισμό του λογισμικού στοιχειοθεσίας LuaTeX. Χρησιμοποιήσαμε αρκετές συναρτήσεις Lua σε αυτό το άρθρο, `tex.print()`, `texio.write()`, `tex.setcount()` και αυτές, μαζί με *πολλές* άλλες, τεκμηριώνονται στο [Εγχειρίδιο Αναφοράς του LuaTeX](http://www.pragma-ade.com/general/manuals/luatex.pdf) στο οποίο ομάδες σχετικών συναρτήσεων αναφέρονται ως *βιβλιοθήκες*.

Μπορείτε να σκεφτείτε αυτές τις συναρτήσεις Lua ως το Lua API του LuaTeX (**Ένα**Εφαρμογής **Π**ρογραμματισμού **I**Διεπαφή) το οποίο παρέχει τα εργαλεία για την κατασκευή εξελιγμένων λύσεων στοιχειοθεσίας και μηχανικής εγγράφων, ελέγχοντας τη συμπεριφορά στοιχειοθεσίας του LuaTeX χρησιμοποιώντας τη Lua ως οδηγό.

Όπως σημειώθηκε, το LuaTeX οργανώνει το API του σε ένα σύνολο συναρτήσεων που το αποκαλεί βιβλιοθήκες: ομάδες συναρτήσεων που σχετίζονται μεταξύ τους μέσω του σκοπού ή των ενεργειών τους. Κάθε σύνολο συναρτήσεων έχει σχεδιαστεί ώστε να παρέχει πρόσβαση σε μια συγκεκριμένη πτυχή των εσωτερικών διεργασιών, των δομών δεδομένων, της αποθήκευσης δεδομένων και των αλγορίθμων στοιχειοθεσίας του LuaTeX. Εσωτερικά, το LuaTeX αποτελείται από πολλαπλά στοιχεία: βιβλιοθήκες/εργαλεία λογισμικού (κυρίως γραμμένα σε C) που όχι μόνο συγκροτούν την ίδια τη μηχανή TeX αλλά και άλλα υποσυστήματα, όπως τα Lua, MetaPost, Kpathsea, FontForge, libpng και zlib. Αυτές οι βιβλιοθήκες είναι ενσωματωμένες για να δομήσουν τα χαρακτηριστικά και τις λειτουργίες του εκτελέσιμου λογισμικού LuaTeX και είναι μέσω του Lua API που οι χρήστες αποκτούν πρόσβαση στις δυνατότητες του LuaTeX που προκύπτουν από την ενσωμάτωση και τον συντονισμό αυτών των πολλαπλών στοιχείων λογισμικού.

## Μερικά παραδείγματα και παγίδες

Σε αυτή την ενότητα παρουσιάζουμε μερικά επιπλέον παραδείγματα που αξιοποιούν τα θέματα, τις έννοιες και τις εξηγήσεις που παρέχονται σε αυτό το άρθρο.

### Χρήση του χαρακτήρα περισπωμένης (\~)

Η γλώσσα Lua χρησιμοποιεί τον `~` χαρακτήρα (που ονομάζεται περισπωμένη) ως μέρος της σύνταξής της, συμπεριλαμβανομένης της σύνταξής της για την εκτέλεση ελέγχου «όχι ίσο»· για παράδειγμα, για να ελέγξουμε αν μια μεταβλητή `x` δεν είναι ίση με `4` μπορούμε να γράψουμε:

```
   local x=3
   if x ~= 4 then
   print("το x δεν είναι ίσο με 4")
   end
```

Αν προσπαθήσουμε να εκτελέσουμε αυτόν τον απλό κώδικα Lua μέσω `\directlua`:

```
\directlua{
   local x=3
   if x ~= 4 then
   print("το x δεν είναι ίσο με 4")
   end
}
```

εμφανίζεται ένα σφάλμα:

`[\directlua]:1: αναμενόταν το 'then' κοντά στο '\'.`

Αυτό είναι περίεργο, γιατί ο κώδικάς μας είναι σωστός: έχουμε χρησιμοποιήσει `'then'` και δεν υπάρχει `\` χαρακτήρας στον κώδικά μας, οπότε τι πήγε στραβά; Για να το καταλάβουμε αυτό, πρέπει να θυμόμαστε ότι, για το TeX/LaTeX, `~` συνήθως ορίζεται ως «ειδικός χαρακτήρας» με κωδικό κατηγορίας 13: οι λεγόμενοι ενεργοί χαρακτήρες, που είναι μικρο-μακροεντολές και επομένως υπόκεινται σε επέκταση. Όταν `\directlua` εντοπίζει τον `~` χαρακτήρα, αυτός επεκτείνεται με *την αφαίρεσή του* αφαιρείται από την είσοδο και *αντικαθιστώντας το* με το αποτέλεσμα της επέκτασής του. Χρησιμοποιώντας το plain TeX, το παραγόμενο κείμενο (κώδικα) που παράγει το LuaTeX και περνά στον διερμηνευτή Lua στην πραγματικότητα δεν περιέχει τον `~` χαρακτήρα, και είναι:

`local x=3 if x \penalty \@M \ = 4 then print("το x δεν είναι ίσο με 4") end`

Η `~` ο χαρακτήρας έχει *αφαιρείται* και *επεκταθεί* στα επιμέρους εντολές του — ο παραπάνω κώδικας Lua προκύπτει από τον ορισμό του plain TeX για τον ενεργό χαρακτήρα `~`. Τώρα μπορούμε να δούμε γιατί η Lua απαντά με το σφάλμα `αναμενόταν το 'then' κοντά στο '\'`— αρχίζει να αναλύει αυτόν τον κώδικα αλλά συναντά τη λέξη `\penalty` που δεν σημαίνει τίποτα για τη Lua και δημιουργεί συντακτικό σφάλμα.

Για να το διορθώσουμε αυτό, ο `~` χαρακτήρας πρέπει να έχει έναν ασφαλή κωδικό κατηγορίας τη στιγμή που `\directlua` επεξεργάζεται τον κώδικά σας· για παράδειγμα, μπορούμε προσωρινά να αλλάξουμε τον κωδικό κατηγορίας του `~` σε 11 (γράμμα) περικλείοντας τον κώδικα σε μια ομάδα:

```
\begingroup
\catcode`\~=11
\directlua{
   local x=3
   if x ~= 4 then
   print("το x δεν είναι ίσο με 4")
   end
}
\endgroup
```

Αυτός ο κώδικας λειτουργεί όπως αναμένεται και `το x δεν είναι ίσο με 4` εκτυπώνεται στην κονσόλα. Υπάρχουν και άλλες επιλογές: μπορούμε να χρησιμοποιήσουμε τις επεκτάσιμες εντολές `\noexpand` ή `\string`.

#### Χρησιμοποιώντας \string⟨token⟩

Μπορούμε να εφαρμόσουμε `\string` στον μονοχαρακτηρικό `⟨token⟩` `~` που έχει κωδικό κατηγορίας 13 (ενεργός χαρακτήρας)· `\string` μετατρέπει το `~` χαρακτήρα για να δημιουργήσουμε ένα token χαρακτήρα που έχει κωδικό κατηγορίας 12. Αν κάνουμε

```
\directlua{
   local x=3
   if x \string~= 4 then
   print("το x δεν είναι ίσο με 4")
   end
}
```

παράγει τον κώδικα Lua που χρειαζόμαστε:

`local x=3 if x ~= 4 then tex.print("το x δεν είναι ίσο με 4") end`

#### Χρησιμοποιώντας \noexpand⟨token⟩

Μπορούμε να χρησιμοποιήσουμε `\noexpand~` για να καταστείλουμε την επέκταση του ενεργού χαρακτήρα `~`

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("το x δεν είναι ίσο με 4")
   end
}
```

Το μη επεκταμένο `~` token περνά στη λίστα tokens που δημιουργείται στο `\directlua` και θα μετατραπεί ξανά σε κείμενο, το οποίο παράγει λειτουργικό κώδικα Lua.

### Χρησιμοποιώντας τον χαρακτήρα \#

Στη γλώσσα Lua ο `#` χαρακτήρας μπορεί να χρησιμοποιηθεί για να βρούμε το μήκος ενός πίνακα. Ωστόσο, αν δοκιμάσουμε τον ακόλουθο κώδικα

```
\directlua{
   local tbl = {}
   tbl[1] = "Γεια"
   tbl[2] = "Κόσμε"
   tex.print("Το μήκος του πίνακα είναι "..#tbl)
}
```

θα περιμέναμε το LuaTeX να στοιχειοθετήσει

`Το μήκος του πίνακα είναι 2`

αλλά παράγει ένα σφάλμα:

`\directlua]:1: απόπειρα λήψης του μήκους μιας αριθμητικής τιμής`

Αυτό το σφάλμα προκαλείται επειδή ο `#` χαρακτήρας συνήθως έχει κωδικό κατηγορίας 6 (παράμετρος μακροεντολής) — ο `#` χαρακτήρας έχει δύο χρήσεις στο TeX/LaTeX: για να υποδηλώνει παραμέτρους μακροεντολών (`#1`, `#2`… `#9`) και το κείμενο αντικατάστασης σε πρότυπα στοίχισης (για `\halign` και `\valign`).

Όταν `\directlua` δημιουργεί tokens για να χτίσει τη λίστα tokens του, βλέπει τον `#` χαρακτήρα με κωδικό κατηγορίας 6 και δημιουργεί ένα κατάλληλο token χαρακτήρα για να τον αναπαραστήσει. Όταν έρθει η ώρα να μετατραπεί η τελική λίστα tokens ξανά σε κειμενική μορφή, το token χαρακτήρα για το # (με κωδικό κατηγορίας 6) δέχεται ειδική μεταχείριση: εξάγεται ως *δύο διαδοχικοί χαρακτήρες*: `##`, με αποτέλεσμα να περνά στη Lua ο ακόλουθος κώδικας:

`local tbl = {} tbl[1] = "Γεια" tbl[2] = "Κόσμε" print(##tbl)`

Κατά τη μετατροπή σε κώδικα Lua, το αρχικό `#` έχει διπλασιαστεί και αυτό προκαλεί σφάλμα:

`\directlua]:1: απόπειρα λήψης του μήκους μιας αριθμητικής τιμής`

Αυτό το πρόβλημα προκύπτει από τη σύνταξη του TeX, η οποία χρησιμοποιεί σύμβολο διπλής δίεσης `##` για να αναπαραστήσει ή να δημιουργήσει ένα μεμονωμένο `#` token· αυτή η σύνταξη χρησιμοποιείται σε μακροεντολές που ορίζουν άλλες μακροεντολές οι οποίες δέχονται παραμέτρους, ή σε μακροεντολές που χρησιμοποιούνται για τη δημιουργία προτύπων για τις `\halign` ή `\valign` εντολές κατασκευής πινάκων. Αυτό είναι αρκετά μπερδεμένο, οπότε ας δούμε ένα παράδειγμα.

#### Παράδειγμα

Ας υποθέσουμε ότι ορίζουμε μια μακροεντολή `\mymacro` που δέχεται μία μόνο παράμετρο, `#1`, αλλά ορίζει επίσης μια δεύτερη μακροεντολή `\foo` η οποία με τη σειρά της δέχεται μία μόνο παράμετρο. Για να γίνει διάκριση μεταξύ της παραμέτρου `#1` που χρησιμοποιείται με `\mymacro` και της ανάγκης να οριστεί `\foo` ώστε να χρησιμοποιεί τη δική της παράμετρο `#1` η σύνταξη του TeX απαιτεί να χρησιμοποιήσετε `##1` μέσα στο `\mymacro` για να αναπαραστήσετε την παράμετρο που θα χρησιμοποιηθεί με `\foo`:

`\def\mymacro#1{\def\foo##1{#1 Γεια##1}}`

Αν γράφατε `\mymacro{Hey!}` θα όριζε τη μακροεντολή `\foo` να είναι

`\def\foo#1{Hey! Γεια#1}`

Σημειώστε ότι το `\mymacro`της παραμέτρου του `#1` (`Hey!`) έχει ενσωματωθεί στον ορισμό της `\foo` και η ακολουθία `##1` έχει μετατραπεί σε `#1` στον ορισμό της `\foo`. Έτσι μπορούμε να χρησιμοποιήσουμε `\foo` ως εξής:

`\foo{, Κόσμε!}`

να στοιχειοθετήσει `Hey! Γεια, Κόσμε!`

Μπορούμε να επιλύσουμε `\directlua`τη μεταχείριση του `#` χαρακτήρα αλλάζοντας προσωρινά τον κωδικό κατηγορίας του πριν το LuaTeX επεξεργαστεί τον κώδικα. Για παράδειγμα:

```
\begingroup
   \catcode`\#=11
   \directlua{
   local tbl = {}
   tbl[1] = "Γεια"
   tbl[2] = "Κόσμε"
   tex.print("Το μήκος του πίνακα είναι "..#tbl)
}
\endgroup
```

Αυτό δημιουργεί τον κώδικα Lua

```
local tbl = {} tbl[1] = "Γεια" tbl[2] = "Κόσμε" tex.print("Το μήκος του πίνακα είναι "..#tbl)
```

το οποίο στοιχειοθετεί το αποτέλεσμα που περιμέναμε:

`Το μήκος του πίνακα είναι 2`

### Χρησιμοποιώντας τον χαρακτήρα %

Στο TeX/LaTeX, ο `%` χαρακτήρας χρησιμοποιείται συνήθως για να περιλάβει σχόλια μίας γραμμής στον κώδικά σας: για να σηματοδοτήσει στη μηχανή TeX ότι πρέπει να αγνοήσει τα πάντα από εκείνο το σημείο μέχρι το τέλος της γραμμής στην οποία το `%` γράφεται. Ωστόσο, μέσα στη γλώσσα Lua, ο `%` χαρακτήρας χρησιμοποιείται σε ορισμένες πολύ χρήσιμες συναρτήσεις επεξεργασίας συμβολοσειρών, όπως `string.format(...)`, `string.gmatch(...)`, και `string.gsub(...)` στις οποίες ο `%` χαρακτήρας παίζει σημαντικό ρόλο ως μέρος της σύνταξης αυτών των συναρτήσεων.

Όταν χρησιμοποιείται με TeX/LaTeX, `%` λειτουργεί ως χαρακτήρας σχολίου επειδή του έχει αποδοθεί κωδικός κατηγορίας 14. Για να συμπεριφέρεται ως κανονικός χαρακτήρας και να απενεργοποιήσουμε τη συνήθη συμπεριφορά του στο TeX/LaTeX, πρέπει να αλλάξουμε τον κωδικό κατηγορίας του σε κάτι ασφαλές, όπως το 12. Το `\directlua` παράδειγμα παρακάτω χρησιμοποιεί αρκετές τεχνικές που συζητήθηκαν νωρίτερα στο άρθρο, μαζί με μία που δεν έχουμε ακόμη αναφέρει: ``\catcode`\^^M=12``, το οποίο μας επιτρέπει να χρησιμοποιούμε σχόλια Lua στον κώδικά μας· αυτό συζητείται παρακάτω.

#### Παράδειγμα

Τα ακόλουθα παραδείγματα είναι δανεισμένα από το [lua-users.org](http://lua-users.org/wiki/StringLibraryTutorial), κατάλληλα τροποποιημένα για χρήση μέσα στο `\directlua`.

```
\documentclass{article}
\begin{document}
\begingroup
\ttfamily
\let\\\relax
\catcode`\^^M=12 %<---το εξετάζουμε περαιτέρω παρακάτω!
\catcode`\%=12
\directlua{
   local str -- δηλώστε μια τοπική μεταβλητή για να κρατήσει το αποτέλεσμα

   tex.print("Χρήση της string.format():".."\\par")

   str=string.format("%s %q", "Γεια", "χρήστη Lua!") -- συμβολοσειρά και εισαγωγική συμβολοσειρά
   tex.print(str.."\\par")
   str = string.format("%c%c%c", 76, 117, 97) -- χαρακτήρας
   tex.print(str.."\\par")
   str=string.format("%e, %E", math.pi, math.pi) -- εκθετική μορφή
   tex.print(str.."\\par")
   str=string.format("%f", math.pi) -- κινητή υποδιαστολή
   tex.print(str.."\\par")
   str=string.format("%g, %g", math.pi, 10^9) -- κινητή υποδιαστολή ή εκθετική μορφή
   tex.print(str.."\\par")
   str = string.format("%o, %x, %X", 99, 125, 125)  -- οκταδικό, δεκαεξαδικό, δεκαεξαδικό
   tex.print(str.."\\par")

   tex.print("\\vskip3mm".."Χρήση της string.gmatch():".."\\par")

   for word in string.gmatch("Γεια σου χρήστη TeX", "%a+") do
      tex.print(word.."\\par")
   end

   tex.print("\\vskip3mm".."Χρήση της string.gsub():".."\\par")
   str=string.gsub("banana", "(an)", "%1-") -- καταγράψτε τυχόν εμφανίσεις του "an" και αντικαταστήστε
   tex.print(str.."\\par")
}
\endgroup
\end{document}
```

Το ακόλουθο στιγμιότυπο οθόνης δείχνει το στοιχειοθετημένο αποτέλεσμα του παραπάνω κώδικα:

![Χρήση των συναρτήσεων συμβολοσειρών Lua στο \directlua](/files/ecd807444069be4b0a3725ebea01f4e7fb0692b1)

## Γιατί ο κώδικας Lua εμφανίζεται σε μία μόνο γραμμή;

Όπως ίσως παρατηρήσατε, όλα τα (παραγόμενα) αποσπάσματα κώδικα Lua που εμφανίζονται στα παραδείγματα αυτού του άρθρου παρουσιάζονται ως μία μόνο γραμμή κειμένου: οι αλλαγές γραμμής που υπήρχαν αρχικά στα `\directlua` αποσπάσματα κώδικα δεν διατηρούνται. Γιατί συμβαίνει αυτό; Είναι επειδή οι αλλαγές γραμμής στον κώδικα Lua έχουν *αφαιρεθεί* κατά την προεπεξεργασία του LuaTeX μέσα στο `\directlua`, με αποτέλεσμα ο κώδικας Lua να γίνεται μία μακριά γραμμή κειμένου. Αυτή η συμπεριφορά μπορεί να αποδοθεί στον τρόπο με τον οποίο οι μηχανές TeX χειρίζονται τους χαρακτήρες τέλους γραμμής — που δηλώνονται με `\\r` (επιστροφή μεταφοράς) και `\n` (τροφοδότηση γραμμής) στη βιβλιογραφία προγραμματισμού. Γιατί ακριβώς μπορεί να χρειάζεται να ανησυχούμε για αυτές τις λεπτομέρειες θα γίνει σαφές όταν συζητήσουμε τη χρήση των μηχανισμών της Lua για σχολιασμό τμημάτων κώδικα.

Όταν το λογισμικό γράφει (αποθηκεύει) ένα αρχείο κειμένου, κάθε ξεχωριστή γραμμή κειμένου τερματίζεται από τους λεγόμενους χαρακτήρες «νέας γραμμής» — ο πραγματικός χαρακτήρας(ες) νέας γραμμής εξαρτάται από την εφαρμογή και το λειτουργικό σύστημα που χρησιμοποιείται για τη γραφή αυτού του αρχείου. Η Wikipedia έχει ένα [ενδιαφέρον άρθρο](https://en.wikipedia.org/wiki/Newline) το οποίο εξερευνά την ιστορία/εξέλιξη των χαρακτήρων νέας γραμμής που χρησιμοποιούνται σήμερα.

Δεδομένου οποιουδήποτε αρχείου κειμένου, οι επιμέρους γραμμές του θα μπορούσαν να τερματίζονται από διάφορους συνδυασμούς χαρακτήρων, οι οποίοι αναφέρονται ως carriage return (χαρακτήρας ASCII/Unicode 13) και/ή line feed (χαρακτήρας ASCII/Unicode 10), και δηλώνονται με `\\r` και `\n` αντίστοιχα. Επειδή οι μηχανές TeX έχουν σχεδιαστεί να είναι ανεξάρτητες από την πλατφόρμα χρειάζονται μια μέθοδο για να παρακάμψουν την εγγενώς εξαρτώμενη από την πλατφόρμα φύση των καταλήξεων γραμμής που χρησιμοποιούνται σε αρχεία κειμένου. Φυσικά, οι μηχανές TeX διαθέτουν μια ενσωματωμένη (αλλά παραμετροποιήσιμη) μέθοδο για τον χειρισμό των χαρακτήρων τερματισμού γραμμής.

### Πώς οι μηχανές TeX χειρίζονται τις καταλήξεις γραμμής

Όταν το LuaTeX επεξεργάζεται `\directlua{⟨code⟩}` διαβάζει το κείμενο που περιέχεται στο `⟨code⟩` και εφαρμόζει τις τυπικές μεθόδους της μηχανής TeX για την επεξεργασία τυχόν καταλήξεων γραμμής που περιέχονται στο `⟨code⟩`. Από προεπιλογή, αυτές οι τυπικές μέθοδοι του TeX προκαλούν την αφαίρεση όλων των χαρακτήρων τερματισμού γραμμής (carriage returns και line feeds) και την αντικατάστασή τους με χαρακτήρες διαστήματος. Λέμε «από προεπιλογή» επειδή ο χειρισμός των χαρακτήρων τερματισμού γραμμής από μια μηχανή TeX μπορεί να τροποποιηθεί μέσω μιας ρυθμιζόμενης από τον χρήστη παραμέτρου που ονομάζεται `\endlinechar`. Εδώ θα δώσουμε μια σύντομη επισκόπηση σε δύο βήματα, αλλά περισσότερες λεπτομέρειες μπορείτε να βρείτε στο άρθρο του Overleaf [Μια εισαγωγή στο \endlinechar: Πώς το TeX διαβάζει γραμμές από αρχεία κειμένου](/latex/el/se-vathos-arthra/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

#### Βήμα 1: Το TeX εισάγει τον δικό του χαρακτήρα τέλους γραμμής

Αφού διαβάσουν μια γραμμή κειμένου από το αρχείο εισόδου σας, οι μηχανές TeX αφαιρούν αμέσως τυχόν `\\r` ή `\n` χαρακτήρες από το τέλος αυτής της γραμμής. Στη συνέχεια, οι μηχανές TeX *εισάγουν* (επαναπροσθήκη) τον δικό τους χαρακτήρα τερματισμού γραμμής στο τέλος της γραμμής. Αυτός ο χαρακτήρας καθορίζεται από την τιμή μιας παραμέτρου TeX που ρυθμίζεται από τον χρήστη και ονομάζεται `\endlinechar` και μέσω αυτού του μηχανισμού οι μηχανές TeX μπορούν να επεξεργάζονται τους χαρακτήρες τέλους γραμμής με τρόπο ανεξάρτητο από την πλατφόρμα: επιλέγουν και ορίζουν τον χαρακτήρα τέλους γραμμής ανεξάρτητα από το τι υπήρχε αρχικά στο αρχείο κειμένου εισόδου.

Συνήθως, οι μηχανές TeX χρησιμοποιούν τη ρύθμιση

`\endlinechar=13`

που είναι ο χαρακτήρας carriage-return (`\\r`). Ωστόσο, οι χρήστες μπορούν πάντα να ορίσουν έναν άλλο κωδικό χαρακτήρα ως τιμή του `\endlinechar`— όπως θα δούμε αργότερα σε αυτό το άρθρο.

Κατά συνέπεια, οποιοιδήποτε χαρακτήρες(ες) τερματισμού γραμμής που περιέχονται στο `⟨code⟩` που πρόκειται να επεξεργαστεί το `\directlua{⟨code⟩}` αφαιρούνται και αντικαθίστανται από έναν μόνο χαρακτήρα που καθορίζεται από την ίδια τη μηχανή TeX. Σημειώστε ότι οι μηχανές TeX εκτελούν αυτή την επεξεργασία στο τέλος της γραμμής αμέσως μετά την ανάγνωση μιας νέας γραμμής κειμένου από ένα αρχείο και *πριν* την επεξεργασία τυχόν χαρακτήρων σε εκείνη τη γραμμή (για τη δημιουργία tokens). Ωστόσο, αυτή δεν είναι η πλήρης ιστορία: ό,τι η μηχανή TeX *δεν* κάνει με αυτούς τους χαρακτήρες τέλους γραμμής (τους έχει εισαγάγει) εξηγεί γιατί ο κώδικας Lua γίνεται μία μόνο γραμμή.

#### Βήμα 2: Το TeX μετατρέπει τον χαρακτήρα τέλους γραμμής του σε διάστημα

Εκτός από την εισαγωγή του δικού τους χαρακτήρα τερματισμού γραμμής, που ορίζεται από την τιμή του `\endlinechar`, οι μηχανές TeX χρησιμοποιούν επίσης κωδικό κατηγορίας 5 για χαρακτήρες που πρέπει να *αντιμετωπίζονται ως* έναν χαρακτήρα τέλους γραμμής. Αυτό έχει ως αποτέλεσμα οι μηχανές TeX συνήθως να λειτουργούν με:

1. έναν χαρακτήρα τέλους γραμμής που ορίζεται από `\endlinechar`;
2. τον ίδιο αυτόν χαρακτήρα *συνήθως* στον οποίο έχει αποδοθεί κωδικός κατηγορίας 5.

Είναι αυτό που κάνει το TeX σε εκείνον τον χαρακτήρα τέλους γραμμής που εξηγεί το αδιέξοδό μας σχετικά με τις μονές γραμμές κώδικα Lua. Όταν μια μηχανή TeX επεξεργάζεται μια γραμμή εισόδου, τελικά θα εντοπίσει τον τελευταίο χαρακτήρα σε εκείνη τη γραμμή: τον χαρακτήρα που ορίζεται από `\endlinechar`. Συνήθως, αυτός ο χαρακτήρας έχει κωδικό κατηγορίας 5, γεγονός που κάνει το TeX να *τον αντικαθιστά* με έναν χαρακτήρα διαστήματος: δηλαδή, στο τέλος των γραμμών το TeX, στην ουσία, αφαιρεί τον χαρακτήρα τερματισμού γραμμής και τον αντικαθιστά με ένα διάστημα. Σημειωτέον, οι μηχανές TeX χρησιμοποιούν επίσης χαρακτήρες με κωδικό κατηγορίας 5 για να εντοπίζουν κενές γραμμές και να ξεκινούν νέα παράγραφο, αλλά δεν θα το εξετάσουμε εδώ.

Φυσικά, επειδή πρόκειται για TeX, μπορείτε να κάνετε κάθε λογής ειδικά τεχνάσματα προγραμματισμού μακροεντολών επαναρυθμίζοντας το `\endlinechar` σε κάποιον άλλο χαρακτήρα, και/ή δίνοντας στον χαρακτήρα που έχει αποδοθεί στο `\endlinechar` μια τιμή κωδικού κατηγορίας της επιλογής σας.

Αν θέλετε να αποτρέψετε το να γίνει ο κώδικας Lua μία μόνο γραμμή κειμένου, μπορείτε είτε να αλλάξετε (προσωρινά) την τιμή που έχει αποδοθεί στο `\endlinechar` ή να αλλάξετε τον κωδικό κατηγορίας του τυπικού τερματιστή γραμμής `\\r`.

### Η παράξενη σημειογραφία ^^ του TeX

Στις επόμενες ενότητες θα συναντήσουμε την ασυνήθιστη σημειογραφία `^^` , η οποία είναι γνωστή ως «μηχανισμός εκτεταμένων χαρακτήρων». Σχεδιάστηκε από τον Knuth ως τρόπος διευκόλυνσης της πληκτρολόγησης «control characters» όπως τερματιστές γραμμής, tab και ούτω καθεξής. Για παράδειγμα:

* `^^J` αντιπροσωπεύει τον κωδικό χαρακτήρα 10 (`\n`, line feed)·
* `^^M` αντιπροσωπεύει τον κωδικό χαρακτήρα 13 (`\\r`, carriage return).

Ακολουθίες χαρακτήρων όπως `^^M` μετατρέπονται στους αντίστοιχους κωδικούς χαρακτήρων νωρίς στη διαδικασία σάρωσης εισόδου του TeX, όταν το TeX διαβάζει χαρακτήρες εισόδου για να δημιουργήσει τα αντίστοιχα tokens χαρακτήρων.

### Αλλάζοντας τον χαρακτήρα που έχει αποδοθεί στο \endlinechar

Θυμίζοντας ότι πρέπει ακόμη να αποτρέψουμε την επέκταση του `~` χαρακτήρα, μπορούμε να γράψουμε

```
\begingroup
\endlinechar=10 % Αλλαγή του χαρακτήρα τέλους γραμμής σε \n
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("το x δεν είναι ίσο με 4")
   end
}% δεν θέλουμε να εμφανίζεται εδώ το \n
\endgroup% ούτε ένα \n εδώ
```

Η παραπάνω ρύθμιση του `\endlinechar` κάνει το LuaTeX να προσθέτει τον κωδικό χαρακτήρα 10 (`\n`, line feed) στο τέλος κάθε γραμμής που διαβάζει. Το κάνουμε αυτό επειδή `\n` (line feed) συνήθως έχει κωδικό κατηγορίας 12, κάτι που μπορείτε να ελέγξετε γράφοντας ``\the\catcode`\^^J``. Επειδή `\n` δεν έχει κωδικό κατηγορίας 5, το LuaTeX δεν θα το μετατρέψει σε χαρακτήρα διαστήματος, οπότε παραμένει στο τέλος κάθε γραμμής που διαβάζει το LuaTeX. Αυτό έχει ως αποτέλεσμα να παραμένει στο τέλος κάθε γραμμής ένας χαρακτήρας με κωδικό 10, περνώντας έτσι στη λίστα tokens που δημιουργείται από το `\directlua` και στη συνέχεια επανεμφανίζεται στον κώδικα Lua μόλις η λίστα tokens μετατραπεί σε κείμενο. Με την παραπάνω αλλαγή, ο κώδικας Lua στέλνεται στον διερμηνευτή Lua ως η ακόλουθη ακολουθία χαρακτήρων:

**\n**local x=3\*\*\n**if x \~= 4 then**\n**print("το x δεν είναι ίσο με 4")**\n**end**\n\*\*

όπου η **\n** σημειογραφία προορίζεται να αναπαραστήσει τον κωδικό χαρακτήρα 10 *όχι* κάποια άγνωστη μακροεντολή `\n`. Τώρα, ο διερμηνευτής Lua θα δει αλλαγές γραμμής στον κώδικα, ακριβώς όπως γράφτηκε αρχικά στο `\directlua` εντολή:

```
   local x=3
   if x ~= 4 then
   print("το x δεν είναι ίσο με 4")
   end
```

Παρεμπιπτόντως, σημειώστε ότι ο πρώτος χαρακτήρας στη συμβολοσειρά κώδικα Lua είναι `\n` (πριν από τη `τοπική` λέξη-κλειδί). Αυτό `\n` προκύπτει από τη γραμμή

`\directlua{`

επειδή υπάρχει αλλαγή γραμμής αμέσως μετά το ανοιχτό `{` και αυτό επίσης διατηρείται. Για να το αποτρέψετε, μπορείτε να γράψετε

`\directlua{%`

### Αλλάζοντας τον κωδικό κατηγορίας του \r

Για να διατηρήσουμε τις αλλαγές γραμμής στον κώδικα Lua μας μπορούμε επίσης να αλλάξουμε τον κωδικό κατηγορίας του `\\r` σε κάτι διαφορετικό από το 5, έτσι ώστε `\\r` να μην αναγνωρίζεται πλέον (να μην αντιμετωπίζεται) ως χαρακτήρας τέλους γραμμής. Με αυτή την τεχνική το LuaTeX εξακολουθεί να χρησιμοποιεί `\endlinechar=13` και θα συνεχίσει να προσθέτει ένα `\\r` στο τέλος κάθε γραμμής· ωστόσο, επειδή `\\r` δεν έχει πλέον κωδικό κατηγορίας 5, το LuaTeX δεν θα αναγνωρίζει τον `\\r` χαρακτήρα ως τέλος γραμμής: δεν θα τον μετατρέπει σε διάστημα και θα τον περνά αλώβητο ώστε να εμφανίζεται στον κώδικα Lua.

Θυμίζοντας ότι πρέπει ακόμη να αποτρέψουμε την επέκταση του `~` χαρακτήρα, μπορούμε να γράψουμε

```
\begingroup
\catcode`\^^M=12 % αλλαγή του κωδικού κατηγορίας του \r σε 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("το x δεν είναι ίσο με 4")
   end
}
\endgroup
```

Σε αυτή την περίπτωση ο κώδικας Lua αποστέλλεται στον διερμηνευτή Lua ως:

**\\\r**local x=3\*\*\r**if x \~= 4 then**\\\r**print("το x δεν είναι ίσο με 4")**\\\r**end**\r\*\*

όπου η `\\r` η σημειογραφία προορίζεται να αναπαραστήσει τον κωδικό χαρακτήρα 13 και όχι κάποια άγνωστη μακροεντολή `\\r`. Όπως και στο `\endlinechar` παράδειγμα, ο διερμηνευτής Lua θα δει τώρα αλλαγές γραμμής στον κώδικα, ακριβώς όπως γράφτηκε αρχικά στο `\directlua` εντολή:

```
   local x=3
   if x ~= 4 then
   print("το x δεν είναι ίσο με 4")
   end
```

Παρεμπιπτόντως, σημειώστε ξανά ότι ο πρώτος χαρακτήρας στη συμβολοσειρά κώδικα Lua είναι `\\r` (πριν από τη λέξη-κλειδί local): αυτό επίσης προκύπτει από τη γραμμή

`\directlua{`

#### Γιατί το \r χρησιμοποίησε κωδικό κατηγορίας 12 αλλά όχι κωδικό κατηγορίας 11;

Η απάντηση οφείλεται στον κίνδυνο να εισαχθούν κατά λάθος σφάλματα που προκαλούνται από `\\r` (με κωδικό κατηγορίας 11) να προστεθεί στο τέλος εντολών TeX/LaTeX που διαβάζονται από το αρχείο εισόδου μας. Δείτε αυτό το παράδειγμα:

```
\begingroup
\catcode`\^^M=11 % αλλαγή του κωδικού κατηγορίας του \r σε 11
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("το x δεν είναι ίσο με 4")
   end
}
\endgroup
```

το οποίο δημιουργεί σφάλμα:

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

Πώς μπορεί να ισχύει αυτό αφού ο `\endgroup` είναι μια τυπική πρωταρχική εντολή του TeX; Η αιτία του σφάλματος είναι αρκετά λεπτή: Όταν το LuaTeX διάβασε την τελευταία γραμμή κειμένου — αυτή που περιείχε `\endgroup`— πρόσθεσε επίσης το `\endlinechar` χαρακτήρα `\\r` στο τέλος εκείνης της γραμμής. Τώρα, στη μνήμη του, το LuaTeX βλέπει την ακολουθία χαρακτήρων

`\endgroup\r`

όπου χρησιμοποιούμε `\\r` για να δηλώσουμε τον χαρακτήρα με κωδικό 13 — όχι το όνομα κάποιας άγνωστης μακροεντολής TeX `\\r`.

Τη στιγμή που το LuaTeX διάβασε αυτή τη γραμμή από το αρχείο κειμένου μας, ο αρχικός `\begingroup` εξακολουθεί να λειτουργεί: βρισκόμαστε μέσα σε μια ομάδα που δεν έχει ακόμη κλείσει εκτελώντας την αντίστοιχη `\endgroup` εντολή — η οποία θα προκαλούσε `\\r` να επανέλθει στην προηγούμενη τιμή κωδικού κατηγορίας του, δηλαδή το 5.

Όταν το LuaTeX αρχίζει να επεξεργάζεται (να δημιουργεί tokens) από τη γραμμή κειμένου `\endgroup\r` αναγνωρίζει τον πρώτο χαρακτήρα `\` ως τον χαρακτήρα διαφυγής, ο οποίος ενεργοποιεί το LuaTeX να αρχίσει να αναζητά το όνομα μιας εντολής. Για να αναγνωρίσει ένα όνομα εντολής το LuaTeX αναζητά μια ακολουθία χαρακτήρων με κωδικό κατηγορίας 11, αλλά επειδή `\\r` επίσης έχει κωδικό κατηγορίας 11, το LuaTeX νομίζει ότι ο `\\r` χαρακτήρας (ακόμη με κωδικό κατηγορίας 11) σχηματίζει *μέρος μιας εντολής* με το όνομα `\endgroup\r` το οποίο, φυσικά, δεν υπάρχει, οπότε το LuaTeX αναφέρει ένα `Απροσδιόριστη ακολουθία ελέγχου` σφάλμα. Γι’ αυτό χρησιμοποιήσαμε κωδικό κατηγορίας 12 και όχι 11.

Επειδή το μήνυμα σφάλματος του LuaTeX γράφτηκε στην κονσόλα, δεν μπορούσαμε εύκολα να δούμε/προσέξουμε τον `\\r` χαρακτήρα, οπότε δεν ήταν προφανές τι είχε προκαλέσει το σφάλμα.

### Γιατί ανησυχούμε για τις καταλήξεις γραμμής;

Ο λόγος είναι για να επιτρέψουμε τη χρήση της μεθόδου σχολιασμού της Lua στον κώδικά σας! Μπορείτε να χρησιμοποιήσετε τον τυπικό μηχανισμό του LuaTeX για την προσθήκη `%` χαρακτήρων για να σχολιάζετε μεμονωμένες γραμμές μέσα στον κώδικά σας· ωστόσο, η γλώσσα Lua έχει τους δικούς της, πολύ χρήσιμους, *πολλαπλών γραμμών* μηχανισμούς σχολιασμού τους οποίους ίσως θέλετε να αξιοποιήσετε.

Ας ξεκινήσουμε βλέποντας τι συμβαίνει αν προσπαθήσουμε να χρησιμοποιήσουμε σχόλια μίας γραμμής στη γλώσσα Lua χωρίς να αντιμετωπίσουμε ζητήματα αλλαγών γραμμής. Ενώ το TeX χρησιμοποιεί τον `%` χαρακτήρα για να σχολιάζει μεμονωμένες γραμμές κώδικα, η Lua χρησιμοποιεί διπλή παύλα: `--`.

Τι συμβαίνει αν προσπαθήσουμε να εκτελέσουμε αυτό:

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Πρόκειται να εμφανίσω το αποτέλεσμα αυτής της σύνθετης δοκιμής
   print("το x δεν είναι ίσο με 4")
   end
}
```

Παίρνουμε ένα σφάλμα:

`[\directlua]:1: αναμενόταν το 'end' κοντά στο <eof>`

Αυτό το σφάλμα προκαλείται από την απουσία αλλαγών γραμμής στον κώδικα Lua που περνά στον διερμηνευτή, ο οποίος βλέπει μόνο μία ενιαία συνεχόμενη συμβολοσειρά στην οποία το σχόλιο ξεκινά στη μέση αυτής της συμβολοσειράς:

```

local x=3 if x ~= 4 then -- Πρόκειται να εμφανίσω το αποτέλεσμα αυτής της σύνθετης δοκιμής print("το x δεν είναι ίσο με 4") end
```

Όλα όσα ακολουθούν μετά το `**local x=3 if x ~= 4 then**` αντιμετωπίζεται ως σχολιασμένο, γεγονός που κάνει τον διερμηνευτή να βλέπει ένα ατελές τμήμα κώδικα Lua, με αποτέλεσμα το σφάλμα

`αναμενόταν το 'end' κοντά στο <eof>`.

όπου `<eof>` σημαίνει τέλος αρχείου.

Όπως πιθανότατα μαντέψατε, πρέπει να το διορθώσουμε διασφαλίζοντας ότι οι αλλαγές γραμμής μεταδίδονται στον παραγόμενο κώδικα Lua, κάτι που μπορούμε να πετύχουμε, για παράδειγμα, αλλάζοντας τον κωδικό κατηγορίας του `\\r` σε 12:

```
\begingroup
\catcode`\^^M=12 % αλλαγή του κωδικού κατηγορίας του \r σε 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Θα εξάγω το αποτέλεσμα αυτής της πολύπλοκης δοκιμής
   print("το x δεν είναι ίσο με 4")
   end
}
\endgroup
```

Τώρα, ο διερμηνέας Lua βλέπει μια συμβολοσειρά, αλλά αυτή περιέχει `\\r` αλλαγές γραμμής όπως γράφονται στο `\directlua` απόσπασμα:

**\\\r**local x=3\*\*\r**if x \~= 4 then**\r\*\*-- Θα εξάγω το αποτέλεσμα αυτής της πολύπλοκης δοκιμής\*\*\r**tex.print("x δεν είναι ίσο με 4")**\\\r**end**\r\*\*

Αυτό, στην πράξη, ισοδυναμεί με το να γράφουμε

```
   local x=3
   if x \noexpand~= 4 then
   -- Θα εξάγω το αποτέλεσμα αυτής της πολύπλοκης δοκιμής
   print("το x δεν είναι ίσο με 4")
   end
```

που σημαίνει ότι η Lua μπορεί να επεξεργαστεί σωστά αυτόν τον κώδικα και να αγνοήσει τη γραμμή που σχολιάσαμε.

**Σχόλια μπλοκ**

Η γλώσσα Lua υποστηρίζει επίσης μια σύνταξη που αποκαλεί [«σχόλιο μπλοκ»](https://www.lua.org/pil/1.3.html) (ή *μακρύ σχόλιο*): αυτά ξεκινούν με `--[[` και ισχύουν μέχρι το αντίστοιχο `]]`. Μπορούμε να χρησιμοποιήσουμε αυτή την πρακτική σύνταξη για να γράψουμε σχόλια πολλών γραμμών ή να σχολιάσουμε τμήματα κώδικα που θέλουμε να αφαιρέσουμε προσωρινά:

```
\begingroup
\catcode`\^^M=12 % αλλαγή του κωδικού κατηγορίας του \r σε 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   --[[ Θα εξάγω το αποτέλεσμα αυτής της πολύπλοκης δοκιμής
   απλώς επειδή πραγματικά είναι
   ένα τόσο εκπληκτικό συμπέρασμα]]
   print("το x δεν είναι ίσο με 4")
   end
}
\endgroup
```

## Συμπερασματικά

Καταρχάς, συγχαρητήρια αν καταφέρατε να διαβάσετε ολόκληρο αυτό το εκτενές άρθρο! Προσπαθήσαμε να δημιουργήσουμε έναν αρκετά ολοκληρωμένο οδηγό για έννοιες και θέματα σχετικά με το TeX που παρέχουν το απαραίτητο υπόβαθρο για να αξιοποιήσετε στο έπακρο το LuaTeX μέσω της `\directlua` εντολής. Ελπίζουμε να έχουμε δημιουργήσει ένα άρθρο που είναι διδακτικό και προσφέρει κάτι χρήσιμο και αξίας στην κοινότητα χρηστών του Overleaf και πέρα από αυτήν. Όπως πάντα, χαιρόμαστε να λαμβάνουμε σχόλια, οπότε μη διστάσετε να [επικοινωνήσετε μαζί μας](https://www.overleaf.com/contact) μας στείλετε σχόλια για αυτό το άρθρο ή προτάσεις για επιπλέον θέματα για τα οποία θα θέλατε να γράψουμε.

Καλή $$\text{Lua}\mathrm{\TeX}\text{-ing!}$$ από τον Graham Douglas και την ομάδα του Overleaf.

### Και τέλος... απλώς χρησιμοποιήστε το πακέτο luacode

Παρόλο που το TeX και η Lua λειτουργούν με θεμελιωδώς διαφορετικούς τρόπους, αυτές οι γλώσσες μοιράζονται έναν αριθμό χαρακτήρων που έχουν «ειδικές σημασίες» στο πλαίσιο κάθε γλώσσας—όπως \\, %, \~, #, ^, &—φυσικά, η Lua και το TeX αποδίδουν αυτές τις ειδικές σημασίες για *πολύ* διαφορετικούς σκοπούς. Η διερεύνησή μας των προβληματικών χαρακτήρων δείχνει γιατί μπορεί να προκύψουν δυσκολίες και πώς μπορείτε να τις επιλύσετε· ωστόσο, η χειροκίνητη διόρθωση πολλών μικρών αποσπασμάτων κώδικα Lua θα μπορούσε να είναι αρκετά κουραστική, επομένως οι περισσότεροι χρήστες προτιμούν να χρησιμοποιούν πακέτα LaTeX που εξαλείφουν αυτές τις προκλήσεις. Ένα τέτοιο πακέτο είναι [`luacode`](https://ctan.org/pkg/luacode?lang=en) το οποίο παρέχει μια σειρά από δυνατότητες σχεδιασμένες να απλοποιούν την εργασία με `\directlua`, αλλά τουλάχιστον τώρα ίσως να έχετε μια καλύτερη κατανόηση των ζητημάτων `luacode` που επιλύει για εσάς.


---

# 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/el/se-vathos-arthra/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.
