# استمارات لقوالب Typst

امنح دوال Typst الخاصة بك استمارة، ليرى من يملأ تقريرًا حقولًا ذات تسميات في الوضع المرئي بدلًا من صياغة استدعاء الدالة.

غالبًا ما يأتي قالب Typst بدوال خاصة به: صفحة غلاف، أو مربع معلومات، أو كتلة توقيع. ومن يكتب التقرير يستدعيها، كما في `#info-box(title: "Supply risk", tone: "risk")[...]`. وإذا كنت تصون القالب، يمكنك وصف وسائط كل دالة مرة واحدة. فيعرض الوضع المرئي عندها كل استدعاء لتلك الدالة استمارةً: حقولًا ذات تسميات، وقائمة للخيارات الثابتة، ومفتاح تبديل لنعم أو لا. وتعديل حقل يعيد كتابة وسيط واحد فقط في ملف `.typ`، فيبقى التقرير مصدر Typst عاديًا يُجمَّع بالطريقة نفسها.

## ما يراه القارئ

الاستدعاء الذي يقع على أسطره الخاصة يصبح **بطاقة**. تعرض ترويسة البطاقة اسم الاستمارة، وملخصًا قصيرًا، مثل عنوان المربع، إن اخترت واحدًا. ويحصل كل وسيط على صف فيه تسميته وعنصر تحكم.

الاستدعاء داخل جملة، مثل `#badge("review")`، يصبح **شارة** في سطر النص. والنقر على الشارة يفتح الحقول نفسها في نافذة منبثقة صغيرة.

تُحفظ حقول النص وحقول الترميز عند الضغط على Enter (أو ⌘ Enter أو Ctrl Enter في حقل متعدد الأسطر) أو عند مغادرة الحقل. ويعيد Esc القيمة القديمة. وتُحفظ القوائم ومفاتيح التبديل فورًا. وكل تغيير خطوة تراجع واحدة.

نقل المؤشر إلى استدعاء يُظهر مصدره، مثل أي عنصر آخر في الوضع المرئي. ويفعل **Edit in source** على البطاقة الشيء نفسه.

## أين تعلن الاستمارات

هناك مكانان، بالصيغة نفسها:

- **في حزمة.** أضف قسم `[tool.oleafly]` إلى ملف `typst.toml` الخاص بالحزمة. يحتفظ Typst بأقسام `[tool.*]` لأدوات أخرى، فتظل الحزمة تُثبَّت وتُجمَّع في كل مكان. وهذا يعمل مع حزم `@local` ومع حزم `@preview` من Typst Universe.
- **في المشروع.** للقوالب المحفوظة كملفات `.typ` عادية داخل المشروع، أنشئ `oleafly-forms.toml` في جذر المشروع. وتسمّي كل استمارة أيضًا الملف الذي يعرّف الدالة، بالمفتاح `module`.

استمارة حزمة:

```toml
[tool.oleafly]
schema = 1

[[tool.oleafly.forms]]
function = "info-box"
label = "Info box"
summary = "title"

  [[tool.oleafly.forms.fields]]
  arg = "title"
  kind = "text"
  label = "Heading"
  placeholder = "Short heading"
  required = true

  [[tool.oleafly.forms.fields]]
  arg = "tone"
  kind = "choice"
  label = "Tone"
  default = "note"
  options = [{ value = "note", label = "Note" }, { value = "risk", label = "Risk" }, "neutral"]

  [[tool.oleafly.forms.fields]]
  arg = 0
  kind = "content"
  label = "Text"
```

استمارة مشروع، في `oleafly-forms.toml`:

```toml
[tool.oleafly]
schema = 1

[[tool.oleafly.forms]]
module = "template/memo.typ"
function = "memo-header"
label = "Memo header"
fields = [
  { arg = "to", kind = "text", label = "To" },
  { arg = "subject", kind = "text", label = "Subject" },
]
```

## المفاتيح

`schema = 1` مطلوب. والملف الذي يخلو منه، أو يحمل رقمًا آخر، يُتجاهل.

لكل مدخل `[[tool.oleafly.forms]]`:

| المفتاح | مطلوب | المعنى |
| --- | --- | --- |
| `function` | نعم | اسم الدالة، معرّفًا واحدًا في Typst. الواصلات مقبولة. |
| `module` | في `oleafly-forms.toml` فقط | ملف المشروع الذي يعرّف الدالة، نسبةً إلى جذر المشروع، مع `/` بين المجلدات. |
| `label` | لا | اسم الاستمارة على البطاقات والشارات. الافتراضي هو اسم الدالة. |
| `summary` | لا | الوسيط الذي تظهر قيمته بجوار التسمية، ويُكتب مثل `arg` في الحقل. |
| `fields` | نعم | حقل واحد أو أكثر. |

لكل حقل:

