Unicode - není to jednoduché

Zde můžete volně diskutovat o programu Altap Salamander. Ptejte se, odpovídejte a vyjadřujte své názory. Prosíme, nevkládejte sem hlášení problémů či návrhy na nové funkce.
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Unicode - není to jednoduché

Post by zarevak »

Původně jsem tento příspěvek chtěl napsat do jednoho z vláken, které tu řeší vývoj Salamandera, ale pak narostl, tak raději zakládám vlastní vlákno. Problematiku Unicode a jeho složitosti jsme tady řešili před lety. Mezitím vývoj Unicode pokročil a já získal nové zkušenosti (Osobně jsem psal editor využívající API Uniscribe a ani to nestačí na podchycení všech okolností...)

Pokusím se trochu nastínit, co je součástí Unicode a co je nutné vzít v potaz. Rozhodně to není tak jednoduché, jak si představujeme. Tímto však nechci říct, že Salamander musí podporovat všechny záležitosti, je však dobré o nich vědět a zaujmout k nim nějaké stanovisko.


1) Když zůstaneme u češtiny, tak narážíme na to, že jeden znak lze zapsat několika způsoby:
Ř = U+0158 LATIN CAPITAL LETTER R WITH CARON
Ř = U+0052 LATIN CAPITAL LETTER R, U+030C COMBINING CARON

- při zobrazení čekáte, že se oba způsoby zobrazí stejně
- při hledání čekáte, že oba způsoby budou ekvivalentní (a to ještě nepočítám hledání s ignorováním malých a velkých písmen)
- při řazení čekáte, že oba způsoby budou ekvivalentní
- pro Vietnamštinu a Korejštinu je toto obzvláště důležité


2) Určitě jste si všimli, že v poslední době náš život doprovází emotikony a ty se také staly součástí Unicode:
😀 = U+1F600 GRINNING FACE
🇨🇿 = U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C, U+1F1FF REGIONAL INDICATOR SYMBOL LETTER Z (vlajka České republiky)
👶🏿 = U+1F476 BABY, U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (dítě tmavé pleti)
👩🏿‍🤝‍👨🏻 = U+1F469 WOMAN, U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6, U+200D ZERO WIDTH JOINER [ZWJ], U+1F91D HANDSHAKE, U+200D ZERO WIDTH JOINER [ZWJ], U+1F468 MAN, U+1F3FB EMOJI MODIFIER FITZPATRICK TYPE-1-2 (paní tmavé pletí drží za ruku pána světlé pleti)
🏴󠁧󠁢󠁳󠁣󠁴󠁿 = U+1F3F4 WAVING BLACK FLAG, U+E0067 TAG LATIN SMALL LETTER G, U+E0062 TAG LATIN SMALL LETTER B, U+E0073 TAG LATIN SMALL LETTER S, U+E0063 TAG LATIN SMALL LETTER C, U+E0074 TAG LATIN SMALL LETTER T, U+E007F CANCEL TAG (vlajka Skotska)

- barevné znaky myslím umí až Windows 10 a zmíněný Uniscribe na to nestačí (DirectWrite už ano)
- k tomu, abyste správně složili některé sekvence potřebujete je znát - součástí Unicode standardu je seznam všech povolených


