> 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/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md).

# كيف تعمل \expandafter: من المبادئ الأساسية إلى استكشاف الشفرة المصدرية لـ TeX

[الجزء 1](/latex/ar/mqalat-mtamqh/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md) [الجزء 2](/latex/ar/mqalat-mtamqh/22-how-does-expandafter-work-the-meaning-of-expansion.md) [الجزء 3](/latex/ar/mqalat-mtamqh/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) [الجزء 4](/latex/ar/mqalat-mtamqh/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) [الجزء 5](/latex/ar/mqalat-mtamqh/17-how-does-expandafter-work-a-detailed-macro-case-study.md) [الجزء 6](/latex/ar/mqalat-mtamqh/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)

## مقدمة

لقد غطّينا الآن الموضوعات الخلفية اللازمة لاستكشاف شامل لـ `\expandafter`:

* أساسيات رموز TeX وكيفية حسابها؛
* المبادئ الكامنة وراء عملية التوسيع في TeX؛
* استخدام/إنشاء TeX لقوائم الرموز المؤقتة أثناء معالجة المستند؛
* كيف يستخدم TeX مصادر إدخال متعددة (بما في ذلك قوائم الرموز المؤقتة) ويتعامل معها.

في هذه المقالة سنجمع هذه الموضوعات/المفاهيم معًا لشرح الآليات الكامنة وراء `\expandafter` الأمر: باختصار، كيف يعمل.

## وهكذا، إلى \expandafter

الفكرة وراء `\expandafter` هي إجبار TeX على توسيع أمر (رمز) قبل أن يفعل ذلك عادةً. عند إعطاء رمزَين، $$\mathrm{T\_1}$$ و $$\mathrm{T\_2}$$ فإن فعل `\expandafter` $$\mathrm{T\_1T\_2}$$ يؤدي إلى معالجة TeX لـ $$\mathrm{T\_1}\text{<}$$التوسيع لـ $$\mathrm{T\_2}\text{>}$$، حيث $$\text{<}\dots\text{>}$$ تشير إلى قائمة من الرموز. يقوم TeX بتوسيع $$\mathrm{T\_2}$$ مسبقًا بحيث إن الرمز $$\mathrm{T\_1}$$ يتمكن الرمز $$\mathrm{T\_2}$$ (مثلًا أمرًا بدائيًا أو ماكروًا) من رؤية الرموز الناتجة عن توسع $$\mathrm{T\_2}$$ إذا كان الرمز `\expandafter` لِعنصر غير قابل للتوسيع مثل حرف غير نشط أو (معظم) الأوامر البدائية، فإن فعل $$\mathrm{T\_1T\_2}$$ لا يغيّر شيئًا: سيواصل TeX معالجة الرموز

### مقدمة إلى استخدام \expandafter

إذا لم تكن قد استخدمت `\expandafter`، فإليك مثالًا على استخدامه مع الأمر البدائي `\uppercase{...}`. لنفترض أننا نريد تنضيد اسم ملف الإدخال الرئيسي ولكن بأحرف كبيرة. قد نعرف أوامر TeX البدائية التالية: `.tex` الأوامر البدائية التالية في TeX:

* `\uppercase`: يفعل ما يوحي به اسمه، يحوّل رموز الأحرف إلى نظيرها بأحرف كبيرة (حيث يوجد ذلك)؛
* `\jobname`: كما رأينا، يتوسع ليعطي اسم الملف الرئيسي `.tex` الملف.

بافتراض أن ملف TeX الخاص بنا يُسمّى `mycode.tex` قد نتوقع بشكل معقول `\uppercase{\jobname}` أن ينضّد `MYCODE`. لكن لا، بل ينضّد `mycode` بحروف صغيرة. فما الذي «أخطأ»؟

إذا صغنا الاستخدام العام لـ `\uppercase` على أنه

```
\uppercase{<token list>}
```

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

على سبيل المثال، حتى لو عرّفنا ماكروًّا هو مجرد نص

```
\def\foo{some lower-case text}
```

