टेक्स्ट असल में क्या है, और टूल्स उस पर एकमत क्यों नहीं होते
टेक्स्ट फ़ाइल बाइट्स और एक एन्कोडिंग का मेल है, और एन्कोडिंग फ़ाइल में सेव नहीं होती। किसी प्रोग्राम को सिर्फ़ एक परिपाटी बताती है कि कोई ख़ास बाइट “é” है — इसीलिए वही फ़ाइल एक जगह ठीक खुलती है और दूसरी जगह “é” दिखाती है। UTF-8 आधुनिक जवाब है, जो आम लैटिन अक्षरों को एक बाइट में, एक्सेंट वाले अक्षरों को दो में, और ज़्यादातर चीनी, जापानी, अरबी और हर इमोजी को तीन या चार बाइट में रखता है। UTF-16 वह है जो Windows और JavaScript अंदरूनी तौर पर इस्तेमाल करते हैं, और यह लगभग हर चीज़ को दो बाइट में और बाक़ी को चार में रखता है। Windows-1252 और Latin-1 वे सिंगल-बाइट एन्कोडिंग हैं जो पुराने सिस्टम आज भी बनाते हैं, और बिगड़े हुए अक्षरों (mojibake) की आम वजह यही हैं। इन पेजों के बारे में जानने लायक बात: “CSV व्यूअर” आपकी छोड़ी गई फ़ाइल की एन्कोडिंग पहचान लेता है, UTF-16 और Windows-1252 समेत, और आपको उसे बदलने भी देता है। सादे टेक्स्ट बॉक्स ऐसा नहीं करते — छोड़ी गई फ़ाइल UTF-8 की तरह पढ़ी जाती है, इसलिए Latin-1 एक्सपोर्ट के एक्सेंट वाले अक्षर ग़लत दिखेंगे, और इसका हल है पहले उसे कन्वर्ट करना।
“कैरेक्टर” के चार मतलब हैं, और आपको कौन-सा चाहिए यह इस पर निर्भर है कि लिमिट कौन लगा रहा है। इंसान को जो एक कैरेक्टर दिखता है, वह ग्रैफ़ीम क्लस्टर है। रेगुलर एक्सप्रेशन जिससे मैच करता है, वह कोड पॉइंट है। JavaScript का string.length जो बताता है, वह UTF-16 यूनिट हैं। डेटाबेस कॉलम या HTTP हेडर जो मापता है, वह UTF-8 बाइट हैं। सादी अंग्रेज़ी के लिए चारों एक ही होते हैं, इसलिए किसी का ध्यान नहीं जाता — और फिर एक फ़ैमिली इमोजी एक ग्रैफ़ीम, सात कोड पॉइंट, ग्यारह UTF-16 यूनिट और पच्चीस बाइट निकलता है, और 200 कैरेक्टर का मैसेज 255 कैरेक्टर वाली फ़ील्ड में रिजेक्ट हो जाता है। ठीक इसी वजह से “अक्षर गिनें (कैरेक्टर काउंटर)” चारों दिखाता है।
अदृश्य कैरेक्टर भी असली कैरेक्टर हैं। नॉन-ब्रेकिंग स्पेस दिखने में स्पेस जैसा ही है, पर पूरी तरह अलग कैरेक्टर है — यह वेब पेज या वर्ड प्रोसेसर से कॉपी किए टेक्स्ट में लगातार आता है, और सर्च, CSV पार्सिंग और स्पेस पर बांटने वाले कोड को तोड़ देता है। ज़ीरो-विड्थ जॉइनर ही कई लोगों वाले इमोजी को जोड़े रखते हैं। सॉफ़्ट हाइफ़न, दिशा के निशान और बाइट-ऑर्डर मार्क, सब पेस्ट किए टेक्स्ट के साथ चले आते हैं। इनमें से कोई भी स्क्रीन पर नहीं दिखता, इसलिए आपको बस एक ही संकेत मिलता है: ऐसी गिनती जो आपको दिख रही चीज़ से मेल नहीं खाती — कैरेक्टर काउंटर का यह एक ईमानदार इस्तेमाल है। ध्यान दें कि “टेक्स्ट की तुलना करें” में स्पेसिंग को अनदेखा करने वाला विकल्प सामान्य स्पेस और टैब को समेटता है; यह नॉन-ब्रेकिंग स्पेस को स्पेस नहीं मानता, क्योंकि दोनों एक चीज़ नहीं हैं।
लाइन एंडिंग ही वह वजह है जिससे diff कभी-कभी हर लाइन को बदली हुई दिखाता है। Windows लाइन को कैरेज रिटर्न और लाइन फ़ीड से ख़त्म करता है; बाक़ी सब सिर्फ़ लाइन फ़ीड इस्तेमाल करते हैं। किसी LF फ़ाइल को Windows एडिटर से सेव करें, तो उसकी हर लाइन एक अदृश्य बाइट से अलग हो जाती है, इसलिए बाइट-लेवल की तुलना — git diff, diff(1) — पूरी फ़ाइल को दोबारा लिखी हुई बताती है और वह एक बदलाव छिप जाता है जो आपने सच में किया था। हमारे “टेक्स्ट की तुलना करें” और “डुप्लिकेट लाइनें हटाएं” तुलना से पहले तीनों परिपाटियों पर लाइनें बांटते हैं, इसलिए जिस फ़ाइल की सिर्फ़ लाइन एंडिंग बदली है, वह यहां लाल रंग की दीवार की तरह नहीं दिखती। पढ़ने वाले टूल में यह सुविधा है और रिपॉज़िटरी में एक जाल: इसे जड़ से ठीक करें, अपने एडिटर से या git की अपनी लाइन-एंडिंग सेटिंग्स से।
एक जैसी दिखने वाली दो स्ट्रिंग तुलना में अलग निकल सकती हैं, और आमतौर पर इसकी वजह नॉर्मलाइज़ेशन होती है। Unicode “é” को दो तरह से लिख सकता है: एक कोड पॉइंट के रूप में, या सादे “e” के बाद एक जुड़ने वाले एक्यूट एक्सेंट के रूप में। दोनों एक जैसे दिखते हैं पर बाइट्स के अलग-अलग क्रम हैं, इसलिए तुलना, डुप्लिकेट हटाना या डेटाबेस लुकअप उन्हें दो अलग वैल्यू मानते हैं। macOS और Windows फ़ाइल नामों के लिए कौन-सा रूप इस्तेमाल करें, इस पर पहले से असहमत रहे हैं, और इसी तरह दो मशीनों से जुटाई गई सूची में ऐसे हूबहू डुप्लिकेट दिखने वाले आइटम आ जाते हैं जो हटते ही नहीं। “अक्षर गिनें (कैरेक्टर काउंटर)” से आप इसे पकड़ सकते हैं — दोनों रूपों की ग्रैफ़ीम गिनती एक होती है और कोड पॉइंट गिनती अलग। इनमें से कोई भी टूल इन रूपों के बीच कन्वर्ट नहीं करता; यह Unicode लाइब्रेरी वाली किसी स्क्रिप्ट के लिए एक लाइन का काम है, जैसे Python का unicodedata.normalize।
“शब्दों की गिनती” एक फ़ैसला है, माप नहीं। व्हाइटस्पेस पर बांटना अंग्रेज़ी का नियम है, और इसे चीनी, जापानी या थाई पर लागू करने से — जिनमें शब्दों के बीच स्पेस नहीं होते — एक लंबा लेख एक ही शब्द गिना जाता है। हमारा काउंटर इसकी जगह ब्राउज़र का Unicode वर्ड सेगमेंटेशन इस्तेमाल करता है, जो हर लिपि में जानता है कि शब्द कहां शुरू होते हैं। बाक़ी असहमतियां हाइफ़न को लेकर हैं (“well-known” यहां और Word में एक शब्द है, कुछ टूल्स में दो), अकेले नंबरों को लेकर, और इस बात को लेकर कि वाक्य किसे माना जाए — “We met Dr. Smith” एक वाक्य है और एक सीधा-सादा स्प्लिटर इसे दो बताता है। पढ़ने का समय इसके ऊपर एक और अनुमान है: मन में पढ़ने के लिए 238 शब्द प्रति मिनट, जो एक मेटा-एनालिसिस से लिया गया है, न कि वह गोल संख्या जो ब्लॉग पोस्टों में एक-दूसरे से कॉपी होती रहती है।
कहां ब्राउज़र सचमुच सही टूल नहीं है
इस मॉड्यूल में कुछ भी कभी भेजा या स्टोर नहीं किया जाता, और यही बात अप्रकाशित ड्राफ़्ट या प्रोप्राइटरी सोर्स कोड पेस्ट करना सुरक्षित बनाती है। यही सीमा भी तय करती है, और हम चाहेंगे कि वह सीमा कहां है यह पहले ही बता दें, बजाय इसके कि आपको काम के बीच में पता चले।
बड़ी फ़ाइलें। पूरा टेक्स्ट टैब की मेमोरी में रखा जाता है और आपके टाइप करते ही दोबारा जांचा जाता है। कुछ मेगाबाइट आराम से चलते हैं; कई सौ मेगाबाइट की लॉग फ़ाइल नहीं, और फ़ोन लैपटॉप से पहले हार मान लेता है। कमांड लाइन में यह समस्या नहीं है क्योंकि वह स्ट्रीम करती है: grep और ripgrep आपकी मेमोरी से बड़ी फ़ाइलें खोजते हैं, sed और awk उन्हें लाइन-दर-लाइन बदलते हैं, और unique फ़्लैग के साथ sort डिस्क का सहारा लेकर करोड़ों लाइनों की सूची से डुप्लिकेट हटा देता है। ये सभी मुफ़्त हैं और macOS व Linux पर पहले से इंस्टॉल हैं।
बहुत अलग डॉक्यूमेंट। “टेक्स्ट की तुलना करें” 8,000 अंतरों पर रुक जाता है, क्योंकि उसके बाद एल्गोरिदम की मेमोरी की लागत इतनी तेज़ी से बढ़ती है कि टैब अटक जाए, और इतना बड़ा diff वैसे भी पढ़ा नहीं जा सकता। एक ही डॉक्यूमेंट के दो वर्शन लगभग कभी वहां तक नहीं पहुंचते; दो असंबंधित डॉक्यूमेंट तुरंत पहुंच जाते हैं। कोड की समीक्षा के लिए diff और git diff किसी भी साइज़ को संभाल लेते हैं, और एक ढंग का थ्री-वे मर्ज टूल वह करता है जो यह पेज बिल्कुल नहीं कर सकता।
एन्कोडिंग बदलना, या Unicode नॉर्मलाइज़ करना। ये पेज पढ़ते और बताते हैं; एन्कोडिंग के बीच कन्वर्ट नहीं करते। iconv हर मौजूद एन्कोडिंग के बीच कन्वर्ट करता है, file कमांड अंदाज़ा लगाती है कि आपके पास क्या है, और Unicode नॉर्मलाइज़ेशन Python की एक लाइन या ICU के uconv की एक कॉल है। अगर आप बिगड़े अक्षरों वाला एक्सपोर्ट ठीक कर रहे हैं, तो यही टूलचेन है।
बार-बार दोहराया जाने वाला कोई भी काम। ये टूल तभी चलते हैं जब कोई व्यक्ति क्लिक करता है। चार सौ डॉक्यूमेंट के शब्द गिनना, या हर कमिट पर किसी डायरेक्टरी को मिनिफ़ाई करना, स्क्रिप्ट या बिल्ड स्टेप का काम है — और ख़ास तौर पर मिनिफ़ाई करने के लिए, आपका बिल्ड टूल वही मिनिफ़िकेशन करता है, सोर्स मैप, वॉच मोड और कैशिंग के साथ, जो कोई पेस्ट बॉक्स नहीं दे सकता। यह पेज उस एक फ़ाइल के लिए है जो आपके सामने है।
आधुनिक CSS। “CSS मिनिफ़ाई करें” नेटिव नेस्टिंग और आधुनिक मीडिया रेंज सिंटैक्स को मिनिफ़ाई करने के बजाय मना कर देता है, क्योंकि इसके पीछे का मिनिफ़ायर इन दोनों से पुराना है और जो नहीं समझता उसे चुपचाप हटा देता है। यह कोई फ़ीचर नहीं, एक ईमानदार इनकार है, और इसका हल है पहले Sass, PostCSS या Lightning CSS से नेस्टिंग को कंपाइल करके हटाना — जो आपका बिल्ड टूल लगभग निश्चित रूप से पहले से करता है।
एक जैसे सुनाई देने वाले टूल्स में से कैसे चुनें
शब्द गिनें (वर्ड काउंटर) बनाम अक्षर गिनें (कैरेक्टर काउंटर)। गिनती वही, मुख्य आंकड़े अलग। वर्ड काउंटर सबसे पहले शब्द, वाक्य, पैराग्राफ़ और पढ़ने का समय दिखाता है, जिनमें निबंध, लेख या भाषण मापे जाते हैं। कैरेक्टर काउंटर सबसे पहले कैरेक्टर, बिना स्पेस के कैरेक्टर और UTF-8 बाइट दिखाता है, जिनमें मेटा डिस्क्रिप्शन, SMS सेगमेंट या डेटाबेस फ़ील्ड मापे जाते हैं। अगर किसी चीज़ ने आपका टेक्स्ट बहुत लंबा होने की वजह से रिजेक्ट कर दिया, तो आपको कैरेक्टर वाला चाहिए, और ख़ास तौर पर उसकी बाइट गिनती।
टेक्स्ट की तुलना करें बनाम डुप्लिकेट लाइनें हटाएं। तुलना बताती है कि “इन दो वर्शन के बीच क्या बदला”, और उसे दो टेक्स्ट चाहिए। डुप्लिकेट हटाने वाला टूल एक सूची पर काम करता है और बताता है कि “इसमें क्या एक से ज़्यादा बार आया है”, और यह भी बताएगा कि कौन-सी एंट्री दोहराईं और कितनी बार, स्वाभाविक क्रम में सॉर्ट करेगा ताकि item2, item10 से पहले आए, या सिर्फ़ वे लाइनें रखेगा जो ठीक एक बार आईं। दो सूचियों में से किसी एक में ही मौजूद एंट्री ढूंढना डुप्लिकेट हटाने वाले टूल का काम है, तुलना वाले का नहीं।
HTML मिनिफ़ाई करें बनाम CSS मिनिफ़ाई करें बनाम JavaScript मिनिफ़ाई करें। तीन भाषाएं, तीन मिनिफ़ायर, और एक ओवरलैप जो जानने लायक है: HTML मिनिफ़ायर style ब्लॉक के अंदर की CSS और script ब्लॉक के अंदर की JavaScript को भी मिनिफ़ाई करता है, ठीक बाक़ी दो पेजों की तरह। इसलिए एक HTML फ़ाइल के लिए एक टूल चाहिए, तीन नहीं। अलग .css और .js फ़ाइलों के लिए उनके अपने पेज चाहिए।
“XML व्यूअर” बनाम “XML फ़ॉर्मैटर” और “XML वैलिडेटर”। यहां का व्यूअर आपको खोजबीन के लिए समेटा जा सकने वाला ट्री देता है, और डॉक्यूमेंट बड़ा हो और आप कुछ ढूंढ रहे हों, तब आपको यही चाहिए। डेवलपर टूल्स में मौजूद फ़ॉर्मैटर और वैलिडेटर आपको फ़ाइल में वापस पेस्ट करने लायक इंडेंट किया टेक्स्ट और गड़बड़ी की सटीक लाइन और कॉलम देते हैं। एक तरफ़ पढ़ना, दूसरी तरफ़ एडिट करना और ठीक करना।
“CSV व्यूअर” बनाम फ़ाइल को Excel में खोलना। यह कोई प्रतिद्वंद्वी टूल नहीं, लेकिन लोग असल में यही तुलना कर रहे होते हैं। Excel खोलते समय ही बदल देता है और पूछता नहीं: 00123 प्रोडक्ट कोड 123 बन जाता है, 5-3 पार्ट नंबर 5 मार्च बन जाता है, लंबा ऑर्डर नंबर साइंटिफ़िक नोटेशन बन जाता है, और किसी जर्मन सिस्टम का सेमीकोलन से अलग किया एक्सपोर्ट पूरा का पूरा कॉलम A में आ जाता है। व्यूअर हर वैल्यू को टेक्स्ट के रूप में दिखाता है, ठीक वैसे जैसे वह सेव है, ताकि आप देख सकें कि आपको असल में क्या भेजा गया था।
Markdown प्रीव्यू बनाम Markdown को PDF में बदलें। प्रीव्यू यह जांचने के लिए है कि README ठीक वैसे रेंडर होता है जैसे GitHub उसे रेंडर करेगा, आपके टाइप करते-करते। डॉक्यूमेंट टूल्स में मौजूद “Markdown को PDF में बदलें” पेज ब्रेक वाला तैयार डॉक्यूमेंट बनाने के लिए है। यहां जांचें, वहां पब्लिश करें।