Редактирането на текст ви ненавижда

Оригиналът е на Robert Lord

Най-четени

Даниел Десподов
Даниел Десподов
Новинар. Увличам се от съвременни технологии, информационна безопасност, спорт, наука и изкуствен интелект.

През далечната 2017 година разработвах интерактивен текстов редактор, който работи в средата на браузъра. Неудовлетворен от съществуващите програмни библиотеки в ContentEditable си помислих: „Защо пък да не си направя от нулата функцията за маркирането на текст? Едва ли е много сложно„. Бях млад. Наивен. Направих си сметката, че ще се справя за две седмици. Всъщност опитът да реша този проблем ми отне няколко години от моя живот, включително една година платена работа, когато работих от сутрин до вечер върху разработването на нов текстов редактор за нова операционна система.

В компанията, където работя, успях много да разбера от по-опитните от мен в тази област. Чух твърде много страшни истории. Включително тази за специалиста, който поддържал приложение за Windows със собствена реализация на текстовото поле. В крайна сметка пожелах да се прехвърля от остарелия API за въвеждане на текст към по-новата версия. Ето го и списъка с интерфейсите за въвеждането на текст в тази нова версия:

Редактирането на текст ви ненавижда

Точно така: 128 интерфейса за въвеждане на текст. Сигурен съм, че има още 8 различни типа блокажи за премахване проблемите на паралелната работа, но не прочетох тази документация. Въпросният специалист от година и половина (на пълен работен ден!) довършваше своя текстов редактор, но не успя и си остана със стария API.

Въвеждането на текст е наистина сложно. Да разгледаме някои основни положения.

Вертикалното преместване на курсора в текстовите редактори

В показания тук пример, ако натиснем стрелка нагоре, то курсорът ще се измести в началото на реда, преди думата hello. Дотук всичко е съвсем разумно. Но ако натиснем първо нагоре, а след това надолу, курсорът първо ще отиде пред hello, а след това ще застане след some.

Редактирането на текст ви ненавижда

Това някак не изглежда логично. Може би ще запитате, защо отива надясно? Е, при вертикалното преместване, всеки курсор запомня позицията Х в пиксели, която се обновява само при движение наляво и надясно, а не нагоре и надолу. И в този случай е запомнена позицията на курсора между буквите h и i на думата this на първия ред. Когато натиснем стрелката надолу курсорът застава на същата хоризонтална позиция, която на втория ред се пада точно след some.

Същото е поведението на курсора при движението му наляво и надясно при къси редове.

Афинитетът

Добре, вече се досетихме, че при маркирането на текст са ни необходими два фрагмента на състоянието: байтовото изместване в рамките на реда и координатата Х в пиксели, която показахме по-горе. Това достатъчно ли е? Не.

Да погледнем две позиции на курсора при един много дълъг ред.:

Редактирането на текст ви ненавижда

Тъй като loooooooooong е една дума, двете позиции на курсора имат съвсем еднакво байтово изместване в реда. Между тях няма символ за нов ред и в самия ред се осъществява мек пренос. Тоест, на тези две позиции на курсора е необходим допълнителен байт, който да покаже на кой ред трябва да се осъществи преноса. В повечето текстови системи този байт се нарича афинитет (affinity). Той се използва в смесения в две направления текст, например английски плюс арабски, за което след малко ще поговорим.

Модификаторите на емоджитата

Да си представим, че изпращам съобщение на някой приятел. За да изразя по-добре чувствата си, искам да добавя забавен емотикон. Въвеждам в текстовото поле вдигнат нагоре палец, буква и модификатора на емоджито за тона на кожата. Това изглежда по следния начин:

Редактирането на текст ви ненавижда

Къде гледам, не исках да въвеждам буква! Слагам курсора точно след нея и натискам Backspace. Какво ще стане? Вариантите са няколко в зависимост от редактора:

Редактирането на текст ви ненавижда

Лош вариант №1 може да ви се стори правилен. Но така работят текстовите редактори с поддръжката на остарялото рендиране на емоджитата, като например Sublime Text. Това е лошо понеже емоджито на светлия палец се кодира като жълт палец, след който следва модификатора за цвета на кожата. Дори и ако копирам светъл палец от друго място, той пак ще се изобрази неправилно, точно като тук

Лош вариант №2 – това го прави Chrome 77 в адресния ред. Не в уеб страниците, а само в адресния ред. Това не е проблем на рендирането, понеже копирането и поставянето на емоджи с тона на кожата работи. Вместо това Chrome изтрива буквата, но след като забележи идентификатора след нея, изтрива и него. Опа.

Лош вариант №3 съответства на спецификациите на уникод и емоджито изглежда добре. Но това е твърде неразбираемо за потребителите и между другото, трябва да се премести курсора, за да не заседне на половината път между емоджито и идентификатора за цвят.

Всички варианти са лоши и може би сте предположили, че има някакъв четвърти вариант. Има! Много текстови редактори като например TextEdit дори не позволяват да се постави курсора след буквата, тъй като модификаторът за цвета на кожата се разглежда като едно цяло с предишния символ. Това има смисъл в контекста с емоджито и дори добре работи в този случай. Но какво ще стане, ако емотиконът е първият символ в първия ред?

Редактирането на текст ви ненавижда

Сега модификаторът променя символа на новия ред. TextEdit не позволява да се постави курсора в началото на втория ред! Лично аз считам това решение за съвсем, лошо.

Може би забелязахте, че вдигнатият нагоре палец сега сочи надолу. Това го направих аз, за да покажа своите чувства по повод тази ситуация.

Между другото TextEdit явно нарочно прави курсора на първия ред ужасно бъгав. Познайте например, какво ще стане, ако при следната ситуация натисна 4.