3) RTL jazyky přináší do Unicode jednu z nejšílenějších záležitostí, co může být (Unicode bidirectional algorithm).
- některé znaky jsou LTR (latinka)
- některé znaky jsou RTL (hebrejština, arabština)
- některé znaky jsou slabě LTR (římské číslice)
- některé znaky se řídí tím, kde se zrovna nachází
- některé znaky mění tvar podle toho, zda jsou v RTL nebo LTR sekvenci
- existují znaky na změnu z RTL na LTR a opačně (U+200E LEFT-TO-RIGHT MARK [LRM], U+200F RIGHT-TO-LEFT MARK [RLM])
- označení kusu texty v kombinovaném textu vypadá pro nás chaoticky:
‏بعد 14 يناير 2020، لن توفر Microsoft التحديثات الأمنية أو الدعم التقني لأجهزة الكمبيوتر التي تعمل‎
--- (tento text je špatně! protože je text v LTR bloku a přestože jsem použil RLM a LRM, tak jsou slova přeházena :( )


4) Některé jazyky jsou ještě více citlivější na tvar znaků a jejich ovlivnění znaky v okolí.
- Arabština je "jednoduchá"
- Dévanágarí (používá například hindština ~350 milionů lidí) je značně složitější:
क् = [ka क - U+0915 DEVANAGARI LETTER KA] [virāma ् - U+094D DEVANAGARI SIGN VIRAMA]
क्‍ = [ka क - U+0915 DEVANAGARI LETTER KA] [virāma ् - U+094D DEVANAGARI SIGN VIRAMA] [U+200D ZERO WIDTH JOINER [ZWJ]]
क्ष = [ka क - U+0915 DEVANAGARI LETTER KA] [virāma ् - U+094D DEVANAGARI SIGN VIRAMA] [ṣa ष - U+0937 DEVANAGARI LETTER SSA]
क्‍ष = [ka क - U+0915 DEVANAGARI LETTER KA] [virāma ् - U+094D DEVANAGARI SIGN VIRAMA] [U+200D ZERO WIDTH JOINER [ZWJ]] [ṣa ष - U+0937 DEVANAGARI LETTER SSA]


5) Co se týče karetu (textového kurzoru), tak je nutné rozlišovat mezi "znakem", "symbolem" a "pozicí ve stringu (codepoint)"
- počet pozic ve stringu vůbec nesouvisí s délkou řetězce z pohledu jazyka. Již jsem uvedl příklad, kdy Ř bylo uloženo jako dvě pozice (R a háček)
- jeden symbol (glyf) může obsahovat více znaků z hlediska jazyka. V latince se týká například:
fi = U+FB01 LATIN SMALL LIGATURE FI
… = U+2026 HORIZONTAL ELLIPSIS
- zatímco v latince je toto neobvyklé v jiných jazycích je vazba mezi znaky a pozicemi ve stringu mnohem volnější


6) Podobně jako v bodě 1) jsou některé znaky z hlediska jazyka stejné, přestože vypadají jinak a to je nutné zohlednit při řazení a hledání:
Z = U+005A LATIN CAPITAL LETTER Z
Z = U+FF3A FULLWIDTH LATIN CAPITAL LETTER Z
𝐙 = U+1D419 MATHEMATICAL BOLD CAPITAL Z
𝖹 = U+1D5B9 MATHEMATICAL SANS-SERIF CAPITAL Z


7) A to jsme se ještě nedostali k problematice neplatných sekvencí
- UTF-8 a UTF-16 jsou náchylné na chyby již na úrovni dat, kdy se může stát, že sekvence nelze převést na číslo Unicode znaku.
--- Jak se s tím vypořádat? Z hlediska účelu vieweru by bylo podle mne nevhodné nějaká data přeskočit.
--- Je nutné pak dekodér sesynchronizovat (naštěstí UTF-8 i UTF-16 mají jasné, které byte/word jsou první a které následující)
- pokud už dekódujeme čísla znaků, tak na úrovni Unicode jsou některé symboly definovány sekvencí, která nemusí být platná.
--- třeba vlajky států jsou kódované pomocí právě dvou znaků "REGIONAL INDICATOR SYMBOL" a jen některé kombinace mají smysl. Ostatní se musí zobrazit nějakým alternativním způsobem.


8 ) Zalamování textu je další kapitola. V mnoha jazycích se používají mezery mezi slovy a tak není tak velký problém text zalomit v mezeře za slovem. Ale třeba v čínštině mezery v textu nenajdeme. Algoritmus, který zalamuje na základě mezer tak selže. "Naštěstí" je v Unicode pro každý znak definováno, zda je možné zalomit text před ním či za ním. Při nedávném testování jsem však narazil na to, že ani známé textové editory některé situace neřeší správně.
A pak přijde thajština, kterou raději neřeší ani Unicode standard, protože nepoužívá mezery a zalomit je možné jen mezi slabikami, takže je nutné provést sémantickou analýzu textu...


