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

أدوات للنصوص لا تحتفظ بنصك أبدًا

إحدى عشرة أداة لعدّ النصوص ومقارنتها وتنظيفها وقراءتها. لا تُخزَّن المسودات والقوائم والشيفرات المصدرية أبدًا.

11 أداة، دون تسجيل ودون علامة مائية

«عدّاد الكلمات» و«عدّاد الأحرف» يجيبان عن سؤال «كم طول هذا النص»، و«مقارنة النصوص» تجيب عن سؤال «ما الذي تغيّر»، و«حذف الأسطر المكررة» ترتّب القائمة. أما العارضات فللملفات التي أرسلها إليك أحدهم ولا تُفتح كما ينبغي، وأدوات التصغير الثلاث للكود في طريقه إلى بيئة الإنتاج. وتشرح الملاحظات أسفل القائمة لماذا قد تعدّ أداتان النص نفسه بشكل مختلف، ولماذا قد لا يكون سطران متطابقان في الشكل هما السطر نفسه على الإطلاق.

العارضات

3 أدوات

اقرأ ملف CSV أو XML أو مستند Markdown كما ينبغي، دون أن يعبث به جدول بيانات أولًا.

ما هو النص فعلًا، ولماذا تختلف الأدوات بشأنه

الملف النصي بايتات زائد ترميز، والترميز لا يُخزَّن في الملف. لا شيء سوى العُرف يخبر البرنامج بأن بايتًا معينًا يعني «é» — ولهذا يُفتح الملف نفسه بشكل صحيح في مكان ويظهر «Ã©» في مكان آخر. 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) لا من الرقم التقريبي الذي تتناقله المدونات.

متى يكون المتصفح الأداة الخطأ فعلًا

لا يُرسَل أي شيء في هذه الفئة ولا يُخزَّن أبدًا، وهذا ما يجعل لصق مسودة غير منشورة أو شيفرة مصدرية مملوكة فيها آمنًا. وهو أيضًا ما يضع الحد الأقصى، ونفضّل أن نقول أين يقع على أن تكتشفه في منتصف العمل.

الملفات الكبيرة. يُحفظ النص كله في ذاكرة علامة التبويب ويُعاد فحصه أثناء الكتابة. بضعة ميغابايتات مريحة؛ أما ملف سجل بمئات الميغابايتات فليس كذلك، والهاتف يستسلم أسرع من الحاسوب المحمول. سطر الأوامر لا يعاني هذه المشكلة لأنه يعالج البيانات تدفقيًا: يبحث grep وripgrep في ملفات أكبر من ذاكرتك، ويحوّلها sed وawk سطرًا بسطر، ويزيل الأمر sort مع خيار unique التكرار من قائمة بعشرات الملايين من الأسطر مستعينًا بالقرص. كلها مجانية ومثبّتة مسبقًا على macOS وLinux.

المستندات المختلفة جدًا. تتوقف «مقارنة النصوص» عند 8,000 اختلاف، لأن تكلفة الخوارزمية من الذاكرة بعد ذلك تنمو بسرعة كافية لتجميد علامة التبويب، كما أن مقارنة بهذا الحجم غير قابلة للقراءة أصلًا. نسختان من المستند نفسه لا تبلغان هذا الحد تقريبًا أبدًا؛ ومستندان لا علاقة بينهما يبلغانه فورًا. ولمراجعة الكود، يتعامل diff وgit diff مع أي حجم، وأداة الدمج الثلاثي الحقيقية تفعل شيئًا لا تستطيعه هذه الصفحة على الإطلاق.

تغيير الترميز، أو تطبيع Unicode. هذه الصفحات تقرأ وتُبلغ؛ ولا تحوّل بين الترميزات. أما iconv فيحوّل بين كل الترميزات الموجودة، والأمر file يخمّن ما لديك، وتطبيع Unicode سطر واحد في Python أو استدعاء لأداة uconv من ICU. وإذا كنت تصلح ملفًا مُصدَّرًا بنص مشوّه، فهذه هي مجموعة الأدوات المناسبة.