Редактирането на текст ви ненавижда

Да. Можете да си помислите, че между символите има спейсове. Няма такова нещо.

Двупосочният текст

Вижте как изглежда маркирането на текст при TextEdit в смесен двупосочен текст, в който има думи на английски и арабски език:

Редактирането на текст ви ненавижда

В това има смисъл, понеже арабският език в редовете текст се записва отдясно наляво, така че това маркиране на текст изглежда логично. На екрана може да се вижда, че маркирането е разделено, но по байтове това е един непрекъснат диапазон.

Ето защо е доста учудващо, че можем да видим следното маркиране на текст:

Редактирането на текст ви ненавижда

Да, това е визуално непрекъснато, но разделно по байтове маркиране на текст. Не е добре. Така правят някои текстови редактори, когато маркирането на текст става с клавишите на клавиатурата вместо с мишката. Може би алтернатива би била да се използват по друг начин клавишите за маркиране на текст и когато имаме например арабски език, десният да се използва за маркиране наляво – не, не е решение. Тук няма приемливи варианти.

Като бонус, опитайте се да разберете какво става тук:

Редактирането на текст ви ненавижда

Вижте какво е станало… дори не искам да коментирам.

Проблемите с методите на въвеждане

Софтуерът, който преобразува натискането на клавиш във въвеждане на символ се нарича “метод на въвеждане”. За латинската азбука това е един съвсем безинтересен софтуер, понеже всяко натискане на клавиш директно се съпоставя с един единствен символ. Но в редица писмености всичките символи на техните азбуки не могат да се съберат в обикновената клавиатура и се налага да се използва нещо по-творческо. В китайския език например, често се използва фонетичното описание на звук от думата, след което се появява списък с подобни по звучене йероглифи:

Редактирането на текст ви ненавижда

Появяващото се поле се нарича “композиционна област” (composing region) и най-често се появява под подчертания текст. Често пъти методът на въвеждане трябва да я стилизира. Така например, методът за въвеждане на японски език при ОС Android използва цвета на фона за създаване на област за разделяне на предложенията:

Редактирането на текст ви ненавижда

Дали маркирането ще работи с всички тези методи на въвеждане и композиционни области, когато имаме двупосочен текст? По-добре да не се замисляме за това.

Методите на въвеждане трябва да работят навсякъде, дори и в терминала:

Редактирането на текст ви ненавижда

Нищо няма да отиде към Vim, докато не бъде избран съответния китайски йероглиф от предложения списък. Навярно вече се питате “как ли ще работи това, когато Vim не е стартиран в терминала?”. Не работи добре. Ето защо в интернет въвеждането на текст и натискането на клавиш са отделни събития. В терминала или командния ред те са смесени и създават проблеми.

Това е само един пример от многобройните различни начини за въвеждане на текст. Не бива да забравяме и методите за въвеждане без клавиатура – чрез глас или чрез ръкописен текст. За щастие операционната система ни предоставя всички тези методи. Само че за съжаление вашето текстово поле трябва да съответства на общия протокол за въвеждане на текст, в който са предвидени всички тези методи. За Windows това са именно тези 128 интерфейса, за които споменахме в началото на статията. В другите операционни системи интерфейсите са по-опростени, но също не са лесни за реализиране.

Вероятно сте се досетили, че въвеждането на текст става в рамките на отделен процес. Ясно е, че в текстовото поле могат да правят промени както различните методи на въвеждане, така и самото приложение. На практика това е един паралелен протокол за редактирането на текст. За да избегне възникването на проблеми Windows използва осем (8!) вида блокировки. Другите платформи използват евристика, за да избегнат проблемите на паралелизма. Или се надяват да не се случи нещо съвсем лошо. Но според мен молитвите не са много ефикасни срещу проблемите в паралелизма.

Защо е толкова сложно?

Популярният Джонатан Блоу в лекциите си за деградирането на софтуера споменава текстовия редактор на Кен Томпсън, написан за една седмица. По-голямата част от кода е случайно внесена сложност. Наистина ли Windows има нужда от 128 интерфейса и 8 вида блокировки при въвеждането на текст? В никакъв случай. Наистина ли грешките на TextEdit са резултат от твърде сложния модел за редактиране? Да. Трябва ли да се безпокоим от купищата бъгове в съвременните програми? Според мен да.

Само че текстовият редактор на Кен Томпсън бе много и много по-опростен в сравнение с това, което очакваме от днешните текстови редактори. Уникод поддържа почти всички живи езици в света (те са около 7000) и още редица мъртви. Има най-различни писмености, с различни посоки на текста и методи на въвеждане, всяка от които налага сложни и често пъти нерешими ограничение на който и да било текстов редактор. А той трябва да поддържа дори и четене от екрана!

Неизбежно е натрупването на огромна сложност. Дотук само се докоснахме до този проблем. Истинско чудо на програмирането е, че можем просто да цопнем <textarea> в уеб страницата и мигновено да осигурим въвеждането на текст за всеки интернет потребител от произволна точка на света.

АбонаментВсичко важно от света на технологиите, директно в пощата ти.

С абонирането приемате нашите Условия и Политика за поверителност. Може да се отпишете с един клик по всяко време.


Коментирайте статията в нашите Форуми. За да научите първи най-важното, харесайте страницата ни във Facebook, и ни последвайте в Google Новини, TikTok, Telegram и Viber или изтеглете приложението на Kaldata.com за Android, iPhone, Huawei, Google Chrome, Microsoft Edge и Opera!

8 Коментара
стари
нови оценка

Нови ревюта

Подобни новини