فإن `\uppercase{\foo}` ما يزال ينضّد `some lower-case text` وليس `SOME LOWER-CASE TEXT` كما كنا نأمل، وذلك ببساطة لأن فعل `\uppercase` لا يحاول تحديد ما الذي `\foo` يمثله: فهو يراه `\foo` كعنصر أمر ويتجاهله، كما فعل مع `\jobname`.

### كيف نصلح هذا؟ \expandafter للإنقاذ

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

```
\uppercase\expandafter{\jobname}
```

فإنه يعمل: `MYCODE` سيُطبع. ما يحدث هو أن TeX يبدأ بمعالجة `\uppercase` ويتحقق فورًا من وجود حرف القوس المفتوح الإلزامي (`{`); ومع ذلك، يكتشف TeX `\expandafter` أمرًا يجعله «يُحوّل انتباهه» مؤقتًا إلى معالجة `\expandafter{\jobname}`.

إذا قارنا

`\expandafter` $$\mathrm{T\_1T\_2}$$

بمثالنا

`\expandafter{\jobname}`

يمكننا أن نرى

* $$\mathrm{T\_1} =\space$$`{`<sub>الرمز</sub>
* $$\mathrm{T\_2} =\space$$`\jobname`<sub>الرمز</sub>

حيث `{`<sub>الرمز</sub> و `\jobname`<sub>الرمز</sub> تشير إلى قيم الرموز المحسوبة بواسطة TeX — وتُستخدم الصياغة السفلية <sub>الرمز</sub> لتذكير أنفسنا بأن TeX يعمل في عالم الرموز الصحيحة.

كتابة `\uppercase\expandafter{\jobname}` تنجح لأن، على نحوٍ عام (والتفاصيل لاحقًا)، `\expandafter` تجعل TeX ينفذ المهام التالية:

1. قراءة وحفظ القوس `{`<sub>الرمز</sub>;
2. قراءة الرمز التالي: `\jobname`<sub>الرمز</sub>. يتعرف TeX على أن `\jobname`<sub>الرمز</sub> يمثل أمرًا قابلاً للتوسيع ويقوم بتوسيعه. `\jobname`<sub>الرمز</sub> يُستبدل بتوسعه — سلسلة من رموز الأحرف؛
3. بعد توسيع `\jobname` الأمر، يضع TeX `{`$$\_\mathrm{token}$$ «مرة أخرى في الإدخال» ويستخدم قائمة الرموز الناتجة عن توسع `\jobname` بحيث يقرأ TeX `\uppercase{`<sub>الرمز</sub>`<توسيع \jobname>`<sub>قائمة رموز (أحرف)</sub>`}`، وهذا ينتج النتيجة التي نريدها.

يوضح المخطط التالي كيف يعالج TeX `\uppercase\expandafter{\jobname}`—اقرأ الرسم من الأسفل واعمل صعودًا لتتبع مسار العملية.

![كيف يعمل \expandafter](/files/d6b8cf15dcb1b0ed7f5acedf2836aceb02939886)

تشرح الملاحظات التالية المراحل المختلفة للمعالجة.