أي شيء متكرر. تعمل هذه الأدوات عندما ينقر شخص ما. أما عدّ الكلمات عبر أربعمئة مستند، أو تصغير مجلد مع كل commit، فمكانه سكربت أو خطوة في عملية البناء — وفي التصغير تحديدًا، تقوم أداة البناء لديك بالتصغير نفسه، مع خرائط المصدر (source maps) ووضع المراقبة والتخزين المؤقت، وهو ما لا يستطيع مربع لصق توفيره. هذه الصفحة للملف الواحد الذي أمامك.

CSS الحديث. ترفض أداة «تصغير كود CSS» التداخل الأصلي (nesting) وصيغة نطاقات media الحديثة بدل تصغيرهما، لأن أداة التصغير التي تعتمد عليها أقدم من كليهما وتحذف بصمت ما لا تفهمه. هذا رفض صادق لا ميزة، والحل هو تحويل التداخل أولًا باستخدام Sass أو PostCSS أو Lightning CSS — وهو ما تقوم به أداة البناء لديك على الأرجح بالفعل.

الاختيار بين الأدوات المتشابهة في أسمائها

عدّاد الكلمات أم عدّاد الأحرف. العدّ نفسه بأرقام رئيسية مختلفة. يبدأ «عدّاد الكلمات» بالكلمات والجمل والفقرات ووقت القراءة، وهي ما يُقاس به المقال أو البحث أو الخطاب. ويبدأ «عدّاد الأحرف» بالأحرف، والأحرف دون المسافات، وبايتات UTF-8، وهي ما يُقاس به الوصف التعريفي (meta description) أو مقطع رسالة SMS أو حقل قاعدة البيانات. وإذا رُفض نصك لأنه طويل جدًا، فأنت تحتاج إلى عدّاد الأحرف، وتحديدًا إلى عدد البايتات فيه.

مقارنة النصوص أم حذف الأسطر المكررة. المقارنة تجيب عن سؤال «ما الذي تغيّر بين هاتين النسختين» وتحتاج إلى نصين. أما أداة حذف التكرار فتعمل على قائمة واحدة وتجيب عن سؤال «ما الذي يظهر أكثر من مرة هنا»، كما تخبرك بالعناصر التي تكررت وعدد مرات تكرارها، وترتّب ترتيبًا طبيعيًا بحيث يأتي item2 قبل item10، أو تحتفظ فقط بالأسطر التي ظهرت مرة واحدة بالضبط. وإيجاد العناصر التي تنفرد بها إحدى قائمتين مهمة أداة حذف التكرار، لا أداة المقارنة.

تصغير كود HTML أم تصغير كود CSS أم تصغير كود JavaScript. ثلاث لغات، وثلاث أدوات تصغير، وتداخل واحد يستحق المعرفة: أداة تصغير HTML تصغّر أيضًا CSS داخل كتل style وJavaScript داخل كتل script، بالطريقة نفسها التي تعمل بها الصفحتان الأخريان. لذا يحتاج ملف HTML واحد إلى أداة واحدة، لا ثلاث. أما ملفات .css و.js المنفصلة فتحتاج إلى صفحاتها الخاصة.

«عارض XML» مقابل «تنسيق XML» و«التحقق من XML». يمنحك العارض هنا شجرة قابلة للطي لاستكشافها، وهذا ما تريده عندما يكون المستند كبيرًا وتبحث عن شيء ما. أما أداتا التنسيق والتحقق، ضمن أدوات المطورين، فتمنحانك نصًا بمسافات بادئة لتلصقه مرة أخرى في ملف، والسطر والعمود بالضبط حيث يوجد الخلل. قراءة، مقابل تعديل وإصلاح.

«عارض CSV» مقابل فتح الملف في Excel. ليس أداة منافسة، لكنه المقارنة التي يعقدها الناس فعلًا. يحوّل Excel البيانات أثناء الفتح دون أن يسأل: رمز المنتج 00123 يصبح 123، ورقم القطعة 5-3 يصبح 5 مارس، ورقم الطلب الطويل يتحول إلى صيغة علمية، والملف المُصدَّر المفصول بفواصل منقوطة من نظام ألماني يستقر بالكامل في العمود A. أما العارض فيعرض كل قيمة كنص، تمامًا كما خُزّنت، لترى ما أُرسل إليك فعلًا.

معاينة Markdown أم تحويل Markdown إلى PDF. المعاينة للتأكد من أن ملف README يُعرض كما سيعرضه GitHub، مباشرة أثناء الكتابة. أما «تحويل Markdown إلى PDF»، ضمن أدوات المستندات، فلإنتاج مستند نهائي بفواصل صفحات. تحقق هنا، وانشر هناك.

