المستوى المطلوب: متوسط. يفترض المقال إنك تعرف Node.js على مستوى أساسي، تتعامل مع async/await، وعندك فكرة عن Docker. لو لسه مبتدئ في الكلام ده، ابدأ بـ Hono Quickstart الأول وارجع.
لو بتدير منصة عربية وكل أول شهر بييجي عميل يطلب تقرير PDF من dashboard، الحلول الجاهزة بتاعدك بتكلفك $0.05 لكل صفحة وبتفشل في الـ RTL في نص الحالات. الـ 100 سطر اللي قدامك بيولّدوا تقرير 5 صفحات بنص عربي صحيح في 1.2 ثانية، وبيشتغلوا على VPS بـ $9.4 شهريًا.
بناء خدمة Markdown to PDF عربية بـ Puppeteer و Hono
المشكلة باختصار
أغلب مكتبات تحويل Markdown لـ PDF (PDFKit، jsPDF، html-pdf-node القديم) بنيت على bidi engine ضعيف أو معدوم. النتيجة: عنوان "تقرير المبيعات" بيطلع في الـ PDF "تاعيبملا ريرقت" — الحروف بتتعكس، علامات الترقيم بتقع في الناحية الغلط، وأي لاتيني داخل عربي بيكسر السطر. عميلك بيشوف المخرج، بيقفل التذكرة، وبيدور على منافس.
الحل المنطقي: بدل ما تحاول تكتب bidi engine من الصفر، استخدم محرك متصفح كامل (Chromium headless) عشان يضمنلك CSS، font shaping، و Unicode bidirectional algorithm صحيحين. وبعدين خد المخرج كـ PDF عبر API الـ print built-in.
تخيّل المطبعة الورقية القديمة (مثال للمبتدئ)
تخيّل عندك مطبعة قديمة من اللي بنشوفها في أفلام الأبيض والأسود. الماكينة دي فيها صناديق صغيرة، وكل صندوق فيه قوالب حروف معدنية. لما تيجي تطبع جملة، أنت اللي بتختار القوالب وتركبها بإيدك، حرف ورا حرف، من اليمين للشمال للعربي.
لو ركّبت قوالب لاتينية وحاولت "تطبعها بالعكس" عشان تطلع عربي، مش هتظبط. الكسرات مش هتلتصق بالحروف، الهمزات هتقع تحت كلمة تانية، والأرقام داخل الكلام هتسيب فجوات. ده بالظبط اللي بيحصل لما PDFKit يحاول يرسم نص عربي: هو شايفه حروف منفصلة بدون قواعد ربط.
لما تستخدم Chromium headless، زي ما تكون شغّلت ماكينة طباعة ديجيتال حديثة فيها processor كامل بيفهم اللغة. إنت بتدّيله الجملة كنص HTML، وهو بيقرر ترتيب الحروف، أماكن الكسرات، وحجم كل حرف بناءً على اللي قبله واللي بعده.
التعريف العلمي الدقيق
الـ Headless Chrome هو نسخة من Chromium بتشتغل بدون واجهة رسومية — مفيش render إلى شاشة، الناتج بيتكتب على off-screen buffer. مكتبة Puppeteer بتتحكم فيه عبر Chrome DevTools Protocol، نفس البروتوكول اللي بيستخدمه DevTools اللي بتفتحه F12.
المهم في موضوعنا: نفس الـ font rendering، CSS engine، و bidirectional algorithm (UAX #9) بتاع Chrome العادي اللي بيشتغل على ٣ مليار جهاز يوميًا. الـ page.pdf() method بتمر على Chromium's print pipeline، وبتطلع PDF فيه embedded fonts و selectable text — مش صورة. ده يعني عميلك يقدر ينسخ الكلام، يعمل Ctrl+F، ويترجم بـ Google Translate.
الكود الكامل في 100 سطر TypeScript
المعمارية بسيطة: Hono framework يستقبل POST بـ Markdown، يحوّله HTML بـ marked، يحقن CSS RTL وخط Cairo، يفتح page في Chromium مشغّل من قبل، ويرجّع PDF binary.