9) Někdy se stane, že je potřeba zobrazit jen část textu, a tak je nutné ho oříznout. Teď už víme, že mnoho znaků je složeno z více pozic v řetězci a tak nelze jednoduše odřezávat pozice odzadu dokud se text nevejde, protože to změní význam nebo vytvoří blbost. Zkracovací algoritmus by tak měl odřezávat spíše po symbolech než po znacích.


10) Fonty - když už máme nějaký Unicode znak, který chceme zobrazit, tak potřebujeme font, pomocí kterého ho nakreslíme. Neexistuje žádný font, který obsahuje všechny znaky (pokus Arial Unicode MS ukázal, že to ani nelze).
- musíme tedy text skládat z několika fontů a napasovat je k sobě tak, aby to vypadalo rozumně
- ne každý font se hodí k druhému - například BabelPad tak nabízí velký konfigurační dialog, kde každému Unicode bloku můžete určit vlastní font
- ani když poskládáme veškeré fonty v systému, tak nezískáme 100% pokrytí Unicode
- pro potřeby Vieweru je tedy nutné chybějící znaky zobrazit nějak alternativně (osobně bych rád viděl kód znaku místo pověstného čtverečku)


Osobní komentář:
- Zobrazení Internal Viewer: Vzhledem k tomu, jakým způsobem používám Internal Viewer (analýza dat souborů), tak by mi vyhovovalo, kdyby jednoduše zobrazil jeden symbol pro každou pozici ve stringu (codepoint). Tedy Ř uložené pomocí dvou znaků by se mi zobrazilo jako dva symboly. Šílené řetězce znaků, které jsem zde v příkladech uvedl, by se zobrazily rozloženě po jednotlivých znacích. Chyby v samotném kódování bych zobrazil speciálně zvýrazněné. Neplatné sekvence Unicode znaků se nemusí řešit, protože je zde každý znak za sebe...
--- Tento způsob by však mohl být asi dost matoucí pro ne-latinkové jazyky, kdy jednotlivé části znaku nemusí vypadat jako části složeného symbolu (například Dévanágarí, Arabština, …). BabelPad toto řeší přepínačem "Simple Rendering"/"Complex Rendering"
- Zobrazení v panelu: Zde bych naopak uvítal plnou podporu Unicode, protože nechci luštit, jaký je skutečný název souboru na základě komponent symbolů.
- Hledání: Tady by se hodila logika, která by umožnila najít všechny varianty znaků řetězce, které jsou sémanticky shodné nezávisle na to, jakým způsobem jsou uloženy. Při nalezení by se ve Vieweru pak označil odpovídající počet znaků který v souboru kóduje hledaný řetězec.
- Řazení v panelu: S tímto snad pomohou Windows, protože již pro aktuální Locale nabízejí funkce pro porovnání dvou Unicode řetězců, které by měly brát v potaz veškerá pravidla řazení v daném Locale.
Raptor

Re: Unicode - není to jednoduché

Post by Raptor »

Diky za summary. Je toho hodne.

Ale jak sam na konci rikas - opravdu je nutno to podporovat a umet na 100%? Porad se nabizi takove to srovnani - umi tohle vse i Total Commander? Pokud ano, pak nemam co dodat. Pokud ne, tak jak slozite je udelat to, co umi on?

Mi pije krev jedna vec - nemoznost si zobrazit ani hloupy utf-8 soubor. Nepotrebuji unicode jako takove. Nezobrazuji cinstinu, ani azbuku. Ano, jini treba ano. Ale fakt by stacila podpora pro zakladni kodovani a pak klidne pridavat dalsi.