1. يبدأ TeX بمعالجة `\uppercase` ويتحقق من حرف القوس المفتوح الإلزامي (`{`) لكنه يكتشف `\expandafter` الأمر.
2. إذا قارنا `\expandafter` $$\mathrm{T\_1T\_2}$$ في مدخلنا لـ `\expandafter{\jobname}` يمكننا أن نرى $$\mathrm{T\_1} =$$`{`<sub>الرمز</sub> و $$\mathrm{T\_2} =$$`\jobname`<sub>الرمز</sub>. لاحظ أنه هنا سنستخدم الصياغة السفلية <sub>الرمز</sub> للدلالة على أن TeX يعالج قيم الرموز الصحيحة.
3. `\expandafter` يقرأ، ثم يحفظ مؤقتًا، `{`<sub>الرمز</sub> عن طريق تخزين قيمة ذلك الرمز الصحيح في متغيّر داخلي. لاحقًا، سيعيد TeX إدراج ذلك الرمز مرة أخرى في الإدخال، بعد معالجة `\jobname` الأمر.
4. `\expandafter` يقرأ الرمز التالي، `\jobname`<sub>الرمز</sub>، ويوسّع `\jobname` الأمر.
5. توسيع `\jobname` ينشئ قائمة رموز مؤقتة تحتوي على تسلسل من رموز الأحرف التي تمثل `.tex` اسم الملف. لاحظ أن جميع رموز الأحرف التي يولدها `\jobname` تُحسب باستخدام فئة الرمز 12.
6. بمجرد أن `\jobname` يكون قد تم توسيعه، يعيد TeX إدراج الرمز المحفوظ في الخطوة 3 (`{`<sub>الرمز</sub>) ويضعه مرة أخرى في الإدخال. يفعل TeX ذلك بإنشاء قائمة رموز أخرى تحتوي على *الوحيد* `{`<sub>الرمز</sub>
7. لقد انتهى TeX الآن من معالجة `\expandafter`، مما ينتج قائمتين من الرموز جاهزتين لاستخدامهما كمصادر لإدخال TeX. يعود TeX الآن إلى معالجة `\uppercase` لكنه ضبط إدخاله بحيث تصبح قائمتا الرموز اللتان أنشأهما `\expandafter` مصدرًا للرموز بالنسبة لـ `\uppercase`—الذي يرى الآن `\uppercase{`<sub>الرمز</sub>`<توسيع \jobname>`<sub>قائمة رموز (أحرف)</sub>`}`. `\uppercase` يرى الآن تسلسلًا من رموز الأحرف ويمكنه إنتاج النتيجة التي نريدها.
8. بعد قراءة جميع رموز الأحرف التي ينتجها `\jobname`، يعود TeX إلى الحصول على الرموز من مصدر الإدخال السابق له (ملفنا `.tex` ) حيث سيقرأ الرمز التالي: القوس `}` الإغلاق المطلوب لإنهاء قائمة الرموز التي ستتم معالجتها بواسطة `\uppercase`.

### \expandafter والقوائم الداخلية من الرموز

قوائم الرموز المؤقتة هي *عنصرًا* حيويًا `\expandafter`من سلوك المعالجة لدى `\expandafter` ؛ ففهم استخدام ووجود تلك القوائم من الرموز يمكن أن يساعد على توضيح كيف `\expandafter` يحقق نتائجه، خصوصًا عند محاولة كتابة أو فهم ماكروهات تستخدم عدة أوامر `\expandafter\expandafter\expandafter...`

عنصرًا أساسيًا آخر في سلوك `\expandafter`، خاصة مع عدة `\expandafter` متتالية، هو استخدام *الاستدعاء الذاتي* (داخل برنامج TeX نفسه)—وهو موضوع سننظر فيه لاحقًا في هذه المقالة.

ولمزيد من المساعدة في فهم قوائم الرموز المؤقتة سنلقي نظرة على مثال آخر لـ `\expandafter`، وهذه المرة مع `\the` الأمر.

#### \expandafter والقوائم الداخلية من الرموز: المثال 2

في هذا المثال سنرى كيف يمكن استخدام `\expandafter` للتأثير في الرموز المخزنة في مسجل رموز عبر الأمر `\toks` فيما يلي البدائيات في TeX التي سنستخدمها:

* `**\count** *مسجل*=*عدد*`: بدائية في TeX تُستخدم لتخزين القيمة `*عدد*` في موقع TeX `*مسجل*`;
* `**\toks** *مسجل*={*قائمة رموز*}`: بدائية في TeX تُستخدم لتخزين `*قائمة رموز*` في موقع مسجل الرموز `*مسجل*`—لحفظ سلسلة من الرموز لاستخدامها لاحقًا؛
* `**\the** *رمز*`: أمر بدائي قابل للتوسيع في TeX يعالج `*رمز*`، رغم أن النتائج الدقيقة تعتمد على طبيعة `*رمز*` قيد المعالجة. `\the` له عدد من الاستخدامات: من بينها تنضيد القيمة المخزنة في معلمة أو متغيّر في TeX (مثلًا مسجل). تشمل الاستخدامات الأخرى لـ `\the` إدراج نسخة من الرموز المخزنة في مسجل رموز. هنا، سنستخدم `\the` لتنضيد القيمة المخزنة في `\count` مسجل.

