لماذا النص في ملف PDF ليس نصًّا حقيقةً
لمحة سريعة
قسم بعنوان «لمحة سريعة»حين تقرأ ملف PDF، ترى كلمات. لكن الملف لا يحتوي على كلمات. إنه يحتوي على تعليمات لرسم أشكال عند إحداثيات، والأشكال يصادف أنها تبدو مثل أحرف. الفجوة بين ما يرسمه ملف PDF وما يعنيه هي السبب في أنّ صفحة قد تبدو خالية من العيوب ومع ذلك تُنسَخ هراءً. تتناول هذه الصفحة تلك الفجوة، والخريطة الصغيرة المنفصلة التي تسدّها.
لماذا يهمّ هذا
قسم بعنوان «لماذا يهمّ هذا»كل ما تفعله بملف PDF بوصفه نصًّا — تحديده، ونسخه، والبحث فيه، وفهرسته للاسترجاع، وقراءته بصوت عالٍ عبر قارئ شاشة — يعتمد على استرجاع أحرف لم يخزّنها الملف مباشرةً قطّ. فإذا فشل ذلك الاسترجاع، كان الفشل غير مرئي. الصفحة لا تزال تُعرَض. لا يلاحظ أحد شيئًا حتى ينسخ أحدهم فقرة في بريد إلكتروني فيحصل على □□□□، أو يبحث في عقد من 400 صفحة عن بند موجود فيه بوضوح فلا يجد شيئًا.
هذا صنف باهظ من العلل تحديدًا لأنه ينجو من كل مراجعة بصرية. ليس هناك ما يُرى. يبدو المستند موثوقًا، وهو، لأغراض الآلة، صامت.
النسخة المختصرة
قسم بعنوان «النسخة المختصرة»- يرسم ملف PDF محارف — أشكالًا مرئية تُختار برموز عددية إلى داخل خط — لا أحرف Unicode.
- الشكل نفسه قد يعني أحرفًا مختلفة، والحرف نفسه قد يُرسَم بمحارف مختلفة. المظهر والمعنى منفصلان بحكم التصميم.
- لاسترجاع النص، يشغّل القارئ مسار العرض بالعكس: من الرمز إلى الحرف. خريطة CMap في
/ToUnicodeالخاصة بالخط هي جدول البحث لتلك الخطوة العكسية (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). - غياب
/ToUnicode، أو وجود خريطة خاطئة، يعني نسخًا ولصقًا مشوَّهين وبحثًا فاشلًا — مع بقاء الصفحة مثالية البكسل. - هذه مشكلة المعنى. أمّا ما إذا كان المحرف يبدو صحيحًا فهي مشكلة المظهر المنفصلة التي تتناولها صفحة الخطوط: موضع الصعوبة. يُصدر NextPDF خريطة
/ToUnicodeصحيحة كي تكون الرحلة ذهابًا وإيابًا أمينة.
كيف يتعامل NextPDF مع الأمر
قسم بعنوان «كيف يتعامل NextPDF مع الأمر»ابدأ بكيفية وصول النص إلى الصفحة أصلًا. دفق المحتوى لا يقول “اكتب الكلمة file.” إنه يختار خطًّا، ثم يسلّم سلسلة من الرموز إلى مُعامِل عرض النص (Spec: ISO 32000-2, §9ISO 32000-2 §9). كل رمز فهرس — موضع في برنامج خط — ويحوّل الخط ذلك الفهرس إلى مُخطَّط محرف ويرسمه. الرمز 70 ليس الحرف F. إنه “الخانة 70 في هذا الخط”، ويصادف أنّ الخانة 70 تحمل منحنى على شكل F. اختر خطًّا مختلفًا، وقد تكون الخانة 70 ندفة ثلج.
إذًا الرمز لا يعني شيئًا إلا نسبةً إلى ترميز خطّه. بالنسبة إلى خط بسيط، يكون ذلك الترميز نحو بايت واحد لكل محرف تقريبًا. أمّا بالنسبة إلى الأنظمة الكتابية التي تحتاج آلاف المحارف — CJK، أو أي مستند Unicode كامل — فهذا متّسع غير كافٍ، فيلجأ ملف PDF إلى خط مركَّب (Type 0) (Spec: ISO 32000-2, §9.7ISO 32000-2 §9.7). يقرأ الخط المركَّب رموزًا متعدّدة البايتات عبر خريطة CMap، ويحوّلها إلى معرّفات محارف (CIDs)، ويخطّط المعرّفات إلى محارف. إنها مواربة أنيقة تتيح لخط واحد معالجة مجموعة محارف هائلة. وهي أيضًا موضع إضافي قد يبرد فيه الأثر من “ما يُعرَض” إلى “ما يعنيه”.
الآن شغّله بالعكس. لاستخراج النص، يأخذ القارئ الرموز التي يجدها في دفق المحتوى وعليه أن يسترجع الأحرف (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). الترميز الذي رسم المحرف ذهب من الحرف إلى المحرف؛ ويحتاج الاستخراج من رمز المحرف إلى الحرف، وذلك الاتجاه ليس مضمونًا أن يكون قابلًا للعكس. قد يكون خط مجزَّأ قد أعاد ترقيم محارفه. وقد تكون معرّفات محارف خط مركَّب خاصة. الشكل على الصفحة لا يحمل أي معنى Unicode متأصّل.
الحل هو شحن الخريطة العكسية إلى جانب الخط. تلك الخريطة هي خريطة CMap في /ToUnicode: فلكل رمز يستخدمه المستند، تسجّل قيمة (أو قيم) Unicode التي يمثّلها ذلك الرمز. بوجودها، يكون الاستخراج بحثًا نظيفًا. وبغيابها، يُترَك القارئ ليخمّن من ترميزات الخطوط والاستدلالات الإرشادية — والتخمين هو بالضبط حيث يصير fi علامة استفهام.
- Your charactersThe Unicode text you set, for example the word 'file'.
- Encoding → codesThe font's encoding turns characters into numeric codes; a composite font routes them through a CMap to CIDs.
- Codes → glyphsEach code selects a glyph outline, which is painted to the page. This is the part you see.
- Extraction reverses itA reader reads the codes back and looks each one up in /ToUnicode to recover Unicode.
- Text againWith a correct /ToUnicode, copy, search, indexing, and screen readers all get the original characters back.
يكتب NextPDF الخريطة العكسية بحكم العادة. عندما يضمّن خطًّا مركَّبًا، يُصدر السليل CIDFontType2، والأصل Type0، وخريطة CMap في /ToUnicode كي تُحلّ الرموز عودةً إلى Unicode — وهو عمل الترميز الموصوف في صفحة الخطوط: موضع الصعوبة. لكنّ النقطة الجديرة بالفصل هنا هي لماذا: دفق /ToUnicode ليس بصدد جعل الصفحة تبدو صحيحة. المحارف تبدو صحيحة فعلًا من دونه. إنه القطعة الوحيدة التي تُبقي النص قابلًا للاستخراج.
مثال عملي
قسم بعنوان «مثال عملي»أشهر موضع يظهر فيه هذا هو رابطة fi. كثير من الخطوط ترسم f وi محرفًا مدمجًا واحدًا، لأنّ نقطة i تصطدم بخطّاف f. على الصفحة، إنه شكل واحد، يرسمه رمز واحد. والسؤال هو ما الذي يحدث عند نسخه.
% A /ToUnicode entry that maps the single ligature code to TWO characters,% so selecting the 'fi' glyph copies out as 'f' then 'i' — not one mystery box.1 beginbfchar<0085> <00660069> % code 0x85 -> U+0066 'f' U+0069 'i'endbfcharذلك المُدخَل الواحد هو الفرق بين بحث عن “file” يطابق، وبحث عن “file” يفوّت بصمت كل ورود مُصيَّر بالرابطة. خطّط رمز الرابطة إلى متتالية الحرفين f + i، فتصبح الكلمة قابلة للبحث والنسخ. اتركه غير مخطَّط، فتظل الصفحة تُظهر file على نحو مثالي بينما يقول النص بهدوء شيئًا لا تستطيع آلة قراءته.
لهذا قد تُستخرَج “fi” محرفًا واحدًا أو محرفين، ولهذا لا يكون الفرق عشوائيًا — إنه أيًّا كان ما طُلِب من خريطة /ToUnicode أن تقوله. الخريطة الصحيحة تفكّك الرابطة عودةً إلى أحرفها. يُصدر NextPDF بالضبط هذا النوع من المُدخَلات، كي تكون الرابطة على الصفحة حرفين عاديين على الحافظة.
مفهوم خاطئ شائع
قسم بعنوان «مفهوم خاطئ شائع»الفخّ، بصريح العبارة: “النص يُعرَض، إذًا النص بخير.” العرض والاستخراج آليتان مختلفتان تقرآن بيانات مختلفة. يتبع العرض مسار الرمز إلى المحرف وهو ما تتحقّق منه عيناك. ويتبع الاستخراج مسار الرمز إلى الحرف عبر /ToUnicode وهو ما يتحقّق منه كل مستهلِك آليّ. يمكن لمستند أن يتفوّق في الأول ويفشل في الثاني فشلًا تامًّا، لأنه بحكم البناء لا يوجد شيء مرئي يكشفه.
فخّ ثانٍ أدقّ: افتراض أنّ المحرف “بداهةً” يعرف أيّ حرف هو. إنه لا يعرف. المحرف شكل له فهرس. والتخطيط عودةً إلى حرف هو معلومة إضافية على المُنتِج أن يوفّرها. فإذا لم يكتبها المُنتِج قطّ، لا يستطيع أي قارئ استرجاعها بأمانة — لا يستطيع سوى التخمين.
الحدود والنطاق
قسم بعنوان «الحدود والنطاق»| Edition | Availability |
|---|---|
| Core | NextPDF emits a correct /ToUnicode CMap for the fonts it embeds, including the ligature and composite-font cases, so the documents it produces are searchable and copyable. |
| Pro | Not in this edition |
| Enterprise | Not in this edition |
خريطة /ToUnicode لا تستطيع حمل سوى المعلومات التي يكشفها الخط المصدري فعلًا. وحيث لا يكون للمحرف حرف يمكن تحديده — علامة زخرفية بحتة، أو رمز ذو استخدام خاص بلا تعيين Unicode — لا تستطيع أي خريطة اختراع معنى لم يكن موجودًا قطّ. يُصدر NextPDF التخطيط الصادق الذي يستطيع اشتقاقه؛ ولا يفبرك أحرفًا لسدّ فجوة.
تتناول هذه الصفحة المستندات التي يكتبها NextPDF. وهي ليست أداة إصلاح لملفات PDF واردة اعتباطية يكون /ToUnicode فيها غائبًا أو خاطئًا أصلًا؛ فاسترجاع النص من تلك مشكلة منفصلة استدلالية. كما أنّ الاستخراج الأمين ضروري للوصول لكنه ليس كله — فترتيب القراءة، والوسوم، والنص البديل تتناولها صفحة ما الذي يجعل ملف PDF متاحًا للوصول.
أسئلة شائعة مختصرة
قسم بعنوان «أسئلة شائعة مختصرة»لماذا يُنسَخ ملف PDF نفسه على نحو جيّد في قارئ وسيّئ في آخر؟
تتراجع القارئات بطرق مختلفة عند غياب /ToUnicode. بعضها يخمّن من الترميز المدمج في الخط فيحالفه الحظ في النص اللاتيني الشائع؛ وبعضها لا. خريطة /ToUnicode الصحيحة تزيل اليانصيب — فيحصل كل قارئ مطابق على الأحرف نفسها.
هل هذا الشيء نفسه كون الخط غير مضمَّن؟
لا. التضمين بصدد المظهر — ما إذا كان المحرف يُرسَم دون تثبيت الخط. أمّا /ToUnicode فبصدد المعنى — ما إذا كان الرمز يُخطَّط عودةً إلى حرف. يمكن لخط أن يكون مضمَّنًا على نحو مثالي ومع ذلك لا يملك /ToUnicode صالحًا، وهو إخفاق “غير قابل للبحث لكنه جميل”.
هل يحتاج الاستخراج يومًا إلى أكثر من حرف واحد لكل رمز؟
نعم — حالة الرابطة هي ذلك بالضبط: رمز واحد يُخطَّط إلى حرفين. يستطيع مُدخَل /ToUnicode تخطيط رمز واحد إلى متتالية قصيرة، وهكذا تعود الروابط، وبعض الأشكال المركَّبة، أحرفها المكوِّنة لها.
مستندات ذات صلة
قسم بعنوان «مستندات ذات صلة»- الخطوط: موضع الصعوبة — القطعة الرفيقة على جانب المظهر: التضمين، والتجزئة، وكيف يُبنى الترميز. هذه الصفحة هي جانب المعنى من العملة نفسها.
- ما الذي يجعل ملف PDF متاحًا للوصول — النص الأمين مكوِّن واحد؛ وترتيب القراءة، والوسوم، والنص البديل هي البقية.
- ما هو ملف PDF فعلًا — نموذج الكائنات
الذي تعيش فيه الخطوط والترميزات ودفوق
/ToUnicode.
مسرد المصطلحات
قسم بعنوان «مسرد المصطلحات»- المحرف — شكل مرئي في خط (مُخطَّط). ما يرسمه ملف PDF فعلًا. للمحرف فهرس لكن لا معنى حرفيّ متأصّل.
- الحرف — وحدة من اللغة المكتوبة، تُعرَّف بنقطة ترميز Unicode. ما تقصده، وما يحاول الاستخراج استرجاعه.
- الرمز — القيمة العددية في دفق المحتوى التي تختار محرفًا من الخط الحالي. ليس حرف Unicode؛ وله معنى فقط نسبةً إلى الخط.
- معرّف المحرف (CID) — معرّف يستخدمه خط مركَّب لمعالجة محرف ضمن مجموعة كبيرة؛ خطوة وسيطة بين الرمز والمحرف.
- الخط المركَّب (Type 0) — خط يقرأ رموزًا متعدّدة البايتات عبر خريطة CMap للوصول إلى معرّفات المحارف والمحارف، يُستخدَم حين يجب على خط واحد معالجة آلاف المحارف.
/ToUnicode— دفق خريطة CMap يخطّط الرموز التي يستخدمها مستند عودةً إلى قيم Unicode؛ وهو ما يجعل نص PDF قابلًا للبحث والنسخ والوصول.- الرابطة — محرف واحد يرسم حرفين أو أكثر شكلًا واحدًا (على
سبيل المثال
fi)؛ ويفكّك مُدخَل/ToUnicodeالخاص بها عودةً إلى أحرفها.