Co se tyka upravy core, aby fungovalo hledani a zobrazovani... ano, to je asi uz tezsi. Ale jde to, ne? Za tech 10 let slibovani uz to mohlo byt nejak hotovo. Ale ono je to uz asi jedno. Existuji jine managery, co to umi. Holt se neda nic delat.
-=Majkl=-
Posts: 80
Joined: 12 Dec 2005, 14:51
Location: Brno, Czech Republic
Contact:

Re: Unicode - není to jednoduché

Post by -=Majkl=- »

zarevak wrote: 04 Jul 2019, 02:53 1) Když zůstaneme u češtiny, tak narážíme na to, že jeden znak lze zapsat několika způsoby:
Ř = U+0158 LATIN CAPITAL LETTER R WITH CARON
Ř = U+0052 LATIN CAPITAL LETTER R, U+030C COMBINING CARON

- při zobrazení čekáte, že se oba způsoby zobrazí stejně
- při hledání čekáte, že oba způsoby budou ekvivalentní (a to ještě nepočítám hledání s ignorováním malých a velkých písmen)
- při řazení čekáte, že oba způsoby budou ekvivalentní
Uživatel sice očekává, ale neměl by očekávat. Pak by se z toho programátor mohl zbláznit. Uživatel má prostě smůlu, přece nemůžu řešit tohle všechno za uživatele, třeba ta Vietnamština se dá díky bohaté diakritice (tónům) zapsat mnoha způsoby s různým pořadím modifikátorů. Stejně tak za uživatele nebude vývojář řešit podobnost pomlčky, spojovníku a znaku minus, mezery, nedělitelné mezery, znaku s kódem 255 a kdoví, čím ještě, nebo třeba typograficky správně napsanými uvozovkami a znakem pro stopu.
Raptor wrote: 04 Jul 2019, 07:54 Mi pije krev jedna vec - nemoznost si zobrazit ani hloupy utf-8 soubor. Nepotrebuji unicode jako takove. Nezobrazuji cinstinu, ani azbuku. Ano, jini treba ano. Ale fakt by stacila podpora pro zakladni kodovani a pak klidne pridavat dalsi.
Nebo nemožnost otevřít adresář, který má v názvu nějaký znak mimo aktuální znakovou sadu.

Není potřeba zobrazit přesně danou vlajku, emotikonu se správně modifikovanou barvou pleti. To neřeší Explorer, TC ani třeba Multi Commander, který jsem kvůli tomu teď vyzkoušel. Zobrazí jen zjednodušené černobílé ikonky (černá vlajka místo skotské, nějaký obličej ze základní sady, atd.)
Jan Rysavy
ALTAP Staff
ALTAP Staff
Posts: 5229
Joined: 08 Dec 2005, 06:34
Location: Novy Bor, Czech Republic
Contact:

Re: Unicode - není to jednoduché

Post by Jan Rysavy »

Určitě je to o nastavení míry kompromisů. Možná by k problému šlo přistupovat kvantitativně - kolik stovek miliónů lidí odřízneme, pokud danou vlastnost Unicode nepodoříme. S ohledem na freeware licenci již tržní potenciál dané skupiny nemá smysl brát v potaz.
Slanec
Posts: 66
Joined: 17 Nov 2009, 19:00

Re: Unicode - není to jednoduché

Post by Slanec »

Pro některé jazyky a znaky neplatí, že by se daly jednoznačně převést na malé/velké písmenko: https://www.b-list.org/weblog/2018/nov/26/case/.

Jinak samozřejmě, základní krok je alespoň zobrazovat to, co 90% západního světa bude stačit. Pak se dají přidávat kontinenty a/nebo komplikovanější Unicode vlastnosti.
User avatar
tukanos
Posts: 410
Joined: 21 Dec 2005, 19:14

Re: Unicode - není to jednoduché

Post by tukanos »

