> 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/47-tex-tables-how-tex-calculates-spanned-column-widths.md).

# جداول TeX: كيف يحسب TeX عروض الأعمدة الممتدة

## هدف هذه المقالة

في هذه المقالة نستكشف كيف $$\mathrm\TeX$$ يحسب عروض أعمدة الجدول عندما تحتوي الجداول على إدخالات (مثل عناوين الجداول) تمتد عبر عدة أعمدة (مثلًا باستخدام $$\mathrm\TeX$$ البدائيات `\omit` و `\span`). وباستخدام [جدول «مرجعي»](#reference-table) كنقطة انطلاق، ننشئ مجموعة من الأمثلة —المستمدة من ذلك الجدول المرجعي— عبر تعديل إدخالات مختلفة لإنشاء أعمدة ممتدة. ومن خلال فحص أثر تلك التعديلات يمكننا البدء في تكوين فهم للخوارزمية الأساسية التي $$\mathrm\TeX$$ يستخدمها لحساب عرض الأعمدة الممتدة.

### باستخدام $$\mathrm\TeX$$ تحتوي $$\mathrm\LaTeX$$

لفحص وشرح *كيف* $$\mathrm\TeX$$ يحدد عروض الأعمدة الممتدة، من الضروري الاستغناء عن أيٍّ من حزم الجدول الرائعة $$\mathrm\LaTeX$$ والعودة إلى أوامر إنشاء الجداول الأساسية منخفضة المستوى (الأولية): وبوجه خاص، `\halign{...}`, `\span` و `\omit`. [الحزم $$\mathrm\TeX$$/$$\mathrm\LaTeX$$ الجدولية](https://ctan.org/topic/table) هي بالطبع أدوات إنتاجية أساسية وتوفر ثروة من الوظائف شديدة الفائدة التي تُمكِّن المستخدمين من إنتاج طيف واسع من المواد الجدولية بسرعة باستخدام $$\mathrm\LaTeX$$. وتوفر تلك الحزم «هياكل ماكرو» أساسية مبنية حول $$\mathrm\TeX$$سلوك المستوى المنخفض، ويقدّم مطوروها تجريدات وطبقات عزل مرحبًا بها جدًا تتكفّل بالتعقيدات الكامنة. وكثيرٌ من تلك الحزم يُعَدّ إنجازات مذهلة حقًا من برمجة $$\mathrm\TeX$$ معقدة: ينبغي لنا جميعًا أن نكون ممتنين لوجودها كي تحمينا من الاضطرار إلى استخدام $$\mathrm\TeX$$!

الخوارزمية الفعلية التي $$\mathrm\TeX$$ يستخدمها لحساب عروض الأعمدة الممتدة موضحة في الصفحة 245 من [$$\mathrm\TeX\text{book}$$](https://www.amazon.co.uk/TeXbook-Donald-E-Knuth/dp/0201134489) ومع مزيد من التفاصيل، في القسم 801 (الصفحة 336) من الكتاب المطبوع الذي يحتوي على $$\mathrm\TeX$$شفرة مصدر [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373). ومع ذلك، بالنسبة لكثير من الناس (وأنا منهم) تكون شروح كنوث أحيانًا موجزة ومكثفة إلى حدّ ما، وقد يصعب تتبّعها بالتفصيل أحيانًا: فالأمثلة المرسومة تكون دائمًا مفيدة جدًا.

### نعم، الجداول معقدة

في القسم 768 (الصفحة 322) من الكتاب [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373)، يورد كنوث تعليقًا مثيرًا للاهتمام:

> «إنه نوع من المعجزة كلما `\halign` و `\valign` تعمل، لأنها تتقاطع مع الكثير من هياكل التحكم الخاصة بـ $$\mathrm\TeX$$.»

بالإضافة إلى ذلك، يخصص المجلد الرابع من سلسلة الكتب ذات المجلدات الأربعة [$$\mathrm\TeX\text{ in Practice}$$](https://www.amazon.co.uk/Tex-Practice-Set-Stephan-Bechtolsheim/dp/038797296X/ref=sr_1_11?s=books\&ie=UTF8\&qid=1504256043\&sr=1-11\&keywords=TeX+in+Practice) ما لا يقل عن 180 صفحة (ص 199–379) لإنشاء الجداول في $$\mathrm\TeX$$ عبر `\halign` و `\valign`.

لذا، من الآمن ملاحظة أن $$\mathrm\TeX$$ الجداول بالفعل «صعبة إلى حد ما».

### تمديد الأعمدة: \omit و\span و\multispan

كما ذُكر، لاستكشاف $$\mathrm\TeX$$حسابات عرض الأعمدة الخاصة بـ $$\mathrm\TeX$$; وما يعنيه ذلك هو مزيج من الأوامر الأولية وواحد $$\text{Plain }\mathrm\TeX$$ ماكرو يُسمى `\multispan`. ورغم أننا لن نستخدم هذه الأوامر لتوضيح جداول أمثلتنا مباشرةً (أي، مع شرح جميع $$\mathrm\TeX$$ الشفرة)، فمن المفيد إيراد ملاحظة موجزة لشرحها:

* `\halign`: أحد أمرين $$\mathrm\TeX$$ الأوامر الأولية (primitives) لإنشاء الجداول. والآخر هو `\valign` لكن هذا لا يُستخدم على نطاق واسع بالقدر نفسه، ولن نناقشه في هذه المقالة.
* `\omit`: $$\mathrm\TeX$$ أمرٌ أولي يوجّه $$\mathrm\TeX$$ إلى تجاهل قالب التمهيد الخاص بإدخال الجدول.
* `\span`: $$\mathrm\TeX$$ أمرٌ أولي يُستخدم لدمج إدخالين متجاورين في الجدول.
* `\multispan{n}`ماكرو $$\mathrm\TeX$$ بسيط لتمديد `n` الأعمدة.

في الجوهر، لتمديد الأعمدة $$\mathrm\TeX$$ يتجاهل العدد المناسب من قوالب تمهيد الجدول ويجمع العدد المطلوب من إدخالات الجدول في إدخال واحد. `\multispan{n}` يعمل عن طريق التوسع إلى تسلسل من `\omit` و `\span` الرموز اللازمة لتمديد `n` الأعمدة. على سبيل المثال، `\multispan{3}` يتوسع إلى `\omit\span\omit\span\omit`.

## تقديم جدولنا «المرجعي»

إليك جدولنا المرجعي متبوعًا بنسخة مشروحة تشرح العناصر المستخدمة في بنائه:

![{{{alt}}}](/files/0263e4f26da80da07fe05aab9a2cc4832cff08ef)

من خلال تعديل جدولنا المرجعي سنلاحظ ما يحدث لعرض الجدول، وعرض الأعمدة الفردية، عندما نضيف إدخالات تمتد عبر أعمدة مختلفة. وقد أُنتج هذا الجدول المرجعي بصيغة خام $$\mathrm\TeX$$ باستخدام `\halign{...}` الأمر الأولي مع عدد من الماكروات المخصصة اللازمة لتنسيق الجداول —لن نناقش تلك الماكروات لأنها ليست أساسية لفهم الأمثلة والشروح.

إليك نسخة مشروحة من جدولنا المرجعي لتوضيح خصائصه:

![{{{alt}}}](/files/32c0bc0800d6f206545835e1e7dc4e1c86ec9356)

لقد ضبطت مجموعتنا الأولى من جداول الأمثلة، وكذلك الجدول المرجعي الأولي، كلها على `\tabskip=0pt` بحيث $$\mathrm\TeX$$ لا يضيف أي فراغ بين أعمدتنا: فعليًا، تلامس كلها بعضها بعضًا. والسبب في ذلك هو تبسيط النقاش الأولي والحسابات اللاحقة —وفيما بعد في المقالة سنعيد إدخال قيمة غير صفرية لـ `\tabskip` اللواصق (glue) لدراسة تأثيرها على حساب عروض الأعمدة الممتدة.

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

### ملاحظة موجزة حول عروض الجداول

ال `\halign{...}` له ثلاث صيغ:

* `\halign{...}`: اضبط الجدول على أي عرض $$\mathrm\TeX$$ يحسِبه، استنادًا إلى أحجام الإدخالات (و `\tabskip` اللواصق);
* `\halign to *width* {...}`: يوجّه $$\mathrm\TeX$$ إلى تنضيد الجدول بعرض محدد `*width*`;
* `\halign spread *amount*{...}`: عدّل العرض المحسوب بمقدار `*amount*`.

عندما $$\mathrm\TeX$$ ينضّد جدولًا باستخدام `\halign{...}` يتعين عليه قراءة الجدول بالكامل إلى الذاكرة لإجراء الحسابات المختلفة المطلوبة لتنضيده. وبالتالي، ما لم تكن قد حدّدت العرض باستخدام `\halign to *width* {...}` فلن تتمكن من معرفة العرض النهائي حتى $$\mathrm\TeX$$ ينتهي من معالجته (تنضيده). وإحدى طرق الحصول على عرض جدول أُنتج بواسطة `\halign{...}` هي أن تنضّد الجدول أولًا داخل `\vbox{...}` (مثلًا، `\setbox0=\vbox{\halign{...}}`) ثم، على سبيل المثال، تستخدم `\the\wd0` للحصول على العرض.

### لا يوجد كسر تلقائي للأسطر في إدخالات الجدول

من المهم ملاحظة أنه عندما $$\mathrm\TeX$$ يقوم بتنضيد جدول أُنشئ باستخدام `\halign{...}` فإن أي نص داخل إدخالات الجدول لا يخضع تلقائيًا لكسر الأسطر: إذ تنضَّد إدخالات الجدول في *النمط الأفقي المقيّد*—تمامًا مثل `\hbox`. ولتمكين كسر الأسطر، يجب أن يُحاط نص إدخال الجدول داخل `\vbox{...}` مع استخدام قيمة مناسبة لـ `\hsize` داخل ذلك `\vbox{...}`. لكن لاحظ أن النص داخل `\noalign{...}` أمر ( $$\mathrm\TeX$$ أمر أولي) يُستخدم في `\halign{...}` يخضع لـ $$\mathrm\TeX$$كسر الأسطر الخاص بـ `\noalign{...}` يتيح $$\mathrm\TeX$$ لـ«الخروج» من `\halign{...}` ووضع مواد بين صفوف الجدول —عادةً لإنتاج خطوط أفقية بين صفوف الجدول.

### غير مسموح: \halign{...} داخل \hbox{...}

لا يمكنك *تحرير* تنضيد `\halign{...}` داخل `\hbox{...}`. إن محاولة استخدام `\hbox{\halign{...}}` ستنتج خطأً مربكًا إلى حدّ ما:

```latex
! Missing } inserted.
<نص مُدرَج>
                }
<ليُقرأ مرة أخرى>
                   \halign
l.1 \hbox{\halign
```

#### شرح لهذا الخطأ

بسبب الإحاطة بـ `\hbox{...}` $$\mathrm\TeX$$ يكون في *النمط الأفقي المقيّد*; ثم يكتشف `\halign{...}` الذي يُعد *النمط العمودي* أمرًا. على سبيل المثال، إذا استخدمت `\halign{...}` داخل فقرة، $$\mathrm\TeX$$ فسيُنهي الفقرة، ويعالج `\halign{...}` ثم يواصل مع بقية الفقرة.

عندما يُستخدم داخل `\hbox{...}`، و `\halign{...}` فإنه يفعّل $$\mathrm\TeX$$ للمحاولة للعودة إلى النمط العمودي عبر محاولة فرض إغلاق المجموعة الحالية: $$\mathrm\TeX$$ يبلّغ عن «`! Missing }`» ويصدر خطأً لأنه يعتقد أنك ارتكبت خطأً في استخدامك للتجميع. ورغم أن القوس المعقوف الأيمن (`}`) قد لا يكون مفقودًا من $$\mathrm\TeX$$ الشفرة الخاصة بك، فإن رسالة الخطأ هي أحد أعراض `\hbox{...}` «التدخّل في الطريق» و $$\mathrm\TeX$$ تخمينه «الأفضل» لمسار الإجراء المناسب لحل المشكلة.

## أمثلة على جداول بأعمدة ممتدة

تقدّم سلسلة الرسومات الجدولية التالية مجموعة من الأمثلة لتوضيح أثر تمديد أعمدة الجدول: بما يشير إلى أن الإدخالات الطويلة في الجدول قد تكون لها نتائج غير متوقعة على عرض بعض الأعمدة —وبالتالي على عرض الجدول نفسه. والسؤال الذي سنعالجه هو ماذا يفعل $$\mathrm\TeX$$ عندما يمتد إدخالٌ معيّن في الجدول عبر عدد من الأعمدة ولكنه يكون «عريضًا جدًا بحيث لا يتسع». كما ذُكر أعلاه، $$\mathrm\TeX$$ يطبّق بالفعل خوارزمية محددة على مشكلة حساب عروض الأعمدة هذه: صُممت الأمثلة التالية للمساعدة في تكوين «إحساس» بآلية عمل تلك الخوارزمية.

### جدول المثال 1

في هذا المثال نستخدم `\multispan{2}` لتمديد العمودين 1 و2 بإدخال نصه هو **عنوان جدول**:

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

#### ملاحظات

* عرض هذا الجدول هو نفسه عرض [الجدول المرجعي](#reference-table): $$327.71722\text{pt}$$.
* عرض الإدخال الذي يمتد عبر العمودين 1 و2 هو $$81.04953\text{pt}$$ وهو أقل من العرض الكلي للإدخالات في الأعمدة التي يمتد عبرها: $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$

## جدول المثال 2

كما في [جدول المثال 1](#example-table-1)، يستخدم هذا المثال أيضًا `\multispan{2}` لتمديد العمودين 1 و2، لكننا هنا نستخدم إدخالًا أطول نصه **عنوان جدول أطول قليلًا**.

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

#### ملاحظات

إذا قارنت هذا المثال بـ [الجدول المرجعي](#reference-table) يمكننا أن نلاحظ ما يلي:

* زاد عرض هذا الجدول من $$327.71722\text{pt}$$ إلى $$374.37032\text{pt}$$: بمقدار إجمالي قدره $$46.6531\text{pt}$$.
* عرض الإدخال الذي يمتد عبر العمودين 1 و2 ($$156.28664\text{pt}$$) أكبر من العرض الكلي للإدخالات في الأعمدة التي يمتد عبرها: $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$. وذلك الفرق هو $$156.28664\text{pt}-109.63355\text{pt} = 46.6531\text{pt}$$ وهو نفس المقدار الذي زاد به عرض الجدول.
* $$\mathrm\TeX$$ قام بتعديل عرض العمود 2 لتوفير المساحة الإضافية المطلوبة. وسنرى لاحقًا كيف $$\mathrm\TeX$$ يحسب المقدار الذي يجب أن يزداد به العمود 2.
* العمود 1 غير متأثر: فلم يتأثر عرضه بالإدخال الذي يمتد عبر العمودين 1 و2.

### جدول المثال 3

في هذا المثال نستخدم `\multispan{3}` لتمديد الأعمدة 1 إلى 3 بإدخال نصه هو نفسه نص [جدول المثال 2](#example-table-2): **عنوان جدول أطول قليلًا**.

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

#### ملاحظات

* عرض هذا الجدول هو نفسه عرض [الجدول المرجعي](#reference-table): $$327.71722\text{pt}$$.
* عرض الإدخال الذي يمتد عبر الأعمدة 1 إلى 3 ($$156.28664\text{pt}$$) أقل من العرض الكلي للإدخالات في الأعمدة الثلاثة التي يمتد عبرها: $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} = 168.67254\text{pt}$$.
* لم يتأثر أيٌّ من عروض الأعمدة بالإدخال الممتد عبر الأعمدة 1 إلى 3.

هل بدأت ترى نمطًا يتبدّى؟

### جدول المثال 4

كما في [جدول المثال 3](#example-table-3)، نستخدم هنا `\multispan{3}` لتمديد الأعمدة 1 إلى 3، ولكن هذه المرة بإدخال نصه أطول بكثير: **عنوان جدول أطول بكثير يمتد لمسافة طويلة**.

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

#### ملاحظات

* بالمقارنة مع [الجدول المرجعي](#reference-table)، زاد عرض هذا الجدول من $$327.71722\text{pt}$$ إلى $$465.95685\text{pt}$$: بزيادة مقدارها $$138.23963\text{pt}$$.
* عرض الإدخال الذي يمتد عبر الأعمدة 1 إلى 3 هو $$306.91216\text{pt}$$.
* العرض الكلي للإدخالات في الأعمدة الثلاثة الممتدة هو $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} = 168.67254\text{pt}$$.
* فرق العرض بين الإدخال الممتد الطويل والإدخالات في الأعمدة 1 إلى 3 هو $$306.91216\text{pt}-168.67254\text{pt}=138.23962\text{pt}$$. وهو نفس المقدار (حتى 4 منازل عشرية!) الذي زاد به عرض الجدول.
* العمود 3 وحده هو الذي زاد عرضه: لم يتأثر لا العمود 1 ولا العمود 2.

#### يبدأ نمط في الظهور

إذا نظرنا إلى [جدول المثال 2](#example-table-2) و [جدول المثال 4](#example-table-4) يمكننا أن نرى أنه في كلتا الحالتين يكون **العمود الأخير في الامتداد** هو الذي زاد عرضه لإفساح المجال للإدخال الطويل الذي امتد عبر الأعمدة:

* في [جدول المثال 2](#example-table-2): امتد الإدخال الطويل عبر العمودين 1 و2. وأصبح العمود 2 «مشدودًا».
* في [جدول المثال 4](#example-table-4): امتد الإدخال الطويل عبر الأعمدة 1 إلى 3. وأصبح العمود 3 «مشدودًا».

#### عرض العمود 3: هل تظهر خوارزمية؟

تُعطي الحسابات التالية مؤشرًا أوضح على ما $$\mathrm\TeX$$ يفعله. وإليك ما نعرفه:

* عرض الإدخال الطويل الممتد عبر الأعمدة 1 إلى 3 هو $$306.91216\text{pt}$$.
* العرض الكلي للإدخالات في العمودين 1 و2 هو $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$.

ما الفرق بين تلك القيم؟ إنه $$306.91216\text{pt}-109.63355\text{pt} = 197.2786\text{pt}$$ وهذا هو العرض المستخدم للعمود 3: وهو ينتج مباشرةً من الخوارزمية التي يستخدمها $$\mathrm\TeX$$.

### جدول المثال 5

قبل أن ننتقل إلى مثال أكثر تعقيدًا، إليك مثالًا «بسيطًا» آخر. يحتوي هذا الجدول على الإدخال الطويل نفسه كما في [جدول المثال 4](#example-table-4): **عنوان جدول أطول بكثير يمتد لمسافة طويلة**؛ إلا أننا هذه المرة نستخدم `\multispan{6}` مما يسمح لذلك الإدخال أن يمتد عبر الجدول بأكمله. وكما ترى، يحتفظ الجدول الناتج بالعرض نفسه لجدولنا [الجدول المرجعي](#reference-table) ($$327.71722\text{pt}$$) مما يعني أن أياً من الأعمدة لم يتأثر بهذا الإدخال الطويل جدًا. ومن الواضح أن ذلك لأن عرض الإدخال ($$306.91216\text{pt}$$) أقل من العرض الكلي لجميع الإدخالات التي يمتد عبرها: $$327.71722\text{pt}$$; أي عرض الجدول.

![{{{alt}}}](/files/295d09c1662459b684165392bad1402ed48618c5)

### جدول المثال 6: أكثر تعقيدًا قليلًا

هنا، ننظر إلى سلسلة من ثلاثة جداول أمثلة (6(أ)–6(ج)) لإظهار تأثير إدخالين مختلفين يمتدان كلاهما إلى العمود 5. [جدول المثال 6(أ)](#example-table-6a) و [جدول المثال 6(ب)](#example-table-6b) يعرض كلٌّ منهما جدولًا يحتوي على إدخال واحد يمتد عبر عدة أعمدة حتى العمود 5. [جدول المثال 6(ج)](#example-table-6c) يجمع كلا الإدخالين الممتدين في جدول واحد ويطرح السؤال: أي إدخال يحدد فعليًا عرض العمود 5، ولماذا؟ يقودنا الجواب إلى جوهر الخوارزمية التي يستخدمها $$\mathrm\TeX$$.

#### جدول المثال 6(أ)

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

**ملاحظات**

* بالمقارنة مع [الجدول المرجعي](#reference-table)، زاد عرض هذا الجدول من $$327.71722\text{pt}$$ إلى $$371.11153\text{pt}$$: بزيادة مقدارها $$43.39431\text{pt}$$.
* عرض الإدخال الذي يمتد عبر الأعمدة 3 إلى 5 هو $$215.06683\text{pt}$$.
* العرض الكلي للإدخالات في الأعمدة 3 إلى 5 هو $$59.03899\text{pt} + 52.98344\text{pt} + 59.6501\text{pt} = 171.67253\text{pt}$$.
* فرق العرض بين الإدخالات الممتدة في الأعمدة 3 إلى 5 وعرض الإدخال الممتد هو $$215.06683\text{pt}-171.67253\text{pt}=43.3943\text{pt}$$: المقدار الدقيق (حتى 4 منازل عشرية!) الذي زاد به عرض الجدول.

#### جدول المثال 6(ب)

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

**ملاحظات**

* بالمقارنة مع [الجدول المرجعي](#reference-table)، زاد عرض هذا الجدول من $$327.71722\text{pt}$$ إلى $$353.3233\text{pt}$$: بزيادة مقدارها $$25.60608\text{pt}$$.
* عرض الإدخال الذي يمتد عبر الأعمدة 1 إلى 5 هو $$306.91216\text{pt}$$.
* العرض الكلي للإدخالات في الأعمدة 1 إلى 5 هو $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} + 52.98344\text{pt} + 59.6501\text{pt} = 281.30608\text{pt}$$.
* فرق العرض بين الإدخالات الممتدة في الأعمدة 1 إلى 5 وعرض الإدخال الممتد هو $$306.91216\text{pt}-281.30608\text{pt}=25.60608\text{pt}$$: **note** هذا هو *أقل* من القيمة المحسوبة لـ [المثال 6(أ)](#example-table-6a)، والتي كانت $$43.3943\text{pt}$$.

#### جدول المثال 6(ج)

هنا، نجمع الإدخالات في جدولي المثال [6(أ)](#example-table-6a) و [6(ب)](#example-table-6b) في جدول واحد: ماذا يحدث؟

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

**ملاحظة**

* بالمقارنة مع [الجدول المرجعي](#reference-table)، زاد عرض هذا الجدول من $$327.71722\text{pt}$$ إلى $$371.11153\text{pt}$$: بزيادة مقدارها $$43.39431\text{pt}$$. نلاحظ أن هذا هو بالضبط نفس [جدول المثال 6(أ)](#example-table-6a).

#### ما الذي $$\mathrm\TeX$$ يفعله؟

لفهم نتائج $$\mathrm\TeX$$وخوارزميته وعمليات اتخاذ القرار الخاصة بـ نلاحظ أن هذا الإدخال

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

يمتد إلى ما وراء الإدخالات التي يمتد عبرها $$25.60608\text{pt}$$؛ غير أن هذا الإدخال

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

يمتد إلى أبعد من الإدخالات التي يمتد عبرها: بمقدار $$43.3943\text{pt}$$. ومن ثم «يفوز السباق» هذا الإدخال ويزداد عرض العمود 5 بمقدار **الحد الأقصى** لهاتين القيمتين ($$43.3943\text{pt}$$). ويصبح عرض العمود 5 الآن $$59.6501\text{pt} + 43.3943\text{pt} = 103.0444\text{pt}$$ للتّسَع الإدخال الذي يمتد عبر الأعمدة 3 إلى 5. وقد بَسّطنا قليلًا وصف «تسلسل الأحداث» الدقيق، لكن النتيجة كما وصفناها.

## إعادة بعض التعقيد

لتقليل تعقيد نقاشاتنا (حتى الآن) استخدمنا أمثلة بسيطة نسبيًا لتوضيح مبادئ $$\mathrm\TeX$$خوارزمية  `\tabskip=0pt`. عمليًا، من المرجح أن تحتوي الجداول «الواقعية» على العديد من الإدخالات التي تمتد عبر نطاق من الأعمدة، وبالطبع ستحتوي على قيم غير صفرية لـ `\tabskip` اللواصق —وهو موضوع سنعود إليه الآن.

### \tabskip glue وعروض الأعمدة الممتدة

غالبًا ما يتطلب تصميم الجداول إضافة مسافات بيضاء بين الأعمدة، وبالطبع $$\mathrm\TeX$$ يملك هذه الإمكانية من خلال أمر أولي يُسمى `\tabskip`. ويمكن استخدام هذا الأمر لوضع لواصق ثابتة أو مرنة (مسافات):

* قبل الجدول (أي، إلى يسار العمود 1);
* بين عمود واحد أو أكثر;
* بعد الجدول (أي، إلى يمين العمود الأخير).

وهنا مثال لتذكير أنفسنا:

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

### كيف تؤثر لواصق \tabskip في عروض الأعمدة الممتدة؟

إن وجود قيمة غير صفرية لـ `\tabskip` اللواصق بين الأعمدة يوفر مساحة إضافية يمكن للإدخالات الممتدة «امتصاصها» قبل أن $$\mathrm\TeX$$ يحتاج إلى التفكير في زيادة عرض العمود الأخير في الامتداد.

في مثالنا التالي سنستخدم جدولين لمقارنة نتائج تمديد عمودين. والفرق الوحيد بين الجدولين هو استخدام `\tabskip` اللواصق.

* يستخدم المثال الأول جدولنا «المرجعي» الأصلي الذي، إن كنت تتذكر، قد ضُبط فيه `\tabskip=0pt`.
* يستخدم المثال الثاني نسخة معدلة من [الجدول المرجعي](#reference-table) (المشروح أعلاه) والذي يحتوي على `\tabskip=10pt` قبل الجدول وبعده، ولكن الأهم من ذلك أنه ضبط `\tabskip=20pt` بين الأعمدة.

داخل *المعدّل* الجدول المرجعي، لا يكون للعمودين الممتدين أي تأثير في عروض الأعمدة (وعرض الجدول)، لكنهما يؤثران في عرض العمود 2 (وعرض الجدول) في *الأصلي* [الجدول المرجعي](#reference-table).

### الجدول المرجعي الأصلي: \tabskip=0pt

هنا، نعرض جدولنا الأصلي [الجدول المرجعي](#reference-table) إلى جانب جدول ثانٍ (مشتق من جدولنا الأصلي [الجدول المرجعي](#reference-table)) يحتوي على إدخال «**اختبار عنوان جدول أطول**» يمتد عبر العمودين 1 و2، ومن الواضح تمامًا أن العمود 2 (في الجدول الثاني في الشكل) وبالتالي الجدول كله، كلاهما يتأثر بالأعمدة الممتدة.

![{{{alt}}}](/files/582f510d4d88b8e3822f7afcd04df53a558fc1e5)

### الجدول المرجعي المعدّل: \tabskip=20pt

هنا، نعرض جدولنا المرجعي المعدّل إلى جانب جدول ثانٍ (مشتق من جدولنا المرجعي المعدّل) يحتوي أيضًا على إدخال «**اختبار عنوان جدول أطول**» يمتد عبر العمودين 1 و2، ومن الواضح تمامًا أنه داخل الجدول الثاني في الشكل، لا يتأثر لا عرض العمود 2 ولا الجدول بالأعمدة الممتدة. في هذه الحالة، إن وجود `\tabskip` اللواصق (`20pt`) بين الأعمدة قد ساعد على «امتصاص» المساحة التي يتطلبها النص في الإدخال الممتد عبر العمودين 1 و2:

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

## جوهر $$\mathrm\TeX$$خوارزمية&#x20;

نأمل أن تكون مجموعة الأمثلة الواردة أعلاه قد ساعدت في تكوين «إحساس» بما $$\mathrm\TeX$$ يفعله لاستيعاب الإدخالات الممتدة وكيف $$\mathrm\TeX$$ سيقوم، إذا لزم الأمر، بتعديل عرض **الأخير** العمود داخل كل نطاق من الأعمدة الممتدة. بالإضافة إلى عرض الإدخالات داخل الأعمدة الفردية الممتدة، فإن وجود `\tabskip` اللواصق غير الصفرية عامل مهم $$\mathrm\TeX$$ يأخذه في الحسبان عند تقرير ما إذا كان يحتاج إلى تعديل أي من عروض الأعمدة. والنقطة الأساسية التي ينبغي تذكرها هي أن $$\mathrm\TeX$$هدفه هو حساب عرض مناسب لـ **العمود الأخير** ضمن كل نطاق من الأعمدة الممددة.

### مثال الجدول النهائي: الأعمدة الأخيرة في نطاق ممدد

في هذا المثال النهائي نستخدم مرة أخرى جدولنا المرجعي المعدّل (مع `\tabskip` قيم الـ glue المذكورة أعلاه) لاشتقاق جدول آخر يحتوي على أعمدة مختلفة تمتد عبر قواعد—لقد استخدمنا القواعد لجعل الامتدادات أسهل في الرؤية.

تمت محاذاة الجدولين بعناية لإظهار أنه، في الجدول العلوي، لم تتأثر أي أعمدة قبل العمود 5 بالأعمدة الممددة. تُظهر المنطقة الخضراء الداكنة إلى يسار المخطط أن الأعمدة 1 إلى 4 في كلا الجدولين لا تزال مصطفّة تمامًا. وعلى اليمين توجد منطقة مظللة بالأخضر الفاتح تُظهر أن الأعمدة 5 و6 فقط قد تأثرت بالإدخالات الممددة.

في الجدول العلوي، الامتدادات هي كما يلي:

* الأعمدة 1 إلى 5: تمتد عبر $$400\text{pt}$$ قاعدة؛
* الأعمدة 3 إلى 5: تمتد عبر $$200\text{pt}$$ قاعدة؛
* الأعمدة 4 إلى 6: تمتد عبر $$250\text{pt}$$ قاعدة.

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

ومرة أخرى، التفسير هو أنه داخل سلسلة من الأعمدة الممددة، لا يتم تعديل إلا عرض العمود الأخير (إذا لزم الأمر): الأعمدة الواقعة بينها لا تتأثر، وهنا يعني ذلك الأعمدة 1 إلى 4—مع أن عرض الأعمدة 1 إلى 4 (والأعمدة الواقعة بينها `\tabskip` والـ glue) يُؤخذ في الاعتبار عند حساب العروض المعدلة للأعمدة 5 و6.

### شرح تفصيلي لـ $$\mathrm\TeX$$خوارزمية&#x20;

سنختتم بـ *مبسّط* شرح تفصيلي لـ «$$\mathrm\TeX$$» لعمليات التفكير الخاصة به أثناء حساب عروض الأعمدة في الإدخالات الممددة. إن وصف $$\mathrm\TeX$$خوارزمياته ليس دائمًا أمرًا مباشرًا، لذا سنلجأ إلى بعض «الترخيص الفني التبسيطي» لتقديم نظرة عامة عمّا يحدث. ويُحال القراء المهتمون بجميع التفاصيل المعقدة إلى القسم 801 (الصفحة 336) من الكتاب المطبوع الذي يحتوي على $$\mathrm\TeX$$شفرة مصدر [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373).

غالبًا ما تُنشأ الجداول الواقعية مع استخدامات عديدة لـ `\span` البدائية (مثلاً داخل $$\mathrm\LaTeX$$ الحزم) لبناء عدة حالات من الأعمدة الممددة داخل الجدول. ولإدارة ذلك، تحتفظ هياكل البيانات (في عمق $$\mathrm\TeX$$) بمعلومات (ما يُسمّى *عقد الامتداد*) التي تُخبر $$\mathrm\TeX$$ عن الروابط (الامتدادات) بين إدخالات/أعمدة الجدول. وبوضوح، $$\mathrm\TeX$$ يتعين عليه تطبيق خوارزمياته بطريقة منهجية وسيحتاج إلى معالجة الجدول بأكمله لإجراء حساباته النهائية—لتحديد جميع عروض الأعمدة، والعرض الكلي للجدول، وإذا لزم الأمر، مقدار ما يجب أن تتمدد أو تنكمش به مواد الربط المرنة المستخدمة في الجدول. وليس من المستغرب حقًا أن $$\mathrm\TeX$$ لا يمكنه إخبارك بعرض الجدول النهائي حتى ينتهي تمامًا من معالجة `\halign{...}` الأمر—فلديه حقًا الكثير من العمل!

نقطة البداية لحساب عروض الأعمدة هي العمود 1 لأنه، بطبيعة الحال، لا يمكن لأي شيء أن يمتد من يسار (و *عبر/إلى داخل*) العمود 1. $$\mathrm\TeX$$ يبدأ بتحديد عرض العمود 1 من خلال تحديد أي إدخال لديه الحد الأقصى من *العرض الطبيعي*. لِنسمِّ هذا العرض الأقصى $$w\_1$$وإذا كانت هناك إدخالات تمتد من العمود 1 إلى العمود 2 فلنسمِّ عرض ذلك الإدخال $$w\_{12}$$ (العرض من 1 إلى 2). بالإضافة إلى ذلك، سنرمز إلى `\tabskip` الـ glue بين العمودين 1 و2 بـ $$t\_{1}$$—لاحظ أننا لا نأخذ في الاعتبار إلا *العرض الطبيعي* ذلك الـ `\tabskip` من الـ glue، ومؤقتًا نتجاهل أي مكوّنات للتمدد أو الانكماش قد يمتلكها. كذلك، لنفرض أن أقصى عرض طبيعي لجميع الإدخالات غير الممددة في العمود 2 هو $$w\_2$$.

النقطة الأساسية التي يجب ملاحظتها هي أن $$\mathrm\TeX$$ يحاول حساب عرض العمود 2 من خلال النظر فقط في تلك الإدخالات التي يبدأ فيها الامتداد *يبدأ* بالعمود 1 وينتهي *ينتهي* عند العمود 2. والاعتبار الأساسي لـ $$\mathrm\TeX$$ هو الاختبار $$\max(w\_{2}, w\_{12} - (w\_1+ t\_1))$$—قد تكون هناك عدة إدخالات تمتد عبر العمودين 1 و2: قد يكون بعضها ضيقًا (صغير $$w\_{12}$$) وأخرى عريضة جدًا (كبيرة $$w\_{12}$$) لذلك $$\mathrm\TeX$$ يبحث عن الذي له أكبر تأثير (ومن هنا $$\max(\text{...})$$). هنا، قيمة $$w\_{12} -(w\_1+ t\_1)$$ هي مقدار ما “يفيض” به إدخال يمتد عبر العمودين 1 و2 من العمود 1 إلى العمود 2: لاحظ أن $$\mathrm\TeX$$ يستخدم عرض العمود 1 **و** موقع `\tabskip` اللواصق ($$t\_{1}$$) بين العمودين 1 و2. وبمجرد أن $$\mathrm\TeX$$ يحدد ما إذا كانت أي امتدادات من العمود 1 إلى 2 تؤثر فعلًا في عرض العمود 2، فإنه يضبط عرض العمود 2 على القيمة القصوى التي حددها (باستخدام الاختبار الموصوف). $$\mathrm\TeX$$ يواصل العمل عبر جميع الأعمدة الأخرى، ويجري اختبارات مماثلة.

وأخيرًا، وللاستكمال فقط، نقتبس هنا جوهر $$\mathrm\TeX$$خوارزمية حساب عروض الأعمدة الخاصة به (مأخوذة من وثائق الشفرة المصدرية لـ Knuth الخاصة بـ $$\mathrm\TeX$$):

لتكن $$w\_{ij}$$ هي القيمة القصوى للعروض الطبيعية لجميع الإدخالات التي تمتد عبر الأعمدة $$i$$ حتى $$j$$، شاملة. وتُعرَّف العروض النهائية للأعمدة بالصيغة

$$\begin{equation\*} w\_j=\max\_{1\leq i\leq j}\biggl(w\_{ij}-\sum\_{i\leq k< j}(t\_k+w\_k)\biggr) \end{equation\*}$$

حيث $$t\_k$$ هو العرض الطبيعي لـ tabskip glue بين الأعمدة $$k$$ و $$k+1$$.

## الذيل: استخدام Overleaf لإنتاج الجداول كرسومات SVG

جميع $$\mathrm\TeX$$ الجداول المعروضة في هذه المقالة هي ملفات رسومات متجهية قابلة للتدرج (SVG) أُنتجت على منصة Overleaf. أُضيفت التعليقات التوضيحية (الأسهم والمربعات الخضراء) بفتح الرسم SVG في Inkscape—لاحظ، مع ذلك، أن نص التعليقات التوضيحية جرى تنسيقه في $$\mathrm\TeX$$ كنص إضافي يرافق الجدول: لم تُضف في Inkscape سوى الأسهم والخلفيات الخضراء. إذا كنت مهتمًا بمعرفة كيف تم ذلك، فتابع القراءة.

تستخدم خوادم Overleaf توزيعة $$\mathrm\TeX \text{ Live}$$ التي، بالإضافة إلى $$\mathrm\TeX$$محركات تنضيد قائمة على TeX، وتوفر ثروة من الأدوات البرمجية المفيدة جدًا $$\mathrm\TeX$$أدوات وبرامج وخدمات مساعدة متعلقة بـ [`dvisvgm`](https://dvisvgm.de) التي، كما يوحي اسمها، تُحوِّل $$\mathrm\TeX$$صيغة DVI التقليدية الخاصة بـ**D**e**V**ice **I** (أي المستقلة) إلى SVG. ومن بين العديد من [خيارات سطر الأوامر](https://dvisvgm.de/Manpage/) `dvisvgm` توفر خيارًا (`-n` أو `--no-fonts`) والذي سيأمرها بتحويل كل النص إلى *مسارات* وهذا يعني أن النص في رسومات SVG يُرسم باستخدام خطوط ومنحنيات بدلًا من الخطوط الطباعية والرموز الحقيقية. قد يؤدي هذا إلى زيادة حجم ملف الرسم SVG الناتج، لكنه يضمن أن تكون رسومات SVG شديدة القابلية للنقل، ومن شبه المؤكد أن تعمل جيدًا على أي جهاز.

### إذًا... كيف تم ذلك؟

في [مقال سابق](https://www.overleaf.com/blog/510-using-luatex-to-run-tools-and-utilities-installed-on-overleafs-servers) ناقشت كيف يمكنك استخدام $$\text{Lua}\mathrm\TeX$$ لتشغيل مختلف الأدوات والبرامج المساعدة المثبتة على خوادم Overleaf—وهي تقنية سهلة ومريحة للغاية. وقد استُخدمت تلك التقنية لتوليد رسومات SVG لجداول منضَّدة $$\mathrm\TeX$$ ، كما يلي. ومن داخل ملف $$\mathrm\TeX$$ المستند الرئيسي، كُتب الكود الخاص بتنضيد كل جدول (المنشأ باستخدام باستخدام `\halign`) إلى ملف `.tex` . وقد تحقق ذلك بإحاطة كود الجدول داخل زوج من الأوامر التي سميتها `\beginscoop` و `\endscoop`. ومن المحتمل أن توجد طرق أخرى كثيرة لتحقيق النتائج المرجوة، لكن فيما يلي تعريفات الماكرو التي استخدمتها:

```latex
\def\cc{\catcode`\#=12\relax}
\long\def\scoop#1\endscoop{\global\fulltoks={#1}\egroup}
\def\beginscoop{\global\advance\numfigs by1\relax\bgroup\cc\scoop}
```

تستخدمها هكذا:

```latex
\beginscoop
\halign{...}
\endscoop
```

لاحظ أن `\endscoop` الرمز token لا يؤدي إلا وظيفة تحديد معامل `\scoop` الماكرو: $$\mathrm\TeX$$ يتجاهل فعليًا الرمز `\endscoop` token، لذا لا نحتاج فعلًا إلى تعريفه (مثلًا عبر `\def\endscoop{...}`).

ال $$\mathrm\TeX$$ الكود الموجود في `\halign{...}` يُحفظ في `toks` سجل يُسمّى `\fulltoks`. ومن النقاط الصعبة التي واجهتها (مع $$\text{Lua}\mathrm\TeX$$) كانت الحاجة إلى منع `#` الأحرف داخل `\halign{...}` التمهيد من أن تُحوَّل إلى «مضاعفة» إلى `##` عند كتابتها إلى ملف `.tex` . ولتجنب ذلك اضطررت إلى ضبط `\catcode`لـ `#` الأحرف مؤقتًا إلى 12 قبل حفظ $$\mathrm\TeX$$ الكود (الرموز) في `\fulltoks` سجل الرموز.

الخطوة التالية هي كتابة الرموز الموجودة في `\fulltoks` كـ $$\mathrm\TeX$$ ملف—ولأنني كنت أستخدم $$\text{Lua}\mathrm\TeX$$ كان هذا *شديدة* سهلًا بفضل $$\text{Lua}\mathrm\TeX$$واجهة Lua البرمجية الرائعة الخاصة به. باختصار، كتبت ماكرو يُسمّى `\writefile{...}` والذي يأخذ كمعامل له اسم سجل رموز تريد كتابة رموزه إلى ملف (مثل، `\writefile{fulltoks}`). وداخل `\writefile{...}` الماكرو استخدمت واجهة Lua البرمجية للحصول على تمثيل نصي لـ `\fulltoks` سجل الرموز:

```latex
\def\writefile#1{%
\directlua{
...
...
 local p=tex.toks["#1"]
...
...
}}
```

إليك لقطة شاشة تُظهر مزيدًا قليلًا من `\writefile{...}` الأمر:

[![{{{alt}}}](/files/930a9ec55dd75d36a8f779e2fc75edf38270db38)](https://www.filepicker.io/api/file/ngeDmgRStGWvG044RE1A)

لغة Lua وواجهة Lua البرمجية التي توفرها $$\text{Lua}\mathrm\TeX$$ يمكنهما غالبًا تبسيط $$\mathrm\TeX$$ مهام البرمجة، ولهذين الميزتين المفيدتين والقويتين استخدمت $$\text{Lua}\mathrm\TeX$$ منذ \~2009—ولا أزال من أشد المعجبين بهذا $$\mathrm\TeX$$ المحرّك الرائع حقًا. حسنًا، $$\text{Lua}\mathrm\TeX$$ ينتهي الإعلان الآن.

بعد الحصول بسهولة على $$\mathrm\TeX$$ الكود المخزَّن في `\fulltoks` يُكتب إلى ملف مع بعض الكود الإضافي لجعله $$\mathrm\LaTeX$$ ملفًا صحيح التكوين. الخطوات التالية هي:

1. عالج `.tex` الملف الذي يحتوي على جدولنا باستخدام $$\text{pdf}\mathrm\LaTeX$$ (في وضع DVI) بحيث يقوم بتنضيد الجدول ويولّد `.dvi` ملفًا لـ `dvisvgm` ليعالجه. نعم، يمكنك استخدام $$\text{Lua}\mathrm\TeX$$ لتشغيل $$\text{pdf}\mathrm\LaTeX$$—مرة أخرى استخدمت الطريقة التي نوقشت في [مقال سابق](/latex/ar/mqalat-mtamqh/52-using-luatex-to-run-tools-and-utilities-installed-on-overleaf-s-servers.md).
2. وأخيرًا، شغّل `dvisvgm` لمعالجة `.dvi` الملف لتوليد رسم SVG للجدول المنضَّد $$\mathrm\TeX$$ .
3. للحصول على رسومات SVG الفعلية يمكنك تنزيل ملف ZIP من Overleaf—مع التأكد من تحديد **ملفات الإدخال والإخراج** .


---

# 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/47-tex-tables-how-tex-calculates-spanned-column-widths.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.
