تخطَّ إلى المحتوى

ما هي لغة PDFLang؟

‏PDFLang لغة برمجة نصية لها غرض واحد: تدوين كيف يبدو ملف PDF سليم، حتى يستطيع الحاسوب فحص الملفات على أساسه.

تحمل النصوص البرمجية الامتداد .pdfl، وينفّذها pdfl، وهي أداة سطر أوامر مكتوبة بلغة Rust.

لا بد أن يقرر أحدهم ما إذا كان ملف PDF صالحًا للطباعة أو للإيداع أو للإرسال إلى العميل.

القواعد وراء هذا القرار ملموسة: تغطية حبر أقل من ٣٠٠٪، وكل الخطوط مضمَّنة، ومربع قص في كل صفحة، وباركود مطابق للرقم المطبوع بجانبه، ولا صفحة دُوّرت عن طريق الخطأ.

هذه القواعد تعيش عادةً في ثلاثة أماكن في آنٍ واحد: في رأس من يمارس العمل منذ أطول مدة، وفي قائمة تحقق لا يفتحها أحد، وفي برنامج لا يقدر على صيانته إلا كاتبه. ثم يترك ذلك الشخص العمل، وتتقادم القائمة، ويصبح البرنامج شيئًا لا يُمَس.

‏PDFLang موجودة كي تعيش القواعد في ملف واحد يستطيع من يعرفها أن يقرأه.

profile "press-ready" {
check "كمية الحبر ضمن الحد" tags: ["prepress"] {
require prepress::validate_tac_limits(300)
}
check "الخطوط مضمَّنة" {
doc.fonts.each { |font|
assert font.is_embedded, "الخط #{font.name} غير مضمَّن"
}
}
}

أربع كلمات تحمل معظم اللغة:

  • profile يجمع الفحوص ويسمّي المجموعة.
  • check قاعدة واحدة، ويصبح قسمًا في التقرير.
  • require يوقف الفحص عند اختلال شرط مسبق.
  • assert يسجّل ملاحظة، بالرسالة التي كتبتها أنت.

لا أصناف ولا وراثة ولا تصريح بالأنواع ولا فواصل منقوطة. هذا قرار لا إغفال: القارئ المستهدف يعرف ما قبل الطباعة، لا البرمجة.

النية نفسها تظهر في تفاصيل أصغر. الصفحات تُعدّ من ١، كما يعدّها كل من هو خارج المصرِّفات. والمقاسات تقبل 3mm و1in مباشرة. والنسب المئوية تُكتب 300%.

سبعة فضاءات أسماء، واحد لكل نوع من العمل:

  • text:: — الاستخراج والتوحيد والبحث والتحققات والبيانات الشخصية
  • struct:: — الكائنات والبيانات الوصفية وXMP والأمان والبصمات
  • visual:: — الدقة والمقارنة البصرية والبصمة الإدراكية والجودة
  • prepress:: — تغطية الحبر والفصل والألوان الخاصة والخطوط والمربعات
  • codes:: — كشف الباركود ورمز QR وفكّ ترميزهما والتحقق منهما
  • fix:: — المربعات والصفحات والعلامات المائية والدمج والتقسيم والتحسين
  • data:: — المسارد ومجموعات البيانات وجداول البحث من خارج الملف

تقرير. وباختصار، يبدو الفحص الفاشل هكذا:

{
"script_name": "prepress.pdfl",
"input_file": "magazine.pdf",
"status": "FAIL",
"error_count": 2,
"diagnostics": [
{
"id": "PDFL-093751a2",
"severity": "error",
"check_name": "Ink coverage",
"message": "page 7: 324% ink (limit 300%)"
}
]
}

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

‏JSON هو الافتراضي. أما CSV وHTML وPDF فلمن يحتاج إلى قراءة التقرير لا إلى تحليله، وSARIF وJUnit حين يجب أن تظهر الملاحظة حيث ينظر الفريق أصلًا.

Terminal window
pdfl run press-ready.pdfl magazine.pdf > report.json

رمز الخروج يحمل الحكم، فيتفرّع عليه نص صدفة أو مهمة تكامل مستمر دون تحليل أي شيء:

الرمز المعنى
0 نجح كل شيء
1 تحذيرات فقط
2 أخطاء تحقق
3 خطأ صياغة في النص البرمجي
10 تعذّرت قراءة المستند أصلًا

الأداة بالإنجليزية، ونصوصك ليست ملزمة بذلك

Section titled “الأداة بالإنجليزية، ونصوصك ليست ملزمة بذلك”

الرسائل التي يطبعها pdfl نفسه — التشخيصات والأخطاء ومساعدة سطر الأوامر — بالإنجليزية، جريًا على عادة أدوات سطر الأوامر. هذا التوثيق مترجم إلى سبع لغات، لكن الفحص الفاشل يظل يُبلغ page 7: 324% ink (limit 300%).

أما الرسائل داخل نصوصك فهي لك. اكتبها بلغة من سيقرأ التقرير.

دليل اللغة هو الفصل الوحيد الذي يستحق القراءة من أوله إلى آخره. وكل ما بعده مرجع: فصل لكل فضاء أسماء، وأوامر سطر الأوامر، والوصفات العملية المبنية على حالات كاملة — مطبعة، ودار نشر قانونية، ومختبر، وخط تكامل مستمر.

وإن كنت تفضّل قراءة الشيفرة على قراءة النثر، فإن الأمثلة ملفات تعريف قابلة للتنفيذ بتعليقاتها كاملة.

DigitalOceanشكرًا لـ DigitalOcean على استضافة هذا الموقع.