> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/ar/mqalat-mtamqh/54-what-is-a-tex-token-list.md).

# ما هي قائمة رموز TeX

## إذًا، ما هي بالضبط «قائمة رموز TeX»؟

في [المقال السابق](/latex/ar/mqalat-mtamqh/53-what-is-a-tex-token.md)—أيضًا جزء من هذا [السلسلة حول التفاصيل التقنية المنخفضة المستوى في TeX](/latex/ar/mqalat-mtamqh/01-a-new-series-of-articles-tex-tokens-and-related-concepts-but-why-and-how.md)—استكشفنا العمليات التي يَمسح فيها TeX ملفَّك `.tex` لإنشاء رموز جديدة: فحصنا الطبيعة الأساسية لرمز TeX وكيف ينشئها TeX (انظر [ما هو «رمز TeX»؟](/latex/ar/mqalat-mtamqh/53-what-is-a-tex-token.md)).

في هذا المقال المتابع ننظر إلى *قائمة رموز*ات: ما هي وكيف تنشئها/تستخدمها محركات TeX. قد يكون فهم قوائم الرموز صعبًا بعض الشيء لأنها مخزنة في أعماق البنية الداخلية لـTeX: فهذه التفاصيل مخفية عن المستخدم—مع أن هذا اليوم ليس صحيحًا دائمًا إذا كنت تقوم ببرمجة أكثر تقدمًا باستخدام LuaTeX. لكن، في الوقت الحالي، يمكنك أن تبدأ في التفكير في قوائم الرموز على أنها طريقة TeX لتخزين سلسلة من القيم الصحيحة، حيث يكون كل عدد صحيح رمزًا مشتقًا من حرف أو أمر كان TeX قد قرأه من ملف الإدخال الخاص بك.

تلعب قوائم الرموز دورًا محوريًا في التشغيل الداخلي لـTeX، وغالبًا بطرق مفاجئة، مثل التشغيل الداخلي لأوامر مثل `\uppercase` و `\lowercase`. ومن الاستخدامات المهمة جدًا لقوائم الرموز تخزين الماكروات وتنفيذها، وهو موضوع سنفحصه بالتفصيل كجزء من مقال مستقبلي في هذه السلسلة.

### يحصل TeX على مدخله من الملفات وقوائم الرموز

لدى محركات TeX ثلاثة مصادر للإدخال—اثنان قد تعرفهما:

* ملفات نصية مادية مخزنة على القرص؛
* النص الذي يكتبه المستخدم في الطرفية (سطر الأوامر)؛

لكن لديه أيضًا طريقة ثالثة لقراءة/الحصول على المدخلات: قوائم الرموز!

قوائم الرموز هي، في الواقع، وسيلة تخزين بيانات داخلية يستخدمها TeX كجزء من عملياته. ولأن قوائم الرموز في TeX تعمل كـ«وسيلة تخزين» للرموز التي أُنشئت مسبقًا، فمن المنطقي أن يتمكن TeX من إعادة استخدامها كمصدر إدخال آخر. عندما يصبح من الضروري أن يأخذ TeX مدخله التالي من قائمة رموز معينة (أو عندما يُؤمر بذلك)، سيتوقف TeX مؤقتًا عن قراءة الإدخال من ملف مادي (أي إنشاء *رموز جديدة* ) وينتقل إلى الحصول على مدخله من *الرموز الموجودة*: الموقع الموجود في الذاكرة حيث تُخزَّن قائمة الرموز. وبوضوح، مع قائمة الرموز تكون عملية المسح + توليد الرموز قد حدثت بالفعل، لذلك لا يحتاج TeX إلا إلى النظر إلى كل رمز في القائمة وأن يقرر ماذا يفعل بكل واحد منها.

وبمثال سريع، فإن الأمر منخفض المستوى (البدائي في TeX) `\toks` يمكّنك من إنشاء قائمة من الرموز يحفظها TeX في الذاكرة لإعادة استخدامها لاحقًا:

```latex
\toks100={Hello}
```

لاسترجاع تلك الرموز (أي، إخبار TeX بأن يعاملها كمصدر الإدخال التالي) يمكنك إصدار أمر مثل

```latex
\the\toks100
```

سيؤدي هذا إلى جعل TeX ينتقل من إنشاء رموز جديدة من ملف الإدخال الخاص بك إلى الحصول على التالي من حيث تُخزَّن تلك الرموز (التي أنشأها `\toks` )—في ما يسمى *سجل رموز مميزة* وهو ببساطة موقع ذاكرة داخلي معروف لدى TeX (هنا هو السجل 100).

بالإضافة إلى ذلك، يمكن إنشاء قوائم الرموز داخليًا، بشكل فوري، بواسطة عدد من أوامر TeX. أحد الأمثلة هو الأمر `\jobname` الذي يولد سلسلة من الرموز الحرفية—رمزًا واحدًا لكل حرف في اسم الملف الرئيسي الذي يعالجه TeX. مثال آخر هو أمر `\string` ؛ على سبيل المثال

