الفصل 3.7 · الجزء II · الحرفة
الإعدادات: القوائم والصيغ الرياضية
القوائم المرقّمة وغير المرقّمة، وعلاماتها وإزاحاتها وتداخلها، وقوائم المهام، وحجم الصيغ الرياضية ولونها والمسافات حولها
باختصار
تتناول هذه الصفحة القوائم والصيغ. تضع القائمة غير المرقّمة رمزًا أمام كل بند، وتعدّ القائمة المرقّمة بنودها بالأرقام أو الحروف. تحدد علامة كل قائمة وإزاحتها ومسافاتها، وتغيّرها للقوائم الموضوعة داخل قوائم أخرى. وترسم قوائم المهام مربعًا يمكن التأشير عليه. ويضبط القسم الأخير حجم الصيغ الرياضية ولونها والمسافة حولها.
#القوائم غير المرقّمة
تتحكم الخاصية unorderedLists في طريقة إخراج القوائم النقطية (-، *، +) وقوائم المهام بصيغة GFM (- [ ]، - [x]). يمكن أن تتداخل القوائم حتى خمسة مستويات.
#القيم الافتراضية للقوائم غير المرقّمة
| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
fontFamily | string | ترث bodyText.fontFamily | الخط المستخدم لنص البند. |
color | ColorValue | اللون الرئيسي (#295AA3) | لون نص البنود ونقاطها. مربوط بالمُدخل main-color في لوحة الألوان الافتراضية. |
fontWeight | number | 700 | وزن خط نص البند (100–900). ترث النقاط هذا الوزن ما لم يُتجاوز في مستوى بعينه. |
italic | boolean | false | يُخرج نص البند بخط مائل. |
bulletChar | string | '•' | الرمز (glyph) المستخدم علامةً للنقطة. |
bulletFontSize | Dimension | 1 em | حجم رمز النقطة. تتغير الوحدات النسبية بتغير حجم خط المتن. |
gap | Dimension | 0.5 em | المسافة الأفقية بين النقطة ونص البند. |
indent | Dimension | 0 em | الإزاحة الأساسية للمستوى 1. تتسلسل المستويات الأعمق من موضع بداية نص المستوى الأب ما لم تُتجاوز (انظر أدناه). |
bulletVerticalOffset | Dimension | 0 em | ضبط دقيق للموضع الرأسي للنقطة. القيم السالبة ترفع النقطة، والموجبة تخفضها. |
marginTop / marginBottom | Dimension | 1.5 em | المسافة قبل القائمة كلها وبعدها. |
itemSpacing | Dimension | 0 em | مسافة رأسية إضافية تُدرج بين البنود فوق ارتفاع السطر. حول قائمة متداخلة في بند من قائمة أخرى، تُطبَّق مسافة القائمة الخارجية على الجانبين: قبل البند الأول من القائمة المتداخلة وبعد آخر بند فيها (حتى postext 1.4 كان البند التالي لقائمة متداخلة يأخذ مسافة القائمة المتداخلة). |
snapTopToGrid | boolean | false | يقرّب المسافة فوق القائمة إلى الأعلى كي تستقر نقطتها الأولى على شبكة خطوط الأساس، كما يفعل النص تحت العنوان؛ وتصبح marginTop حينئذ حدًّا أدنى. نهاية القائمة تعيد التدفق إلى الشبكة في الحالتين، فإذا كانت itemSpacing تساوي 0 اصطفّ كل بند مع النص في العمود المجاور. معطّل افتراضيًا، كما كان حتى postext 1.4: قيمة marginTop التي لا تساوي عددًا صحيحًا من الأسطر تُبقي البنود خارج الشبكة حتى نهاية القائمة. لا يتأثر بذلك القوائم داخل الإطارات (callout)، إذ إن دواخلها خارج الشبكة أصلًا. |
hangingIndent | boolean | true | عند تفعيله، تصطف الأسطر الملتفّة مع أول حرف من النص بدلًا من أن تبدأ تحت النقطة. |
levels | UnorderedListLevelConfig[] | — | تجاوزات لكل عمق من المستويات 1–5. انظر أدناه. |
#امتدادات قوائم المهام
تُخرَج بنود المهام بصيغة GFM (- [ ] …، - [x] …) بنودًا غير مرقّمة يحل فيها مربع اختيار محل النقطة. يرسم المحرّك المربع بنفسه: إطار مربع، وفيه علامة صح إذا أُنجزت المهمة. لا يُطلب من أي خط، فهو واحد على كل جهاز، في اللوحة وفي PDF وفي HTML وفي EPUB، وتقرؤه التقنيات المساعدة ☐ أو ☑. طول ضلعه 0.6 em من حجم العلامة (bulletFontSize، أو fontSize للمستوى)، وهذا هو الحيّز الذي يأخذه قبل gap؛ وعند حجم النص يقف على خط الأساس لأول سطر في البند. سُمك خطه يتبع fontWeight للعلامة، ولونه يتبع color للعلامة. الحقول الآتية لا تنطبق إلا على بنود المهام:
| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
taskCheckboxChar | string | '☐' | حرف المهمة غير المنجزة. الحرف الافتراضي لا يُصفّ نصًّا: المحرّك يرسم المربع. وأي حرف آخر يُصفّ نصًّا بخط القائمة، وعلى هذا الخط أن يحتويه. |
taskCheckedChar | string | '☑' | حرف المهمة المنجزة. الحرف الافتراضي يُرسم كذلك، مربعًا فيه علامة صح؛ وأي حرف آخر يُصفّ نصًّا بخط القائمة. |
taskBox | 'drawn' | 'character' | 'drawn' | طريقة صفّ الحرفين الافتراضيين. 'drawn': المحرّك يرسم المربع. 'character': يُصفّ ☐ و☑ نصًّا بخط القائمة، كما كان حتى postext 1.28؛ فإذا خلا الخط منهما اختار المتصفح خطًّا من خطوط النظام، وبدأ نص البند بعد العرض الذي يعطيه ذلك الخط. والإعداد المحفوظ قبل الإصدار 13 يُقرأ بقيمة 'character'، فتبقى سطوره في مواضعها. |
taskCompletedStrikethrough | boolean | true | يرسم خط شطب عبر نص المهام المنجزة. |
taskCompletedColor | ColorValue | يرث لون البند | لون اختياري يُطبَّق على نص المهام المنجزة. إذا أُغفل استُخدم لون البند المعتاد. |
#تجاوزات كل مستوى في القوائم غير المرقّمة
كل مُدخل في levels يستهدف عمقًا واحدًا (1–5) ويمكنه أن يتجاوز أيًّا مما يلي:
| الخاصية | النوع | الوصف |
|---|---|---|
bulletChar | string | رمز النقطة لهذا العمق. |
fontFamily | string | عائلة خط البند لهذا العمق. |
fontSize | Dimension | حجم رمز النقطة لهذا العمق. |
color | ColorValue | لون البند. |
fontWeight | number | وزن خط البند. |
italic | boolean | تفعيل الخط المائل أو تعطيله. |
indent | Dimension | إزاحة صريحة للنقطة في هذا العمق. انظر قاعدة التسلسل أدناه. |
verticalOffset | Dimension | ضبط رأسي دقيق للنقطة في هذا العمق. |
تسلسل الإزاحة. يبدأ المستوى 1 دائمًا عند قيمة indent العامة (وهي افتراضيًا 0 em، أي أن النقاط مثبّتة عند حافة العمود). في المستويات 2–5، إذا تركت indent دون تعريف وضع المحرّك النقطة عند موضع بداية نص المستوى السابق (إزاحة الأب + عرض النقطة + gap). عيّن indent صريحة لمستوى ما لتقطع التسلسل وتثبّت ذلك العمق حيث تشاء.
unorderedLists: {
bulletChar: '—',
gap: { value: 0.4, unit: 'em' },
hangingIndent: true,
levels: [
{ level: 2, bulletChar: '·' },
{ level: 3, bulletChar: '◦', color: { hex: '#666666', model: 'hex' } },
],
}#القوائم المرقّمة
تتحكم الخاصية orderedLists في القوائم المرقّمة (1.، 2)، إلخ). يمكن أن تتداخل القوائم حتى خمسة مستويات، ويمكن لكل عمق أن يستخدم تنسيق ترقيم مختلفًا.
#القيم الافتراضية للقوائم المرقّمة
| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
fontFamily | string | ترث bodyText.fontFamily | الخط المستخدم لنص البند ولعلامة الرقم. |
color | ColorValue | اللون الرئيسي (#295AA3) | لون نص البنود وعلامات أرقامها. مربوط بالمُدخل main-color في لوحة الألوان الافتراضية. |
fontWeight | number | 700 | وزن خط نص البند وعلامات الأرقام (100–900). |
italic | boolean | false | يُخرج نص البند بخط مائل. |
numberFormat | OrderedListNumberFormat | 'arabic' | نمط الترقيم: 'arabic'، 'lower-alpha'، 'upper-alpha'، 'lower-roman'، 'upper-roman'. تعمل كذلك الكتابات المستخدمة في الإعدادات الأخرى ('decimal'، 'roman-lower'، 'i'…؛ انظر صيغ كتابة تنسيق الترقيم)؛ والقيمة غير المعروفة تُرقّم بالأرقام العربية (0–9) ويُبلَّغ عنها. |
prefix | string | '' | نص يوضع قبل الرقم، بنمط الفاصل: مع '(' هنا و')' فاصلًا تُقرأ القائمة الصينية (一)، (二). وحين يُرسم الفاصل مقطعًا مستقلًا، تُرسم البادئة مقطعًا مستقلًا كذلك، قبل الرقم مباشرة. |
separator | string | '.' | الحرف الموضوع بين الرقم والنص، وهو عادةً '.' أو ')'. |
separatorFontFamily | string | ترث fontFamily | خط الفاصل. إذا اختلف أي جانب من نمط الفاصل عن نمط الرقم، رُسم الفاصل مقطعًا مستقلًا بعد الرقم (المحاذى إلى اليمين)، مثل 1 بخط Optima Bold أسود يليه • بخط DIN Pro Bold أزرق. |
separatorFontWeight | number | ترث fontWeight | وزن خط الفاصل (100–900). |
separatorItalic | boolean | ترث italic | يُخرج الفاصل بخط مائل. |
separatorColor | ColorValue | ترث color | لون الفاصل. تُحترم الإشارات إلى لوحة الألوان. |
separatorGap | Dimension | 0 em | المسافة بين الرقم والفاصل. يبقى نص البند يبدأ على بُعد gap بعد الفاصل. |
numberFontSize | Dimension | 1 em | حجم علامة الرقم. |
gap | Dimension | 0.5 em | المسافة الأفقية بين الرقم ونص البند. |
indent | Dimension | 0 em | الإزاحة الأساسية للمستوى 1؛ تتسلسل المستويات الأعمق من موضع بداية نص المستوى الأب ما لم تُتجاوز. |
numberVerticalOffset | Dimension | 0 em | ضبط دقيق للموضع الرأسي لعلامة الرقم. |
marginTop / marginBottom | Dimension | 1.5 em | المسافة قبل القائمة كلها وبعدها. |
itemSpacing | Dimension | 0 em | مسافة رأسية إضافية بين البنود. حول قائمة متداخلة في بند من قائمة أخرى، تُطبَّق مسافة القائمة الخارجية على الجانبين: قبل البند الأول من القائمة المتداخلة وبعد آخر بند فيها (حتى postext 1.4 كان البند التالي لقائمة متداخلة يأخذ مسافة القائمة المتداخلة). |
snapTopToGrid | boolean | false | يقرّب المسافة فوق القائمة إلى الأعلى كي يستقر رقمها الأول على شبكة خطوط الأساس، كما يفعل النص تحت العنوان؛ وتصبح marginTop حينئذ حدًّا أدنى. نهاية القائمة تعيد التدفق إلى الشبكة في الحالتين، فإذا كانت itemSpacing تساوي 0 اصطفّ كل بند مع النص في العمود المجاور. معطّل افتراضيًا، كما كان حتى postext 1.4: قيمة marginTop التي لا تساوي عددًا صحيحًا من الأسطر تُبقي البنود خارج الشبكة حتى نهاية القائمة. لا يتأثر بذلك القوائم داخل الإطارات (callout)، إذ إن دواخلها خارج الشبكة أصلًا. |
numberWidth | 'run' | 'level' | 'item' | 'run' | عرض عمود الرقم في البند، وهو ما يحدد موضع بداية نصه؛ وتُصفّ الأرقام فيه محاذاةً إلى اليمين. 'run': أعرض رقم في السلسلة التي ينتمي إليها البند، أي بنود العمق الواحد التي لا يفصل بينها إلا بنود أعمق. الشكل أو الفقرة أو الإطار بين بندين يبدأ سلسلة جديدة، فقد يبدأ نص ii) بعد جدول أبعد قليلًا إلى اليمين من نص i) قبله، وتبدأ قائمة من تسعة بنود نصها إلى يسار نص قائمة من اثني عشر بندًا. 'level': أعرض رقم في عمق البند في المستند كله (الفصل، في الكتاب)، فتبدأ كل قائمة، وكل جزء من قائمة متقطعة، نصها في الموضع نفسه، كما تفعل أصلًا إزاحات المستويات الأعمق. 'item': رقم البند نفسه، فيبدأ نص كل بند بعد تسميته بمقدار gap واحد: يتبع 第九條 و第十一條 الفراغُ نفسه وتبدأ نصوصهما من موضعين مختلفين، كما تطبع الجريدة الرسمية اليابانية مواد القانون. والأسطر التالية تتبع hangingIndent: مع false تعود إلى إزاحة القائمة، ومع true تتدلى تحت نص البند نفسه. وإزاحة المستوى الأعمق تبقى قيمة واحدة لكل مستوى. منذ postext 1.28. |
numberAlign | 'end' | 'start' | 'end' | موضع الرقم في عموده. 'end': بجوار النص، فتنتهي أرقام السلسلة عند موضع واحد وتتحاذى نقطتا 9. و10.. 'start': في أول العمود (اليسار في صفحة تُقرأ من اليسار إلى اليمين، واليمين في صفحة تُقرأ من اليمين إلى اليسار، ورأس السطر في النص العمودي)، فتبدأ التسميات المختلفة الطول من موضع واحد، كما تبدأ مواد القانون (第九條، 第十一條). يحتفظ العمود بالعرض الذي يحدده numberWidth، فيبدأ نص البنود من الموضع نفسه في الحالتين؛ وإذا كان للفاصل نمط خاص به تبع الفاصل رقمه. منذ postext 1.26. ومع numberWidth: 'item' يكون العمود هو الرقم نفسه، فتُنضّد القيمتان القائمة نفسها. |
hangingIndent | boolean | true | تصطف الأسطر الملتفّة مع أول حرف من النص بدلًا من أن تبدأ تحت الرقم. |
levels | OrderedListLevelConfig[] | — | تجاوزات لكل عمق من المستويات 1–5. |
#تجاوزات كل مستوى في القوائم المرقّمة
يمكن لكل مُدخل في levels أن يتجاوز numberFormat وprefix وseparator وfontFamily وfontSize وcolor وfontWeight وitalic وindent وverticalOffset ونمط الفاصل (separatorFontFamily، separatorFontWeight، separatorItalic، separatorColor، separatorGap)، وتنطبق قاعدة تسلسل الإزاحة نفسها المطبقة على القوائم غير المرقّمة. يرث نمط الفاصل في مستوى ما نمط الرقم في المستوى نفسه، ما لم يُعطَ إعداد الفاصل على مستوى القائمة كلها.
المحاذاة إلى اليمين. يقيس المسار أعرض رقم منسَّق داخل السلسلة ويزيح كل بنود تلك السلسلة كي تصطف علامات الأرقام على حافتها اليمنى. في قائمة من عشرة بنود تُخرج من 1. إلى 10.، تُحشى الأرقام ذات الخانة الواحدة من جهة اليمين كي يبقى الفاصل في العمود نفسه.
orderedLists: {
numberFormat: 'arabic',
separator: '.',
levels: [
{ level: 2, numberFormat: 'lower-alpha' },
{ level: 3, numberFormat: 'lower-roman', separator: ')' },
],
}ينتج عن ذلك المزيج المتداخل المألوف:
1. First item
a. Sub-item
i) Deep note
b. Sub-item
2. Second item
تراتبية المستندات الصينية (GB/T 15834—2011، الملحق B.3) تتألف من خمسة مستويات: 一、 ثم (一) ثم 1. ثم (1) ثم ①:
orderedLists: {
levels: [
{ level: 1, numberFormat: 'simp-chinese-informal', separator: '、' },
{ level: 2, numberFormat: 'simp-chinese-informal', prefix: '(', separator: ')' },
{ level: 3, numberFormat: 'arabic', separator: '.' },
{ level: 4, numberFormat: 'arabic', prefix: '(', separator: ')' },
{ level: 5, numberFormat: 'circled-decimal', separator: '' },
],
}#الصيغ الرياضية
تتحكم الخاصية math في طريقة تحليل صيغ LaTeX وإخراجها، سواء داخل المحدِّدين $...$ (ضمن السطر) أو $$...$$ (صيغة منفصلة، display). المحرّك الذي تقوم عليه هو MathJax (الحزمة mathjax-full) في وضع الإخراج SVG، ويُحوَّل إلى صورة نقطية في Canvas ويُضمَّن في PDF رموزًا قابلة للتحجيم.
interface MathConfig {
enabled?: boolean; // Render LaTeX. When false, spans pass through as literal TeX.
fontSizeScale?: number; // × the surrounding text's size (the body size for display maths).
color?: ColorValue; // Formula colour; inherits body colour if omitted.
marginTop?: Dimension; // Space above display math blocks.
marginBottom?: Dimension; // Minimum space below; baseline grid snap may enlarge it.
indentAfterDisplay?: boolean; // Indent a paragraph that follows a display formula.
keepWithLeadIn?: boolean; // Keep a display formula with the line that leads into it.
equationNumbering?: { // Number the display formulas that carry a \label.
enabled?: boolean; // default true
numberingTemplate?: string; // '{n}'; '{h1}.{n}' numbers by chapter
resetOn?: ResourceCounterReset; // 'never' | 'h1' … 'h6'
counterFormat?: ResourceCounterFormat; // 'decimal'
format?: string; // '({n})': what the formula and \eqref print
};
}| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
enabled | boolean | true | عند القيمة false تبقى مقاطع $...$ و$$...$$ تُحلَّل (فتظل تحذيرات المحدِّدات غير المغلقة تُطلق)، لكنها تُخرج بنص TeX المصدري كما هو. يفيد ذلك حين يحتوي المحتوى على علامات الدولار عمدًا، أو حين تريد تعطيل إخراج الرياضيات تمامًا. |
fontSizeScale | number | 1.0 | معامل يُضرب في حجم النص المحيط قبل الإخراج: الـ em الواحد من خط TeX في الصيغة يساوي ذلك الحجم × fontSizeScale، والحجم هو bodyText.fontSize للصيغة المنفصلة وللرياضيات ضمن السطر في نص المتن، وحجم الكتلة الحاوية للرياضيات ضمن السطر في عنوان أو نمط فقرة أو تعليق أو متن إطار. القيمة 1.0 تطابق النص المحيط؛ والقيم بين 0.9 و1.1 شائعة حين يبدو خط الرياضيات أكبر قليلًا أو أصغر قليلًا من خط النثر. تغيّر في postext 1.5: حتى 1.4 كانت الصيغ تخرج أكبر من ذلك بنحو 13% (انظر أدناه). |
color | ColorValue | يرث لون المتن | لون الصيغة المُخرجة. أغفله ليرث bodyText.color. عيّنه صراحةً حين تريد للصيغ لونًا مختلفًا عن النثر، كأن يطابق لون إبراز العناوين. |
marginTop | Dimension | 0.8em | المسافة فوق كتلة الصيغة المنفصلة. تُهمل في الرياضيات ضمن السطر. |
marginBottom | Dimension | 0.8em | المسافة تحت كتلة الصيغة المنفصلة. وهي حد أدنى: قد يمدّها الالتصاق بالشبكة كي يقع خط الأساس التالي على أحد خطوط الشبكة (سواء رسمت page.baselineGrid الشبكة أم لا). |
indentAfterDisplay | boolean | true | يزيح السطر الأول من الفقرة التي تلي صيغة منفصلة، كأي فقرة أخرى. أما false فتجعل كل فقرة تلي صيغة منفصلة مباشرةً بلا إزاحة، بوصفها تتمة للجملة التي قطعتها الصيغة ("where L is…"). والصيغة المكتوبة داخل فقرة، بلا سطر فارغ فوقها ولا تحتها، يليها دائمًا نص بلا إزاحة: النص الواقع تحت $$ الختامية يتابع تلك الفقرة ولا يُزاح أبدًا (انظر الصيغ الرياضية). |
keepWithLeadIn | boolean | false | يُبقي الصيغة المنفصلة في عمود السطر الذي يمهّد لها، وهو ما يسميه TeX جزاء ما قبل الصيغة (predisplay penalty). حين لا تتسع الصيغة تحت السطر الأخير من الفقرة التي قبلها، ينتقل ذلك السطر مع الصيغة إلى العمود أو الصفحة التالية؛ وحين يكون عدد الأسطر المتروكة خلفه أقل من bodyText.widowMinLines (أقل من سطر واحد حين يكون bodyText.avoidWidows معطّلًا)، تنتقل الفقرة التي تبدأ في ذلك العمود كاملةً (مع العناوين التي تختم العمود فوقها، بحسب headings.keepWithNext). يقف السطر المنقول وحده في رأس العمود التالي، أيًّا كان ما تطلبه قاعدة الأسطر اليتيمة (orphans). ومع false تنتقل الصيغة وحدها، وقد يختم السطرُ الذي يقدّمها العمودَ السابق، أو يقع فوق شكل يتصدر العمود التالي. |
equationNumbering | { enabled, numberingTemplate, resetOn, counterFormat, format } | true، '{n}'، 'never'، 'decimal'، '({n})' | طريقة ترقيم الصيغ المنفصلة التي تحمل \label (انظر المعادلات المرقّمة أدناه). تعمل numberingTemplate وresetOn وcounterFormat كما تعمل في نوع المورد: '{h1}.{n}' مع resetOn: 'h1' يرقّم (2.1)، (2.2)… بحسب الفصل، و'{h1}.{h2}.{n}' مع 'h2' بحسب القسم. وformat هو الرقم كما تطبعه الصيغة و\eqref، ويقوم فيه {n} مقام الرقم: '[{n}]' يطبع [3]. ومع enabled: false لا يُرقَّم شيء: يُسقَط \label، وتطبع الإحالة إليه صفحته. ويقبل الرمز نمطًا بعد نقطتين أيضًا ('{h1:A}.{n}': (A.1) في ملحق مرقّم بالحروف). |
math: {
enabled: true,
fontSizeScale: 1.0,
color: { hex: '#295AA3', model: 'hex' },
marginTop: { value: 1, unit: 'em' },
marginBottom: { value: 1, unit: 'em' },
}حجم الصيغ، تغيّر في postext 1.5. يعطي MathJax صندوق الصيغة بوحدة ex، والـ ex الواحد من خط TeX فيها يساوي 0.442 em. حتى postext 1.4 كان المحرّك يعدّه نصف em، فكانت كل صيغة تُنضَّد أكبر بنحو 13% من bodyText.fontSize × fontSizeScale. صارت الصيغ الآن تخرج بالحجم الموثَّق، فيُعاد تدفق الأسطر والصفحات التي فيها رياضيات. والإعدادات المكتوبة برمجيًا للإصدار 1.4 تحتفظ بحجم صيغ 1.4 إذا مُرّرت عبر pinLegacyMathSize من postext/bundle، مرة واحدة، كما كُتبت:
import { pinLegacyMathSize } from 'postext/bundle';
config = pinLegacyMathSize(config); // formulas, and the space around display formulas, as 1.4 set themوثمة تغييرات أخرى في القواعد في 1.5 قد تحرّك صفحاتها أيضًا: فواصل أسطر العناوين، والمسافة حول الشكل ضمن السطر (في النص الجاري وفي الإطارات)، والعلامات المضمَّنة في عناوينها، وحجم حروفها الاستهلالية، والحيّز المحجوز تحت سطر ينتهي بنقطتين للقائمة التي يقدّمها، والأسطر التي يتركها قطع الإطار من فقرة أو بند قائمة، وفواصل الأسطر بعد الشَّرطة، وتقسيم أسطر النص غير المضبوط، وانقسام الفقرة تحت العنوان، وفواصل الأسطر بعد واصلة الكلمة المركّبة، والمسافة تحت الحاوية :::paragraphs. الدالة migrateConfig، إذا شُغّلت مرة واحدة مع نص Markdown الذي يُخرجه الإعداد، تثبّت ما يحتاجه هذا النص من تلك التغييرات، بما فيها حجم الصيغ (انظر الحزم التي كتبها postext 1.4 أو ما قبله):
import { migrateConfig } from 'postext/bundle';
config = migrateConfig(config, undefined, { content: markdown }); // heading breaks, formulas, inline gaps, heading marks, drop caps, colon lines, box cuts, dash breaks, compound breaks, ragged breaking, splits under a heading and container space as 1.4 set themيمنع ذلك ما كانت تغييرات القواعد هذه ستحرّكه، لكنه لا يحفظ كل صفحة من صفحات 1.4. فالإصدار 1.5 يصلح أيضًا أخطاء في الإخراج، والإصلاح لا يُثبَّت: يحصل عليه الإعداد القديم كما يحصل عليه الجديد، فقد تتحرك صفحة يمسّها. ومن هذه الإصلاحات: العنوان الممتد عبر الصفحة بلا تصميم خاص به يُقاس على عرض الصفحة ويُنضَّد بتباعد أسطر مستواه؛ لا يُحجز شيء تحت خط أساس الحرف الاستهلالي في تصميم العنوان؛ يأخذ الحرف الاستهلالي لون لوحة القسم، ويُنضَّد حتى في نص التصميم الذي ليست قيمة overflow فيه 'wrap'، فيلتف النص حينئذ؛ الفقرة داخل الإطار تُرسم بالتتبّع الذي قيست به؛ الإطار المقسوم يحتفظ بعمود أيقونته في كل جزء منه؛ سطر الإطار الذي كانت مسافاته ستتمدد إلى أكثر من 3× يُنضَّد غير مضبوط، كما في النص الجاري؛ أداة الفقرة المرخاة لا تجعل أبدًا سطرًا مضبوطًا أعرض مما تسمح به maxWordSpacing؛ الإطار العائم يحتفظ بقيمة marginBottom (في الشريط العلوي) أو marginTop (في الشريط السفلي) إذا كانت أعرض من فجوة العناصر العائمة؛ نص التصميم المتوسّط أو المحاذى إلى اليمين الذي فيه تتبّع (كالترويسة أو عنوان صفحة الافتتاح) يوضع بحسب حروفه، دون التتبّع الذي بعد الحرف الأخير؛ تحت عنوان افتتاح ممتد عبر الصفحة، يبدأ النص الذي يفتتح العمود الثاني حيث كان سيبدأ النص الواقع مباشرة تحت عنوان الافتتاح، حتى حين يلي عنوانٌ عنوانَ الافتتاح؛ تتوقف نقاط جدول المحتويات قبل رقم الصفحة في الخط الذي يباعد بتقنين الأزواج (kerning) بين النقاط المتتالية؛ تقرأ الترويسة العنوان كما كُتب، بلا مسافة حيث ينتهي أحد أسطره بعد واصلة أو شَرطة أو داخل كلمة قُطعت لضيق العرض (MEDIOAMBIENTALES لا MEDIOAMBIENTALE S)، ويقرؤه {titleText} في تصميم العنوان بالطريقة نفسها (thousand-colour لا thousand- colour)؛ النص المثبَّت في أسفل شريط تصميم العنوان أو وسطه يُبقي الشريط طويلًا بما يكفي لاحتوائه، فلم يعد يرتفع فوق النص الذي يعلو العنوان؛ الكلمة الأعرض من سطرها، إذا قُطعت بجوار واصلة تحملها، تُقطع بعد تلك الواصلة ولا تُضاف إليها واصلة ثانية؛ البند التالي لقائمة متداخلة في أخرى يأخذ itemSpacing قائمته هو، لا قيمة القائمة المتداخلة؛ وبقية الكلمة المقطوعة لأنها أعرض من سطرها تحتفظ بمواضع القطع الخاصة بها، فيظل عنوان الويب ينقطع عند مفاصله والكلمة المركّبة عند واصلاتها، بدلًا من مقاطع القاموس.
تضرب pinLegacyMathSize المقياس في 1.1312 (0.5 ÷ 0.442) وتقسم هوامش الصيغ المنفصلة المعبَّر عنها بوحدة em على المعامل نفسه. المقياس وحده لا يكفي لكتاب فيه صيغ منفصلة: فهوامشها أطوال بمقياس حجم الصيغة نفسها، فكانت ستكبر بنسبة الـ 13% نفسها وتدفع النص الذي تحتها إلى الأسفل. وهذه هي القيم الثلاث مكتوبةً للهوامش الافتراضية:
math: {
fontSizeScale: 1.131,
marginTop: { value: 0.7072, unit: 'em' },
marginBottom: { value: 0.7072, unit: 'em' },
} // formulas as large as 1.4 set them, with the space 1.4 left around themحيث يكون الإعداد مخزَّنًا، يستطيع المحرّك أن يتعرّف على ذلك ويقوم به عنك: openBundle / readBundle لحزمة .postext كُتبت قبل 1.5 (انظر الحزم التي كتبها postext 1.4 أو ما قبله)، وSandbox للكتب ونسخة العمل وملفات postext-config.json المحفوظة آنذاك (انظر Sandbox › حفظ العمل). تُقرأ هذه عبر migrateConfig، التي تثبّت الحجم (pinLegacyMathSize): تصبح fontSizeScale مساويةً للمقياس المخزَّن (1 إن لم يُعيَّن) × 1.1312، ويُقسَم هامش الصيغة المنفصلة المعبَّر عنه بوحدة em أو rem، وهو طول بمقياس حجم الصيغة نفسها، على المعامل نفسه، فتبقى المسافة حول الصيغة المنفصلة كما تركها 1.4 (تصبح القيمة الافتراضية 0.8 em هي 0.7072 em). أما الهامش بوحدة من وحدات الصفحة (pt، mm…) فيُترك كما هو، وكذلك الإعداد الذي فيه enabled: false أو الذي ليس في كتابه أي $. عندئذ يُخرَج الكتاب القديم كما أخرجه 1.4، ويُظهر قسم math فيه الحجم الذي يُنضَّد به. ولتنضيد هذا الكتاب بحجم اليوم بدلًا من ذلك، أعد تعيين تلك القيم: الصيغ الرياضية › معامل الحجم والهامش العلوي للصيغة المعروضة والهامش السفلي للصيغة المعروضة في Sandbox، أو برمجيًا:
math: { ...config.math, fontSizeScale: 1, marginTop: undefined, marginBottom: undefined } // today's size and marginsالمعادلات المرقّمة. الصيغة المنفصلة ذات الرقم تمتد على عرض قياسها (العمود، أو العرض الداخلي للإطار الذي تقع فيه): تُوسَّط المعادلة ويُصفّ رقمها محاذىً إلى اليمين على سطر المعادلة، في كل صف مرقّم من بيئة align. ويأتي الرقم من \label{eq:x} (منذ postext 1.19): تُرقَّم الصيغ التي تحمل \label، والصفوف التي تحمله في align أو gather أو alignat أو flalign أو eqnarray، بترتيب القراءة وفق equationNumbering، ما لم يحمل الصف \nonumber أو \notag. والبيئات مثل equation لا تُرقَّم من تلقاء نفسها: فالصيغة التي لا تسمية لها لا رقم لها. ويطبع \tag{…} التسمية التي تعطيها له بين قوسين، و\tag*{…} كما كُتبت؛ ولا يدخل أيٌّ منهما في العدّ، و\label المجاور لأحدهما يسمّيه. والمعادلة المرقّمة الأعرض من قياسها تفيض إلى اليمين، كأي صيغة منفصلة. (حتى postext 1.4 لم تكن الصيغة التي فيها \tag تُرسم أصلًا؛ وحتى 1.18 لم يكن يرقّمها إلا \tag.)
يطبع \eqref{eq:x} في النص الرقمَ بصيغة format، أي (3)، ويطبع \ref{eq:x} الرقم مجرّدًا؛ وكذلك يفعل :ref{id="eq:x"} و@eq:x (انظر الإحالات)، وداخل الصيغة يطبع \eqref الرقم نصًا. وفي كتاب يُخرَج فصلًا فصلًا يستمر العدّاد من الفصل السابق: تحمله continuationAfter في LayoutContinuation.statementCounters (equation)، ويعطي مخطّط الكتاب كل تسمية رقمها (OutlineEntry.numberLabel)، فتطبعه الإحالة إلى معادلة في فصل آخر.
math: {
equationNumbering: { numberingTemplate: '{h1}.{n}', resetOn: 'h1' }, // (1.1), (1.2)… (2.1)
}دالتا الحل والتجريد مماثلتان لنظيراتهما في الأقسام الأخرى:
import {
DEFAULT_MATH_CONFIG,
resolveMathConfig,
stripMathDefaults,
} from 'postext';
const resolved = resolveMathConfig(config.math);
const minimal = stripMathDefaults(config.math);#تشغيل محرّك الرياضيات
يُحمَّل MathJax عند الطلب، لا مع بقية المحرّك. حين تُجري الإخراج على الخيط الرئيسي، شغّله قبل بناء مستند فيه صيغ:
import { buildDocument, initMathEngine, renderPage } from 'postext';
await initMathEngine(); // loads MathJax once; later calls resolve at once
const doc = buildDocument({ markdown: 'Euler: $e^{i\\pi}+1=0$.' }, config);
document.body.append(renderPage(doc.pages[0], doc));- إلى أن يعمل المحرّك، تكون الصيغ عناصر نائبة. تُخرَج كل صيغة صندوقًا رماديًا بحجم تقديري. وإذا أُخرج مستند فيه رياضيات قبل أن تُستدعى
initMathEngine()ولو مرة، أظهرت وحدة التحكم تحذيرًا واحدًا بذلك. - عامل الإخراج (worker) يشغّله عنك. البناء في
postext/workerيستدعيinitMathEngine()بنفسه حين يحتوي نص Markdown على$. - أخرج الآن، ثم أعد الإخراج حين يجهز. تخبرك
isMathReady()هل المحرّك يعمل. وتستدعيonMathReady(fn)الدالةfnحين يجهز (فورًا إن كان جاهزًا) وتعيد دالة تلغي الاستدعاء. يستطيع المحرّر أن يعرض العناصر النائبة فورًا ثم يعيد الإخراج حين يصل MathJax؛ ولا يُطبع أي تحذير ما دامتinitMathEngine()قيد التنفيذ. - الإخفاق. ترفض
initMathEngine()(reject) حين يتعذر تحميل MathJax، والاستدعاء اللاحق يحاول من جديد. - أي مُجمِّع (bundler)، أو Node، أو CDN. يأتي MathJax داخل الحزمة وحدةً واحدة مجمَّعة مسبقًا (نحو 1.8 MB قبل الضغط، ولا تجلبها إلا
initMathEngine). يعمل الاستيراد البسيطimport { initMathEngine } from 'https://esm.sh/postext'؛ ولا حاجة إلى?bundle. الحزمةmathjax-fullلا تلزم إلا لبناء postext، فتثبيت postext لا يثبّتها. MathJax ومحلّل mhchem المضمَّن فيه مرخّصان بترخيص Apache-2.0: تأتي إشعاراتهما ونص الترخيص بجوار الوحدة، فيdist/math/THIRD_PARTY_LICENSES.txt. - محرّك واحد لكل صفحة. يتشارك المحرّك وذاكرته المؤقتة للصيغ المُخرجة كلُّ ما يستورد
postextفي نطاق JavaScript نفسه (انظر الحالة العامة المشتركة في صفحة واحدة).
لقواعد الكتابة في جانب المستند ($...$، $$...$$، تهريب علامة الدولار الحرفية)، انظر صيغة المستند.