کونسول میں دائیں سے بائیں متن
Text.js، Unicode Bidirectional Algorithm نافذ کرتا ہے اور BidiTest.txt کے تمام 770,241 ٹیسٹ کیسز پاس کرتا ہے۔ عبرانی اور عربی بصری ترتیب میں، عربی حروف کی شکل بندی کے ساتھ، سیل گرڈ کے مطابق رینڈر ہوتی ہیں۔
Text.js اب عبرانی، عربی، فارسی اور دائیں سے بائیں لکھے جانے والے دیگر رسم الخط درست ترتیب میں رینڈر کرتا ہے، عربی حروف کو جوڑتا ہے اور باقی سب کی طرح اسی سیل گرڈ پر دکھاتا ہے۔
import { Box, Text } from "@textjs/react";export default function Page() { return ( <Box flexDirection="column" padding={1}> <Text>שלום עולם! זהו טקסט בעברית.</Text> <Text>مرحبا بالعالم! هذا نص عربي.</Text> <Text>Order #1234 (<Text color="accent">שלום</Text>) total: 25.50 ₪</Text> <Text>user <Text dir="auto" color="success">שלום!</Text> replied 3 times</Text> </Box> );}ہر پیراگراف اپنے پہلے مضبوط حرف سے بنیادی سمت چنتا ہے، جیسے HTML میں dir="auto" کرتا ہے، اور دائیں سے بائیں پیراگراف دائیں جانب سیدھ میں آتے ہیں۔ نیسٹڈ <Text> پر dir اسی طرح span کو الگ کرتا ہے جیسے <bdi> کرتا ہے، اس لیے نامعلوم سمت والا صارف نام اپنے آس پاس کے متن کی ترتیب نہیں بدل سکتا۔
الگورتھم
دائیں سے بائیں سپورٹ Unicode Bidirectional Algorithm (UAX #9، Unicode 18.0) کا نفاذ ہے، جسے @textjs/core میں ابتدا سے لکھا گیا ہے۔ یہ ہر پیراگراف کے لیے ایمبیڈنگ لیول طے کرتا ہے، جن میں واضح ایمبیڈنگز اور آئسولیٹس، کمزور اور غیر جانب دار اقسام اور بریکٹ کے جوڑے شامل ہیں۔ پھر ہر لپٹی ہوئی سطر کی ترتیب الگ سے بدلی جاتی ہے، اور دائیں سے بائیں لیول پر آئینہ نما حروف بدلتے ہیں، اس لیے عبرانی کے اندر (abc)، (abc) ہی رہتا ہے۔
Unicode اس الگورتھم کے لیے مطابقت کی جانچ کی دو فائلیں شائع کرتا ہے۔ دونوں ریپوزٹری میں gzip سے کمپریس کرکے رکھی گئی ہیں، اور ٹیسٹ سوئٹ ہر کیس چلاتا ہے:
BidiTest.txtان پٹس کو bidi کلاسوں کی ترتیبوں کے طور پر درج کرتی ہے، ہر ترتیب کے ساتھ وہ پیراگراف سمتیں بھی ہیں جن پر وہ لاگو ہوتی ہے۔ Text.js تمام 770,241 کیس پاس کرتا ہے۔BidiCharacterTest.txtاصل سٹرنگز کو متوقع لیول اور ترتیب کے ساتھ درج کرتی ہے۔ Text.js تمام 91,707 پاس کرتا ہے۔
for (const [bit, dir] of [[1, -1], [2, 0], [4, 1]] as const) { if ((bitset & bit) === 0) continue; cases++; const r = run(types, null, dir); const gotLevels = fmtLevels(r.levels); const gotOrder = r.order.join(" "); if (gotLevels !== levels || gotOrder !== reorder) { if (failures.length < 20) failures.push(`${input.trim()} [dir ${dir}]: levels ${gotLevels} (want ${levels}), order ${gotOrder} (want ${reorder})`); else failures.push(""); }}منطقی ترتیب سے سیل تک
دائیں سے بائیں متن کی ایک سطر کونسول تک پہنچنے سے پہلے چار مرحلوں سے گزرتی ہے:
- منطقی ترتیب میں لپیٹنا۔ سیل کی چوڑائی کے مطابق سطریں وہیں ٹوٹتی ہیں جہاں بائیں سے دائیں متن کی سطریں ٹوٹتیں۔
- ہر سطر کی ترتیب بدلنا۔ طے شدہ لیول سطر کے گرافیمز کی ڈسپلے ترتیب طے کرتے ہیں۔
- عربی کی شکل بنانا۔ حروف اپنی سیاقی شکلیں (الگ، ابتدائی، درمیانی، آخری) Arabic Presentation Forms بلاکس سے لیتے ہیں۔ ایک حرف ایک سیل ہے، اور لفظ کے بیچ کرسر یا رنگ کی تبدیلی سے جڑی ہوئی شکلیں برقرار رہتی ہیں۔
- ترتیب کو مقرر رکھنا۔ سیل اب گلفس کو ڈسپلے ترتیب میں رکھتے ہیں۔
آخری مرحلہ اس لیے ہے کہ DevTools متن پر دوبارہ bidi چلا کر اسے پھر الٹ دے گا۔ %c اسٹائل اسے بند نہیں کر سکتا، کیونکہ DevTools کا سینیٹائزر direction اور unicode-bidi کو ہٹا دیتا ہے۔ اس لیے ڈرائیور دائیں سے بائیں حروف والے ہر span کو LRO اور PDF (U+202D اور U+202C) میں لپیٹتا ہے، جو عین وہی مواد بائیں سے دائیں دکھانے پر مجبور کرتے ہیں جو سیل میں موجود ہے۔
آدھے سیل کا انحراف
SF Mono اور Menlo دونوں میں عبرانی یا عربی گلفس نہیں ہیں، اس لیے براؤزر ہر حرف کے لیے متبادل فونٹ استعمال کرتا ہے۔ macOS پر یہ Courier New ہے، جو مونو اسپیسڈ بھی ہے، اور 12 px پر اس کے ہر گلف کی چوڑائی 7.2012 px ہے، جبکہ Menlo کی 7.2246 px ہے۔ یہ 0.3% کم چوڑا ہے، جو عبرانی کی پوری قطار کو تقریباً آدھے سیل تک کھسکانے کے لیے کافی ہے۔
CssConsoleDriver کونسول فونٹ میں کینوس کے ساتھ ہر دائیں سے بائیں span کی پیمائش کرتا ہے، جو DevTools جیسا ہی Blink فونٹ فال بیک استعمال کرتا ہے، اور LayoutUnits (1/64 px) میں عین فرق کے مطابق span میں پیڈنگ شامل کرتا ہے۔ ہر span کی چوڑائی اتنی ہی ہو جاتی ہے جتنی ان گرڈ سیل کی جن پر وہ پھیلا ہے۔ کسی span کو زیادہ سے زیادہ آدھے سیل تک اندر کھینچا جاتا ہے، اس لیے بہت زیادہ چوڑا متبادل فونٹ اگلے span پر چڑھنے کے بجائے باہر نکلتا ہے۔
bun bench/devtools/bidi-shot.ts کمانڈ اصل DevTools فرنٹ اینڈ میں عبرانی، عربی، مخلوط اور عبرانی میں ایموجی والی سطروں کے 64×21 فریم پر نتیجے کی پیمائش کرتی ہے:
| فریم | قطاروں میں دائیں کنارے کا انحراف |
|---|---|
| ترتیب مقرر کیے بغیر لاگ کیے گئے سیل | 14.5 px |
| ترتیب مقرر، چوڑائی کی فٹنگ کے بغیر | 2.22 px |
| جاری کردہ ڈرائیور | 0.156 px |
کنٹرول: ہر RTL گلف کی جگہ x | 1.67 px |
کنٹرول وہی فریم ہے جس میں لاطینی متن ہے۔ جاری کردہ ڈرائیور کنٹرول سے بہتر سیدھ بناتا ہے کیونکہ دائیں سے بائیں spans کے اندر ایموجی کی فٹنگ بھی ان کے ساتھ ہوتی ہے۔
بائیں سے دائیں متن میں کوئی تبدیلی نہیں
دائیں سے بائیں حروف کے بغیر متن ان تمام مراحل سے نہیں گزرتا۔ یہ جانچ گرافیمز کی تقسیم کے دوران ہوتی ہے، ہر گرافیم کے لیے ایک موازنہ، اور خالص بائیں سے دائیں متن پہلے والے ہی راستے سے پینٹ ہوتا ہے، اس لیے اس کے کونسول فریم بائٹ بہ بائٹ یکساں ہیں۔
دائیں سے بائیں متن کی سپورٹ Text.js 1.0 میں شامل ہے۔ بین الاقوامی زبانوں کی سپورٹ میں ان پٹ، ایڈیٹنگ، ٹرمینلز اور API کی تفصیل ہے۔