```latex
\string\mymacro
```

يولد سلسلة من الرموز الحرفية لكل حرف في الاسم `\mymacro`—بما في ذلك الحرف `\` الأولي. سنلقي نظرة أقرب على بعض «الأوامر المولِّدة للرموز» في نهاية هذا المقال.

## قائمة الرموز: شرح بالمماثلة

ما لم تكن لديك خلفية برمجية و/أو بعض المعرفة بعلم الحاسوب، فقد تكون «قوائم الرموز» مفهومًا ضبابيًا إلى حد ما، وربما مربكًا قليلًا. ومع ذلك، إذا كنت ترغب في أن تصبح ماهرًا في كتابة ماكروات TeX/LaTeX فإن فهمًا جيدًا لموضوعات مثل رموز TeX وقوائم الرموز وأكواد الفئات (`\catcode`) سيكون مفيدًا للغاية.

في هذا القسم سنستخدم مماثلة لشرح/توضيح الأفكار/المبادئ الأساسية لقائمة رموز TeX: كيف يخزن TeX الرموز في الذاكرة. ومن الجدير أن تأخذ وقتك في قراءة هذا لأنه *أساسي* من جوانب TeX ويستحق الفهم بمزيد من التفصيل.

### قوائم الرموز: مماثلة (تجربة فكرية)

سنخوض في «تجربة فكرية» لتوفير أساس لفهم قوائم رموز TeX. تخيل أن لديك وصولًا إلى مجموعة كبيرة من الحاويات، مثل مئات العلب—لا يمكننا استخدام مصطلح «صندوق» لوصف حاويات تجربتنا الفكرية لأن «box» له، بالطبع، معنى محدد جدًا في TeX، لا علاقة له بما نناقشه هنا. لذا سنسمي حاوياتنا «علبًا»، حيث إن كل علبة:

* لها رقم تعريفي فريد مطبوع على خارجها؛
* مقسمة (داخليًا) إلى حجرتين.

تُصمَّم هاتان الحجرتان كما يلي:

* الحجرة اليسرى تحتفظ بالعنصر الذي تريد وضعه في العلبة؛
* الحجرة اليمنى مصممة لتحتوي على قطعة ورق يمكنك أن تكتب عليها رقمًا واحدًا: الرقم الذي يعرّف علبة أخرى.

![اختبار](/files/acaa3fc0a65bb40a01ffe8301a3ccc9cb784c28c)

افترض أنك لديك مجموعة من، لنقل، 5 عناصر وتريد تخزين تلك المجموعة من العناصر داخل تلك العلب؛ لكن، للأسف، كل علبة لا يمكنها إلا أن تحتوي عنصرًا واحدًا من النوع الذي تريد تخزينه.

وللتبسيط، لنفترض أننا أردنا تخزين 5 دوائر ملوّنة:

![{{{alt}}}](/files/f763fa691546b5a2620cedccd8f899f6851638d0)

وعلاوة على ذلك، عندما تعود لاسترجاع تلك العناصر من نظام التخزين الخاص بك (العلب) فإن تلك العناصر *يجب* يجب أن تُسترجَع/تُعثر عليها بترتيب معين—الترتيب الذي خُزِّنت به: يجب الحفاظ على تلك السلسلة. كيف يمكنك تحقيق ذلك؟

يمكننا الاستفادة من حقيقة أن كل علبة:

* لها رقم تعريفي فريد مثبت على خارجها؛
* لها حجرتان—سنستخدم واحدة فقط منهما لاحتواء عنصرنا، بينما تحتوي الأخرى على قطعة ورق كُتب عليها رقم علبة أخرى.

سنفترض أن كل علبة فارغة—لكن لا شيء يمنعك من فتح أي علبة معينة للتأكد من أنها فارغة؛ فإذا لم تكن كذلك، جرّب التالية حتى تجد علبة فارغة.

ما يمكننا فعله هو ما يلي. ضع أول عنصر لدينا (الدائرة الخضراء الداكنة) في إحدى علبنا (مثلًا، العلبة 124) وسجّل رقم هذه العلبة الأولى—لا يهم ما هو رقم تلك العلبة الأولى، المهم فقط أن نكتبه في مكان ما ونحتفظ به لاستخدامه لاحقًا.

![{{{alt}}}](/files/94d1d08b7080b9e6291d29e88103f6347e4c79e4)

ابحث عن علبة ثانية—أي رقم علبة (مثلًا، العلبة 432)—وسجّل رقمها. اكتب رقم تلك العلبة الثانية (432) على قطعة من الورق وضع تلك الملاحظة *في العلبة الأولى* (العلبة 124). نضع عنصرنا الثاني (الدائرة الخضراء الفاتحة) في العلبة الثانية. إذن، لدينا الآن الوضع التالي:

* ملاحظة مكتوبة—غير مخزنة في علبة—تنص على أن العلبة الأولى رقمها 124 (وتحتوي عنصرنا الأول)؛
* داخل العلبة 124 أضفنا ملاحظة أخرى تقول إن العنصر التالي يوجد في العلبة 432.

في الجوهر، لقد *ربطنا* أول علبتين لدينا: نعرف من أين نبدأ (العلبة 124) وأن ملاحظة في العلبة 124 تخبرنا أي علبة تحتوي العنصر التالي (العلبة 432).

![{{{alt}}}](/files/a2f0a38d3ce6641eeae8166d7c91348b14b443cb)

ثم نجد علبة ثالثة، ونكتب رقمها (مثلًا، العلبة 543) على قطعة من الورق ونضعها في *الثانية* علبة (الرقم 432). ثم نضع عنصرنا الثالث (الدائرة الحمراء) في العلبة الثالثة.

الآن ربطنا ثلاث علب في السلسلة: نقطة البداية لدينا، العلبة 124 (الدائرة الخضراء الداكنة) → العلبة 432 (الدائرة الخضراء الفاتحة)→ العلبة 543 (الدائرة الحمراء) →…

![{{{alt}}}](/files/8a6783772f7ace9226493a50207cf3a3154f16e3)

كرر هذه العملية للعنصرين الأخيرين (الدائرتين الزرقاوين الفاتحة والداكنة) باستخدام العلبة 213 (الدائرة الزرقاء الفاتحة) والعلبة 102 (الدائرة الزرقاء الداكنة).

![{{{alt}}}](/files/2b1e9f57dadb7c9f4ab68c8d64fb61a7fc106a04)

لقد أصبح لدينا الآن جميع العلب الخمس مرتبطة معًا (باستخدام المعرّف الرقمي لكل علبة) ونستطيع استرجاع كل عناصرنا المخزنة—بالترتيب الصحيح—بمجرد المرور على كل علبة بالتتابع، وإزالة عنصرنا والنظر إلى الملاحظة التي تخبرنا أي علبة تحتوي عنصرنا التالي.

### وماذا عن العنصر الأخير في قائمتنا (العلبة 102)؟

لماذا ينبغي أن نهتم بهذه العلبة على وجه الخصوص؟ حتى الآن خزنّا كل عنصر في علبة، مع ملاحظة تقول أي علبة تحتوي العنصر التالي: بالنسبة للعنصر الأخير في قائمتنا، ماذا يجب أن تقول تلك الملاحظة—لأنه لا توجد علبة تالية.

عندما نصل إلى العنصر النهائي (العلبة) يجب أن يكون واضحًا أن هذه العلبة (التي تحتوي العنصر الأخير) هي العنصر النهائي في قائمتنا—ولا نحتاج إلى البحث عن علبة أخرى، لأنه لا توجد واحدة. إحدى الطرق لفعل ذلك هي وضع رقم علبة «خاص» داخل علبتنا النهائية (102). يمكننا استخدام أي رقم نريده بشرط أن نختار رقمًا فريدًا ليس رقم علبة حقيقية—مثلًا «العلبة -1»، «العلبة 0»: لا يهم ما دام نعلم أن «العلبة -1» أو «العلبة 0» وما إلى ذلك تخبرنا فورًا بأن نتوقف عن البحث: لسنا بحاجة إلى البحث عن مزيد من العلب لأن هذه هي الأخيرة وبالتالي لا توجد مزيد من العناصر لاسترجاعها.

### من «العناصر» و«العلب» إلى الرموز وTeX

نحتاج الآن إلى الانتقال من مماثلتنا إلى وصف أقرب إلى واقع TeX. أولًا، بدلًا من تخزين دوائر بألوان مختلفة في علبنا الخيالية، ينبغي أن يكون واضحًا أنه يمكننا التفكير في تلك العلب على أنها تخزن رموز TeX: أعدادًا صحيحة بسيطة. هذا هو الجزء الأسهل من نقل مماثلتنا إلى عالم البرمجيات (TeX). لكن ما الذي قد يكون المقابل البرمجي لعلبنا المرقمة المادية ذات «الحجرات»؟

لا نريد أن نتوغل كثيرًا في مفاهيم البرمجة، لكن يمكنك التفكير في «علبنا» على أنها تمثل بضعة بايتات من ذاكرة الحاسوب تم «تجميعها» في وحدة تخزين ملائمة. ويمكن اعتبار استخدامنا لمعرّف رقمي لكل علبة بوصفه الموقع داخل ذاكرة الحاسوب حيث توجد كل حزمة صغيرة من الذاكرة. وداخل TeX نفسه تُسمى تلك الحزم الصغيرة من التخزين «كلمات الذاكرة»—وهو مصطلح يعكس الزمن/العصر الذي أُنشئ فيه TeX (السبعينيات). هذه «كلمات الذاكرة» هي اللبنة الأساسية المستخدمة داخل TeX لكن لا نحتاج إلى استكشافها بمزيد من التفصيل هنا—يمكن لأي شخص يريد تفاصيل إضافية أن يرجع إلى مقال على [المدونة الشخصية للمؤلف](http://www.readytext.co.uk/?p=3537).

بمصطلحات برمجة الحاسوب، ما كنا نناقشه يُسمى [*قائمة مرتبطة*](https://en.wikipedia.org/wiki/Linked_list)‏: قائمة رموز TeX هي قائمة مرتبطة مبنية من حاويات التخزين الخاصة بـTeX المسماة *كلمات الذاكرة* حيث يمكن استخدام كل كلمة ذاكرة لتخزين:

* a *القيمة*‏: قيمة الرمز (عدد صحيح)؛
* a *الرابط*‏: موقع الذاكرة لكلمة الذاكرة التالية التي تحتوي الرمز التالي في قائمتنا.

## أين يستخدم TeX قوائم الرموز؟

في كل مكان! هذا صحيح لأن تعريف ماكرو TeX/LaTeX (مثلًا، أمر LaTeX) يُخزَّن كصيغة (متخصصة قليلًا) من قائمة الرموز—متخصصة بمعنى أنها تحتوي على رموز لا تراها في «قوائم الرموز» «القياسية» (ذات صلة بمطابقة معاملات الماكرو وما إلى ذلك). لا تقلق بشأن هذا لأننا سنتناول تلك التفاصيل في مقال مستقبلي.

### مثال على ماكرو

يمكن التفكير في الماكرو على أنه يتألف من ثلاثة أجزاء:

```
\def\<macro name><parameter text>{<replacement text>}
```

لاحظ أنه بدلًا من `\def` يمكنك أن تكون قد استخدمت `\edef`, `\gdef` أو `\xdef`.

**ملاحظة لمستخدمي LaTeX**‏: هنا نحن نعرّف الماكروات باستخدام أوامر TeX الخام منخفضة المستوى (تُسمى *البدائيات*). سيكون مستخدمو LaTeX أكثر ألفة مع إنشاء الماكروات عبر `\newcommand` LaTeX الخاصة بـ

(التي هي بحد ذاتها ماكرو). `<اسم الماكرو>` و *قائمة رموز* عندما تطلب من TeX إنشاء (تعريف) ماكرو، فإنه سينشئ رمزًا يمثل `<نص المعامل>` و `<نص الاستبدال>`الذي يمثل `<اسم الماكرو>` المركب`<نص المعامل>` و `<نص الاستبدال>`).

على سبيل المثال، إذا عرّفنا `\mymacro` بهذا الشكل:

```latex
\def\mymacro abc #1 defz{I typed "#1"!}
```

يمكننا أن نرى أن أجزاؤه المكوِّنة هي:

* `<اسم الماكرو>` = `mymacro`
* `<نص المعامل>` = `abc #1 defz`
* `<نص الاستبدال>` = `I typed "#1"!`

