> For the complete documentation index, see [llms.txt](https://ayakaleaf-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://ayakaleaf-pro.ayaka.space/latex/tr/derinlemesine-makaleler/09-an-introduction-to-luatex-part-2-understanding-directlua.md).

# LuaTeX'e Giriş (Bölüm 2): \directlua'yı anlamak

## Bu makalenin amacı

Bu makalenin ilk bölümünde, [LuaTeX'e Giriş (Bölüm 1): Nedir—ve onu bu kadar farklı kılan nedir?](/latex/tr/derinlemesine-makaleler/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md), LuaTeX'i son derece çok yönlü bir TeX motoru olarak kısaca inceledik: belge mühendisliği ve üretim çözümleri oluşturmak için geniş bir araç yelpazesi sunan, gelişmiş ve programlanabilir bir dizgi sistemi.

Bu son bölümde, LuaTeX araç setinin en hayati bileşenine yakından bakıyoruz: `\directlua` Lua betik dili aracılığıyla LuaTeX'in dizgi işlemini programatik olarak denetlemek için “geçit” sağlayan komut.

Ancak, LuaTeX'i aracılığıyla tam olarak kullanabilmek `\directlua` biraz arka plan bilgisi gerektirir: TeX'in belirteçleri, belirteç listeleri ve genişletme mekanizması. Bu makalenin amacı, bu temel TeX kavramlarını araştırmak ve açıklamaktır: `\directlua` LuaTeX kullanarak kendi dizgi çözümlerinizi geliştireceğiniz temelleri oluşturmak ve bunun nasıl çalıştığını anlamanızı sağlamak.

Bu makale, temel yönlerini göstermek ve açıklamak için çok sayıda kısa örnek içerir. `\directlua`’nin davranışı, özellikle kısa kod parçalarını tercih ederek aşırı karmaşık kodlardan bilinçli olarak kaçınır. Gerektiğinde, örnekler temel (ham/saf) TeX kullanır—her ne kadar çoğu kişi LaTeX'i (makroları) kullanıp tercih etse de, temel TeX komutlarının avantajı basitliktir.

## LuaTeX İçindeki Lua'ya Giriş

[Lua](https://www.lua.org/about.html) bir betik dilidir; [kaynak kodu](https://www.lua.org/download.html) son derece taşınabilirdir ve yazılım uygulamalarına gömülmesi kolaydır; bu da geliştiricilerin programlarına betik yetenekleri eklemesine olanak tanır. Lua, [birçok uygulamaya](https://en.wikipedia.org/wiki/List_of_applications_using_Lua) gömülmüştür ve yazılım oyunları sektöründe popüler bir seçimdir—belki de en ünlü örnek [World of Warcraft](https://wowwiki.fandom.com/wiki/Lua_functions).

LuaTeX, adından da anlaşılacağı gibi, Lua betik dilini gömülü olarak içeren bir TeX motorudur ve kullanıcıların Lua programlarını (betiklerini) belgelerine ekleyerek LuaTeX'in dizgi davranışını denetlemesine olanak tanır. LuaTeX'i doğrudan denetlemenin yanı sıra, kullanıcılar Lua'yı, TeX dili kullanılarak elde edilmesi son derece zor olabilecek görevleri gerçekleştirmek için son derece yetenekli bir programlama dili olarak da kullanabilirler—ki bu dil, her adil ölçüte göre, öğrenmesi ve ustalaşması zor bir dildir. Lua'nın eklenmesi ve entegrasyonu sayesinde LuaTeX, doğrudan iki programlama dilini destekleyen çok yönlü ve güçlü bir TeX motoru haline gelir.

### Belgenizde Lua ve TeX kullanmak: \directlua girin

Lua ve TeX iki *çok farklı* programlama dilidir: Lua, çoğu insanın programlama dili olarak düşündüğüne çok daha yakındır; ancak TeX, kategori kodları, belirteçler, makrolar ve genişletme mekanizmasıyla, program yazılacak bir dil hakkındaki çoğu insanın deneyiminden/beklentisinden oldukça uzaktır. Ancak tarih gösterdi ki, TeX dili varlığını sürdürmüştür; çünkü tasarlandığı işte iyidir: çalışma biçimi biraz esrarengiz olsa bile dizgiyi denetlemek.

Lua ve TeX dillerini tek bir TeX belgesinde bir araya getirme zorluğunu ele almak için LuaTeX geliştiricileri, `\directlua` adı verilen yeni bir komut tanıttı; bu komut Lua'yı—hem bağımsız bir programlama dili olarak hem de LuaTeX'in dizgi davranışını denetlemek için—kullanmanın yoludur.

Bu `\directlua` komutu, kullanıcıların TeX belgelerine Lua kodu gömmesine olanak tanır; bu kod daha sonra LuaTeX'in yerleşik Lua dil yorumlayıcısına iletilir. Ancak, `\directlua` size ayrıca *birleştirme* Lua ve (La)TeX kodunu aynı `\directlua` komut içinde bir araya getirme olanağı da sağlar—ancak bu, Lua ve TeX tabanlı programlama dilleri arasındaki temel farklılıklar nedeniyle ek karmaşıklıklar getirir. (La)TeX ve Lua kodu birleşimini kullanırken temel zorluk, bu iki dilin uyum içinde bir arada bulunmasını ve “birbirinin işine karışmamasını” sağlamaktır.

`\directlua` kısa belge içi Lua kod parçalarıyla kullanım için en uygunudur; ancak isterseniz daha kapsamlı Lua programlarıyla da kullanabilirsiniz. Genel olarak, daha büyük Lua programları ve Lua kod kütüphaneleri, Lua'nın `dofile()` işlevi kullanılarak bir `\directlua` komutu içinde yüklenebilen harici dosyalara kaydedilir. TeX işleme açısından, harici Lua kod dosyaları kullanmanın önemli bir avantajı, TeX'in kategori kodu mekanizmasından kaynaklanan karmaşıklıklardan kaçınmaktır—bu konu bu makalede tam olarak incelenmektedir.

### \directlua'nın daha resmi tanımı

Bu [LuaTeX Başvuru Kılavuzu](http://www.pragma-ade.com/general/manuals/luatex.pdf) şöyle açıklar (biraz değiştirilmiş hâliyle): `\directlua` Lua kodunu TeX girdisiyle birleştirmek için birkaç yeni ilkel komuta ihtiyaç vardır. İlkel komut

> Lua kodunu hemen yürütmek için kullanılır. Temel sözdizimi şöyledir: `\directlua` \directlua{⟨kod⟩} `\directlua{⟨kod⟩}`. The `⟨kod⟩` tamamen genişletilir ve ardından Lua yorumlayıcısına aktarılır. Okuma ve genişletme işlemi `⟨kod⟩`ya uygulandıktan sonra, ortaya çıkan belirteç listesi `\the\toks`.

ile gösteriliyormuş gibi bir dizgeye dönüştürülür. Elbette bu teknik olarak doğrudur, ancak belki de belirteçler ve genişletme gibi daha alt düzey TeX süreçleri hakkında biraz bilgi olmadan anlamak pek kolay değildir.

## \directlua'yı anlamak: Hangi konuları ele alacağız?

Bu makalede bazı temel arka plan konularına daha yakından bakacak ve nasıl `\directlua` çalıştığını ve TeX ile Lua'yı belgenizde birleştirirken nerede (veya neden) dikkatli olmanız gerektiğini göstermek üzere tasarlanmış bir dizi örnek sunacağız. `⟨kod⟩`.

\directlua'yı anlamak için bir temel sağlamak üzere aşağıdaki konuları yeterli ayrıntıda inceleyeceğiz `\directlua` ve içindeki kodun “ön işleme” tabi tutulmasını sağlayan süreçler:

* kategori kodları ve TeX belirteçleri: metni belirteçlere ve belirteçleri metne dönüştürmek;
* TeX'in genişletme süreci (ve genişletmeyi engelleme);
* karakterler ve dizgiler için Lua kaçış dizileri/mekanizmaları;
* Lua tarzı yorumlar kullanmak;
* LuaTeX'in Lua API'sine kısa bir giriş.

TeX motorlarının belirteçleri nasıl oluşturup kullandığını anlarsanız ve TeX'in genişletme mekanizmasının farkına varırsanız, LuaTeX'in inanılmaz çok yönlülüğünü açığa çıkarmak için gerekli temellere sahip olursunuz `\directlua` komutunu.

## Temeller: metinden belirteçlere ve belirteçlerden metne

Overleaf, TeX belirteçlerine ve ilgili kavramlara ayrıntılı bir bakış sunan birkaç makale yayımladı; bu yüzden burada tüm bu materyali tekrarlamayacağız; bunun yerine, `\directlua`.

hakkında daha iyi bir anlayış geliştirmekle ilgili alanları/konuları özetleyeceğiz.

* [TeX belirteci nedir?](/latex/tr/derinlemesine-makaleler/53-what-is-a-tex-token.md)
* [TeX belirteç listesi nedir?](/latex/tr/derinlemesine-makaleler/54-what-is-a-tex-token-list.md)
* [\expandafter nasıl çalışır: TeX belirteçlerine giriş](/latex/tr/derinlemesine-makaleler/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)
* [Altı bölümlük bir seri: TeX makroları gerçekte nasıl çalışır?](/latex/tr/daha-fazla-konu/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### Karakter belirteçlerini anlama

Bir TeX motorunun bir metin dosyasından okuyabildiği herhangi bir karakter iki sayısal değerle temsil edilir:

* onun *karakter kodu* (ASCII değeri ya da günümüzde Unicode kod noktası);
* ikincisi, TeX merkezli bir değer olup adı *kategori kodu*.

Kategori kodları hakkında daha fazla bilgi edinmek isteyen okuyucular, Overleaf tarafından yayımlanan şu girişi okuyabilirler: [Peki nereden başlayalım? Kategori kodlarıyla](/latex/tr/daha-fazla-konu/19-how-tex-macros-actually-work-part-1.md#so2c-where-do-we-start3f-with-category-codes).

Örneğin, bir TeX motoru bir karakteri okusa `Bir` iki bilgi parçasına erişimi olur: `Bir`karakter kodu (65) ve kategori kodu (genellikle 11). TeX bu karakteri girdiye kattığında `Bir`, kategori kodu değişmeyecektir; ancak kullanıcı makroları, sonrakileri etkileyebilecek kategori kodu değişiklikleri yapabilir *sonraki* karakteri `Bir` henüz okunmamış olan *karakterler için* TeX tarafından. Sonuç olarak, TeX'in o *bu* karakteri `Bir`, *az önce okunan*karakterin kategori kodunun 11 olduğunu kaydetmesi gerekir. Bunu yapmak için TeX, (65,11) tamsayı çiftini kullanarak kendisinin bir *karakter belirteci*adını verdiği başka bir tamsayı değerini hesaplar. TeX'in iç işlemesine iletilen bu belirteç değerini hesaplayarak, söz konusu `Bir` ve kategori kodu *birbirine bağlanır*; gerçekte, o karakter belirteci *şifreler* TeX motorunun daha iç katmanlarında herhangi bir sonraki dizgi işlemi için o karakter hakkında bilmesi gereken veriyi.

#### Karakter belirteçleri nasıl hesaplanır?

İlk olarak, TeX motorlarının sözde *aktif karakterler*oluşturmak amacıyla kategori kodu 13 kullandığını hatırlamalıyız: kategori kodu 13 olan herhangi bir karakter mini bir makro gibi davranır; dolayısıyla, aşağıda göreceğimiz gibi, aktif karakterlerin belirteçleri 10, 11 veya 12 gibi diğer kategori kodlarına sahip normal karakterlerden farklı şekilde hesaplanır.

için *aktif olmayan* karakterler:

* eski 8-bit motorlar (Knuth'un TeX'i, e-TeX, pdfTeX) için karakter belirteçlerini *aktif olmayan* karakterler için kullanarak hesaplar

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

* LuaTeX için ise, Unicode karakter değerleriyle başa çıkması gerektiğinden, *aktif olmayan* karakterlerin hesabı benzerdir ancak çok daha büyük tamsayı değerleri üretir:

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

Daha önce kategori kodu 11 olan A harfi için verdiğimiz örneğe geri dönersek, LuaTeX bir $$2^{21} \times 11 + 65 = 23068737$$karakter belirteci değeri *hesaplar* Bu belirli A karakterini kategori kodu değeri 11'e bağlar. Kullanıcı makroları sonraki herhangi bir A karakteri için kategori kodunu değiştirebilir; ancak bunun kategori kodu, LuaTeX'in iç işleyişinden geçerken kullanılmak üzere bir belirtece dönüştürülerek sabitlenmiştir. LuaTeX, bu karakterin okunduğu anda belirlenen amaçlanan anlamını korumuş veya şifrelemiştir.

TeX motorları toplam [16 farklı kategori kodu](/latex/tr/daha-fazla-konu/43-table-of-tex-category-codes.md) ve *kullanır;* bu kategori kodlarının herhangi biri, `\catcode` komutu aracılığıyla, *kullanır;* TeX motorunun okuyabildiği herhangi bir karaktere atanabilir. Kategori kodlarındaki değişiklikler, TeX motorlarının girdideki belirli karakterleri işleme biçimini değiştirmek için kullanılır; bu da TeX kullanıcılarının özel dizgi sonuçları veya davranışları üreten makrolar yazmasına olanak tanır.

**Aktif karakterler**

Belirtildiği gibi, TeX motorları bir karaktere “özel bir anlam” yüklemek için kategori kodu 13 kullanır ve onu sözde *aktif karakter* haline getirir; bu karakter bir mini makro gibi davranır: başında `\` gerekmez; kategori kodu nedeniyle tek başına duran karakter, makro benzeri davranışını tetiklemek için yeterlidir.

Bir aktif karakter mini bir makro gibi davrandığından, bir *karakter belirteci* değil, ikinci bir (tamsayı) belirteç türü olan bir *komut belirteci*ne dönüştürülür. Bunlar şu şekilde hesaplanır:

* eski 8-bit motorlar (Knuth'un TeX'i, e-TeX, pdfTeX) için aktif karakterlerin belirteçleri şu yolla hesaplanır:

1. ara bir değer hesaplanır; buna $$\text{curcs}$$ (**cur**rent **c**ontrol **s**equence) adı verilir; burada $$\text{curcs} = \text{character code} + 1$$3. belirteç değeri hesaplanır; burada $$\text{active character token} = \text{curcs} + \text{4095}$$

* LuaTeX için hesaplama biraz daha karmaşıktır, çünkü aktif hâle getirilebilecek herhangi bir Unicode karakteriyle başa çıkması gerekir:

1. ara tamsayı değeri hesaplayın $$\text{curcs}$$ adı verilen bir *hash işlevi* uygulayarak, aktif karakterin UTF-8 ile ifade edilmiş Unicode kod noktası değerine: $$\text{curcs}=\texttt{hashfunction}\text{(UTF-8 text for Unicode value of active character)}$$3. tamsayı belirteç değerini hesaplayın: $$\text{active character token} = \text{curcs} + 2^{29} - 1$$

**Örnekler**

* 8-bit motorlar: aktif karakter için belirteç hesaplaması `~` (karakter kodu 126) şu sonucu verir $$\text{curcs} = 126 + 1 = 127$$ve böylece şu belirteç değerini verir $$4095 + 127 = 4222$$.
* LuaTeX: aktif karakter için belirteç hesaplaması `~` şu sonucu verir $$\text{curcs}=3186$$ ve şu belirteç değerini verir $$3186 + 2^{29} - 1 = 536874097$$. LuaTeX belirteçleri çok daha büyük tamsayı değerleri kullanır!

### Komut belirteçlerini anlama

işlemenin yanı sıra *tek tek* karakterleri, TeX motorları elbette *dizileri* işleyebilir; bunlara *komutlar* (ya da daha doğru ifadeyle, *komut dizileri*) adı verilir. Gelenek gereği, `\` karakteri bir komutun başlangıcını belirtmek için kullanılır; ancak bu yalnızca bir uzlaşıdır—aslında, kategori kodu 0 (kaçış karakteri) olan herhangi bir karakter bunun yerine kullanılabilir.

TeX motorları iki tür komut tanır; bunlar *komut sözcükleri* ve *komut sembolleri*:

* **komut sözcükleri**olarak bilinir: kategori kodu 11 olan bir veya daha fazla karakterden oluşan komutlar;
* **komut sembolleri**olarak bilinir: o karakterin kategori kodu *kullanılmıyor* 11 olan tek karakterli komutlar; örneğin `\$`, `\#` ya da `\\`.

**Not**TeX ilkel komutları `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` ve `\toksdef` da komut dizilerini tanımlamak için kullanılır; ancak normal makro tanımlarından farklı olarak, ortaya çıkan komut dizileri (komut sözcükleri veya komut sembolleri) *genişletilebilir değildir*—bunları aşağıda daha ayrıntılı inceleyeceğiz.

#### Komut belirteçleri nasıl hesaplanır?

Aktif karakterlerde olduğu gibi, TeX motorları komutları temsil etmek için ikinci tür tamsayı belirteç değerini kullanır: *komut belirteçleri*—unutmayın ki aktif karakterler de mini makro gibi davrandıkları için komut belirteçleri üretir.

8-bit motorların komut-belirteci tamsayılarını oluşturmak için kullandığı hesaplamalar bu [Overleaf makalesinde](/latex/tr/derinlemesine-makaleler/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#how-tex-calculates-token-values)bulunabilir. Burada, LuaTeX için komut belirteci hesaplamalarının temel adımlarını özetleyeceğiz—bunlar biraz farklıdır, çünkü LuaTeX, 8-bit değerlerden önemli ölçüde daha büyük olabilen Unicode karakter kodu değerlerini işlemelidir; ancak LuaTeX'in hesaplamaları, eski 8-bit motorların kullandığı aynı genel ilkelere uyar.

Gelen bir komutu algıladıktan sonra, LuaTeX de dâhil olmak üzere TeX motorları baştaki `\` karakteri yok sayar: bu karakter, komut belirteci değerlerinin hesaplanmasında kullanılmaz; yalnızca bir TeX motoruna bir komut işlemesi gerektiğini bildiren bir “anahtar” görevi görür. Komut belirteci değeri, komut adında bulunan (bir veya daha fazla) karakter dizisi kullanılarak hesaplanır—LuaTeX, komut sembolleri ve komut sözcükleri için komut belirteçlerini aynı algoritmayı kullanarak hesaplar:

1. ara tamsayı değeri hesaplayın $$\text{curcs}$$ adı verilen bir [hash işlevi](https://en.wikipedia.org/wiki/Hash_function) komut adında bulunan karakterlerin Unicode UTF-8 dizgesine: $$\text{curcs}=\texttt{hashfunction}\text{(Unicode UTF-8 string of characters in command name)}$$3. komut belirteci değeri hesaplanır; burada $$\text{command token} = \text{curcs} + 2^{29} - 1$$

**Örnekler**

* için `\\` komut (bir komut sembolü), LuaTeX $$\text{curcs}=94$$hesaplar, ve bu da `\\` için bir belirteç değeri oluşturur $$94 + 2^{29} - 1 = 536871005$$.
* için `\vskip` ilkel komut (bir komut sözcüğü) LuaTeX $$\text{curcs}=3560$$hesaplar, ve bu da `\vskip` için bir belirteç değeri oluşturur $$3560 + 2^{29} -1 = 536874471$$.
* kullanıcı tanımlı makro için `\mynewmacro` (bir komut sözcüğü) LuaTeX $$\text{curcs} = 2971$$hesaplar, ve bu da `\mynewmacro` için bir belirteç değeri oluşturur $$2971 + 2^{29} -1 = 536873882$$.

Oluşturulduktan sonra, belirteçler sözde *belirteç listeleri* aracılığıyla daha sonra kullanılmak üzere saklanabilir ya da TeX motorunun içinde daha ileri işlem için hemen aktarılabilirler. Belirteçleri temsil etmek için tamsayı değerlerin kullanılması yalnızca tüm hesaplama platformlarında/işletim sistemlerinde çalışmakla kalmaz, aynı zamanda TeX'in veriyi depolaması/işlemesi için son derece verimli bir yoldur.

### Bir TeX motoru belirteç türünü nasıl tanımlar? (komut ya da karakter)

Belirli bir tamsayı belirteç değeri verildiğinde, $$T$$bir TeX motoru, $$T$$ bir komutu mu yoksa bir karakteri mi temsil ettiğini, $$T$$ belirli bir $$\text{threshold value}$$değeri aşıp aşmadığını test ederek kolayca belirleyebilir; bu $$\text{threshold value}$$ TeX motoruna bağlıdır. Eğer $$T \geq \text{threshold value}$$ sonra $$T$$ bir komut belirtecidir; aksi hâlde $$T$$ bir karakter belirtecidir. Bu $$\text{threshold value}$$ şudur $$4095$$ 8-bit motorlar için $$2^{29}-1$$ ve LuaTeX için 536.870.911'dir. Knuth, belirteç hesaplama formüllerinde kullanılan yöntemleri, kendi TeX motorunun ve koduna/mimarîsine dayanan sonraki tüm motorların belirteç değerlerini hızlı ve kolay bir şekilde test edebilmesi için tasarlamıştır.

## Belirteçler parçalarına ayrılabilir (ve yeniden metne dönüştürülebilir)

Belirteçler (tamsayılar), bir TeX motorunun bir giriş öğesi (karakter veya komut) hakkında kaydetmesi gereken her şeyi “şifrelediği” mekanizmadır. Ancak bazı zamanlarda bir TeX motorunun belirteçleme sürecini tersine çevirmesi gerekir—o belirteç değerini üretmek için başlangıçta neyin okunduğunu bulmak için—tek bir karakter veya bir komut adını oluşturan bir ya da daha fazla karakter dizisi:

* **karakter belirteçleri için**: Her karakter belirteci, onu oluşturan iki parçaya ayrılabilir: karakter kodu ve o karaktere atanmış karşılık gelen kategori kodu *ilk okunduğu anda*. Tüm TeX motorları gibi LuaTeX de bu özgün kategori kodu atamasını değiştirmez; ancak daha sonraki iç işleme faaliyetleri sırasında bundan yararlanır.
* **komut belirteçleri için:** Bunlar biraz daha ayrıntılıdır; ancak aktif karakterlere ait belirteçler de dâhil olmak üzere LuaTeX'in komut belirteçlerini nasıl hesapladığına bakarsanız, bir kalıp izlediklerini görürsünüz: $$\text{command token} = \text{curcs} + 2^{29} -1$$

burada $$\text{curcs}$$ oluşturulan komut belirteci türüne göre hesaplanır: aktif karakter, komut sembolü veya komut sözcüğü. $$\text{curcs}$$ değişkeni *Web2C* bir TeX motorunun iç işlemlerinin önemli bir bileşenidir: herhangi bir komut belirteci (tamsayı) değeri verildiğinde LuaTeX $$\text{curcs}$$ değerini bu komut belirtecinden $$\text{curcs} = \text{token value} - (2^{29} -1)$$.

### Neden $$\text{curcs}$$ bu kadar önemli?

Dahili TeX değişkeni $$\text{curcs}$$ (**cur**rent **c**ontrol **s**dizisi) bir TeX motorunun içindeki “kaput altı” işlemlerinin son derece önemli bir bileşenidir. Kodunuzda bunu doğrudan kullanamaz ve erişemezsiniz; ancak $$\text{curcs}$$ kritik bir rol oynar; çünkü TeX motorları $$\text{curcs}$$ geçerli değeri tüm komutlar hakkında motorun bildiği verileri saklayan dahili tablolarda bir dizin olarak kullanır. Bu tablolar, bir komutun mevcut anlamı hakkında bilgi saklar: ne yapar ya da neyi temsil eder ve ayrıca, o $$\text{curcs}$$ değerini hesaplamak için başlangıçta kullanılan karakter dizisini de kaydederler. Bir komut belirtecinden $$\text{curcs}$$ değerini çıkararak bir TeX motoru, herhangi bir (komut) belirtecine karşılık gelen adı, yani insan tarafından okunabilir metni belirleyebilir ve böylece `\directlua`işleyişinin temel bir yönü olan belirteçten metne dönüştürmeleri gerçekleştirebilir.

### Tamsayı belirteçleri yeniden karakterlere veya karakter dizilerine (komut adları) dönüştürme

TeX motorlarının giriş karakterlerini veya karakter dizilerini tamsayı belirteç değerlerine dönüştürdüğünü gördük; ancak bazen bir TeX motorunun bu süreci *tersine çevirmesi* gerekir—bu tamsayı belirteç değerlerini oluşturmak için başlangıçta kullanılan insan tarafından okunabilir metni çıktı olarak vermek için; örneğin:

* ekrana hata veya uyarı mesajları yazmak veya `.log` dosyası;
* TeX/LaTeX kodunu bir metin dosyasına \write aracılığıyla çıktı olarak vermek `\write` komutuyla;
* belirteç dizisini metne dönüştürürken `\directlua` (az sonra göreceğimiz gibi!)

#### Karakter belirteçlerini metne dönüştürme

Belirtildiği gibi, aktif olmayan karakterlere ait belirteçler, bir giriş karakterinin kategori kodu ve karakter kodu (Unicode değeri) kullanılarak hesaplanır. LuaTeX şu formülü kullanır:

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

Tamsayı $$\text{character token}$$ değerini bölerek bileşen karakter kodunu elde etmek basit bir programlama görevidir ($$\text{Unicode value}$$) ve $$\text{category code}$$.

#### Komut belirteçlerini metne dönüştürme

Tüm TeX motorları, “bildikleri” her komutun adını (karakter dizisini) saklar: ister o komut kullanıcı tanımlı bir makro ister yerleşik bir ilkel komut olsun—ilkel komut adlarının saklanması, TeX motoru çalışmaya başladığında, kodunuzu işlemeye çok daha önce başlar. Kullanıcı tanımlı komutlar (makrolar) için, o makronun adı (başındaki `\`çıkarılmış olarak), TeX motorları içindeki makro tanımlama süreçlerinin bir parçası olarak saklanır.

Bir TeX motorunun, bir tamsayı komut belirtecinin başlangıçta hesaplandığı insan tarafından okunabilir metne erişmesi veya bunu çıktı olarak vermesi gerektiğinde, önce o belirteç için $$\text{curcs}$$ değerini belirler; LuaTeX'te, $$\text{curcs} = \text{token} - (2^{29} -1$$). Bir komut belirtecinden çıkarılan $$\text{curcs}$$ değerini kullanarak bir TeX motoru, *dize havuzu* olarak adlandırılan dahili bir veri yapısına erişerek, o belirli $$\text{curcs}$$ değerini ve dolayısıyla karşılık gelen komut belirtecini hesaplamak için başlangıçta kullanılan insan tarafından okunabilir karakter dizisini belirleyebilir.

Gördüğümüz gibi, bu belirteç işleme faaliyetleri—karakter dizilerini tamsayı belirteç değerlerine dönüştürmek ve tamsayı belirteç değerlerini yeniden karakter dizilerine dönüştürmek (“belirteç çözme”)— *temel mekanizmalar* olup `\directlua`.

## Belirteç listeleri

Bir TeX motoru girdi okurken, karakter ve komut belirteçleri üretirken (ve bunları işlerken), motora belirteçleri daha ileri işleme için geçici olarak ilerletmeyi durdurmasını, bunun yerine daha sonra kullanılmak üzere saklamasını söyleyen bazı komutlarla karşılaşabilir. En yaygın örnek, makro tanımlama komutlarından biri kullanılarak bir makro tanımlamaktır `\def`, `\edef`, `\gdef` ya da `\xdef`—LaTeX komutları gibi `\newcommand` daha sonra gerçek makro tanımlama sürecini gerçekleştiren, düşük seviyeli ilkel komutların etrafında kurulmuş ek işlevler sağlayan makrolardır. Bir makro, belirli bir saklanmış belirteçler listesinin adı olarak düşünülebilir: bir belirteç listesi.

TeX motorları *yoğun* bir şekilde belirteç listelerini kullanır, özellikle de [geçici dahili listeleri](/latex/tr/derinlemesine-makaleler/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) dahili işleme amaçları için kullanılır. Her TeX motoru, kullanıcının veya TeX motorunun kendisinin ihtiyaç duyduğunda kullanabilmesi için saklanan belirteç listeleri oluşturmak üzere kullanıcı düzeyinde komutlar da sağlar. Belirteç-listesi-oluşturma komutlarının sayısı (yerleşik ilkel komutlar), TeX motoruna göre değişir; ancak hepsi, her motor tarafından desteklenen ortak bir asgari komut setini paylaşır; örneğin `\\toks` ilkel komutu.

Uygulamada, bir belirteç listesi yalnızca saklanmış bir tamsayı değerler dizisidir:

* girdi okunur ve tek tek belirteçler oluşturulur (hesaplanır), bir karakteri veya komutu temsil eder;
* ardından her belirteç saklanır ve belirteçlerin girdiden üretildiği sıra korunur.

TeX motorları belirteç listelerini [bağlı liste](https://en.wikipedia.org/wiki/Linked_list) adı verilen bir veri yapısı kullanarak saklar (tek bağlı türü). Belirteç listeleri hakkında daha fazla bilgi edinmek isteyen okuyucular, Overleaf makalesini okumaya davetlidir [TeX belirteç listesi nedir?](/latex/tr/derinlemesine-makaleler/54-what-is-a-tex-token-list.md) ki bu makale, bir belirteç listesinin arkasındaki kavramları/fikirleri kurmak için bir benzetme kullanır. TeX'in belirteç listelerinin derinlemesine incelenmesi ve bunların makro işlemede nasıl kullanıldığı, Overleaf makale serisinde bulunabilir [TeX makroları gerçekte nasıl çalışır?](/latex/tr/daha-fazla-konu/01-a-six-part-series-how-do-tex-macros-actually-work.md)

#### Grafik biçiminde bir belirteç listesi

Aşağıdaki grafik, aşağıdaki girdiden üretilen karşılık gelen belirteç değerleriyle birlikte LuaTeX tarafından oluşturulmuş bir belirteç listesini göstermektedir

`Merhaba, \TeX! \hskip 5bp`

Örneğin, eğer `\mymacro` as `\def\mymacro{Merhaba, \TeX! \hskip 5bp}` tanımının `\mymacro` bellekte böyle bir belirteç listesi kullanılarak saklanacağını düşünelim:

![](/files/2b8381c26fd49b4be7ea0b5d2534219cc1804add)

Belirteç listesi, adı verilen bağlı öğeler dizisidir *düğümler*, LuaTeX'in listedeki her öğeyi tutmak için ayrılan küçük bir bellek paketine verdiği addır (zincirdeki tek tek halkalar gibi). Her düğüm bir tamsayı belirteç değeri ve zincirdeki *sonraki* düğümün bellek adresini içerir ve bir [bağlı liste](https://en.wikipedia.org/wiki/Linked_list)adı verilen veri yapısını oluşturur. Son düğüm, sonraki düğüm için özel bir “boş değer” kullanarak listenin sonunu gösterir—çünkü ortada bir düğüm yoktur.

**Notlar:**

* Kolaylık olması için, her bir düğümün adresini ekledik; ancak uygulamada bu veri belirteç listesi düğümlerinde saklanmaz; yalnızca *sonraki düğüm* adresine
* TeX motoru belirteç listelerini oluşturmak için ihtiyaç vardır. “Her belirtecin anlamı” başlıklı grafikteki ikinci sütun, her düğümde bulunan belirteç hakkındaki bilgileri içeren bir dizi gri kutu gösterir: bunlar yalnızca bilgi amaçlıdır ve *olmaz* gerçekten belirteç listesinde saklanan verinin bir parçasını oluşturmaz.

Yukarıda gösterilen belirteç listesinde bulunan belirteç değerlerinin bir tablosu aşağıdadır:

|                 |                |                                                                              |                     |
| --------------- | -------------- | ---------------------------------------------------------------------------- | ------------------- |
| **Girdi öğesi** | **Girdi türü** | <p><strong>Kategori kodu</strong><br><br><strong>(karakter ise)</strong></p> | **Belirteç değeri** |
| H               | karakteri      | 11                                                                           | 23068744            |
| i               | karakteri      | 11                                                                           | 23068777            |
| ,               | karakteri      | 12                                                                           | 25165868            |
|                 | karakteri      | 10                                                                           | 20971552            |
| \TeX            | komut (makro)  |                                                                              | 536871539           |
| !               | karakteri      | 12                                                                           | 25165857            |
|                 | karakteri      | 10                                                                           | 20971552            |
| \hskip          | komut (ilkel)  |                                                                              | 536874247           |
| 5               | karakteri      | 12                                                                           | 25165877            |
| b               | karakteri      | 11                                                                           | 23068770            |
| p               | karakteri      | 11                                                                           | 23068784            |

**Not:** Orijinal girdi metnimizde `\hskip` komutundan sonra bir a karakteri vardır, ancak belirteç listesindeki bu karakteri temsil eden bir belirteç yoktur. O karakter, LuaTeX'in giriş tarama (okuma) süreci tarafından emilmiştir; çünkü LuaTeX'in `\hskip` komutunu.

## \directlua gerçekten nasıl çalışır

Şimdi tokenları, token listelerini ve tokenları metne dönüştürmeyi incelediğimize göre, bir sonraki zorluk TeX motorunun token kavramını anlamaktır *genişletme*.

Belirtildiği gibi, `\directlua{⟨kod⟩}` işlem yapması istenebilir `⟨kod⟩` hem Lua hem de TeX/LaTeX kodu içeren ancak LuaTeX’in yerleşik Lua dil yorumlayıcısının TeX’i veya LaTeX’i anlamadığı bir şeydir: peki bu nasıl çalışabilir? Bunun mümkün olması nasıl olur da `⟨kod⟩` Lua yorumlayıcısını anlamadığı komutlarla tamamen karıştırmadan TeX/LaTeX yönergelerini içerebilir? Örneğin, aşağıdaki `\directlua` komutu yalnızca TeX makrolarını kullanır, ancak çalışır:

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

Bu `\directlua` komutu LuaTeX'te dizgi çıktısı üretir `Merhaba` ama Lua dili TeX makrolarını anlamadığı hâlde bu neden ve nasıl çalışır?

Cevap, daha önce alıntıladığımız şu açıklamanın içinde yer alıyor: [LuaTeX Başvuru Kılavuzu](http://www.pragma-ade.com/general/manuals/luatex.pdf) ama şunu düşünebiliriz ki `\directlua{⟨kod⟩}` LuaTeX’in başlangıçta “ön işleme” yapmasıyla çalışır `⟨kod⟩` Lua yorumlayıcısına herhangi bir şey aktarılmadan önce. Bu “ön işlem”in niteliği—yani bunun gerçekte ne anlama geldiği ve sizin için sonuçları `⟨kod⟩`—bir sonraki ele alacağımız konu olacak; böylece bunun gücünden ve esnekliğinden yararlanmak isteyen okuyuculara yardımcı olacağız `\directlua`.

### LuaTeX \directlua’yı nasıl işler: İlk bakış

Anlayışımızı geliştirmek için `\directlua`’in “ön işleme” faaliyetlerine, neler olduğuna genel bir bakış sunan aşağıdaki basitleştirilmiş diyagramla başlayabiliriz.  `⟨kod⟩` sağlanan `\directlua{⟨kod⟩}` önce yukarıda tartışılan süreçler ve hesaplamalar kullanılarak tokenlara dönüştürülür; bu token dizisi bir token listesinde saklanır. Bu token listesi oluşturulduktan sonra, listedeki her token yeniden metinsel gösterimine dönüştürülür: her tokenın—karakter tokenı ya da komut tokenı—ürettiği metin birleştirilir (ardışık olarak eklenir) ve yürütme için Lua yorumlayıcısına aktarılan tek bir kod dizgesi oluşturulur.

![](/files/7641734317fe68d25a051d0db8a437050a301ee3)

Ama durun, metinden tokenlara gidip bu tokenları doğrudan tekrar metne dönüştürmenin ne anlamı olurdu? Evet, bu grafikte yer vermediğimiz ek ve hayati bir süreç olduğunu öğrenince şaşırmayabilirsiniz: *token genişlemesi*. Sizin `⟨kod⟩` metninden üretilen her token, LuaTeX’in o tokenın *genişletilebilir komutlar*. Eğer öyleyse, LuaTeX bu komutu *kaldırmak* sizin `⟨kod⟩` ve *onu değiştirerek* TeX motorlarının adlandırdığı bir sürecin sonuçlarıyla *token genişlemesi*.

### LuaTeX \directlua’yı nasıl işler: İkinci bakış (genişleme üzerine)

TeX’in genişleme mekanizması, TeX tabanlı tüm dizgi motorlarının temel bir bileşenidir; çünkü sonuçta her biri Knuth’un TeX için yazdığı özgün kaynak kodundan ve tasarımından türetilmiştir (veya ona dayanır). Ancak genişleme kavramını kısa ama anlaşılır bir dille açıklamak zordur; çünkü uygulamada genişleme, tek bir süreci tanımlamak için kullanılan bir “şemsiye” terimdir—ama bu süreç bir dizi farklı çıktı üretir. Bu farklı sonuçlar, genişlemenin uygulanabildiği biraz eklektik komut kümesinin bir sonucudur; dolayısıyla her genişletilebilir komutun belirli bir “genişleme davranışı” olduğunu düşünebilirsiniz.

Bir *ilk yaklaşım* olarak genişlemeyi anlamak için, bir tokenın (komutun) genişlemesinin şu anlama geldiğini söyleyebiliriz: *kaldırmak* o komutu (tokenı) TeX’in mevcut girdisinden *yerine koymak* onu, o belirli genişletilebilir komutun çalıştırılmasından doğan token dizisiyle değiştirmek—orijinal tokenı genişlemesinin sonuçlarıyla değiştirmek *davranış*. Ancak genişlemenin bu başlangıçtaki “tanımı”—TeX’in okuyacağı yeni tokenlar üretmesi açısından—tüm genişletilebilir komutlar için tamamen doğru değildir, ama başlangıç noktası olarak yeterlidir.

Basit bir örnek vermek gerekirse: TeX ilkel komutu `\\jobname` bir genişletilebilir komuttur ve onun *genişletme* ana TeX giriş dosyasının adını temsil eden karakter tokenlarından oluşan bir dizidir. Eğer TeX bir `\\jobname` komutunu (tokenını) genişletmeye karar verirse, o *çıkarılır* TeX’in mevcut giriş kaynağından ve *değiştirilir* ürettiği karakter tokenları dizisiyle; ardından TeX bu diziyi okumaya/işlemeye devam eder.

İçinde `\directlua` genişletilebilir bir token işlendiğinde (çıkarıldığında) ve yeni tokenlarla değiştirildiğinde, LuaTeX yeni yerleştirdiği bu tokenları okumaya devam eder—ancak bu yeni tokenların bazıları da genişletilebilir olabilir. Çünkü `\directlua` sözde *tam genişleme* gerçekleştirir, LuaTeX bu yeni tokenları okuyacak ve bir kez daha genişleme sürecinden geçerek yeni (genişletilebilir) tokenların tamamını genişletecek (çıkaracaktır)—bu genişleme süreci, genişletilebilir token kalmayana kadar sürer. Ancak bu “genişletmeye devam et” kuralının iki önemli istisnası vardır; bunların ikisini de aşağıda ele alacağız:

* şu yapıyı kullanmak `\the\toks`;
* bir veya daha fazla seçilmiş token için genişlemenin kasıtlı olarak önlenmesi (bastırılması).

Belirtildiği gibi, genişlemeyi anlamak için kullandığımız çalışma tanımı (ilk yaklaşım), genişletilebilir komutlar alt kümesinin gösterdiği tüm genişleme davranışlarını kapsamaz. Örneğin, bazı genişletilebilir komutlar tokenları şu şekilde üretmez: `\\jobname` yapar, ancak şunları yapabilirler:

* girdiden tokenları “süzmek”: bir TeX motorunun koşullu komutları (`\if`, `\ifcat`, `\ifnum`, `\ifdim`, `\ifodd`, `\ifvmode` , …) genişletilebilir. Bunların genişleme davranışı bir tür “token süzme”dir—koşullular `\directlua`.
* girdideki tokenlarla “oynayabilir”: [`\\expandafter` komut](/latex/tr/derinlemesine-makaleler/03-a-six-part-article-series-on-expandafter-tex-tokens-and-expansion.md) genişletilebilirdir ve iki tokenın genişletilme sırasını değiştirir.
* genişlemeyi önlemek: genişletilebilir komutlar `\noexpand` ve `\unexpanded` girdideki komut tokenlarının genişlemesini bastırır.
* girdideki karakter dizilerini komut tokenlarına dönüştürmek: `\csname … \endcsname.`
* dahili nicelikleri karakter tokenlarından oluşan bir diziye dönüştürmek: `\number` ve `\\the` dahili bir niceliğin değerini temsil eden karakter tokenlarından oluşan bir dizi üreten genişletilebilir komutlardır.
* komut tokenlarını karakter tokenlarına dönüştürmek: `\string` ve `\detokenize` argümanlarını kategori kodu 12 olan karakter tokenlarından oluşan bir diziye dönüştüren genişletilebilir komutlardır. Şuna dikkat edin: `\detokenize` şundan farklıdır: `\string`: `\detokenize` birden fazla tokenı işleyebilir ve komut tokenlarını işledikten sonra kategori kodu 10 olan bir boşluk karakteri ekler, bu komut tokenları *komut sözcükleri*. Sonuç olarak, `\detokenize` komut adından sonra sonda bir boşluk karakteri ekler—makalenin ilerleyen kısmında bazı örnekler göreceğiz.

#### Genişleme “tanımımızı” netleştirme

Artık tanımımızı genelleyerek bir komutun (tokenın) genişlemesinin şunları içerdiğini söyleyebiliriz: *çıkarılması* o komutun (tokenın) TeX’in mevcut giriş kaynağından ve *onu değiştirerek* ile *token işlemi/işlemleri* tarafından gerçekleştirilen sonuçla değiştirilmesini içerir. Özünde, genişleme süreci, genişletilebilir bir komuta TeX’in mevcut girdisindeki tokenlar üzerinde bir tür “işlem” yaptırır; bu da TeX’in daha sonra okuyacağı tokenların sayısını veya davranışını etkiler—o “işlemin” tam niteliği, hangi komutun genişletildiğine bağlıdır. Tüm makrolar ve etkin karakterler genişletilebilirdir, ancak bir TeX motorunun yerleşik komutlarının (ilkellerinin) yalnızca küçük bir kısmı genişletilebilir olarak sınıflandırılır—genişletilebilir komutların listesi kullandığınız TeX motoruna bağlıdır.

Her yeni TeX motoru, türetildiği önceki kuşak TeX motor(lar)ında yerleşik ilkel komutları miras alır ve bu miras alınan ilkellerin bazıları genişletilebilir olacaktır. Elbette, yeni bir TeX motoru önceki motorlarda bulunan bazı ilkel komutları uygulamamayı ya da yeni motorun ihtiyaçlarına uyacak şekilde davranışlarını değiştirmeyi seçebilir. Ayrıca yeni TeX motorları, kendi geliştirilmiş işlevlerini desteklemek için genellikle ek ilkeller uygular; bunların bazıları da genişletilebilir olabilir. Sonuç olarak, kullanabileceğiniz genişletilebilir komutların sayısı kullandığınız TeX motoruna göre değişir—LuaTeX’in bunlardan epeyce bir koleksiyonu vardır.

Genişlemeyi açıklamak/anlamakla ilgili bir başka zorluk, belki de asıl mesele, tam olarak bilmektir *ne zaman* bir TeX motorunun gerçekten genişleme sürecini gerçekleştireceği ya da gerçekleştirmeyeceği. Bu büyük ve karmaşık bir konudur; çünkü genişleme, TeX motorlarının iç işleyişine derinlemesine yerleşmiştir: bunu ayrıntılı biçimde ele alacak alanımız yok, yalnızca genişlemenin `\directlua`.

### LuaTeX \directlua’yı nasıl işler: Son bakış

Aşağıdaki diyagram,  `\directlua` LuaTeX motorunun içinde gerçekleşen ön işleme faaliyetlerini özetler. Bu diyagramda gerçekten işi yapan iki düşük seviyeli (dahili) LuaTeX işlevini de gösteriyoruz: `scan_toks()` ve `tokenlist_to_cstring()`. Bu işlevler C dilinde yazılmıştır ve yürütülebilir LuaTeX yazılımının derinlerinde yer alır: bunlar LuaTeX’in iç mekanizmasının bir parçasıdır ve *doğrudan* sizin TeX/LaTeX kodunuzdan erişilebilir değildir.

![](/files/7a673731473d22c7acdf4eb554516b504d996c08)

Aşağıdaki `\directlua ⟨code⟩`ön işleme etkinliğinin açıklaması, yukarıdaki diyagramı özetler.

1. Sizin ⟨code⟩ içindeki karakter dizisi `scan_toks()`işlenir. Amacı, karakter tokenları ve komut tokenları üretmek için ⟨code⟩ metninizi karakter karakter okumaktır. Token ürettiği için, ⟨code⟩ içindeki her karaktere okunma anında atanmış kategori kodu son derece önemlidir.
2. Sırasında `scan_toks()`’in token işleme (üretme) sürecinde herhangi bir genişletilebilir komut (token) *aksi hâlde —* gibi komutlar aracılığıyla engellenir `\protected` (makro tanımları), `\noexpand`, `\unexpanded` vb. Etkin karakterler (kategori kodu 13) de genişletilir (engellenmedikçe).
3. Tarafından oluşturulan token akışı `scan_toks()` tek uzun bir token listesi hâline getirilir—bu listedeki tokenlar, sizin `⟨kod⟩`. Şuna da dikkat edin ki `scan_toks()` *sonlanmıyor;* genişletilemez bir komutu temsil eden herhangi bir tokenın yürütülmesini tetiklemez ya da buna neden olmaz: bu tür genişletilemez tokenlar yalnızca iletilir ve oluşturulmakta olan token listesine eklenir.
4. Token listesi tamamlanıp tüm genişleme etkinliği sona erdiğinde, bu token listesi  `tokenlist_to_cstring()` adlı başka bir işlev tarafından işlenir; bu işlev son token listesindeki her tokenı yeniden metinsel gösterimine dönüştürür. Bu, Lua yorumlayıcısına iletilecek Lua kodu olan bir metin dizgesi üretir. Başarılı yürütme için bu dizge, sözdizimsel olarak doğru Lua kodu içermelidir.
5. Lua’nın bu kodu işlemesi iki adımda gerçekleşir:
6. LuaTeX’in yerleşik Lua yorumlayıcısı, önceki adımlarda üretilen Lua kodunu ayrıştırır ve “derler”. Bu ayrıştırma/derleme başarısız olursa, Lua yorumlayıcısı hatalar (sözdizimi hataları gibi) üretir—bu hatalar, eğer `--interaction=nonstopmode` komut satırında kullanmayı seçmediyseniz LuaTeX çalışmasının başarısız olmasına neden olabilir.
7. Ayrıştırma/derleme başarılı olursa, Lua yorumlayıcısı (5a) adımında derlenen kodu yürütür.

Özünde, `scan_toks()` işlevi LuaTeX’in ön işleme faaliyetlerinin merkezidir: temel görevi, sizin `⟨kod⟩` metninizde bulunan tüm genişletilebilir TeX/LaTeX komutlarını genişletmek ve işlediği her şeyden bir token listesi oluşturmaktır. Yine vurguluyoruz ki `scan_toks()` *genişletilemez komutları yürütmez* tokenları): yalnızca *saklar* bu tokenları oluşturduğu token listesinde. Tamamlandığında, bu token listesi daha sonra dönüştürülür *yeniden metinsel bir gösterime* tarafından `tokenlist_to_cstring()`—bir token listesi yalnızca TeX’e özgü bir kavramdır ve Lua yorumlayıcısı için tamamen yabancıdır; bu yüzden onu metne dönüştürmek gerekir, böylece Lua yorumlayıcısına aktarılacak Lua kodu hâline gelir.

## Bir programlama dili “arabirimi” olarak genişleme

Şöyle düşünebilirsiniz: `\directlua`’in genişleme sürecinin, veriyi/bilgiyi “TeX Dünyası”ndan “Lua Dünyası”na aktarmak için bir mekanizma ya da arabirim olarak kullanılması: TeX dilinin Lua diline veri iletmesi için bir yöntem sağlaması. Örneğin, şu tür TeX kodu `\number\count75` 75 numaralı sayaç yazmacında saklanan bir “TeX Dünyası” değerini “Lua Dünyası”ndaki x tamsayı değişkenine aktarmak için kullanılabilir:

```
\count75=1564 % “TeX Dünyası”nda var olan veri
\directlua{
   local x=\number\count75 \space % TeX verisini “Lua Dünyası”na aktar
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" ve y = "..y)
}
```

Bu, şu Lua kodunu üretir

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

**Not**: Biz `<space>\space` sonrasına `\number\count75` bir boşluk karakterinin şu ikisi arasında korunmasını sağlamak için ekledik: `1564` ve `tex.print`—bunu burada kesinlikle yapmak gerekmez; çünkü onu çıkarırsak Lua yine de kodu doğru şekilde ayrıştırır. Hemen ardından gelen boşluk karakteri `\count75` TeX motorlarının sayısal değerleri aramak için kullandığı süreç sırasında emilir—burada, şu değere sağlanan `\\count`. Sonraki boşluk karakteri `75` işareti `75` sayısı dizisini aramasını sonlandırmak için kullanılır ve girdiden emilir.  `\space` makrosu, metni ayırmak için gereken boşluk karakterini sağlamak üzere genişler `1564` ve `tex.print`.

Yukarıdaki kodu kullanarak LuaTeX şu metni dizgi olarak üretecektir

`x= 1564 ve y = 612.6`

Burada “veri aktarma” mekanizması `\number`şu değerde saklanan değeri getirmesini söyleyen bir genişletilebilir komut: `\\count` kaydında `75` ve bu değerden (`1546`) her basamak için bir karakter tokenı olacak şekilde bir dizi karakter tokenı üretmek; bunun sonucunda şu basamaklar için bir token dizisi oluşur: `1`, `5`, `6` ve `4`. Bu 4 karakter tokenı, tarafından oluşturulmakta olan ana token listesine dâhil edilir `\directlua` ve token listesi metne dönüştürüldüğünde daha sonra yeniden metinsel gösterimlerine çevrilir. Bu, şüphesiz `\count75` LuaTeX içinde saklanan yazmaç değerinden Lua koduna gidecek basamaklara uzanan çok dolambaçlı bir yoldur ama sonuçta çalışır.

**İPUCU:** LuaTeX’in genişleme faaliyetlerinin sonuçlarını incelemek istiyorsanız şu şekilde kod yazabilirsiniz:

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

Bu örnekte bir dizge değişkeni oluşturmak için uzun köşeli parantez yöntemini kullanıyoruz `foo` amacı, arasında kalan her şeyin genişletilmesinden üretilen Lua kodu dizgesini tutmaktır `[[` ve `]]`. Bu dizge, Lua işlev çağrısı aracılığıyla konsola yazdırılır `print(foo)`.

Overleaf’te benzer sonuçları, içeriğini yazarak görüntüleyebilirsiniz `foo` şuna `.log` dosyasının içeriğini LuaTeX Lua işleviyle kullanarak `texio.write()`:

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

## \directlua token listesindeki tokenlar: genişletilemez tokenlar ve genişletilmemiş tokenlar

Şunu belirtmiştik ki `\directlua{⟨kod⟩}` gerçekleştirir *tam genişleme* sizin `⟨kod⟩`: yalnızca genişletilemez tokenlar kalana kadar tüm genişletilebilir komutları çıkarır ve genişletir. Tarafından oluşturulan token dizisi `\directlua`’in işlenmesi sırasında ( `scan_toks()` işlevinde) tek tek tokenları Lua’ya iletilmek üzere yeniden metne dönüştürülecek bir token listesi oluşturacak şekilde bir araya getirilir.

Ancak bu hikâyenin son kısmını henüz ele almadık; çünkü içinde oluşturulmakta olan token listesine ulaşabilen komut tokenlarının iki “sınıfını” düşünmemiz gerekiyor `\directlua`: bunlara şu adları vereceğiz: *kısa komut tokenları* ve *genişletilmemiş* tokenlar:

* **kısa komut tokenları**: Bu tür komut tokenı, TeX ilkellerinden biri kullanılarak tanımlanan denetim dizilerinden ortaya çıkar `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` ve `\toksdef`. Bu ilkel komutlar, sayısal bir değeri temsil eden denetim dizileri tanımlamak için kullanılır—ortaya çıkan denetim dizileri *yapmaz* genişletilebilirdir.
* **genişletilmemiş tokenlar**: Bu token türü, normalde genişletilecek olan ancak `\directlua` has either:
* açıkça talimat verilmiş *yapmaz* bunları genişletmemesi için; örneğin, şu komutlar tarafından genişlemenin bastırılması `\noexpand` ya da `\unexpanded`—bunun nasıl yapıldığını birazdan açıklayacağız;
* şu diziyi işleyerek enjekte edilmiş tokenlar `\the\toks` (aşağıda daha fazlası var).

### Bir \directlua token listesinde tokenların iki “grubu”

Yaptığımız tartışmalara dayanarak, ilk aşama sırasında oluşturulan token listesinde bulunan tokenlar için şunu söyleyebiliriz: `\directlua`’in ön işlemesi sırasında ( `scan_toks()` işlevinde) iki gruba ayrılır:

1. *doğası gereği genişletilemez* tokenlar

* etkin olmayan bir şeyi temsil eden herhangi bir token *karakteri*;
* genişletilemez bir şeyi temsil eden herhangi bir token *ilkel* *komut*;
* bir şeyi temsil eden herhangi bir token *kısa komut* (bunlar genişletilebilir değildir, aşağıya bakın).

3. *genişletilmemiş* tokenlar:

* genişlemesi  *bastırılmış* (veya önlenmiş) herhangi bir token `\directlua`’in ön işlemesi sırasında.

#### Kısa komut tokenları: genişletilemez komutlar oluşturma

Belirtildiği gibi, TeX motorları, oluşturmak için kullanılabilecek bir dizi ilkel (yerleşik komut) sağlar *genişletilemez* denetim dizilerini (burada şu sembolle gösterilen `⟨command⟩`). Bu ilkeller şu biçimi alır:

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

burada `⟨sayısal değer⟩` her komut için uygun bir tamsayı değeridir.

Burada, şu komutun kullanımını kısaca gözden geçireceğiz `\chardef` bu ilkellerin temel özelliğini göstermek için—bir `⟨command⟩` oluşturmak için kullanılabilir, bu da genişletilemezdir. Şunu kullanabilirsiniz ``\chardef\mydollar=`\$`` denetim dizisini oluşturmak için `\mydollar` ve onu bir metni dizgi olarak üretmek için kullanabilirsiniz `$`:

`30 dolar ödedim.`

Bu, şu metni dizgi olarak üretecektir `30 dolar ödedim.` Denetim dizisi `\mydollar` tarafından oluşturulan `\chardef` genişletilebilir değildir; bunu aşağıdaki örnekte görebiliriz:

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

Bu, aşağıdaki metni `.log` dosya

`\mydollar 30 ödedim.`

Bu, şunu gösterir: `\mydollar` idi *yapmaz* sırasında genişletildiğini `\directlua`’in ön işlemesi. Sonrasında görünen boşluk `\mydollar` bir komut tokenı metinsel gösterimine dönüştürüldüğünde eklenir.

Şunu kullandığınızda `\chardef` bir denetim dizisi oluşturmak için, TeX’in o denetim dizisini (komutu) iç sınıflandırması onun *genişletilemez* olmasına yol açar; bu da makro tanımlama komutlarından biriyle: \def, \edef, \gdef veya \xdef tanımlanan denetim dizilerinden çok farklı bir davranıştır. Yukarıda belirtildiği gibi, token listesini oluşturma sürecinde `\directlua` gelen her komut tokenını genişletilebilirlik açısından inceler. Bir komut tokenı genişletilebilir değilse, doğrudan token listesine geçer ve metinsel gösterimi daha sonra tokenların token listesinden yeniden metinsel biçimlerine dönüştürülmesinden doğan Lua kodu dizgesinde yeniden ortaya çıkar.

**plain TeX ile LaTeX üzerine kısa notlar**

Tarihsel olarak, Knuth’un özgün plain TeX’i yaygın kullanılan denetim sembollerini tanımladı `\%`, `\&`, `\#` ve `\$` şunu kullanarak `\chardef`—standart makro tanımlama komutlarından birini kullanmadan `\def`, `\edef`, `\gdef` ya da `\xdef`. Örneğin:

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

Garip `` `\ `` söz dizimi, sayısal karakter kodu değerini elde etmek için kullanılan bir TeX yöntemidir. Eski plain TeX düzeninde, bu denetim sembolleri genişletilebilir değildir (çünkü `\chardef`) ancak LaTeX (veya paketler) onları *makrolar* geliştirilmiş işlevsellik sağlamak için yeniden tanımlayabilir—bu da onları genişletilebilir yapar; bu yüzden bunun farkında olmanız gerekebilir.

**Bu \directlua’yı nasıl etkiler?**

Aşağıdaki kodun plain TeX ve LaTeX altında çalıştırıldığında ortaya çıkan sonucu karşılaştıralım. Basitlik için sonuçları `.log` dosyasına LuaTeX Lua API işleviyle yazacağız `texio.write()`.

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

Bu kodu kullanarak çalıştırmak **plain TeX** şu çıktıyı üretir `.log` dosyasında; bu da herhangi bir genişlemenin sonucunu gösterir:

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

Açıkça, plain TeX altında denetim sembollerinin hiçbiri`\$`, `\#`, `\%` ya da `\&` genişletilmedi—çünkü hepsi şu kullanılarak oluşturulmuştur `\chardef`.

Bu kodu şu belgede çalıştırmak **LaTeX** belgesi:

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

şu çıktıyı üretir `.log` dosya

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

Açıkça, LaTeX’i çalıştırmak plain TeX’ten farklı bir sonuç üretir; çünkü LaTeX altında şu komut `\$` genişletilmiştir; bu da onun bir makro olduğunu gösterir.

**Not:** Hem plain TeX’te hem de LaTeX’te `\directlua` denetim sembollerinin hiçbirini tam olarak işlemedi `\%`, `\&`, `\#` ve `\$` karşılık gelen karakteri üretmek için. Tarafından gerçekleştirilen genişleme süreci sırasında `\directlua` bu denetim sembollerini temsil eden tokenlar—veya LaTeX için, bunların genişlemeleri—doğrudan oluşturulmakta olan ana token listesine geçer.

**Not:** Denetim sembolleri, kategori kodu 11 olmayan tek bir karakterden oluşur; örneğin `\#`. Bir denetim sembolünü temsil eden bir token yeniden metinsel gösterimine dönüştürüldüğünde TeX motorları o metinden sonra bir boşluk karakteri eklemez. Denetim sembollerine yönelik bu özel işlem, TeX motorlarının çalışma biçimine gömülü bir kuraldır.

### Genişletilmemiş tokenlar: genişlemeyi bastırma

`\directlua`’nin ön işleme süreci, bir TeX motorunun genişletme yaptığı bir örnektir, ancak *engellemek* genişletmenin, aksi halde genişletilecek olan bir veya daha fazla belirtece uygulanmasını engellemek isteyebilirsiniz. Başka bir örnek olarak, LuaTeX (ve tüm TeX motorları), aşağıdakini işlerken `\directlua`, işlerken `\write` komutuyla:

`\write dosya-numarası {⟨malzeme⟩}`

\write, bir TeX motoruna şunu çıktılama talimatı verir: `⟨malzeme⟩`—çoğunlukla TeX/LaTeX komutları içeren— bir metin dosyasına (`dosya-numarası`); içindeki genişletilebilir komutlar, aksi engellenmedikçe, `⟨malzeme⟩` önce genişletilir ve ancak sonra `⟨malzeme⟩` gerçekte o dosyaya yazılır.

Tahmin edeceğiniz gibi, TeX motorları genişletmeyi bastırmak ya da denetlemek için komutlar sağlar:

* `\noexpand⟨token⟩`: tek bir `⟨token⟩`;
* `\unexpanded{⟨malzeme⟩}`: içindeki tüm genişletilebilir komutların (belirteçlerin) genişletilmesini engeller `⟨malzeme⟩`. Aslında, bunun çok belirteçli bir sürümüdür `\noexpand`;
* `\protected`: belirli durumlarda (örneğin `\directlua`, `\write` ya da `\edef`).

Aksini düşündüren adlarına rağmen, hem `\noexpand` ve `\unexpanded` ise *genişletilebilir komutlar* ve bir TeX motorunun genişletme sürecini “belirteç işlemleri” gerçekleştiriyormuş gibi görmenin iyi örneklerini sunar: buradaki işlem, sonraki bir veya daha fazla belirtecin (komutun) genişletilmesini engellemektir. Çünkü `\noexpand` ve `\unexpanded` ikisi de genişletilebilir komut olduğundan, `\directlua`’nin ön işlemesi sırasında, belirteç listesini sizin `⟨kod⟩`.

#### \noexpand ⟨token⟩

`\noexpand ⟨token⟩` tek bir `⟨token⟩`. `\noexpand` içinde `\directlua` genişletilir (girdiden kaldırılır) ve “genişleme davranışı”nın sonuçlarıyla değiştirilir. Genişletmenin sonucu `\noexpand` özel (gizli) bir `⟨işaretleyici belirteç⟩` oluşturmak olur; bu belirteç, orijinal `⟨token⟩` önüne yerleştirilir ve genişletilmesi bastırılacak olan `⟨işaretleyici belirteç⟩` “bir sonraki belirteci genişletme” anlamına gelen bir bayrak gibi davranır. Çünkü `\directlua` tam genişleme yapmaktadır, genişletilebilir bir komutun “genişleme davranışı” sonucunda oluşan herhangi bir belirteci yeniden işleyecektir. Sonuç olarak, `\noexpand ⟨token⟩` genişlemesi tamamlandığında, LuaTeX sonuçları okumaya geri döner ve şu iki belirteçli diziyi görür: `⟨işaretleyici belirteç⟩⟨belirteç⟩` bu da orijinal `⟨token⟩` belirtecin, genişletilmemiş halde, `\directlua`.

**Örnek**

Eğer şunu yazarsak

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

şu `\TeX` makrosu, bileşen belirteçlerine genişletilir ve düz TeX’te bu, Lua’ya aşağıdaki metnin iletilmesiyle sonuçlanır (not: Lua bu kodu işleyemez, bu yalnızca süreci göstermek için bir örnektir):

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

Eğer *genişletmeyi* macrosunun `\TeX` ile `\noexpand`

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

aşağıdaki Lua kodu üretilir (yine, Lua bu kodu çalıştıramaz; bu sadece `\noexpand`):

`local x= "\TeX "`

Çünkü `\noexpand`, `\directlua` genişletmez `\TeX` ama yalnızca temsil eden belirteç değerinin `\TeX` komutunun, `\directlua`’in ön işlemesi sırasında.

**Not:** Sonrasında gelen boşluk karakteri `\TeX` LuaTeX’in `\TeX` tamsayı belirteç değerini yeniden metinsel gösterimine dönüştürmesinden kaynaklanır ( `tokenlist_to_cstring()` işlevi içinde).

#### \unexpanded{⟨malzeme⟩}

`\unexpanded` içindeki tüm belirteç türlerinden oluşturulmuş belirteçlerin genişletilmesini engelleyen genişletilebilir bir komuttur. Şunu belirtmiştik ki, bir TeX motoru genişletme yaptığında genişletilebilir herhangi bir komut `⟨malzeme⟩`. Gördüğümüz gibi, *çıkarılır* girdiden kaldırılır ve *değiştirilir* “genişleme davranışı”nın sonuçlarıyla değiştirilir; peki bu `\unexpanded`için gerçekte ne anlama gelir? Genellikle, *tam genişleme*sırasında, belirli bir komut için genişletme süreci tamamlandığında TeX motoru, o komutun “genişleme davranışı”ndan doğan belirteçleri okumaya/işlemeye devam eder—üretilen belirteçleri daha da genişletmesi gerekir. Ancak, `\unexpanded` *atlanır* sonraki herhangi bir genişletmeyi: bunu nasıl yaptığını burada göreceğiz.

TeX motoru içinde, `\unexpanded` komutu önce içindeki karakterleri ve komutları `⟨malzeme⟩` belirteçlerden oluşan geçici bir belirteç listesine dönüştürür. Tüm belirteçler oluşturulup o geçici belirteç listesinde saklandıktan sonra, *genişletilmemiş* komutu `\unexpanded` sırasında `\directlua` ile *atlamaya neden olur* geri dönüp onları okuyup işlemeksizin—her ne kadar \directlua tam genişleme yapıyor olsa da. Bunun yerine, o *genişletilmemiş* belirteçler doğrudan geçer ve `\directlua` (içindeki `scan_toks()` işlevinde). Bu şekilde, `⟨malzeme⟩` içindeki her şey belirteçlere dönüştürülür ve bu belirteç kümesi için genişletme süreci atlanır. `\unexpanded{⟨malzeme⟩}` işlemi `\the\toks`kullanımına benzer; bunu aşağıda tartışıyoruz.

**Örnek**

`\unexpanded` sonuçları `\noexpand` ile benzer bir biçimde üretir, ancak birden çok belirtecin genişletilmesini engelleyebilir; işte bir örnek:

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

Lua için kod olarak aşağıdaki metni üretir:

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

**Not**: Her komut adından sonra boşluk karakterleri vardır. Bunlar yine LuaTeX’in genişletilmemiş belirteçleri daha sonra dönüştürmesinin bir sonucudur `\\foo`, `\bar` ve `\foobar` metne geri `tokenlist_to_cstring()` işlevi içinde.

#### \protected makro tanımları

Bu `\protected` komutu, TeX genişletilmiş bir belirteç listesi oluştururken, örneğin `\directlua`’in ön işlemesi sırasında.

**Örnek**

Aşağıdaki makroları, \protected ön ekini kullanarak ve kullanmayarak tanımladığınızı varsayalım: `\protected` ön ekini

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

Lua’nın dize birleştirme operatörünü (`..`) kullanarak şunu yazarsanız

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

`\directlua`’nin ön işlemesi, Lua’ya iletilmek üzere aşağıdaki kodu üretirdi:

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

`\macroA` \protected kullanılarak tanımlanmamıştır `\protected` bu yüzden genişletilir ve birleştirilecek dizenin ilk bölümünü üretir, ancak `\macroB` \protected kullanılarak tanımlanmıştır `\protected` bu yüzden genişletilmemiştir.

Ön işleme sırasında, LuaTeX’in `scan_toks()` işlevi, için bir belirteç oluşturdu `\macroA`, bunun sıradan bir genişletilebilir komut olduğunu tanıdı ve genişletti: bu genişletme, içindeki her karakter için birer karakter belirteci olmak üzere bir karakter belirteçleri dizisi üretir `"This unprotected macro contains a string"`. Her karakter belirteci aktarılır ve oluşturulmakta olan belirteç listesine eklenir.

Ne zaman `scan_toks()` için belirteci oluşturur `\macroB` komutun \protected olarak tanımlandığını fark eder `\protected` ve onu genişletmez: `\macroB` temsil eden belirteç, dokunulmadan (genişletilmeden) oluşturulmakta olan belirteç listesine geçer. O belirteç listesi oluşturulduktan sonra, ön işlemenin sonraki aşaması, `tokenlist_to_cstring()` işlevi, belirteç listesindeki tüm belirteçleri tekrar metinsel gösterimlerine dönüştürmektir. Temsili genişletilmemiş belirteç `\macroB` algılanır ve metin gösterimine dönüştürülür; bunun sonucunda şu metin ortaya çıkar: `\macroB` Lua için hazırlanmış kodda görünür. Lua’nın gerçekte birleştiremediğine dikkat edin `"This unprotected macro contains a string"..\macroB` son dizeyi üretmek için, çünkü `\macroB` Lua sözdiziminde bir anlamı yoktur; bunun sonucunda şu hata oluşur: `unexpected symbol near '\'`.

**Bilgi Köşesi**: Bu `\protected` komutu tarafından tanıtıldı $$\varepsilon\text{-}\mathrm{\TeX}$$, Knuth’un özgün TeX yazılımının ilk büyük genişletmesidir ve kod soy ağacında $$\varepsilon\text{-}\mathrm{\TeX}$$.

### Genişletilmemiş belirteçler: \directlua içinde \the\toks kullanımı

Programlamada, başa çıkılacak o “özel durumlar” ve `\\the` ile birlikte `\\toks` bir `\directlua` komutu böyle bir özel durumdur.

#### \toks hakkında kısa arka plan

TeX ilkel komutu `\\toks` bir TeX motoruna, daha sonra kullanılmak üzere bazı belirteçleri kaydetmesini söyler: daha ileri işlemeye aktarılmak yerine, bu belirteçler bir kenara konur ve bir kullanılarak belirtilen bellek konumunda saklanır *belirteç yazmacı*. Örneğin, bir TeX motoruna bazı belirteçler oluşturup bunları belirteç yazmacı konumu `100` şunu kullanarak

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

Burada TeX, belirteç yazmacı `100` kullanarak belleği içindeki bilinen bir konuma erişir: belirteç listelerini tutmak için ayrılmış bir depolama alanı.

Arasındaki her şeyi temsil eden belirteçler, `{` ve `}` oluşturulur, *ancak genişletilmez*, ve bir belirteç listesinde yan yana dizilirler—bu makalede daha önce incelediğimiz belirteç listesine benzer şekilde. Bu belirteçleri yeniden kullanmak için şunu yazarız `\the\toks100` burada `\\the` (genişletilebilir bir komut), TeX’e saklanan belirteçleri alıp yazdığınız konuma yerleştirmesini söyler `\the\toks100`. Bunu düşünmenin başka bir yolu da `\the\toks` TeX’in o konuma bazı belirteçler yerleştirmesine neden olur.

Bu `\\toks` komut *genişletmez* oluşturup kaydetmesi istenen belirteçlerin hiçbirini: yalnızca `{` ve `}` belirteklere dönüştürür ve saklar.

#### \directlua’ya geri dönelim

Genişletme tartışmasında şunu belirtmiştik `\directlua{⟨kod⟩}` gerçekleştirir *tam genişleme* için bir belirteç değeri oluşturur `⟨kod⟩`: tüm genişletilebilir komutları kaldırıp bunları genişleme davranışlarının sonucu ile değiştirmek — ve devam ederek *daha fazla genişletmek* bir genişletilebilir komutun ilk genişlemesinden doğan herhangi bir belirteci.

`\\the` bir genişletilebilir komuttur, bu yüzden `\directlua` onu genişletir; ancak `\\the` ile birlikte kullanıldığında `\\toks` içinde `\directlua`, şu örnekte olduğu gibi `\the\toks⟨token register⟩`, eklenen belirteçler *artık daha fazla genişletilmez*. ... genişletilmesi `\the\toks⟨token register⟩` şu diziyi enjekte eder: *genişletilmemiş* belirteçler, ... içinde saklanan `⟨token register⟩`, doğrudan ... tarafından oluşturulmakta olan belirteç listesine `\directlua`: bu davranış, tam genişlemenin olağan sürecini atlar. Aslında, bu belirteçler geçer, *genişletilmemiş*, ... tarafından oluşturulmakta olan ana belirteç listesine dâhil olmak üzere `\directlua`—genişletilmemiş belirteçler için bu geçiş süreci, işleyiş bakımından `\unexpanded`, daha önce tartışıldığı gibi.

**Örnek**

Şimdi makroyu tanımladığımızı varsayalım `\mymacro` as `\def\mymacro{\TeX}`. Bu, ... için yalnızca bir belirteç içerir `\TeX` komutu (ki bu bir makrodur): yani elimizde bir genişletilebilir komut var `\mymacro` başka bir makro içeren `\TeX`, ki bu da genişletilebilirdir.

Aşağıdaki kod, Lua’nın bir dize değişkeni oluşturmaya çalışmasına yol açacaktır `x`:

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

İçinde \\\\`directlua`, ... için belirteç `\mymacro` genişletilir; ancak bunun sonucunda başka bir genişletilebilir belirteç, `\TeX`Plain TeX’te, bu genişletmeler Lua’ya iletilen aşağıdaki metni üretir:

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

Bu kod, ...'ın genişletilmiş sürümünü temsil eden metni içeren bir dize tanımlamaya çalışır `\TeX` makrosu. Bu örneği çalıştırmaya çalışırsanız Lua o dizeyi oluşturmaya çalışacaktır, ancak başarısız olup bir hata üretecektir:

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

Makalede ilerleyen bölümlerde “invalid escape sequence” ifadesinin anlamını inceleyeceğiz.

Şimdi ... kullanımını karşılaştıralım `\mymacro` ile ... yerleştirmeyi `\TeX` bir ... tarafından oluşturulan bir belirteç listesinin içine yerleştirmeyi `\\toks` komutuyla:

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

LuaTeX’in `\directlua` işleme süreci, Lua için bu metin dizgesini üretir:

`local x = "\TeX "`

Sonrasındaki boşluk karakteri `\TeX` LuaTeX’in komut-belirteçten-dizeye dönüştürme süreci tarafından oluşturulur.

**Ancak dikkat edin**: Bu `\TeX` makro *yapmaz* bileşen belirteçlerine genişletilmiştir. `\the\toks100` 100 numaralı yazmaçta saklanan belirteçlerin eklenmesine neden oldu, ama hepsi bu: onlar *yapmaz* artık daha fazla genişletilmez ve ... tarafından oluşturulmakta olan ana belirteç listesine dâhil edilir `\directlua` (... işlevi içinde `scan_toks()`). ... tarafından oluşturulan bir belirteç listesine belirteçler yerleştirmek `\\toks` belirteçlerin genişletilmesini önlemenin bir başka yoludur.

Bu örneği çalıştırırsak o da bir hata üretir:

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

Lua kaçış dizilerini makalenin ilerleyen bölümlerinde inceleyeceğiz.

## Genişletmede kullanılan diğer komutlar/teknikler

Bu bölümde, genişletmenin uygulandığı durumlarda yararlı olabilecek bazı ek TeX komutlarına/yöntemlerine bakıyoruz (örneğin `\directlua`).

### \string ⟨token⟩

`\string` ⟨belirteç⟩'i kategori kodu 12 olan bir dizi karakter belirtecine dönüştüren genişletilebilir bir komuttur.

Örneğin, `\string\TeX` 4 karakter belirteci dizisi üretirdi `\`, `T`, `e` ve `X` burada her karaktere kategori kodu 12 atanır (baştaki `\` karakter de dâhil).

Eğer şunu yazarsak

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

şu `\string` komutu genişletilecek ve kategori kodu 12 olan bir karakter belirteçleri dizisi oluşacaktır. Sonrasında `\string` genişletildikten sonra, ortaya çıkan karakter belirteçleri (içindeki her karakteri temsil eden) `\newcommand` ) `\directlua`... tarafından oluşturulmakta olan ana belirteç listesine dâhil edilecektir `\directlua` . Bir kez

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

Bu kod Lua’ya iletildiğinde, `print(x)` ekrana şu dizeyi yazacaktır `x` ekrana (konsola). Ancak biraz kurnazlık yaptık ve bilerek ... ile başlayan bir örnek komut kullandık `\n`. Bu örneği yerel bir TeX kurulumunda çalıştırabiliyorsanız Lua’nın ekrana aşağıdaki metni yazdığını fark edeceksiniz:

```
   Şunu kullanacağım
   ewcommand
```

Bu kodu Overleaf’te çalıştırmak için LuaTeX’e doğrudan ... yazmasını söyleyebilirsiniz `.log` dosyasına LuaTeX Lua API işleviyle yazacağız `texio.write(*string*)`:

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

Ortaya çıkan `.log` dosyayı incelerseniz, onun da şunu içerdiğini görürsünüz:

```
   Şunu kullanacağım
   ewcommand
```

Bu beklenmedik çıktı, Lua’nın ... yorumlamasından kaynaklanır `\n` başındaki `**\n**ewcommand` satır besleme karakteri (karakter kodu 10) için bir kaçış dizisi olarak: başlangıcında ... bulunan yeni bir metin satırı başlatmak istediğinizi varsayar `ewcommand`. Lua kaçış dizilerini bu makalenin ilerleyen bölümlerinde tartışıyoruz.

### \detokenize{⟨malzeme⟩}

`\detokenize` etkileri bakımından, ...'nin çok belirteçli bir sürümüdür `\string` ve o da içindeki her şeyi dönüştüren genişletilebilir bir komuttur `⟨malzeme⟩` kategori kodu 12 olan bir karakter belirteçleri dizisine —*ancak* boşluk karakterleri (ASCII/Unicode değeri 32), kategori kodu 10 alır. `\detokenize` ayrıca adları ... olan komut adlarının ardından bir sondaki boşluk karakteri ekler *komut sözcükleri* (örneğin, `\\foo`) fakat sonrasında herhangi bir boşluk karakteri eklenmez *komut sembolleri* (örneğin, `\#`, `\%` vb.).

### Örnek

Makrolar `\foohoo`, `\\foo`, `\bar` ve `\foobar` tanımlı olmasa bile, bunu yazarsanız:

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

Lua yorumlayıcısına iletmek üzere aşağıdaki metni kod olarak üretirdi

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

Eğer `\string` ve `\detokenize` ve şunu yazarsanız:

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

`\directlua` işlerdi `\foohoo`, bunun bir komut olduğunu fark eder ve genişletmeye çalışır; ancak `\foohoo` tanımlı olmadığından bir hatayla sonuçlanır:

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

Çünkü `\string` ve `\detokenize` argümanlarını bir dizi karakter belirtecine dönüştürür, `\directlua`’nin genişletme süreci, genişletilebilir komut belirteçlerini algılama fırsatı bulur `\foohoo`, `\\foo`, `\bar`, veya `\foobar`: genişletmeyi tetikleyebilmelerinden çok önce, karakter belirteçleri dizilerine dönüştürülürler.

Daha önce belirtildiği gibi, bir komutun genişletilmesi, onu girdiden kaldırıp “genişleme davranışı”nın sonucu ile değiştirmeyi içerir. Genişletmenin sonuçları (genellikle belirteçler) daha sonra TeX motoru tarafından okunur. Burada, ... için “genişleme davranışı” `\string` ve `\detokenize` girdiden karakter ve komut belirteçlerini soğurup bunları karakter belirteçleri dizilerine dönüştürmektir; bunlar başlangıçta geçici bir belirteç listesinde saklanır ve bu listeyi `\directlua` sonradan okur. Bu karakter belirteçleri, ... tarafından oluşturulmakta olan ana belirteç listesine dâhil edilir `\directlua`.

Aşağıdaki grafik, ... nasıl gösterir `\string` dönüştürdüğünü `\foohoo` komutunu bir karakter belirteçleri dizisine dönüştürür; bunun sonucunda geçici bir belirteç listesi oluşur ve bu liste daha sonra ... tarafından okunur `\directlua` bu karakter belirteçlerini oluşturulmakta olan ana belirteç listesine dâhil etmek için.

![](/files/b4c9f3b1928d1ae876a3d6055af92bff03c21160)

Eğer `\string` ya da `\detokenize` argümanlarında karakterlerle karşılaştıklarında, örn., `\string a` ya da `\detokenize{abc}` bu karakterler (burada kategori kodu 11 ile) karakter belirteçleri üretir, ancak kategori kodu 12 ile.

Notlar:

Yukarıdaki örneğe geri dönersek:

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

Lua yorumlayıcısına iletmek üzere aşağıdaki metni kod olarak üretir

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

şunları gözlemleyebiliriz:

* `\detokenize` her makro adından sonra bir boşluk karakteri eklemiştir ama `\string` eklememiştir.
* `\string` tek bir belirteç üzerinde işlem yapar.
* Dizede `"\foohoo\foo \bar \foobar "` tanımlamak için kullanılan `x` Lua’nın kaçış karakteri mekanizmasıyla (aşağıda tartışılan) yeniden karşılaşacağız:

  * `\bar` ile başlar `\b` bu, ... temsil etmek için kullanılan Lua kaçış dizisidir [geri silme karakteri](https://en.wikipedia.org/wiki/Backspace) (karakter kodu 8);
  * komutlar `\foohoo`, `\\foo` ve `\foobar` hepsi `\f`, ... temsil etmek için kullanılan Lua kaçış dizisidir [sayfa besleme karakteri](https://en.wikipedia.org/wiki/Page_break#Form_feed) (karakter kodu 12).

  Çünkü karakter dizileri `\b` ve `\f` çift tırnak kullanılarak oluşturulan bir dize içinde kullanılır `"..."` Lua’nın sözde *uzun köşeli parantezlerini* kullanarak bunu önlemek için adımlar atılmadıkça istenmeyen sonuçlar üretirler: şimdi Lua kaçış dizileriyle birlikte ele alabileceğimiz bir konu.

## “Lua kaçış dizileri” nedir?

Programlama dilleri, dil sözdiziminin bir parçası olarak belirli karakterleri “özel kullanım” için ayırır: aslında bu karakterlerin bir tür özel anlamı olduğu tanımlanır. Ancak örneğin, bir karakterin standart davranışının sözdizimi hatalarına yol açacağı daha uzun bir dizenin parçası olarak gömülmesini istiyorsanız, o karakterin özel anlamını geçici olarak “kapatmanız” gereken zamanlar vardır. Özünde, bu karakterin işlenmesi gerekir *olmayan* standart yorumunu tetikleyerek—fark edilmeden geçebilmesi için. Bunu yapmak üzere programcılar şu adı verilen bir teknik kullanır: *kaçışlama* burada bir “özel karakter”, sözde *kaçış dizisi*.

Standart bir örnek (Lua tarafından da desteklenir), iç çift tırnakları şu kaçış dizisiyle kaçışlayarak bir dize içinde çift tırnak kullanmaktır: `\"`:

`"LuaTeX hakkında sorulduğunda şöyle yanıt verdiler: \"Harika bir TeX motoru!\" Ben de katıldım."`

Lua dili, kaçış dizileriyle çalışmak için çeşitli mekanizmalar sağlar:

* aşağıdakiler de dâhil olmak üzere standart diziler `\n` (yeni satır), `\r` (satır başı), `\\` (ters eğik çizgi), `\"` (çift tırnak), `\t` (yatay sekme), `\v` (dikey sekme) ve `\'` (tek tırnak);
* `\xXX`, burada `XX` tam olarak iki onaltılık basamaktan oluşan bir dizidir;
* `\ddd`, burada `ddd` en fazla üç onluk basamaktan oluşan bir dizidir;
* bu makalenin yazıldığı sırada (Ağustos 2019), LuaTeX’in en son sürümü henüz Overleaf’te mevcut olmasa da UTF-8 kaçış dizileri desteğini sunan Lua’nın 5.3 sürümünü kullanır: `\u{XXX}`. Bu kaçış mekanizması, `XXX` karakter kod noktasını temsil eden bir veya daha fazla onaltılık basamaktan oluştuğu UTF-8 kodlu Unicode karakterleri içindir. Çevreleyen parantezlerin `{ }` zorunlu olduğunu unutmayın.

### Kaçış dizilerini denetleme

Geleneksel olarak dizeler, şu örnekteki gibi çift tırnak kullanılarak tanımlanır: `"this is a string"`; böyle bir dize içinde kaçış dizileri kullanabilirsiniz: `"this is a string.\nI'll now start on a new line."`. Ancak Lua’nın dizeleri tanımlamak için ikinci ve *çok* elverişli bir mekanizması vardır: sözde *uzun köşeli parantezler* metodu; bu metotta metni şu şekilde çevreleyerek bir dize tanımlarsınız: `[[` ve `]]`:

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

Uzun köşeli parantez yöntemiyle oluşturulan bir dize içinde Lua’nın karakter kaçış mekanizması *devre dışı bırakılır*: kaçış dizileri normal karakterler olarak değerlendirilir. Örneğin, şu dizede:

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

şu `\n` kaçış dizisi, tek satır başı karakteri (ASCII kodu 13) olarak değil, iki normal karakter olarak değerlendirilir: `\` ardından `n`.

### Uzun köşeli parantez dizeleri neden bu kadar yararlıdır?

Daha sonra inceleyeceğimiz üzere LuaTeX, şununla kullanabileceğiniz bir dizi özel, yerleşik Lua işlevi sağlar: `\directlua` LuaTeX’in dizgi davranışını denetlemek için. Bu birçok işlev arasında şu adlı bir işlev bulunur: `tex.print(*string*)` şunu geçirmenizi sağlar: `*string*` Lua kodundaki materyali dizilmek üzere LuaTeX’e geri gönderir. Çok basit bir örnek şudur:

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

bu da LuaTeX’in şunu dizmesine neden olur: `Hello, World!`

Bu `*string*` içinde kullanılan `tex.print(*string*)` LuaTeX’in işlemesi için TeX ve LaTeX komutlarını temsil eden metinler de içerebilir. Ancak TeX/LaTeX komutları bir `\` karakteriyle başlar; bu, çift tırnak kullanılarak oluşturulan dizelerde sorunludur çünkü Lua diziyi ayrıştırmaya, başlangıçtaki `\` karakterini algılamaya ve onu bir kaçış dizisinin başlangıcı olarak yorumlamaya çalışır. Lua kaçış dizisini işlemeye çalıştığında genellikle başarısız olur çünkü başlangıçtaki `\` karakteri, birçok TeX/LaTeX komut adındaki ilk karakterle birleştiğinde Lua’nın bildiği geçerli bir kaçış dizisi oluşturmaz. Örneğin şu tür bir dize işlenirken: `"I like \LaTeX"` Lua şunu görür: `\L` ve “geçersiz kaçış dizisi” hatasıyla başarısız olur; yukarıda belirtilen hataların nedeni de budur.

#### Uzun köşeli parantez dizeleri imdada yetişir!

Dizeleri oluşturmanın (tanımlamanın) uzun köşeli parantez yöntemi son derece yararlıdır; çünkü TeX/LaTeX komutları bir `\` karakteriyle başlasa bile, uzun köşeli parantez dize yöntemi Lua’nın kaçış dizisi mekanizmasını devre dışı bırakır. Makroların örneğin şunu kullanarak genişletilmesini önlememiz gerektiğini hatırlayarak, kısa bir örnek verelim: `\protected` ya da `\noexpand`.

Bir `\newtest` makrosunu şöyle tanımladığımızı varsayalım:

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

ve bunu şunun içinde kullanalım: `\directlua` LuaTeX Lua API işleviyle `tex.print()`:

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

Şunun kullanımı nedeniyle: `\protected`, makro `\newtest` genişletilmez; bunun sonucunda Lua’ya şu metin aktarılır:

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

Şundan sonra eklenen boşluk karakteri: `\newtest` ve açılış küme parantezinden (`{`) önce `\directlua`komut belirteçlerini metinsel gösterimlerine dönüştürmesinin bir yan etkisidir.

Bu kod Lua’ya aktarılır; Lua da daha sonra LuaTeX işlevini çalıştırır: `tex.print()` ancak kullandığınız yazı tiplerine bağlı şekillerde ortaya çıkan bir sorun vardır. Overleaf üzerindeki LaTeX’te şöyle bir çıktı görürdünüz:

![](/files/a3f1b5645eec7f38cffd3ecec2910f47cdeee2c6)

günlük dosyasında şu uyarıyla birlikte:

```
   Eksik karakter:
   (U+000A), [lmroman10-regular]:+tlig;! yazı tipinde yoktur
```

Düz TeX’te buna benzer görünen bir çıktı görebilirsiniz:

![](/files/55510684dd64d2dcf12a45ad5d7ac82ee893081b)

Her iki durumda da `\newtest` makrosu çağrılmaz ve çıktı amaçladığımız gibi olmaz. Hata, Lua’nın kaçış karakteri mekanizmasından kaynaklanır: şu metinde `\newtest {Hello}` makro adı şununla başlar: `\n` Lua bunu satır besleme karakteri için kaçış dizisi olarak tanır; dolayısıyla şunu değiştirir: `\n` ASCII karakteri 10 ile veya onaltılık olarak 0A ile. LaTeX hata iletisinde `U+000A` Unicode değerini 4 onaltılık basamak kullanarak gösterme yoludur.

Çünkü `\n` satır besleme karakterine dönüştürüldüğünde LuaTeX bir makro çağrısı görmez; bunun yerine ASCII karakter kodu 10 ile başlayan bir metni dizmesinin istendiğine inanır:

`⟨ASCII 10⟩ewtest {Hello}`

Kullanılan yazı tipine bağlı olarak LuaTeX, şunu dizebilir veya dizemeyebilir: `⟨ASCII 10⟩` karakteri; ancak kalan metin olduğu gibi çıktılanır ve `{` ve `}` bir grup olarak değerlendirilir ve yazdırılmaz.

Düz TeX farklı bir sonuç verir; çünkü varsayılan yazı tipi, karakter kodu 10 görüldüğünde büyük Omega’nın dizilmesine neden olan garip bir kodlamaya sahip Computer Modern Roman’dır.

Bu sorunları önlemek için Lua’nın kaçışlama mekanizmasının uygulanmasını engelleyecek uzun köşeli parantez dizeleri kullanmamız gerekir. Doğru sonuç şununla üretilir:

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

bu da aşağıdaki ekran görüntüsünde gösterilen sonucu üretir:

![](/files/0b5a808e4a586d6427446e048cbabb3b78087cd2)

### Genişletme ve genişletilemeyen komutların yürütülmemesi

Genişletmeyi ele alırken, bunun bir TeX motorunun *kaldırdığı* geçerli girdiden genişletilebilir bir komutu (belirteci) kaldırdığı ve *değiştirdiği* onu, bu genişletilebilir komutun ürettiği sonuç(lar)la değiştirdiği bir süreç olduğunu belirtmiştik. \directlua *yalnızca genişletme* etkinlikleri (bir belirteç listesi oluşturmak için) gerçekleştirdiğinden, *sonlanmıyor;* LuaTeX’in işlemesini bundan daha ileri götürmez. Genişletilebilir bir komut okunup tamamen genişletildiğinde, bu genişletmenin sonuçları—çoğu zaman genişletilemeyen komutları (belirteçleri) içerir—oluşturulmakta olan belirteç listesine eklenir ve Lua’ya aktarılmak üzere tekrar metne dönüştürülmeye hazır hâle gelir.

Burada işleyen önemli bir ilke vardır: *yalnızca genişletme* bir belirteç listesi üretmek üzere tasarlanmış etkinlikler sırasında LuaTeX de dâhil olmak üzere TeX motorları *yürütmez* hiçbir genişletilemeyen ilkel, yerleşik TeX komutunu.

Şu durumda: `\directlua{⟨kod⟩}`, eğer `⟨kod⟩` tamamen genişletilmiş sürümü genişletilemeyen TeX/LaTeX komutları üretiyor veya içeriyorsa, bunlar *Lua’ya aktarılır* (metin olarak temsil edilerek).

#### Örnek

Yalnızca genişletme işlemesi sırasında (örneğin şunun içinde) genişletilemeyen ilkellerin yürütülmediğini göstermek için bir örnek verelim: `\directlua`). Bir makro tanımladığımızı varsayalım: `\setcountreg` şöyle:

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

**Not**: Şunu kullanırız: `\relax` parametresinden sonra `#2` LuaTeX’in, parametreyle eşleşecek sayısal değeri (bağımsız değişkeni) ararken girdiyi taramasında aşırı ilerlemesini önlemek için `#2`.

Şunun dışında, eğer `\directlua`, daha sonra makroyu şöyle çalıştırırsak:

```
   \setcountreg{100}{50}
   100 numaralı sayım yazmacındaki değer \the\count100’dür.
```

şunu çıktılar:

`100 numaralı sayım yazmacındaki değer 50’dir.`

Bu bağlamda herhangi bir TeX motoru makroyu işlerdi `\setcountreg`—makroyu genişletir, bağımsız değişkenleri belirler ve okumaya devam ederdi *ve makronun değiştirme metninde (tanımında) bulunan komutları eyleme geçirirdi* (yürütürdü). Buradaki sonuç, `50` değerinin şu yazmaçta depolanan değer olarak atanmasıdır: `\count100`.

Ancak, bir TeX motoru *yalnızca genişletme* etkinliklerini gerçekleştirirken, örneğin şununla yaparken: `\directlua`, *yürütmez* makronun tanımında bulunan genişletilemeyen komutları.

Eğer şunu yazarsak

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

Lua kodu olarak aşağıdaki metni üretir:

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

Yukarıda üretilen Lua kodu, şunun içinde `\directlua` şu `\setcountreg` genişletildiğini, bağımsız değişkenlerinin belirlendiğini ve uygun parametreye (`#1` ve `#2`) ikame edildiğini, ancak bundan daha ileri gitmediğini gösterir: genişletilemeyen ilkel TeX komutu `\\count` idi *yürütülmez* sırasında `\directlua`genişletme işlemesi.

Ancak, ortaya çıkan dizeyi `x` *LuaTeX’e geri* şunun aracılığıyla `tex.print(x)` şöyle geçirirsek LuaTeX TeX kodunu yürütür:

```
\count100=50 % \count100’ü başlangıç değeri 50 olarak ayarla
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{250}]]
   tex.print(x)
}
100 numaralı sayım yazmacında depolanan değer \the\count100’dür.
```

Şundan sonra: `\directlua` tamamlandığında çıktı şöyle olurdu:

`100 numaralı sayım yazmacında depolanan değer 250’dir.`

bu da sayım yazmacının `100` artık şu değeri içerdiğini gösterir: `250`.

Yukarıdaki örnekten üretilen Lua kodu şudur:

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

Bu kod `x` değişkenini, hatalı kaçış dizilerinden kaynaklanan hataları önlemek için kullanılan uzun köşeli parantez yöntemiyle oluşturulmuş bir dize olarak tanımlar. x’i tanımlamak için çift tırnak kullansaydık, `"..."` x’i tanımlamak için, karakter birleşimi `\c` başındaki `\\count` bir hatayı tetiklerdi: `invalid escape sequence near ' "\c'`.

LuaTeX Lua API çağrısı `tex.print(x)` LuaTeX’in şu TeX kod dizisini yürütmesiyle sonuçlanır: `\count 100=250\relax` ve `\count100` şu değer atanır: `250` dizilmiş çıktıdan görüldüğü üzere:

`100 numaralı sayım yazmacında depolanan değer 250’dir.`

#### Dikkat: makrolar ve LuaTeX Lua API’si

Yukarıdaki örnekte, şunun sırasında `\directlua`ön işlemesinde (genişletmesinde) LuaTeX şu kodu yürütmedi: `\count 100=250`, bu kod şunu içerir: `genişletilemez` ilkel komut `\\count`: bu kodu çalıştırmak (yürütmek) için onu *LuaTeX’e geri aktarmamız gerekti* şunun aracılığıyla `tex.print()`.

`\directlua` LuaTeX’in bir belirteç listesi oluşturmak için yalnızca genişletme işlemesi gerçekleştirdiği durumlardan yalnızca biridir. Benzer genişletme işleme ve belirteç listesi oluşturma etkinlikleri gerçekleştiren başka komutlar da vardır; örneğin `\write` ve `\edef`: bu komutlar da genişletme işlemleri sırasında genişletilemeyen ilkelleri yürütmez. TeX motorlarının yalnızca genişletme işleme etkinlikleri sırasında bir belirteç listesi oluştururken genişletilemeyen ilkelleri yürütmemesi genel bir ilkedir.

**Makromuzu LuaTeX Lua API’sini kullanacak şekilde yeniden yazmak**

Şunu yeniden yazabiliriz: `\setcountreg` makrosunu, şu adlı bir LuaTeX Lua API işlevini kullanarak `tex.setcount()`, böylece sayım yazmacında depolanan değeri değiştirmek için TeX komutlarından kaçınarak `100`:

```
   \def\setcount#1#2{\directlua{tex.setcount(#1,#2)}}
   \count100=50
   100 numaralı sayım yazmacı \the\count100 içerir\par
   \setcount{100}{250}
   100 numaralı sayım yazmacı artık \the\count100 içerir\par
```

Bu kod şunu dizer:

```
100 numaralı sayım yazmacı 50 içerir
100 numaralı sayım yazmacı artık 250 içerir
```

Burada şunu kullanıyoruz: `tex.setcount()`, LuaTeX’in birçok Lua API işlevinden biri, *doğrudan erişmek için* LuaTeX’in iç veri depolama alanına, şu değeri yerleştirmek için: `250` sayım yazmacını temsil eden bellek konumuna `100`. Aslında *atlamış olduk* LuaTeX’in standart TeX motoru girdi işleme yöntemlerini: girdi okumayı, belirteç oluşturmayı ve TeX ilkel komutlarını yürütmeyi. Ancak burada dikkat edilmesi gereken bir nokta vardır: LuaTeX’in Lua API işlevlerini kullanarak, yalnızca genişletme işleme etkinliği *yan etkilere yol açabilir*: TeX motorunun içinde depolanan ve salt TeX/LaTeX komutlarıyla başka türlü mümkün olmayacak değer değişikliklerine.

**Örnek: beklenmedik yan etkiler**

İşte göstermek için bir örnek: *beklenmedik* şunu kullanan makrolarda ortaya çıkabilecek yan etkiler: `\directlua`. Aşağıdaki kodu yazdığımızı varsayalım:

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

Bu kodu çalıştırmak şunu dizer: `12345`!

Bu nasıl olabilir? Biz *açıkça* o değeri sayım yazmacına koymak için herhangi bir kod veya makro çağırmadık `999`. Yoksa çağırdık mı?

Şunu tanımladık: `\dochange` bir `\directlua` şunu kullanan komut `tex.setcount()` değeri depolamak için `12345` sayım yazmacında `999`: TeX kodunda bunun karşılığı şudur: `\count999=12345`. Ardından standart TeX ilkelini kullandık `\edef` makroyu tanımlamak için `\careful`—beklenmedik yan etkiyi tetikleyen şey şunun kullanımıdır: `\edef` ki bu beklenmedik yan etkiyi tetikler.

`\edef` bağımsız değişkenini tamamen genişletir: burada genişletilebilir bir makroyu algılar `\dochange` ve genişletir. Şu `\dochange` makrosu genişletilebilir komutu kullanır: `\directlua` bu, bir Lua API çağrısı içerir; dolayısıyla şunun genişletilmesi: `\dochange` şunun genişletilmesiyle sonuçlanır: `\directlua` ve bu da şunun `tex.setcount()` çağrılmasına neden olur; bu, sayım yazmacındaki değeri değiştirir `999`.

Eğer şunu yeniden tanımlarsak: `\dochange` TeX komutlarını kullanacak şekilde:

```
   Önce: 999 numaralı sayım yazmacı \the\count999 içerir.\par
   \def\dochange{\count999=12345\relax}
   \edef\careful{\dochange}
   Sonra: 999 numaralı sayım yazmacı \the\count999 içerir.\par
```

bu kodu çalıştırmak şunu dizer:

```
Önce: 999 numaralı sayım yazmacı 0 içerir.
Sonra: 999 numaralı sayım yazmacı 0 içerir.
```

Açıkça, şunun üzerinde hiçbir etkisi olmadı: `\count999`. Şu zaman: `\edef` tanımlar `\careful` onu genişletir `\dochange` ancak bu genişletme yalnızca genişletilemeyen TeX ilkelleri üretir: bunlar *yürütülmez* yürütülmez *saklanır* tanımını oluşturan belirteç listesinde `\careful`.

Eksiksiz olması açısından, aynı ilke bunun neden dizilmiş çıktı ürettiğini de açıklar:

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

## LuaTeX’in Lua API’sine kısa giriş

Gördüğümüz gibi, `\directlua` yalnızca geleneksel Lua kodu veya Lua ile TeX/LaTeX kodunun bir karışımını yazmanıza olanak sağlamaz; aynı zamanda LuaTeX dizgi yazılımının iç işleyişiyle iletişim kurmak veya onu doğrudan denetlemek için kullanabileceğiniz (çağırabileceğiniz), LuaTeX’e özgü ek Lua işlevlerinden oluşan bir pakete erişim sağlar. Bu makalede birkaç Lua işlevi kullandık, `tex.print()`, `texio.write()`, `tex.setcount()` ve bunlar, *çok* daha fazlasıyla birlikte, şu belgede açıklanmıştır: [LuaTeX Başvuru Kılavuzu'nda](http://www.pragma-ade.com/general/manuals/luatex.pdf) burada ilişkili işlev gruplarına şu ad verilir: *kütüphaneler*.

Bu Lua işlevlerini LuaTeX’in Lua API’si olarak düşünebilirsiniz (**Bir**ygulama **P**rogramlama **I**rayüzü); bunlar, Lua’yı sürücü olarak kullanarak LuaTeX’in dizgi davranışını denetlemek suretiyle gelişmiş dizgi ve belge mühendisliği çözümleri oluşturmak için araçlar sağlar.

Belirtildiği gibi LuaTeX, API’sini kütüphaneler olarak adlandırdığı işlev kümeleri hâlinde düzenler: amaçları veya eylemleri aracılığıyla ilişkili işlev grupları. Her işlev kümesi, LuaTeX’in iç süreçlerinin, veri yapılarının, veri depolamasının ve dizgi algoritmalarının belirli bir yönüne erişim sağlamak üzere tasarlanmıştır. LuaTeX dahili olarak birden çok bileşenden oluşur: yalnızca TeX motorunun kendisini değil, Lua, MetaPost, Kpathsea, FontForge, libpng ve zlib gibi diğer alt sistemleri de içeren yazılım kütüphaneleri/araçları (çoğu C ile yazılmıştır). Bu kütüphaneler, LuaTeX yürütülebilir yazılımının özelliklerini ve işlevlerini oluşturmak üzere bütünleştirilmiştir; kullanıcıların bu çok sayıdaki yazılım bileşeninin bütünleştirilmesi ve koordinasyonundan doğan LuaTeX işlevselliğine erişimi Lua API aracılığıyla sağlanır.

## Bazı örnekler ve tuzaklar

Bu bölümde, bu makalede sunulan konuları, kavramları ve açıklamaları kullanan bazı ek örnekler sunuyoruz.

### Tilde karakterinin (\~) kullanımı

Lua dili `~` karakterini (tilde olarak adlandırılır) sözdiziminin bir parçası olarak kullanır; buna “eşit değil” testi gerçekleştirme sözdizimi de dahildir. Örneğin, bir değişkenin `x` şuna eşit olmadığını `4` sınamak için şunu yazabilirdik:

```
   local x=3
   if x ~= 4 then
   print("x 4'e eşit değil")
   end
```

Bu basit Lua kodunu ... üzerinden çalıştırmayı denersek `\directlua`:

```
\directlua{
   local x=3
   if x ~= 4 then
   print("x 4'e eşit değil")
   end
}
```

bir hata alırız:

`[\directlua]:1: '\' yakınında 'then' bekleniyordu.`

Bu tuhaf, çünkü kodumuz doğru: kullanmışız `'then'` ve kodumuzda `\` karakteri yok, öyleyse ne oldu? Bunu anlamak için, TeX/LaTeX açısından `~` genellikle kategori kodu 13 olan bir “özel karakter” olarak tanımlanır: sözde etkin karakterler; bunlar mini-makrolardır ve dolayısıyla genişlemeye tabidir. Ne zaman `\directlua` şunu algıladığında `~` karakteri genişletilir *onu kaldırıp* girdiden kaldırılır ve *onu değiştirerek* genişlemesinin sonucu ile değiştirerek. Düz TeX kullanıldığında, LuaTeX'in ürettiği ve Lua yorumlayıcısına ilettiği sonuç metin (kod) aslında `~` karakterini içermez ve şöyledir:

`local x=3 if x \penalty \@M \ = 4 then print("x 4'e eşit değil") end`

Bu `~` karakteri *çıkarılır* ve *genişletilmiş* bileşen komutlarına dönüştürülmüştür—yukarıdaki Lua kodu, düz TeX'in etkin karakter tanımından kaynaklanır `~`. Şimdi Lua'nın neden şu hatayla yanıt verdiğini görebiliriz `'then' bekleniyordu, '\' yakınında`—bu kodu ayrıştırmaya başlar ama şu sözcükle karşılaşır `\penalty` bu Lua için hiçbir anlam ifade etmez ve bir sözdizimi hatası üretir.

Bunu düzeltmek için, `~` karakterinin, LuaTeX `\directlua` kodunuzu işlerken; örneğin, `~` karakterinin kategori kodunu geçici olarak 11'e (harf) değiştirebiliriz; kodu bir grup içine alarak:

```
\begingroup
\catcode`\~=11
\directlua{
   local x=3
   if x ~= 4 then
   print("x 4'e eşit değil")
   end
}
\endgroup
```

Bu kod beklendiği gibi çalışır ve `x 4'e eşit değil` konsola yazdırılır. Başka seçenekler de vardır: genişletilebilir komutları kullanabiliriz `\noexpand` ya da `\string`.

#### \string⟨belirteç⟩ Kullanımı

Uygulayabiliriz `\string` tek karakterli `⟨token⟩` `~` ki bunun kategori kodu 13'tür (etkin karakter); `\string` dönüştürdüğünü `~` karakterine, kategori kodu 12 olan bir karakter belirteci üretmek için. Eğer şunu yaparsak

```
\directlua{
   local x=3
   if x \string~= 4 then
   print("x 4'e eşit değil")
   end
}
```

gereksinim duyduğumuz Lua kodunu üretir:

`local x=3 if x ~= 4 then tex.print("x 4'e eşit değil") end`

#### \noexpand⟨belirteç⟩ Kullanımı

Kullanabiliriz `\noexpand~` etkin karakterin genişlemesini engellemek için `~`

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x 4'e eşit değil")
   end
}
```

Genişletilmemiş `~` belirteç, ... içinde oluşturulmakta olan belirteç listesine geçer `\directlua` ve çalışan Lua kodu üreten metne geri dönüştürülecektir.

### # karakterini kullanma

Lua dilinde `#` karakteri bir tablonun uzunluğunu bulmak için kullanılabilir. Ancak, aşağıdaki kodu denemeye çalışırsak

```
\directlua{
   local tbl = {}
   tbl[1] = "Merhaba"
   tbl[2] = "Dünya"
   tex.print("Tablo uzunluğu 2")
}
```

LuaTeX'in şu çıktıyı dizgilemesini bekleyebiliriz

`Tablo uzunluğu 2`

ancak bir hata üretir:

`\directlua]:1: bir sayı değerinin uzunluğu alınmaya çalışıldı`

Bu hata şu nedenle tetiklenir: `#` karakterinin kategori kodu genellikle 6'dır (makro parametresi)— `#` karakterinin TeX/LaTeX'te iki kullanımı vardır: makro parametrelerini belirtmek (`#1`, `#2`… `#9`) ve hizalama şablonlarındaki değiştirme metnini belirtmek ( `\halign` ve `\valign`).

Ne zaman `\directlua` belirteç listesini oluşturmak için belirteçler üretirken şunu görür: `#` kategori kodu 6 olan karakteri görür ve onu temsil etmek için uygun bir karakter belirteci oluşturur. Son belirteç listesini yeniden metinsel biçime dönüştürme zamanı geldiğinde, # için olan karakter belirteci (kategori kodu 6 ile) özel bir işleme tabi tutulur: şu şekilde çıktı verilir: *ardışık iki karakter*: `##`, bunun sonucunda aşağıdaki kod Lua'ya iletilir:

`local tbl = {} tbl[1] = "Merhaba" tbl[2] = "Dünya" print(##tbl)`

Lua koduna dönüştürülürken, orijinal `#` iki katına çıkarılmıştır ve bu bir hata üretir:

`\directlua]:1: bir sayı değerinin uzunluğu alınmaya çalışıldı`

Bu sorun, TeX'in çift kare işareti kullanan sözdiziminden kaynaklanır `##` tek bir `#` belirteci temsil etmek veya üretmek için; bu sözdizimi, parametre alan başka makroları tanımlayan makrolarda veya `\halign` ya da `\valign` tablo oluşturma komutları için şablonlar oluşturan makrolarda kullanılır. Bu biraz kafa karıştırıcıdır, o yüzden bir örneğe bakalım.

#### Örnek

Bir makro tanımladığımızı varsayalım `\mymacro` ki bu tek bir parametre alır, `#1`ancak aynı zamanda ikinci bir makro da tanımlar `\\foo` ki bu da tek bir parametre alır. Parametreyi ayırt etmek için `#1` ile kullanılan `\mymacro` ve tanımlama gereksinimi arasında `\\foo` kendi parametresini kullanacak olan `#1` TeX sözdizimi, şunu kullanmanızı gerektirir: `##1` içinde `\mymacro` ile kullanılacak parametreyi temsil etmek için `\\foo`:

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

Şöyle yazacak olsaydınız `\mymacro{Hey!}` bu, makroyu tanımlardı `\\foo` olarak

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

Şuna dikkat edin: `\mymacro`’nin parametresi `#1` (`Hey!`) tanımına dahil edilmiştir `\\foo` ve dizisi `##1` şuna dönüştürülmüştür `#1` tanımında `\\foo`. Dolayısıyla şunu kullanabiliriz: `\\foo` şöyle:

`\foo{, World!}`

şunu dizsin diye `Hey! Merhaba, Dünya!`

Şunu çözebiliriz `\directlua`’nin ... işleyişini `#` karakterinin durumunu, LuaTeX kodu işlemeye başlamadan önce kategori kodunu geçici olarak değiştirerek. Örneğin:

```
\begingroup
   \catcode`\#=11
   \directlua{
   local tbl = {}
   tbl[1] = "Merhaba"
   tbl[2] = "Dünya"
   tex.print("Tablo uzunluğu 2")
}
\endgroup
```

Bu, şu Lua kodunu üretir

```
local tbl = {} tbl[1] = "Merhaba" tbl[2] = "Dünya" tex.print("Tablo uzunluğu "..#tbl)
```

bu da beklediğimiz sonucu dizgiler:

`Tablo uzunluğu 2`

### % karakterini kullanma

TeX/LaTeX içinde, `%` karakteri genellikle kodunuzda tek satırlık yorumlar eklemek için kullanılır: TeX motoruna, söz konusu `%` yazıldığı satırın sonuna kadar o noktadan itibaren her şeyi yok sayması gerektiğini belirtmek için. Ancak Lua dilinde, `%` karakteri, aşağıdakiler gibi çok yararlı bazı dizgi işleme işlevlerinde kullanılır: `string.format(...)`, `string.gmatch(...)`ve `string.gsub(...)` bunlarda `%` karakteri, bu işlevlerin sözdiziminin önemli bir parçası olarak rol oynar.

TeX/LaTeX ile kullanıldığında, `%` kategori kodu 14 atandığı için yorum karakteri gibi davranır. Onu sıradan bir karakter gibi davranacak hâle getirmek ve normal TeX/LaTeX davranışını kapatmak için kategori kodunu 12 gibi güvenli bir değere değiştirmemiz gerekir. Aşağıdaki `\directlua` örnek, makalenin önceki kısımlarında ele alınan birkaç tekniği ve henüz bahsetmediğimiz bir tekniği birlikte kullanır: ``\catcode`\^^M=12``, bu da kodumuzda Lua yorumlarını kullanmamıza olanak tanır; aşağıda bu konu ele alınmaktadır.

#### Örnek

Aşağıdaki örnekler ...'den alınmıştır [lua-users.org](http://lua-users.org/wiki/StringLibraryTutorial), ... içinde kullanım için uygun şekilde değiştirilmiştir `\directlua`.

```
\documentclass{article}
\begin{document}
\begingroup
\ttfamily
\let\\\relax
\catcode`\^^M=12 %<---bunu aşağıda ayrıca inceleyeceğiz!
\catcode`\%=12
\directlua{
   local str -- sonucu tutmak için yerel bir değişken bildir

   tex.print("string.format() kullanımı:".."\\par")

   str=string.format("%s %q", "Merhaba", "Lua kullanıcısı!") -- dizgi ve tırnak içindeki dizgi
   tex.print(str.."\\par")
   str = string.format("%c%c%c", 76, 117, 97) -- karakter
   tex.print(str.."\\par")
   str=string.format("%e, %E", math.pi, math.pi) -- üs
   tex.print(str.."\\par")
   str=string.format("%f", math.pi) -- kayan nokta
   tex.print(str.."\\par")
   str=string.format("%g, %g", math.pi, 10^9) -- kayan nokta veya üs
   tex.print(str.."\\par")
   str = string.format("%o, %x, %X", 99, 125, 125)  -- sekizlik, onaltılık, onaltılık
   tex.print(str.."\\par")

   tex.print("\\vskip3mm".."string.gmatch() kullanımı:".."\\par")

   for word in string.gmatch("Merhaba TeX kullanıcısı", "%a+") do
      tex.print(word.."\\par")
   end

   tex.print("\\vskip3mm".."string.gsub() kullanımı:".."\\par")
   str=string.gsub("banana", "(an)", "%1-") -- "an" örneklerini yakala ve değiştir
   tex.print(str.."\\par")
}
\endgroup
\end{document}
```

Aşağıdaki ekran görüntüsü, yukarıdaki kodun dizgilenmiş sonucunu gösterir:

![\directlua içinde Lua dizgi işlevlerini kullanma](/files/0b9a08d2758b32e6ad3b2fddf09a5e7b250494f8)

## Lua kodu neden tek satırda gösteriliyor?

Bu makalenin örneklerinde gösterilen (üretilmiş) tüm Lua kod parçaları, tek bir metin satırı olarak sunuluyor gibi fark etmiş olabilirsiniz: başlangıçta `\directlua` kod parçacıklarındaki satır sonları izlenmiyor. Bunun nedeni nedir? Bunun sebebi, Lua kodundaki satır sonlarının *çıkarılmıştır* LuaTeX'in içindeki ön işleme sırasında `\directlua`silinmesi, Lua kodunun uzun bir tek satır hâline gelmesine neden olur. Bu davranış, TeX motorlarının satır sonu karakterlerini—programlama literatüründe `\r` (satır başı dönüşü) ve `\n` (satır besleme) olarak gösterilen—nasıl ele aldığıyla açıklanabilir. Kodun bölümlerini yorum satırı hâline getirmek için Lua'nın mekanizmalarını kullanmayı tartıştığımızda, bu ince ayrıntılar hakkında neden endişelenmemiz gerekebileceği daha net olacak.

Yazılım bir metin dosyası yazdığında (kaydettiğinde), metnin her bir satırı sözde “yeni satır” karakterleriyle sonlandırılır—gerçek yeni satır karakteri/karakterleri, o dosyayı yazmak için kullanılan uygulamaya ve işletim sistemine bağlıdır. Wikipedia'da bir [ilginç bir makale](https://en.wikipedia.org/wiki/Newline) günümüzde kullanılan yeni satır karakterlerinin tarihini/evrimini inceler.

Herhangi bir metin dosyasında, tek tek metin satırları, satır başı dönüşü (ASCII/Unicode karakter 13) ve/veya satır besleme (ASCII/Unicode karakter 10) olarak adlandırılan çeşitli karakter kombinasyonlarıyla sona erebilir; bunlar `\r` ve `\n` sırasıyla. TeX motorları platformdan bağımsız olacak şekilde tasarlandıkları için, metin dosyalarında kullanılan satır sonlarının doğası gereği platforma bağlı yapısını aşmak için bir yönteme ihtiyaç duyarlar. Doğal olarak, TeX motorlarının satır sonlandırma karakterleriyle başa çıkmak için yerleşik (ama yapılandırılabilir) bir yöntemi vardır.

### TeX motorları satır sonlarını nasıl işler

LuaTeX işlerken `\directlua{⟨kod⟩}` içindeki metni okur `⟨kod⟩` ve ... içinde bulunan herhangi bir satır sonunu işlemek için standart TeX motoru yöntemlerini uygular `⟨kod⟩`. Varsayılan olarak, bu standart TeX yöntemleri tüm satır sonu karakterlerinin (satır başı dönüşleri ve satır beslemeleri) kaldırılmasına ve boşluk karakterleriyle değiştirilmesine neden olur. “Varsayılan olarak” diyoruz, çünkü bir TeX motorunun satır sonu karakterlerini ele alış biçimi, kullanıcı tarafından yapılandırılabilen şu adlı bir parametre aracılığıyla değiştirilebilir `\endlinechar`. Burada kısa, iki adımlı bir genel bakış sunacağız; ancak daha fazla ayrıntı Overleaf makalesinde bulunabilir [\endlinechar'a giriş: TeX metin dosyalarından satırları nasıl okur](/latex/tr/derinlemesine-makaleler/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

#### Adım 1: TeX kendi satır sonu karakterini ekler

Girdi dosyanızdan bir satır metin okuduktan sonra, TeX motorları hemen herhangi bir `\r` ya da `\n` karakteri o satırın sonundan kaldırır. Ardından, TeX motorları *ekler* (geri ekleyerek) o satırın sonuna kendi satır sonu karakterini ekler. Bu karakter, kullanıcı tarafından ayarlanabilen ve adı `\endlinechar` olan bir TeX parametresinin değeri tarafından belirlenir ve TeX motorları tam da bu mekanizma sayesinde satır sonu karakterlerini platformdan bağımsız bir şekilde işleyebilir: giriş metin dosyasında başlangıçta ne olduğundan bağımsız olarak satır sonu karakterini seçer ve ayarlarlar.

Genellikle, TeX motorları şu ayarı kullanır:

`\endlinechar=13`

ki bu satır başı dönüşü karakteridir (`\r`). Ancak kullanıcılar her zaman ... için değer olarak başka bir karakter kodu atayabilirler `\endlinechar`—bunu bu makalenin ilerleyen kısımlarında göreceğiz.

Sonuç olarak, ... içinde bulunan herhangi bir satır sonu karakteri/karakterleri `⟨kod⟩` tarafından işlenmek üzere `\directlua{⟨kod⟩}` çıkarılır ve TeX motorunun kendisi tarafından belirlenen tek bir karakterle değiştirilir. Dikkat edin, TeX motorları bu satır sonu işlemini bir dosyadan yeni bir metin satırı okur okumaz ve *önce* o satırdaki tüm karakterleri (belirteç üretmek için) işler. Ancak hikâye burada bitmiyor: TeX motorunun *yapar* bu satır sonu karakterlerine ne yaptığı (onları eklemiş olması) Lua kodunun neden tek bir satır hâline geldiğini açıklar.

#### Adım 2: TeX kendi satır sonu karakterini bir boşluğa dönüştürür

Kendi satır sonu karakterini, değeri tarafından tanımlanan karakteri eklemenin yanı sıra, `\endlinechar`TeX motorları ayrıca kategori kodu 5'i olması gereken karakterler için de kullanır *olarak işlenmesi gereken* bir satır sonu karakteri. Bunun sonucu olarak TeX motorları genellikle şunlarla çalışır:

1. ... tarafından tanımlanan bir satır sonu karakteri `\endlinechar`;
2. aynı karakterin *genellikle* kategori kodu 5'e atanması.

Tek satırlık Lua kodu konusundaki açmazımızı açıklayan şey, TeX'in o satır sonu karakterine ne yaptığıdır. Bir TeX motoru bir giriş satırını işlediğinde, sonunda o satırdaki son karakteri algılar: `\endlinechar`Genellikle o karakterin kategori kodu 5'tir; bu da TeX'in *onu yerine koymasına* bir boşluk karakteriyle: yani, satır sonlarında TeX, fiilen, satır sonlandırma karakterini çıkarır ve yerine bir boşluk koyar. Bir not olarak, TeX motorları ayrıca kategori kodu 5 olan karakterleri boş satırları algılamak ve yeni bir paragraf başlatmak için kullanır, ancak burada buna değinmeyeceğiz.

Elbette, TeX olduğu için, `\endlinechar` başka bir karaktere yeniden ayarlayarak ve/veya `\endlinechar` atanan karaktere istediğiniz bir kategori kodu değeri vererek her türlü özel makro programlama hilesini yapabilirsiniz.

Lua kodunun tek bir metin satırı hâline gelmesini önlemek istiyorsanız, ya `\endlinechar` için atanan değeri (geçici olarak) değiştirebilir ya da standart satır sonu sonlandırıcısının kategori kodunu değiştirebilirsiniz `\r`.

### TeX'in tuhaf ^^ gösterimi

Aşağıdaki bölümlerde TeX'in alışılmadık `^^` gösterimiyle karşılaşacağız; bu gösterim, “genişletilmiş karakter mekanizması” olarak bilinir. Knuth tarafından, satır sonlandırıcılar, sekmeler ve benzeri “kontrol karakterleri”ni yazmayı kolaylaştırmak için tasarlanmıştır. Örneğin:

* `^^J` karakter kodu 10’u (`\n`, satır beslemesi);
* `^^M` karakter kodu 13’ü (`\r`, satır başı) temsil eder.

gibi karakter dizileri `^^M` TeX’in giriş tarama sürecinin erken aşamalarında, TeX karşılık gelen karakter belirteçlerini oluşturmak için giriş karakterlerini okurken, bunların karşılık gelen karakter kodlarına dönüştürülür.

### \endlinechar’a atanan karakteri değiştirmek

hâlâ `~` karakterinin genişletilmesini engellememiz gerektiğini hatırlayarak, şöyle yazabiliriz

```
\begingroup
\endlinechar=10 % satır sonu karakterini \n yap
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x 4'e eşit değil")
   end
}% \n’nin burada görünmesini istemiyoruz
\endgroup% ya da burada bir \n
```

Yukarıdaki ayar `\endlinechar` LuaTeX’in okuduğu her satırın sonuna karakter kodu 10’u (`\n`, satır beslemesi) eklemesine neden olur. Bunu yaparız çünkü `\n` (satır beslemesi) genellikle kategori kodu 12’ye sahiptir; bunu şunu yazarak test edebilirsiniz ``\the\catcode`\^^J``. Çünkü `\n` kategori kodu 5’e sahip değildir, LuaTeX bunu bir boşluk karakterine dönüştürmez; bu yüzden LuaTeX tarafından okunan her satırın sonunda kalır. Bunun sonucu olarak kodu 10 olan bir karakter her satırın sonunda kalır ve böylece tarafından oluşturulan belirteç listesine geçer `\directlua` ve ardından belirteç listesi metne dönüştürüldüğünde Lua kodunda yeniden görünür. Yukarıdaki değişiklikle, Lua kodu Lua yorumlayıcısına aşağıdaki karakter dizisi olarak gönderilir:

**\n**local x=3\*\*\n**if x \~= 4 then**\n**print("x 4'e eşit değil")**\n**end**\n\*\*

burada **\n** gösteriminin karakter kodu 10’u temsil etmesi amaçlanmıştır *yapmaz* bilinmeyen bir makro `\n`. Şimdi Lua yorumlayıcısı kodda satır sonlarını, tam olarak başlangıçta yazıldığı gibi görecektir `\directlua` komutuyla:

```
   local x=3
   if x ~= 4 then
   print("x 4'e eşit değil")
   end
```

Bu arada, Lua kodu dizisindeki ilk karakterin `\n` olduğunu ( `yerel` anahtar sözcüğünden önce) not edin. Bu `\n` satırından kaynaklanır

`\directlua{`

çünkü açılış `{` karakterinden hemen sonra bir satır sonu vardır ve bu da korunur. Bunu önlemek için şunu yazabilirsiniz

`\directlua{%`

### \r’nin kategori kodunu değiştirmek

Lua kodumuzda satır sonlarını korumak için `\r` i 5’ten farklı bir şeye de değiştirebiliriz, böylece `\r` artık bir satır sonu karakteri olarak tanınmaz (öyleymiş gibi işlenmez). Bu teknikle LuaTeX yine de `\endlinechar=13` kullanır ve bir `\r` eklemeye devam eder `\r` her satırın sonuna; ancak `\r` artık kategori kodu 5’e sahip olmadığından, LuaTeX

hâlâ `~` karakterinin genişletilmesini engellememiz gerektiğini hatırlayarak, şöyle yazabiliriz

```
\begingroup
karakterini bir satır sonu olarak tanımaz: onu bir boşluğa dönüştürmez ve Lua kodunda görünmesi için onu zarar görmeden aktarır.
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x 4'e eşit değil")
   end
}
\endgroup
```

Bu durumda Lua kodu Lua yorumlayıcısına şöyle gönderilir:

**\r**local x=3\*\*\r**if x \~= 4 then**\r**print("x 4'e eşit değil")**\r**end**\r\*\*

burada `\r` gösterimi, bilinmeyen bir makroyu değil, karakter kodu 13’ü temsil etmesi içindir `\r`. `\endlinechar` örneğinde olduğu gibi, Lua yorumlayıcısı şimdi kodda satır sonlarını, tam olarak başlangıçta yazıldığı gibi görecektir `\directlua` komutuyla:

```
   local x=3
   if x ~= 4 then
   print("x 4'e eşit değil")
   end
```

Bu arada, yine Lua kodu dizisindeki ilk karakterin `\r` olduğunu (yerel anahtar sözcüğünden önce) not edin: bu da satır

`\directlua{`

#### \r neden kategori kodu 12’yi kullandı da kategori kodu 11’i kullanmadı?

Cevap, giriş dosyamızdan okunan TeX/LaTeX komutlarının sonuna yanlışlıkla `\r` (kategori kodu 11 olan) bir karakter eklenmesinin tetikleyeceği hatalar riskinden kaynaklanır. Şu örneğe bakın:

```
\begingroup
\catcode`\^^M=11 % \r’nin kategori kodunu 11 yap
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x 4'e eşit değil")
   end
}
\endgroup
```

bu da şu hatayı üretir:

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

Bu nasıl doğru olabilir çünkü `\endgroup` standart bir TeX temel komutudur? Hatanın nedeni oldukça incedir: LuaTeX metnin son satırını— `\endgroup`\endgroup’ı içeren satırı—okuduğunda, o satırın sonuna ayrıca `\endlinechar` karakteri `\r`  ekledi. Şimdi, kendi belleği içinde LuaTeX şu karakter dizisini görüyor

`\endgroup\r`

burada `\r` kod 13’e sahip karakteri belirtmek için kullanıyoruz—bilinmeyen bir TeX makrosunun adı değil `\r`.

LuaTeX bu satırı metin dosyamızdan okuduğu anda orijinal `\begingroup` hâlâ etkindir: eşleşen `\endgroup` komutunun yürütülmesiyle henüz kapatılmamış bir grubun içindeyiz; bu da `\r` nın önceki kategori kodu değeri olan 5’e geri dönmesine neden olurdu.

LuaTeX metin satırından işlemeye (belirteç oluşturmaya) başladığında `\endgroup\r` ilk karakteri tanır `\` yı kaçış karakteri olarak algılar; bu da LuaTeX’in bir komutun adını aramaya başlamasını tetikler. Bir komut adını belirlemek için LuaTeX kategori kodu 11 olan karakter dizilerini arar, ancak `\r` ayrıca kategori kodu 11’e sahip olduğundan LuaTeX `\r` karakterinin (hâlâ kategori kodu 11 ile) oluşturduğunu düşünür *bir komutun parçası* adlı `\endgroup\r` olduğunu; elbette böyle bir şey olmadığından LuaTeX bir `Tanımsız kontrol dizisi` hatası bildirir. Bu yüzden kategori kodu 12’yi kullandık, 11’i değil.

LuaTeX’in hata iletisi konsola yazıldığı için, `\r` karakterini kolayca göremedik/fark edemedik; bu nedenle hataya neyin yol açtığı açık değildi.

### Neden satır sonları hakkında endişeleniyoruz?

Sebep, kodunuzda Lua’nın yorumlama yöntemini kullanabilmenizi sağlamaktır! LuaTeX’in kodunuz içinde tek tek satırları yorum dışı bırakmak için standart mekanizması olan `%` karakterlerini kullanabilirsiniz; ancak Lua dilinin kendi, çok kullanışlı, *çok satırlı* yorumlama mekanizmaları vardır; bunlardan yararlanmak isteyebilirsiniz.

Satır sonu sorunlarını ele almadan tek satırlık Lua dili yorumlarını kullanmaya çalışırsak ne olduğunu görelim. TeX `%` karakterini kodun tek satırlarını yorum dışı bırakmak için kullanırken, Lua çift tire kullanır: `--`.

Bunu çalıştırmaya çalışırsak ne olur:

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Bu karmaşık testin sonucunu yazdıracağım
   print("x 4'e eşit değil")
   end
}
```

Bir hata alırız:

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

Bu hata, yorumlayıcıya aktarılan Lua kodunda satır sonlarının olmamasından kaynaklanır; yorumlayıcı yalnızca, yorumun o dizinin ortasında başladığı tek, kesintisiz bir dize görür:

```

local x=3 if x ~= 4 then -- Bu karmaşık testin sonucunu yazdıracağım print("x 4’e eşit değil") end
```

Sonrasındaki her şey `**local x=3 if x ~= 4 then**` yorumlanmış olarak kabul edilir; bu da yorumlayıcının eksik bir Lua kodu parçası görmesine neden olur ve sonuçta şu hata ortaya çıkar

`'end' expected near <eof>`.

burada `<eof>` dosya sonu anlamına gelir.

Muhtemelen tahmin ettiğiniz gibi, bunu, örneğin kategori kodunu değiştirerek elde edebileceğimiz sonuçta ortaya çıkan Lua koduna satır sonlarının aktarılmasını sağlayarak düzeltmeliyiz `\r` yı 12’ye:

```
\begingroup
karakterini bir satır sonu olarak tanımaz: onu bir boşluğa dönüştürmez ve Lua kodunda görünmesi için onu zarar görmeden aktarır.
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Bu karmaşık testin sonucunu yazdıracağım
   print("x 4'e eşit değil")
   end
}
\endgroup
```

Şimdi, Lua yorumlayıcısı bir dize görüyor ama içinde `\r` satır sonları, yazıldığı haliyle `\directlua` parçada:

**\r**local x=3\*\*\r**if x \~= 4 then**\r\*\*-- Bu karmaşık testin sonucunu yazdıracağım\*\*\r**tex.print("x 4'e eşit değil")**\r**end**\r\*\*

Bu, gerçekte, şunu yazmakla eşdeğerdir

```
   local x=3
   if x \noexpand~= 4 then
   -- Bu karmaşık testin sonucunu yazdıracağım
   print("x 4'e eşit değil")
   end
```

Bu da Lua'nın bu kodu doğru şekilde işleyebilmesi ve yorum satırı yaptığımız satırı yok sayabilmesi anlamına gelir.

**Blok yorumlar**

Lua dili ayrıca adını verdiği bir sözdizimini de destekler [“blok yorumu”](https://www.lua.org/pil/1.3.html) (veya *uzun yorum*): bunlar şu ile başlar `--[[` ve karşılık gelen `]]`. Bu kullanışlı sözdizimini çok satırlı yorumlar yazmak ya da geçici olarak kaldırmak istediğimiz kod bölümlerini yorum satırı yapmak için kullanabiliriz:

```
\begingroup
karakterini bir satır sonu olarak tanımaz: onu bir boşluğa dönüştürmez ve Lua kodunda görünmesi için onu zarar görmeden aktarır.
\directlua{
   local x=3
   if x \noexpand~= 4 then
   --[[ Bu karmaşık testin sonucunu yazdıracağım
   sırf gerçekten
   böylesine inanılmaz bir sonuç]]
   print("x 4'e eşit değil")
   end
}
\endgroup
```

## Sonuç olarak

Öncelikle, bu kapsamlı makaleyi sonuna kadar okumayı başardıysanız tebrikler! LuaTeX'ten en iyi şekilde yararlanmak için gereken arka planı sağlayan TeX ile ilgili kavramlar ve konular hakkında makul ölçüde kapsamlı bir rehber oluşturmaya çalıştık; bunu şu komut aracılığıyla `\directlua` komut. Umarız öğretici olan ve Overleaf kullanıcı topluluğuna ve ötesine faydalı ve değerli bir katkı sunan bir makale ortaya koymuşuzdur. Her zaman olduğu gibi, geri bildirim almaktan memnuniyet duyarız; bu nedenle lütfen çekinmeden [bize ulaşın](https://www.overleaf.com/contact) bu makaleyle ilgili yorumlar veya hakkında yazmamızı istediğiniz başka konular için önerilerle bize ulaşın.

Mutlu $$\text{Lua}\mathrm{\TeX}\text{-ing!}$$ Graham Douglas ve Overleaf ekibinden.

### Ve son olarak... sadece luacode paketini kullanın

TeX ve Lua temelde farklı şekillerde çalışsalar da, bu diller her birinin bağlamında “özel anlamlara” sahip bir dizi karakteri paylaşır — örneğin \\\\, %, \~, #, ^, & — elbette Lua ve TeX bu özel anlamları için *çok* farklı amaçlar için atar. Sorunlu karakterleri incelememiz, güçlüklerin neden ortaya çıkabileceğini ve bunları nasıl çözebileceğinizi gösteriyor; ancak çok sayıda küçük Lua kod parçasını elle düzeltmek oldukça zahmetli olabilir, bu yüzden çoğu kullanıcı bu zorlukları ortadan kaldıran LaTeX paketlerini kullanmayı tercih eder. Bu paketlerden biri [`luacode`](https://ctan.org/pkg/luacode?lang=en) ile çalışmayı kolaylaştırmak için tasarlanmış bir dizi özellik sunar `\directlua`, ancak en azından artık sorunları daha iyi anlamış olabilirsiniz `luacode` sizin yerinize çözer.


---

# 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://ayakaleaf-pro.ayaka.space/latex/tr/derinlemesine-makaleler/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.