Domnívám se, že autoři měli začít s transformací na unicode pomalu po malých krůčcích. (vím, ne vždy to jde tak jednoduše, ale občas ano). A postupně přepisovat některé funkcinality postupně. Pokud se jim nahromadí takové množství legacy kódu bývá velmi těžké to refaktorovat nějak rozumně.
Jan Rysavy
ALTAP Staff
ALTAP Staff
Posts: 5229
Joined: 08 Dec 2005, 06:34
Location: Novy Bor, Czech Republic
Contact:

Re: Unicode - není to jednoduché

Post by Jan Rysavy »

Autoři začali minimalistickou cestou - převedením pouze jádra. Do/Z pluginů zatím Unicode neprocházel. Ale i to je veliká úloha. Společně s podporou pro dlouhé cesty jde o velký zásah do funkcí pro práci s cestami. Například v rekurzivních funkcích již není možné uložit cesty na stacku, nevejdou se, atd.
User avatar
tukanos
Posts: 410
Joined: 21 Dec 2005, 19:14

Re: Unicode - není to jednoduché

Post by tukanos »

Jan Rysavy wrote: 07 Jul 2019, 18:34 Autoři začali minimalistickou cestou - převedením pouze jádra. Do/Z pluginů zatím Unicode neprocházel. Ale i to je veliká úloha. Společně s podporou pro dlouhé cesty jde o velký zásah do funkcí pro práci s cestami. Například v rekurzivních funkcích již není možné uložit cesty na stacku, nevejdou se, atd.
Otázkou je jestli spojovat ten unicode vůbec s problematikou dlouhých cest. To je obrovský samostatný úkol, který není ještě pořádně podporovaný ani od Microsoftu.
možné uložit cesty na stacku
Tak to určitě nepotěší. To věřím, že je bude velmi pracné.
Jan Rysavy
ALTAP Staff
ALTAP Staff
Posts: 5229
Joined: 08 Dec 2005, 06:34
Location: Novy Bor, Czech Republic
Contact:

Re: Unicode - není to jednoduché

Post by Jan Rysavy »

Přišlo nám logické to spojit, protože se změna dotýká stejných míst, tedy operací nad cestami. Pokud bychom věc řešili dvoufázově, celé bychom to studovali, upravovali, testovali 2x. Možná to nebylo správné rozhodnutí, ale na začátku nám to tak připadalo. A během implementace to také vypadalo OK.

Zároveň jsme zapouzdřili do metod funkcionalitu, která byla dříve roztroušena na více místech, takže takový jarní úklid.
User avatar
tukanos
Posts: 410
Joined: 21 Dec 2005, 19:14

Re: Unicode - není to jednoduché

Post by tukanos »

Jan Rysavy wrote: 07 Jul 2019, 19:50 Přišlo nám logické to spojit, protože se změna dotýká stejných míst, tedy operací nad cestami. Pokud bychom věc řešili dvoufázově, celé bychom to studovali, upravovali, testovali 2x. Možná to nebylo správné rozhodnutí, ale na začátku nám to tak připadalo. A během implementace to také vypadalo OK.

Zároveň jsme zapouzdřili do metod funkcionalitu, která byla dříve roztroušena na více místech, takže takový jarní úklid.
Ano, smysl to dává (je tam synergie), ale problém je ta podpora ze strany MS. Narazil jsem na problémy i v PowerShellu, když jsem chtěl něco implemenovat. Jestli to vypadalo v pořádku při implementaci, pak mohu plést.

Jarní úklid je vždy zapotřebí. Pokud přesunete funkcionalitu z více míst, máte míň možností chyb, to znám velmi dobře :)
User avatar
AD7
Posts: 566
Joined: 28 Jan 2006, 16:21

Re: Unicode - není to jednoduché

Post by AD7 »

Moje 2 centy:
posting.php?mode=quote&f=8&p=68803

Na prezeranie Utf-8/Unicode používam cez F3 Notepad++
kde mám tmavú tému Monokai. Povypínané všetky lišty, read only mód a ukončenie na ESC. Takže sa dá. Naviac farebná syntax (html, js, xml, a pod.)
Post Reply