على سبيل المثال، يمكنك استدعاء `\mymacro` بهذا الشكل:

```latex
\mymacro abc THIS TEXT defz
```

والذي ينتج `I typed "THIS TEXT"!` ليُصفَّ— `abc` و `defz` كنت *تحتوي* ليُصفَّ. `abc` و `defz` هي سلاسل من الرموز الحرفية تُستخدم لـ *تحديد* المعامل الخاص بالماكرو `#1` ويتم امتصاصها والتخلص منها عندما تتم معالجة استدعاء الماكرو الخاص بك بنجاح بواسطة TeX.

عندما عرّفت `\mymacro`، فإن نمط الرموز الموجود في المخزن يعمل كـ«قالب» يمكن لـTeX استخدامه لمعرفة:

* أي الرموز في إدخالك هي رموز الفاصل؛
* أي الرموز في إدخالك تشكل فعليًا المعامل/المعاملات الخاصة بماكروك (هنا، ما تستخدمه لـ `#1` في استدعائك لـ `\mymacro`).

يجب أن تستدعي `\mymacro` بـ `<نص المعامل>` متضمنًا فواصل مطابقة تمامًا لتلك المستخدمة لتعريفه—وهذا يشمل استخدام فواصل حرفية لها أكواد فئات متطابقة. إذا كانت الفواصل في `<نص المعامل>` المستخدمة لاستدعاء `\mymacro` مختلفة عن تلك المستخدمة لتعريفه (القالب المخزن في الذاكرة)، فقد يصبح TeX مرتبكًا بعض الشيء—عندما يحاول معالجة `\mymacro` فلن يتمكن من مطابقة «القالب» المحفوظ في ذاكرته.