سنبدأ برمز TeX التالي لتخزين القيمة `12345` في `\count` مسجل TeX `99`:

```
\count99=12345
```

إذا أردنا تنضيد القيمة المخزنة في `\count99` يمكننا استخدام `\the\count99` (أو `\number\count99`).

بعد ذلك سنستخدم الأمر `\toks` لتخزين بعض الرموز في مسجل الرموز `99`:

```
\toks99={\the\count99 }
```

قائمة الرموز المخزنة في مسجل الرموز `99` ستحتوي على ما يلي:

|                  |                                                                                                 |
| ---------------- | ----------------------------------------------------------------------------------------------- |
| **قيمة رمز TeX** | **العنصر المُمثَّل**                                                                            |
| 5382             | `\the`                                                                                          |
| 7885             | `\count`                                                                                        |
| 3129             | `9` (رمز الحرف 57 مع فئة الرمز 12) مما ينتج قيمة رمز قدرها $$256 \times 12 + 57 = 3129$$        |
| 3129             | `9` (رمز الحرف 57 مع فئة الرمز 12)، مما ينتج قيمة رمز قدرها $$256 \times 12 + 57 = 3129$$       |
| 2592             | `<مسافة>` (رمز الحرف 32 مع فئة الرمز 10)، مما ينتج قيمة رمز قدرها $$256 \times 10 + 32 = 2592$$ |

لاحظ أن قائمة الرموز التي ينشئها `\toks99` لا *تحتوي* على قيمة البيانات الفعلية المخزنة في `\count99` لأن `\toks` الأمر لا يقوم بالتوسيع: إنه ببساطة ينشئ رموزًا ويخزنها. في مثالنا، `\the` لا يتم توسيعه لذا لا يعالج `\count99`؛ هنا `\the` لا يُحوَّل سوى إلى رمز (القيمة 5382) ويُخزن في قائمة الرموز.

إذا أردنا أن تحتوي قائمة الرموز `\toks99` على رموز تمثل البيانات المخزنة في `\count99` فسنحتاج إلى طريقة ما لإنشاء تلك الرموز (جعلها متاحة) بحيث يتمكن `\toks` الأمر من الوصول إليها. وبالطبع `\expandafter` يمكنه فعل ذلك لنا. إذا كتبنا:

```
        \toks99=\expandafter{\the\count99 }
```

فإن فعل/معالجة الأمر `\toks` سيُوضَع «قيد الانتظار» بينما `\expandafter` يسبب (يُجبر) توسيع `\the` الذي بدوره يتعامل مع `\count` لإنتاج قائمة رموز مؤقتة تحتوي على رموز أحرف تمثل البيانات المخزنة في `\count99`. نقطة صغيرة لكن مهمة هي `<مسافة>` الحرف بعد الأرقام `99`: ذلك `<مسافة>` الحرف يعمل على إنهاء عملية المسح لدى TeX عندما يبحث عن كمية عددية.

هنا، فعل `\expandafter` يشبه كثيرًا مثال `\jobname` .

1. اقرأ واحفظ القوس `{`<sub>الرمز</sub>.
2. اقرأ الرمز التالي، `\the`<sub>الرمز</sub>، الذي يمثل أمرًا قابلًا للتوسيع، لذا يوسعه TeX. `\expandafter` يجبر توسيع `\the` الذي يعمل حينها على `\count99` لتحويل البيانات المخزنة في `\count` مسجل TeX `99` (الرقم 12345) إلى قائمة رموز مؤقتة. ستحتوي تلك القائمة على رموز أحرف تمثل الأرقام `1`, `2`, `3`, `4` و `5`—رموز أحرف ذات فئة الرمز 12.
3. بعد توسيع ومعالجة `\the`، يضع TeX `{`<sub>الرمز</sub> «مرة أخرى في الإدخال» ويستخدم قائمة الرموز الناتجة عن `\the\count99` بحيث يقرأ TeX `\toks99={`<sub>الرمز</sub>`<توسيع \the\count99>`<sub>قائمة رموز (أحرف)</sub>`}` وهذا ينتج النتيجة المرغوبة.

