المصدر المفتوح · مثال عملي
إصلاح النص العربي في ملف PDF: مثال عملي
شهادة تجريبية يظهر نصها العربي سليمًا على الشاشة، لكنه يُنسخ مربعات وحروفًا خاطئة، أصلحتها مكتبة arabic-pdf-repair بأمر واحد. نزّل الملفين، وقارن ما يُلصق من كل منهما، وشغّل الكود نفسه على ملفاتك.
1. نزّل الملفين التجريبيين
الملفان شهادة من صفحة واحدة أُعدّت لهذا المثال، وكل ما فيها من أسماء وتفاصيل خيالي. طبقة النص في الأصل معطوبة كما كانت تتركها برامج Windows القديمة، والملف المُصلح هو الأصل بعد الأمر أدناه. والصفحتان متطابقتان تمامًا.
الأصل (certificate.pdf)بعد الإصلاح (certificate.repaired.pdf)
2. انسخ نص الملف الأصلي
هذه أسطره الأولى كما يستخرجها pdf.js، قارئ PDF في Firefox وفي كثير من تطبيقات الويب. وكل □ حرف تحكم: لا يظهر، أو يظهر مربعًا، بحسب المكان الذي تلصق فيه.
□دة إ □□م دورة
□ □□ ا□□ر□□□□دة □□ر □□□□
□ □ إدارة ا□□□□□ □□ن
□ري
□□□"! ا□□رة □"
'□ أ □% □□$□ح دورة3. أصلحه بأمر واحد
مع Node.js 20 أو أحدث، ودون تثبيت أي شيء. يذكر الأمر كل خط أصلحه، ويكتب النسخة المُصلحة بجوار الأصل دون أن يغيّره:
$ npx arabic-pdf-repair certificate.pdf
fixed CertArabic: 65 codes
wrote certificate.repaired.pdf4. انسخ النص مرة أخرى
الأسطر نفسها، منسوخة من certificate.repaired.pdf:
شهادة إتمام دورة
مركز ريادة للتدريب المهني
تشهد إدارة المركز بأن
سارة يوسف المنصوري
قد أتمت بنجاح دورة
أساسيات تحرير المستندات الرقميةوالبحث يعمل أيضًا: كلمة التعلم لا توجد في الأصل، وتوجد مرة واحدة في الملف المُصلح.
5. الإصلاح نفسه في الكود الخاص بك
في Node.js، ثبّت الحزمة (npm install arabic-pdf-repair) ومرّر بايتات الملف إلى repairTextLayer. تعيد الدالة الملف المُصلح والخطوط التي أصلحتها، أو null إن لم يكن هناك ما يُصلح:
import { readFile, writeFile } from "node:fs/promises";
import { repairTextLayer } from "arabic-pdf-repair";
const input = new Uint8Array(await readFile("certificate.pdf"));
const result = await repairTextLayer(input);
if (result) {
await writeFile("certificate.repaired.pdf", result.bytes);
console.log(result.fonts); // [{ name: "CertArabic", codes: 65 }]
}لا تستخدم المكتبة أي واجهة من واجهات Node.js، لذا تعمل أيضًا في المتصفح أو في web worker على ملف يختاره المستخدم، دون رفعه:
import { repairTextLayer } from "arabic-pdf-repair";
const picker = document.querySelector("input[type=file]");
picker.addEventListener("change", async () => {
const file = picker.files[0];
const result = await repairTextLayer(new Uint8Array(await file.arrayBuffer()));
if (!result) return; // nothing to repair
const url = URL.createObjectURL(new Blob([result.bytes], { type: "application/pdf" }));
window.open(url); // the repaired copy; the file never left the browser
});لماذا يُنسخ نص الأصل رموزًا غير مفهومة
- يرسم ملف PDF كل حرف بشكل (glyph) من خط. ولنسخه يحتاج القارئ إلى جدول في الملف اسمه ToUnicode يحدد الحرف الذي يمثله كل شكل.
- خط الملف الأصلي بلا هذا الجدول. أشكاله لا تحمل إلا أسماء Microsoft للحروف العربية (afii62753 وما بعدها)، ولا تعدّها برامج القراءة حروفًا، فيأتي النسخ بحروف تحكم وحروف عشوائية.
- تقرأ arabic-pdf-repair هذه الأسماء وتكتب الجدول الناقص ولا تغيّر شيئًا آخر: الأشكال نفسها في مواضعها، فتبقى الصفحة كما هي.
الخطوات التالية
- ما تصلحه أيضًا (نص Windows-1256 الذي يُنسخ مثل ÇáÚÑÈíÉ، وخطوط Diwan XT، والملفات المشفرة) وترخيصها: صفحة arabic-pdf-repair.
- الصفحة الممسوحة ضوئيًا صورة لا نص فيها لإصلاحه: استخدم التعرف الضوئي على النص في GenPDF.
- لتغيير كلمات ملف PDF عربي، لا نسخها فقط: تعديل النص العربي في PDF مع GenPDF.