عندما يرى TeX أنك تستدعي ماكروًا فإنه سيمسح نص إدخالك لإنشاء رموز جديدة ويحاول، رمزًا بعد رمز، مطابقتها مع قائمة الرموز `<نص المعامل>` القالب المخزَّن كجزء من تعريف الماكرو الخاص بك. إذا أدت الفواصل المستخدمة في نص إدخالك إلى سلسلة من الرموز لا تطابق الرموز المخزنة في «القالب» فسيُلقي TeX عادةً خطأً.

TeX شديد الدقة—تذكّر أن الرموز الحرفية هي مزيج من رمز الحرف ورمز الفئة: إذا غيّرت رمز الفئة لحرف ما ستحصل على قيمة رمز مختلفة ناتجة عن ذلك الحرف.

افترض أننا غيّرنا رمز الفئة لـ `z` إلى، لنقل، 12—بينما هو عادةً 11—وحاولنا استدعاء ماكروّنا هكذا:

```latex
\catcode`z=12
\mymacro abc THIS TEXT defz more text here...
```

هذه المرة لن ينجح الأمر لأن رمز الفئة لـ `z` قد تغيّر. سترى خطأً مثل هذا:

```latex
معامل هارب؟
THIS TEXT defz
! انتهت الفقرة قبل أن يكتمل \mymacro.
<ليُقرأ مرة أخرى>
\par
سطر 22
```

عندما يقرأ TeX ويمسح `z` في `defz` فإنه لا يستطيع التعرف عليه على أنه يشكل نهاية `\mymacro`لـ `<نص المعامل>` المستخدمة في ملف الإدخال الخاص بك. وحتى رؤية ذلك `z` الخطأ، كان TeX قد طابق بشكل صحيح الأحرف الثلاثة الأولى `def` لكن ذلك `z` (برمز فئة 12) يربك مسح TeX. بافتراض أن `z` كان له رمز فئة 11 عندما *عرّفنا* `\mymacro`: فذلك سيؤدي إلى تخزين قيمة رمز 256×11 + 122 = 2938 كجزء من تعريف `\mymacro`(أي، كجزء من «القالب» المخزن). لكن مع رمز فئة 12، `z` سوف ينشئ الآن قيمة رمز 256×12 + 122 = 3194. ولأن قيمة الرمز (لـ `z` ) المقروءة من إدخالك (القيمة 3194) لا تطابق `z`-الرمز الموجود في `<نص المعامل>` المخزن (القيمة 2938)، سيواصل TeX مسح إدخالك. سيستمر TeX في مسح النص الذي يلي ماكروك (*المزيد من النص هنا* ...) للبحث عن رموز إضافية—محاولًا مطابقة القالب المخزن مع الرموز التي يجدها في إدخالك. على الأرجح لن يجد النمط الصحيح من الرموز وستنتج أخطاء عندما «يتجاوز» TeX إدخالك ويقرأ نصًا إضافيًا عن طريق الخطأ لإنشاء رموز إضافية—لا ينبغي أن تكون تلك الرموز الإضافية قد قُرئت في هذه المرحلة ومن شبه المؤكد أنها ستولّد خطأ.

سندخل في هذا بمزيد من التفصيل في مقال مستقبلي.

## استخدامات أخرى لقوائم الرموز

تشمل الأوامر الأخرى المستخدمة لإنشاء/تخزين قوائم الرموز ما يلي:

```latex
\toks<n>={...}
\everypar={...}
\everymath={...}
\everydisplay={...}
\everyhbox={...}
\everyvbox={...}
\output={...}
\everyjob={...}
\everycr={...}
\errhelp={...}
```

كل واحد من هذه الأوامر ينشئ قائمة رموز من الأحرف والأوامر الموجودة داخل الأقواس المعقوفة ‘{...}’، ويُقصد من قائمة الرموز تلك أن يُعاد استخدامها في ظروف معينة. على سبيل المثال، `\everypar={...}` ينشئ ويخزن مجموعة من الرموز (قائمة رموز) يحقنها TeX في الإدخال قبل أن يبدأ فقرة جديدة مباشرة.

## استخدامات خفية لقوائم الرموز: أمثلة

في هذا القسم الأخير سننظر إلى بعض الأمثلة العملية على استخدام قوائم الرموز بطرق قد لا تتوقعها.

### مثال 1: \uppercase{...} و \lowercase{....}—قوائم رموز مؤقتة

بالإضافة إلى الأوامر الصريحة لتوليد قوائم الرموز، توجد ظروف يولّد فيها TeX قائمة رموز داخلية خفية ومؤقتة من أجل إجراء بعض المعالجة الخاصة. تذكّر أنه عندما يقرأ TeX/يعالج أحرف/أوامرك فإنها تتحول إلى رموز: اللبنة الأساسية التي تعمل معها محركات TeX.

من الأمثلة الجيدة على ذلك الأوامر `\uppercase{...}` أو `\lowercase{...}` لأن طريقة عملها، عند أول مواجهة لها، قد تكون مربكة بعض الشيء. بمجرد أن تفهم ما تفعله—في أعماق TeX غير المرئية للمستخدم—تصبح عملياتها أسهل بكثير في الاستيعاب.

افترض أن لديك سلسلة بسيطة من الأحرف تريد تحويلها إلى أحرف كبيرة—مثلًا abcde وتحويلها إلى ABCDE. حسنًا، الأمر بسيط بما يكفي باستخدام `\uppercase` الأمر:

```latex
\uppercase{abcde}
```

سيجعل TeX يخرج `ABCDE`. الآن لنفترض أننا أردنا حفظ سلسلتنا البسيطة من الأحرف لاستخدامها لاحقًا—أي أننا لا نريد إخراجها فورًا، لذا سنستخدم *المحلية* الوحيدة لدى TeX—لا الآلية الخارجية (الملف) لحفظ البيانات: استخدم قائمة رموز. يمكننا فعل ذلك إما بإنشاء ماكرو أو باستخدام أمر صريح لقائمة رموز:

```latex
\toks100={abcde}
\def\mychars{abcde}
```

ثم، في وقت ما، قد تقرر أنك ترغب في إعادة استخدام سلسلة الأحرف الخاصة بك ولكن، هذه المرة، بأحرف كبيرة؛ لذا تحاول

```latex
\uppercase{\the\toks100}
```

و

```latex
\uppercase{\mychars}
```

لكن، للأسف، لا يعمل أي من هذين. لماذا؟

### قوائم رموز سرية!

لفهم كيفية عمل الأوامر `\uppercase{...}` `\lowercase{...}` فعليًا كان عليّ أن أُطلّ على آليات TeX الداخلية لذا فإن الشرح التالي مستمد من ذلك.

عندما يكتشف TeX إما `\uppercase{<material>}` أو `\lowercase{<material>}` في إدخالك فإن أول ما يفعله TeX هو إنشاء قائمة رموز داخلية (مؤقتة) من `<material>` المحاط بين ‘{’ و ‘}’ اللذين يأتيان بعد `\uppercase{...}` أو `\lowercase{...}` الأوامر—وتلك القائمة الرمزية المؤقتة داخلية بالنسبة إلى TeX.

نقطة حاسمة، ومركزية لفهم كيفية عمل `\uppercase{<material>}` و `\lowercase{<material>}` فعليًا، هي أن أي أوامر أو ماكروات موجودة في `<material>` لا تُنفَّذ *توسعيه*‏: كل ما يفعله TeX هو توليد رموز من الأحرف والأوامر الموضوعة بين `{...}`. أثناء تشغيل `\uppercase{<material>}` أو `\lowercase{<material>}` لا يُنفَّذ أي شيء بين الأقواس المعقوفة: بل يتحول ببساطة إلى رموز.

بعد `<material>` داخل `{...}` بعد أن يُحوَّل إلى قائمة رموز (مؤقتة)، يعود TeX بعد ذلك إلى فحص كل رمز في تلك القائمة ويختبر ما إذا كان *الحرف* رمز حرف *الأمر* أو `\uppercase` أو `\lowercase` رمز أمر (باستخدام القيمة العددية للرمز). إذا اكتشف TeX رمز حرف فإنه يعدّل ذلك الرمز لضبط حالة الحرف (بحسب ما إذا كان

تتم معالجته). يتجاهل TeX ببساطة أي رموز أوامر ولا «ينظر داخل» أي رموز أوامر ليرى ما تمثله أو تحتويه (مثلًا، ماكرو يحتوي أحرفًا)—بل يتخطاها فقط: الرموز الحرفية وحدها هي التي تُعالج/تتأثر فعليًا بعمليات تغيير الحالة. `\uppercase{abcde}` سيجعل TeX ينشئ قائمة رموز من `abcde` لا تحتوي سوى على رموز حرفية: كلها تُعدَّل لإنشاء سلسلة من الرموز المعدلة التي تمثل A وB وC وD وE. ثم تُعاد تلك الرموز المعدلة إلى معالج إدخال TeX مما يؤدي إلى `ABCDE` أن يُصفَّ. *داخل ماكرو*—على سبيل المثال `\def\mychars{abcde}`—وحاولنا تحويلها إلى أحرف كبيرة هكذا:

```latex
\uppercase{\mychars}
```

فإن ذلك سيفشل وسيُصفّ abcde—not ABCDE كما قد تتوقع. إذا حاولنا بعد ذلك تخزين أحرفنا في قائمة رموز مثل `\toks0={abcde}` وفعلنا `\uppercase{\the\toks0}` فمرة أخرى، `\uppercase` سيفشل لأن قائمة الرموز ستتكون بالكامل من رموز لا تتأثر بـ `\uppercase`.

لنأخذ مثال ماكروّنا، `\mychars`، بعد أن يكتشف TeX `\uppercase` في الإدخال، يبحث TeX عن معنى `\uppercase` ويتعامل معه، مُنشئًا قائمة رموز مؤقتة من `{\mychars}`. ومن الواضح أن قائمة الرموز المؤقتة تلك تحتوي على رمز واحد فقط ليس رمز حرف، بل رمز يمثل أمر الماكرو الخاص بنا `\mychars`؛ ومن ثم، ولأغراض تنفيذ `\uppercase`، فإن ذلك الرمز يُتجاهل—`\mychars` لا يمثل رمز حرف. لكن، كما ذُكر أعلاه، بمجرد أن يكون `\uppercase` قد أنجز عمله، فإن قائمة الرموز المؤقتة (التي أُنشئت بفعل `\uppercase`) تُعاد إلى آلية المعالجة الكاملة لإدخال TeX (المسح). عندما يعيد TeX قراءة تلك القائمة يكتشف رمزًا يمثل `\mychars` ماكرو الذي ينفذه TeX (يوسّعه) ويولد سلسلة من الأحرف لتصفيف abcde—ولا تزال بأحرف صغيرة لأنها كانت «مغلفة» داخل ماكرو وبالتالي غير مرئية لأفعال `\uppercase`.

بمجرد أن يعيد TeX فحص قائمة الرموز المؤقتة التي أُنشئت لـ `\uppercase{...}` أو `\lowercase{...}`، ويعالج أي رموز حرفية، فإنه ينتقل بعد ذلك إلى استخدام تلك القائمة الرمزية المؤقتة كمصدر لإدخاله: تصفيف الأحرف (الرموز الحرفية المعالجة) وتنفيذ الأوامر والماكروات.

### كيف يمكن إصلاح هذا؟

لأن `\uppercase{...}` أو `\lowercase{...}` لن يعمل إلا على الرموز الحرفية، نحتاج إلى طريقة «لفرض تفريغ التغليف» للأحرف الموجودة في ماكروّنا `\mychars` (أو الموجودة في `\toks` سجل) قبل أن `\uppercase{...}` أو `\lowercase{...}` يتصرف عليها. وبـ«تفريغ التغليف» فإن ما نعنيه حقًا هو عملية TeX لـ *الماكرو*:

* استبدال أمر TeX/LaTeX بـ *السلسلة* من الرموز *التي يتألف منها ذلك الأمر* (*مثلًا، ماكرو*) *مكوَّن،* أو
* منتجًا سلسلة الرموز التي صُمم الأمر لـ *توليدها*. أحد الأمثلة على أمر يولّد رموزًا هو `\jobname`، الذي ينتج سلسلة من الرموز الحرفية تمثل اسم ملف TeX الرئيسي الجاري معالجته.

#### سحر بمستوى أدنى: scantoks(..., ...)

هنا نحن نغوص بالفعل في بعض الزوايا الأشد ظلمة من آليات TeX الداخلية، لذا يمكنك تجاهل هذا القسم ما لم تكن تستمتع بالتفاصيل…

بعد أن يكتشف TeX `\uppercase` أو `\lowercase` في مجرى الإدخال، فإنه ينفذ دالة داخلية تُسمى `scantoks(..., ...)` وتتمثل مهمتها في توليد قائمة الرموز باستخدام العناصر بين ‘{’ المفتوحة و‘}’ المغلقة—كما ذُكر، تُفحَص تلك القائمة الرمزية لاحقًا لاكتشاف (ثم تعديل) أي رموز حرفية لتغيير حالة الحرف حسب المطلوب. لاحظ بعناية أننا نشير إلى `scantoks(..., ...)` على أنها الدالة الداخلية المدمجة في الشيفرة المصدرية لمحركات TeX—هنا لا يُشار إليها باسم سلسلة تحكم.

كجزء من عملها، `scantoks(..., ...)` يمكن أن تُؤمر بما إذا كانت ستوسّع، أم لا توسّع، قائمة الرموز التي تبنيها ولـ `\uppercase` و(`\lowercase`) فهي لا توسّع الرموز: بل تنشئها فقط وتضعها في قائمة رموز.

أحد أول الأشياء التي `scantoks(..., ...)` عليها أن تفعلها هو التحقق من وجود ‘{’ مفتوحة (أو أي حرف ذي `\catcode` 1) لأنها يجب أن تتأكد من أن المستخدم لم يرتكب خطأً نحويًا ونسي ‘{’ المفتوحة (أو أي حرف ذي رمز فئة 1)—لأن حرفًا ذا رمز فئة 1 مطلوب لتحديد بداية قائمة العناصر المطلوب تحويلها إلى رموز.

وهنا الحيلة: مهمة البحث عن ‘{’ مفتوحة تستدعي `scantoks(..., ...)` لتشغيل عملية التوسيع في TeX، ما يعني أن الأمثلة التالية ستعمل:

```latex
\let\ob={
\uppercase\ob abcde}
\def\obb{\ob}
\uppercase\obb xyz}
```

إذا أخذنا مثال `\obb`، وهو ماكرو، فإنه يُعرَف على أنه *أمر قابل للتوسّع* توسيع `scantoks(..., ...)` ويُوسَّع على النحو الواجب بواسطة TeX (عبر`\expandafter` ) في بحثه عن قوس فتح (أي حرف ذي رمز فئة 1). وما يعنيه هذا هو أنه يمكننا استخدام « `\expandafter` الحيلة *أمر قابل للتوسّع*يندرج أيضًا ضمن فئة كونه

إذًا، إذا عرّفت:

```latex
\toks0={abcde}
\def\mychars{abcde}
```

وافعل هذا:

```latex
\uppercase\expandafter{\mychars}
\uppercase\expandafter{\the\toks0}
```

ففي كلتا الحالتين سترى الآن ABCDE تُصفّ لأن `\expandafter` تتسبب في «تفريغ التغليف» (التوسيع) لـ `\mychars` و `\the\toks0`—وكلاهما ينتج `\uppercase` رؤية تدفق من الرموز الحرفية، والتي يمكنهما معالجتها لتغيير الحالة.

### مثال 2: \string—مزيد من قوائم الرموز المؤقتة

داخليًا، يصنف TeX `\string` بوصفه أحد أوامره المسماة «convert»: أي تنفيذ عملية «تحويل إلى نص». ال `\string` تم تصميم الأمر لتحويل رمز إلى نسخة نصية مقروءة للبشر — أي تنضيد السلسلة المقروءة للبشر من الأحرف التي أُنشئ منها ذلك الرمز في الأصل.

على سبيل المثال `\string\hello` ينشئ قائمة رموز مؤقتة تحتوي على الأحرف \\, h، e، l، l، o — نعم، حتى بما في ذلك ‘\’ الأولي. وبمجرد إنشاء تلك القائمة من الرموز، يعاد قراءتها بواسطة TeX ثم يُنضَّد نص الأمر “`\hello`” — نعم، بما في ذلك ‘\’ إذا اخترت الخط الصحيح…

قد تتساءل كيف/لماذا يستطيع TeX تنضيد حرف الهروب بينما يُستخدم عادةً لتحفيز الماسح الخاص بـTeX على إنشاء رمز أمر: لماذا لا يفعل ذلك هنا؟ الجواب يتعلق بأكواد الفئات: عادةً ما يكون للحرف ‘\’ catcode 0 (حرف الهروب)، ولكن عندما `\string` ينشئ قائمة الرموز الداخلية الخاصة به فإنه يفعل شيئًا مختلفًا قليلًا. عندما ينشئ قائمة رموز أحرف فإنه يعيّن رمز الفئة 12 لجميع الأحرف باستثناء حرف المسافة الذي يُعيَّن له catcode 10 — تذكّر أن رموز الأحرف تُحسب من 256 × رمز الفئة + قيمة ASCII. لذا، عندما يعيد TeX قراءة (إدخال) قائمة الرموز المؤقتة التي `\string` تم توليدها من `\hello`، فإن TeX *لا يرى حرف هروب* لأن الرمز الخاص بـ‘\’ حُسب باستخدام catcode 12 وليس 0: فـTeX يتعامل ببساطة مع ‘\’ كحرف عادي وينضِّده.

من الناحية الدقيقة، ينبغي علينا على الأرجح أن نلاحظ أن TeX لا يُولِّد فعليًا رمزًا لحروف الهروب عندما يكتشفها في الإدخال. فبمجرد أن يتعرّف على حرف ذي رمز فئة 0، يُستخدم ذلك الحرف فقط «لتحفيز» توليد رمز تسلسل تحكّم: وبمجرد أن يكون قد حفّز TeX على القيام بذلك، يكون حرف الهروب قد أدّى عمله ولم يعد يُؤخذ في الاعتبار.

### ملاحظة تقنية

أمر يُسمّى `\showtokens{...}` ‏(قدّمه محرك e-TeX) يمكنه عرض قوائم الرموز (في ملف السجل). من دليل e-TeX:

> الأمر `\showtokens{<token list>}` يعرض قائمة الرموز، ويسمح بعرض كميات لا يمكن عرضها بواسطة `\show` أو `\showthe`، على سبيل المثال:
>
> ```latex
> \showtokens\expandafter{\jobname}
> ```

## في الختام

في القسم 291 من شيفرة مصدر TeX (انظر الصفحة 122 من [تيكس: البرنامج](https://www.amazon.co.uk/Computers-Typesetting-TeX-Program-TEX/dp/0201134373)) يصف كنوث قائمة رموز على النحو التالي:

> «قائمة الرموز هي قائمة مرتبطة أحاديًا بعُقَد ذات كلمة واحدة في الذاكرة، حيث تحتوي كل كلمة على رمز ورابط. تُتذكَّر تعريفات الماكرو، وتعريفات روتين الإخراج، والعلامات، `\write` والنصوص، وبعض الأشياء الأخرى بواسطة TeX على هيئة قوائم رموز، ويَسبقها عادةً عقدة تحتوي على عدٍّ مرجعي في الحقل “token\_ref\_count” الخاص بها.»

في القراءة الأولى قد لا يكون هذا سهل الفهم، لكن، نأمل، أنه قد أصبح الآن أكثر وضوحًا قليلًا.


---

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

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

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

```
GET https://overleaf-pro.ayaka.space/latex/ar/mqalat-mtamqh/54-what-is-a-tex-token-list.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.