يُلخَّص هذا التسلسل من الأحداث في المخطط التالي — اقرأ الرسم من الأسفل واعمل صعودًا لتتبع تدفق العملية.

![كيف يعمل \expandafter](/files/8fd2971822a347fda387f7947b51e8ac6aa80df2)

1. يبدأ TeX بمعالجة `\toks`؛ فهو يرى `=` الإشارة الاختيارية`{`، أو أي حرف يحمل فئة الرمز 1) المستخدم للدلالة على بداية قائمة رموز. ومع ذلك، يكتشف TeX `\expandafter` أمرًا ويستمر في تنفيذ ذلك بدلاً منه.
2. إذا قارنا `\expandafter` $$\mathrm{T\_1T\_2}$$ في مدخلنا لـ `\expandafter{\the\count99 }` يمكننا أن نرى $$\mathrm{T\_1} =$$ `{`<sub>الرمز</sub> و $$\mathrm{T\_2} =$$ `\the<رمز>`.
3. `\expandafter` يقرأ، ثم يحفظ مؤقتًا، `{`<sub>الرمز</sub> (يخزن TeX مؤقتًا قيمة ذلك الرمز الصحيح في متغيّر داخلي). لاحقًا، سيعيد TeX إدراج ذلك الرمز مرة أخرى في الإدخال، بعد معالجة `\the`
4. `\expandafter` يقرأ الرمز التالي، `\the`<sub>الرمز</sub> ويقوم بتوسيعه.
5. توسيع `\the` ينشئ قائمة رموز مؤقتة من معالجة `\count99`—تحتوي تلك القائمة على تسلسل من رموز الأحرف التي تمثل قيمة البيانات المخزنة في `\count` مسجل TeX `99`.
6. بمجرد أن `\the` يكون قد تم توسيعه، يعيد TeX إدراج الرمز المحفوظ في الخطوة 3 (`{`<sub>الرمز</sub>) ويضع ذلك الرمز مرة أخرى في الإدخال. يفعل TeX ذلك بإنشاء قائمة رموز أخرى تحتوي على *الوحيد* الرمز `{`<sub>الرمز</sub>.
7. لقد انتهى TeX الآن من معالجة `\expandafter` وأنتج قائمتين من الرموز جاهزتين لاستخدامهما كمصادر الإدخال التالية. يعود TeX إلى معالجة `\toks99=` لكن الآن يكون TeX قد ضبط إدخاله بحيث إن قائمتي الرموز اللتين أنشأهما `\expandafter` مصدرًا للرموز بالنسبة لـ `\toks`—الذي يرى الآن `{`<sub>الرمز</sub>`<توسيع \the\count99>`<sub>قائمة رموز (أحرف)</sub>`}`. `\toks` يمكنهما الآن الوصول إلى، وتخزين، تسلسل من 5 رموز أحرف تمثل قيمة البيانات (`12345`) المخزنة في `\count99`: النتيجة التي نريدها.
8. بعد قراءة جميع رموز الأحرف التي ينتجها `\the\count99`، يعود TeX إلى الحصول على الرموز من مصدر الإدخال السابق له (ملفنا `.tex` ) حيث سيقرأ الرمز التالي: القوس `}` المطلوب لإنهاء قائمة الرموز المراد حفظها بواسطة `\toks99={...}`.

## كيف يعمل \expandafter حقًا

في هذا القسم سنلقي نظرة «منخفضة المستوى» داخل TeX نفسه: نستكشف الشفرة المصدرية/الدوال داخل TeX التي تنفذ سلوك `\expandafter`. تُعبَّر التفاصيل بشيفرة شبه-C لكنها يجب أن تكون مفهومة لأي شخص مألوف بلغات برمجة أخرى.