ما تعتمد عليه هذه الأدوات

محركات مفتوحة المصدر تقوم بالعمل الفعلي، والمواصفات التي تطبّقها.

  • Unicode Annex #15Specification — يشرح التطبيع (normalisation) — ولماذا قد يختلف نصان يبدوان متطابقين.
  • Unicode Annex #29Specification — يعرّف عناقيد الحروف (grapheme clusters)، وهي المعنى الحقيقي لعبارة «حرف واحد».
  • cssoMIT — يصغّر CSS.
  • TerserBSD-2-Clause — يصغّر JavaScript.
  • markdown-itMIT — يعرض معاينة Markdown.

الأسئلة الشائعة

هل يُخزَّن نصي في أي مكان؟

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

لماذا يختلف عدد الكلمات لديكم عن Microsoft Word أو موقع آخر؟

لأن العدّ ينطوي على اختيارات. الكلمات الموصولة بشرطة، والأرقام المستقلة، وما ينهي الجملة، وما يفصل الفقرة، كلها قرارات تتخذها الأدوات بشكل مختلف. أداتنا تعدّ «well-known» كلمة واحدة، وتعتبر السطر الفارغ — لا كل فاصل سطر — حدًّا للفقرة، ولا تقسم الجملة بعد اختصار مثل «Dr.» — وتستخدم تقسيم الكلمات وفق Unicode، فتُعدّ الصينية واليابانية بشكل صحيح بدل أن تُعرض ككلمة واحدة ضخمة. في النثر العادي تتقارب الأرقام كثيرًا؛ أما في قائمة أرقام قطع الغيار فلن تتقارب.

لماذا يظهر الملف الذي أفلتّه بشكل «Ã©» بدل «é»؟

لأنه ليس بترميز UTF-8. تقرأ مربعات النص الملف المُفلَت بترميز UTF-8، الذي يغطي كل ما صُنع تقريبًا في هذا القرن، لكن الملف المُصدَّر القديم قد يكون بترميز Windows-1252 أو Latin-1، وتلك البايتات تعني شيئًا مختلفًا. تحويله مرة واحدة باستخدام iconv يصلحه نهائيًا. و«عارض CSV» هو الاستثناء بين هذه الأدوات — فهو يكتشف الترميز، ويتيح لك تغييره إذا كان الاكتشاف خاطئًا.

لماذا ما زالت هناك تكرارات بعد أن حذفت التكرارات؟

في الغالب بسبب المسافات في نهاية الأسطر، وهي غير مرئية وتجعل السطرين مختلفين فعلًا. ولهذا السبب يكون حذف المسافات من الأطراف قبل المقارنة مفعّلًا افتراضيًا، وهو لا يؤثر إلا في المقارنة — فالسطر الذي يبقى يحتفظ بنصه الأصلي. والسبب الآخر هو Unicode: الحرف المشكول المكتوب كحرف واحد، والمكتوب كحرف زائد تشكيل مُركَّب، يبدوان متطابقين لكنهما غير متساويين. ولا شيء هنا يطبّعهما نيابةً عنك.

هل يمكن استخدام هذه الأدوات مع مستند Word أو ملف PDF أو جدول بيانات؟

ليس مباشرةً — فهذه الأدوات تعمل على النص، وهذا ما يجعلها فورية. حوّل الملف أولًا: أداتا [تحويل PDF إلى نص](pdf-to-text) و[تحويل DOCX إلى TXT](docx-to-txt) لدينا تفعلان ذلك بالضبط، والنتيجة تُلصق هنا مباشرة. وملف CSV هو الاستثناء، إذ يُفتح مباشرة في «عارض CSV».

هل هناك حد للحجم أو حد يومي؟

لا يوجد حساب ولا حصة ولا حد يومي، لأنه لا يوجد خادم يحصي. الحد هو ذاكرة جهازك. والحد الصريح الوحيد موجود في «مقارنة النصوص»، التي تتوقف عند 8,000 اختلاف وتخبرك بذلك بدل تجميد علامة التبويب — ومقارنة نسختين من المستند نفسه لا تقترب منه تقريبًا أبدًا.