ما هو النص فعلًا، ولماذا تختلف الأدوات بشأنه
الملف النصي بايتات زائد ترميز، والترميز لا يُخزَّن في الملف. لا شيء سوى العُرف يخبر البرنامج بأن بايتًا معينًا يعني «é» — ولهذا يُفتح الملف نفسه بشكل صحيح في مكان ويظهر «Ã©» في مكان آخر. UTF-8 هو الحل الحديث، ويخزّن الحروف اللاتينية الشائعة في بايت واحد، والحروف المشكولة في بايتين، ومعظم الصينية واليابانية والعربية وكل الرموز التعبيرية في ثلاثة أو أربعة. UTF-16 هو ما يستخدمه Windows وJavaScript داخليًا، ويخزّن كل شيء تقريبًا في بايتين والباقي في أربعة. أما Windows-1252 وLatin-1 فترميزات أحادية البايت ما زالت الأنظمة القديمة تنتجها، وهي المصدر المعتاد للنص المشوّه (mojibake). ومن المفيد معرفة ما يلي عن هذه الصفحات: يكتشف «عارض CSV» ترميز الملف الذي تفلته فيه، بما في ذلك UTF-16 وWindows-1252، ويتيح لك تغييره يدويًا. أما مربعات النص العادية فلا تفعل ذلك — إذ يُقرأ الملف المُفلَت بترميز UTF-8، لذا سيعرض ملف مُصدَّر بترميز Latin-1 حروفه المشكولة بشكل خاطئ، والحل هو تحويله أولًا.
لكلمة «حرف» أربعة معانٍ، والمعنى الذي تحتاجه يعتمد على الجهة التي تفرض الحد. ما يراه الإنسان حرفًا واحدًا هو عنقود حروف مرئي (grapheme). وما يطابقه التعبير النمطي هو نقطة ترميز (code point). وما تعيده الخاصية string.length في JavaScript هو وحدات UTF-16. وما يقيسه عمود قاعدة البيانات أو ترويسة HTTP هو بايتات UTF-8. في الإنجليزية العادية تتفق المعاني الأربعة، ولهذا لا يلاحظ أحد — ثم يأتي رمز تعبيري لعائلة فيكون عنقودًا مرئيًا واحدًا، وسبع نقاط ترميز، وإحدى عشرة وحدة UTF-16، وخمسة وعشرين بايتًا، فتُرفض رسالة من 200 حرف في حقل يتسع لـ 255 حرفًا. ولهذا السبب بالضبط يعرض «عدّاد الأحرف» المقاييس الأربعة كلها.
الأحرف غير المرئية أحرف حقيقية. المسافة غير القابلة للكسر تبدو مطابقة تمامًا للمسافة العادية، لكنها حرف مختلف كليًا — وتصل باستمرار مع النص المنسوخ من صفحة ويب أو من برنامج معالجة نصوص، فتعطّل عمليات البحث وتحليل CSV والكود الذي يقسّم النص عند المسافات. ومحارف الربط الصفرية العرض (zero-width joiner) هي ما يجمع رمزًا تعبيريًا لعدة أشخاص معًا. والشرطات الناعمة وعلامات الاتجاه وعلامات ترتيب البايتات كلها تنتقل مع النص الملصوق. لا يظهر أيٌّ منها على الشاشة، لذا فالإشارة الوحيدة التي تحصل عليها هي عدد لا يتفق مع ما تراه — وهذا أحد الاستخدامات الصادقة لعدّاد الأحرف. لاحظ أن خيار تجاهل المسافات في «مقارنة النصوص» يدمج المسافات العادية وعلامات الجدولة؛ ولا يعامل المسافة غير القابلة للكسر كمسافة، لأنهما ليسا الشيء نفسه.
نهايات الأسطر هي السبب في أن المقارنة تُظهر أحيانًا كل سطر على أنه تغيّر. ينهي Windows السطر بحرفَي الإرجاع (carriage return) وتغذية السطر (line feed)؛ وكل ما عداه يستخدم تغذية السطر وحدها. احفظ ملفًا بنهايات LF من محرر على Windows، فيختلف كل سطر فيه ببايت واحد غير مرئي، لذا تُبلغ المقارنة على مستوى البايت — git diff وdiff(1) — عن الملف كله على أنه أُعيدت كتابته، وتخفي التغيير الوحيد الذي أجريته فعلًا. تقسّم أداتا «مقارنة النصوص» و«حذف الأسطر المكررة» لدينا النص وفق الأعراف الثلاثة قبل المقارنة، لذا لا يظهر هنا الملف الذي تغيّرت نهايات أسطره فقط كجدار من اللون الأحمر. هذه ميزة مريحة في أداة للقراءة وفخ في المستودع: أصلح الأمر من مصدره بمحررك أو بإعدادات نهايات الأسطر في git نفسه.
قد تُعتبر سلسلتان متطابقتان في الشكل مختلفتين عند المقارنة، والتطبيع (normalisation) هو السبب عادةً. يستطيع Unicode كتابة «é» بطريقتين: كنقطة ترميز واحدة، أو كحرف «e» عادي يليه تشكيل حادّ مُركَّب. تُعرضان بالشكل نفسه لكنهما تسلسلان مختلفان من البايتات، لذا تعاملهما المقارنة أو إزالة التكرار أو البحث في قاعدة البيانات كقيمتين مختلفتين. وقد اختلف macOS وWindows تاريخيًا بشأن الشكل الذي يُستخدم لأسماء الملفات، وهكذا تنتهي قائمة جُمعت من جهازين بما يبدو تكرارات مطابقة تمامًا لكنها لا تُحذف. و«عدّاد الأحرف» هو وسيلتك لاكتشاف ذلك — فللشكلين عدد العناقيد المرئية نفسه وعدد مختلف من نقاط الترميز. لا تحوّل أي من هذه الأدوات بين الشكلين؛ فهذه مهمة من سطر واحد لسكربت يستخدم مكتبة Unicode، مثل unicodedata.normalize في Python.
«عدد الكلمات» حكم تقديري لا قياس. التقسيم عند المسافات قاعدة إنجليزية، وتطبيقها على الصينية أو اليابانية أو التايلاندية — التي لا تضع مسافات بين الكلمات — يجعل مقالًا طويلًا كلمة واحدة. أما العدّاد لدينا فيستخدم بدلًا من ذلك تقسيم الكلمات وفق Unicode المدمج في المتصفح، والذي يعرف أين تبدأ الكلمات في كل نظام كتابة. وتبقى الخلافات حول الشرطات («well-known» كلمة واحدة هنا وفي Word، وكلمتان في بعض الأدوات)، والأرقام المستقلة، وما يُعدّ جملة — فعبارة «We met Dr. Smith» جملة واحدة، بينما يعدّها المقسِّم الساذج جملتين. ووقت القراءة تقدير إضافي فوق ذلك: 238 كلمة في الدقيقة للقراءة الصامتة، مأخوذة من تحليل تلوي (meta-analysis) لا من الرقم التقريبي الذي تتناقله المدونات.