يوضح المخطط المشروح التالي كيف يطبّق TeX `\expandafter` كجزء من دالة أكبر تُسمّى `expand()`—الدالة الأساسية التي تقود معالجة التوسيع في TeX. داخل الجزء المسؤول عن تنفيذ `\expandafter` يمكننا أن نرى [*الاستدعاء الذاتي* السلوك](https://en.wikipedia.org/wiki/Recursion) حيث يُستخدم استدعاء آخر إلى دالة `expand()` لِمعالجة الرمز الثاني المقروء، $$\mathrm{T\_2}$$، في الحالات التي يكون فيها $$\mathrm{T\_2}$$ قابلًا للتوسيع.

على الرغم من أن هذه الشيفرة تظهر في محرك TeX الخاص بنوثل، فإن المبادئ الأساسية الموضحة في هذا الرسم تنطبق على جميع محركات TeX.

![كيف يعمل \expandafter داخل TeX](/files/afd845c70a7bc28f7ef784ad32de1c3abec121b4)

أول مهمة لـ `expand()` هي تحديد ما إذا كان الأمر المراد توسيعه ماكروًا أم أمرًا بدائيًا، لأن الماكروهات لها عملية توسيع متخصصة تُعالج بواسطة دالة تُسمّى `macrocall()`.

إذا كان الأمر المراد توسيعه أمرًا بدائيًا، فإن `expand()` الدالة تستخدم قيمة رمز الأمر الحالي (المخزنة في المتغير العام `curcmd`) لتحديد أي أمر بدائي بالضبط يحتاج إلى المعالجة. يمكننا رؤية هذه التفاصيل في قائمة أكثر اكتمالًا لـ `expand()`:

```
    void expand(void)
    {
    //curcmd متغير عام
    if(curcmd != macro) // curcmd < 111
    {
      switch(curcmd)
      {
        حالة \expandafter: // عالج الأمر \expandafter T1T2
        {
            gettoken(); // اقرأ الرمز T1
            t = curtok; // احفظ الرمز T1 في المتغير المحلي t
            gettoken(); // اقرأ الرمز T2
            if(curcmd > 100) // هل الرمز T2 قابل للتوسيع؟
                expand();    // نعم! الرمز T2 قابل للتوسيع:
                             // نفّذ توسعة T2 عن طريق
                             // إجراء استدعاءٍ عوديٍّ إلى expand()
            وإلا
                backinput(); // الرمز T2 غير قابل للتوسيع: أَعِد هذا الرمز
                             // إلى الإدخال ليُقرأ مرة أخرى (لاحقًا)

            curtok = t ;  // أَعِد المتغير العام curtok إلى القيمة المحفوظة لـ T1
            backinput() ; // أَعِد الرمز T1 إلى الإدخال
                          // قبل الرموز الناتجة عن توسعة T2
        }
        break;

        // شيفرة لمعالجة الأوامر القابلة للتوسيع الأخرى
        case “convert to text” command: // أيًّا من \number أو \string أو \romannumeral،
                                        // \meaning، \fontname، \jobname
                                        // تتشارك القيمة نفسها لـ curcmd
        break;

        case \noexpand: // امنع توسعة الرمز التالي
        ...
        break;

        case \csname:  // أنشئ اسم تسلسل تحكّم.
        ...
        break;

        case \the: // أدرج بعض الرموز
        ....
        break;

        case “\if... test command” : // عالج أحد الشرطيات في TeX:
                                      // \if، \ifcat، \ifnum، \ifdim، \ifodd، \ifvmode،
                                      // \ifhmode، \ifmmode، \ifinner، \ifvoid،
                                      // \ifhbox، \ifvbox، \ifx، \ifeof، \iftrue، \iffalse،
                                      // \ifcase، \ifdefined، \ifcsname، \iffontchar
        ...
        break;

        case “\fi or \else”: // أنهِ الشرط الحالي
        ...
        break;

        // إلخ لأي أوامر بدائية أخرى قابلة للتوسيع مدعومة بواسطة
        // محرك TeX

        }

    }else // ليست أمرًا بدائيًا قابلاً للتوسيع: إنها ماكرو
        {
             macrocall()
        }
        // ... تمت إزالة المزيد من الشيفرة
    }
```

### حب TeX للمتغيرات العامة

ربما يعكس ذلك عمره والفترة التي صُمم فيها، إذ يستخدم الشيفرة المصدرية لـ TeX على نطاق واسع ما يُسمّى [المتغيرات العامة](https://en.wikipedia.org/wiki/Global_variable)—وفي الواقع يوجد منها المئات. وبحكم طبيعتها، يمكن تغيير/تعديل المتغيرات العامة من أي مكان داخل الشيفرة المصدرية لـ TeX — والتي، بالنسبة إلى TeX الخاص بـ Knuth، هي ملف أحادي ضخم واحد يضم أكثر من 25,000 سطر من الشيفرة ومئات الدوال. إن فهم كيفية عمل TeX ليس دائمًا مهمة سهلة...

لمعالجة `\expandafter`، يقرأ TeX الرموز من مدخله الحالي باستخدام دالة تُسمّى `gettoken()` وتتمثل مهمتها في إنشاء رمز وضبط قيمة عدة متغيرات عامة أساسية تُستخدم في أنحاء شيفرة TeX المصدرية. ويُستخدم متغيران من هذه المتغيرات، يتم تحديثهما بفعل `gettoken()`، في تنفيذ `\expandafter`:

* `curtok`: (الرمز الحالي) القيمة الصحيحة للرمز الذي جرى قراءته للتو؛
* `curcmd`: (رمز الأمر الحالي) رمز الأمر (أو الحرف) الذي يمثله الرمز `curtok`.

عند معالجة `\expandafter`$$\mathrm{T\_1T\_2}$$ يقرأ TeX الرمز $$\mathrm{T\_1}$$ ويحفظ قيمته مؤقتًا (عددًا صحيحًا) في متغير محلي يُسمّى `t`. ثم يقرأ TeX $$\mathrm{T\_2}$$ ويتحقق مما إذا كان ذلك الرمز يمثل أمرًا قابلاً للتوسيع —`curcmd`من خلال التحقق مما إذا كان رمز أمره ( $$\mathrm{T\_2}$$ ) > 100. إذا كان الأمر كذلك، يحتاج TeX إلى توسيع الأمر الذي يمثله `expand()`ويجري استدعاءً آخر للدالة *الاستدعاء الذاتي* لأن `expand()` : وهذا مثال على `\expandafter`كون الدالة تستدعي نفسها. إن إدراك الطبيعة العودية لعملية التوسيع، وخاصة عند استخدام `\expandafter` المتتالية `\expandafter\expandafter\expandafter...` من الأوامر—أي،

إذا كان الرمز $$\mathrm{T\_2}$$ قابلًا للتوسيع، فستجري عملية التوسيع، وعندما يعود الاستدعاء العودي إلى `expand()` ، تُعيد الشيفرة داخل تنفيذ `\expandafter` إدراج الرمز $$\mathrm{T\_1}$$ مرة أخرى في الإدخال. ويُعاد إسناد المتغير العام `curtok` إلى قيمة الرمز المحفوظة — المخزنة في المتغير المحلي `t`، وهي قيمة الرمز $$\mathrm{T\_1}$$— ويُجرى استدعاء للدالة `backinput().`

#### الدالة backinput()

كما يوحي اسمها، تضع هذه الدالة رمزًا «في الإدخال» من جديد. وللقيام بذلك، يستخدم TeX القيمة الحالية للمتغير العام `curtok` لإنشاء قائمة رموز تحتوي على رمز واحد فقط (وتُعطى قيمته الصحيحة بواسطة `curtok`). كما يرتب TeX معالجة الإدخال بحيث تُقرأ تلك القائمة ذات الرمز الواحد مرة أخرى، في الوقت المناسب، بواسطة TeX كجزء من معالجة إدخاله اللاحقة. لاحظ بعناية أن الرمز $$\mathrm{T\_1}$$ يُعاد إدراجه *بعد انتهاء التوسعة*، وهذا يضمن أن TeX سيقرأ ذلك الرمز المُعاد إدراجه *قبل أن* عندما يقرأ الرموز الناتجة عن توسعة $$\mathrm{T\_2}$$.

### معالجة الماكروات: الدالة macrocall()

كما نوقش سابقًا، فإن جميع الماكروات، إلى جانب بعض الأوامر البدائية، قابلة للتوسيع، وتتم كل معالجة التوسيع عبر `expand()` الدالة. ومع ذلك، `expand()` تحرص على استخدام `curcmd` ‏(رمز الأمر الحالي) للتمييز بين الأوامر البدائية القابلة للتوسيع والماكروات، لأن عملية توسيع الماكرو تُدار بواسطة دالة مخصصة تُسمّى `macrocall()`. وتحتاج الماكروات إلى عملية توسعة متخصصة لأن وسائط الماكرو والرموز الفاصلة يجب أن تُمسح بطريقة دقيقة وصارمة للغاية؛ ولذلك تُفوَّض هذه العملية إلى دالة صُممت للقيام بذلك: `macrocall()`.

#### توسعة الماكرو مقابل تنفيذ الماكرو

توسعة *الماكرو* ليست هي العملية نفسها مثل *تنفيذ*: فامتداد الماكرو هو عملية ما قبل التنفيذ التي يجريها TeX لإعداد الماكرو *ليكون جاهزًا للتنفيذ*. ويحدث «تنفيذ» الماكرو عندما يقرأ TeX بنشاط ويعالج الرموز الموجودة في تعريف ذلك الماكرو (نص الاستبدال) ووسائطه (المعلمات).

#### توسعة الماكرو

لتوسيع ماكرو، يتحقق TeX أولًا مما إذا كان الماكرو يأخذ وسائط؛ فإذا كان الأمر كذلك، `macrocall()` يمسح المدخلات بعناية فائقة بحثًا عن الرموز المخصصة لتصبح وسائط الماكرو. وتتضمن تلك العملية التحقق من مدخلات المستخدم بحثًا عن أي رموز فاصلة استُخدمت في التعريف الأصلي للماكرو — ويجب أن يطابق نمط الرموز في استدعاء الماكرو تمامًا نمط الرموز الموجود في التعريف المخزن. ومع ذلك، فإن الرموز المستخدمة كفواصل تُهمل ببساطة بواسطة TeX: فهي، في الواقع، ليست إلا شكلًا من «علامات الترقيم» التي يستخدمها TeX لتحديد الرموز الفعلية المخصصة لتصبح وسائط الماكرو — أي الرموز التي يقصد المستخدم أن يعالجها الماكرو. لمزيد من المعلومات عن الرموز الفاصلة، انظر [كيف تعمل ماكروات TeX فعليًا](/latex/ar/mzyd-mn-almwdhwaat/22-how-tex-macros-actually-work-part-4.md).

لكل معلمة (`#1, #2...#9`) موجودة في التعريف الأصلي للماكرو، يمسح TeX استدعاء الماكرو الفعلي لتحديد أي الرموز التي قدمها المستخدم مخصصة لكل معلمة (أي تشكل وسائط الماكرو). وتنتج عن تلك العملية قائمة أو أكثر من قوائم الرموز الصغيرة: واحدة لكل وسيط من وسائط الماكرو.

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

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

للاطلاع المتعمق على معالجة ماكروات TeX، راجع سلسلة المقالات ذات الأجزاء الستة [كيف تعمل ماكروات TeX فعليًا؟](/latex/ar/mzyd-mn-almwdhwaat/01-a-six-part-series-how-do-tex-macros-actually-work.md)

[الجزء 1](/latex/ar/mqalat-mtamqh/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md) [الجزء 2](/latex/ar/mqalat-mtamqh/22-how-does-expandafter-work-the-meaning-of-expansion.md) [الجزء 3](/latex/ar/mqalat-mtamqh/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) [الجزء 4](/latex/ar/mqalat-mtamqh/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) [الجزء 5](/latex/ar/mqalat-mtamqh/17-how-does-expandafter-work-a-detailed-macro-case-study.md) [الجزء 6](/latex/ar/mqalat-mtamqh/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)


---

# 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/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.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.