| المفتاح | مطلوب | المعنى |
| --- | --- | --- |
| `arg` | نعم | اسم لوسيط مسمّى (`"title"`)، أو رقم لوسيط موضعي (`0` هو الأول). وكتلة `[...]` في النهاية تُحسب وسيطًا موضعيًا بعد الوسائط التي بين القوسين. |
| `kind` | نعم | `text` أو `content` أو `choice` أو `number` أو `toggle`. |
| `label` | نعم | تسمية الحقل. |
| `help` | لا | ملاحظة قصيرة تحت الحقل. |
| `placeholder` | لا | نص رمادي في حقل فارغ. |
| `required` | لا | يعلّم `true` الحقل الفارغ على أنه ناقص ويخفي زر **Clear** فيه. ولا يضيف Oleafly الوسيط من تلقاء نفسه أبدًا. |
| `default` | لا | القيمة التي تستخدمها دالتك عند حذف الوسيط. تُعرض، ولا تُكتب أبدًا. |

الأنواع ومفاتيحها الإضافية:

- يكتب `text` سلسلة Typst نصية. أضف `multiline = true` لمربع أكبر.
- يحرّر `content` ترميز Typst ويكتبه ككتلة `[...]`. أما الوسيط النصي فيبقى سلسلة نصية.
- يحتاج `choice` إلى `options`: قائمة سلاسل نصية، أو جداول `{ value, label }` عندما تختلف التسمية عن القيمة. وتُكتب القيم سلاسل نصية.
- يقبل `number` المفاتيح `integer` و`min` و`max` و`step`. والأرقام بلا وحدات.
- يكتب `toggle` القيمة `true` أو `false`.

## أي الاستدعاءات تحصل على استمارة

يتبع Oleafly أسطر `#import` و`#let` في التقرير نفسه على المستوى الأعلى من الملف:

- `#import "@local/acme-report:0.1.0" as acme` يجعل `#acme.info-box(...)` استمارة.
- `#import "@local/acme-report:0.1.0": info-box, status-badge as badge` يجعل `#info-box(...)` و`#badge(...)` استمارتين.
- `#import "@local/acme-report:0.1.0": *` يفعّل الاستمارة لكل دالة تعلن الحزمة استمارة لها.
- `#import "template/memo.typ": memo-header` يطابق استمارة مشروع قيمة `module` فيها هي `template/memo.typ`. وتُقرأ المسارات من مجلد التقرير نفسه، أو من جذر المشروع عندما تبدأ بـ `/`.

يجب أن تتطابق نسخة الحزمة تمامًا. و`#let` بالاسم نفسه، لاحقًا في الملف، يستبدل الاستمارة من تلك النقطة فصاعدًا. أما الاستدعاءات التي يُوصل إليها عبر ملف آخر يعيد استيراد الحزمة فتحتفظ بنص مصدرها.

الدالة التي تحمل اسم عنصر Typst يرسمه الوضع المرئي أصلًا، مثل `table` أو `figure`، تحتفظ بمظهرها المدمج عند استدعائها باسمها المجرد. أما `#acme.table(...)` أو استيراد مُعاد تسميته فيحصل على الاستمارة.

## حقول تُعرض للقراءة فقط

بعض الوسائط لا يمكن تحريرها من استمارة بأمان. يعرض صفها المصدر مع السبب، ويقفز **Edit in source** إليه:

- **Computed in the source:** القيمة تعبير، مثل `title: data.title`.
- **Written as a different kind of value:** مثلًا رقم حيث تتوقع الاستمارة نصًا.
- **Not one of the choices:** قيمة لا تسردها `options` لديك.
- **يحدّده وسيط نشر:** استدعاء بـ `..args` يمرّر قيمًا لا تراها الاستمارة، فيصير كل حقل للقراءة فقط.

عندما يتعذر إضافة حقل في موضعه، مثلًا وسيط موضعي بعد وسيط ناقص، تقول الاستمارة ذلك وتعرض **Add in source**.

## أخطاء في التعريف

افتح `oleafly-forms.toml`، أو ملف `typst.toml` لحزمة مضمّنة، في Oleafly فتظهر كل مشكلة علامةً على سطرها: نوع غير معروف، أو تسمية ناقصة، أو استمارة مكررة، أو `module` خارج المشروع. والاستمارة المعطوبة تُستبعد وتواصل الأخرى عملها. والملف الأكبر من 256 KB لا يُقرأ.

## مشاركة القوالب

يقرأ Oleafly استمارات الحزم من المجلدات نفسها التي يستخدمها المجمّع. والمتعاون الذي لا يملك حزمة `@local` يرى مصدرًا عاديًا ولا يرى أخطاء. ولمشاركة الاستمارات مع كل من في المشروع، افتح مربع حوار **Typst packages**، وفعّل **Use packages from the project folder** واختر **Vendor packages into project**. فتنتقل الحزمة واستماراتها بعد ذلك في مجلد `typst-packages` الخاص بالمشروع (انظر [مشاريع Typst](/docs/typst/)).
