No nejlepší na Unicode je, že to stejně nikdo pořádně nepodporuje...možná tak ICU je rozumná implementace (vivat IBM :)), ale jinak nevím. (A ne, Python opravdu neberu: b=u"ΣΟΦΟΣ" ; print b.lower() - no chudáci Řekové... :-) Spraví to nějaký pythonista? ;-) Skoro mi přijde, že skoro všude si člověk musí něco došolíchat... :/)
Já měl za to, že ve Windows je Unicode slušně podporovaný na úrovni API (NT mají vše primárně unicodové), FS, fontů... v podstatě všude. .NET Framework je pochopitelně také Unicode-based. U aplikací je podpora někdy horší (třeba vypálit CD s Unicode názvy souborů je celkem problém), ale MS SQL Server, MS Exchange, MS Office a řada dalších je plně unicodových.
Na Linuxu je Qt celkem dost unicodové. Problémem jsou mnohonásobné překlady mezi UTF-16 (Qt jede interně v UTF-16), UTF-8 (glibc se běžně krmí UTF-8 stringy, a pro většinu věcí jiné API nemá) a UTF-32 (pár locale-aware funkcí v glibc jede v UTF-32).
Tragédií unixů je samozřejmě obcházení podpory Unicode používáním UTF-8, což vede k problémům na úrovni libc. strchr nemůže vyhledat znak, protože Unicode znak je v UTF-8 reprezentován více byte. scandir a open sice najdou i založí soubor, ale netuší, jestli je jeho název v Unicode. Pokud tedy scandir najde soubor, jehož jméno je v kódové stránce, volající UTF-8 based aplikace dostane nesmyslný UTF-8 string. Smutné také je, že se na unixech v praxi vyskytují jména souborů v code pages i UTF-8 na jednom FS.
Z výše uvedeného je zjevné, že podpora Unicode na unixech by chtěla shodit ze stolu, vrátit se do stádia návrhu, a udělat jí znovu a lépe. Bohužel k tomu kdysi (cca 1990) nebyla vůle, a dnes je asi pozdě :(
To, co zmiňujete, jsou: 1) triviality, které nijak nesouvisejí s problémem, jež jsem nastínil (a který se AFAIK týká i Windows), a 2) polopravdy - používání UTF-8 není vyhýbání se Unicode, protože UTF-8 zde slouží právě jako nosič unicodových codepointů. Kde je tedy to "vyhýbání se"? libc je třeba brát jako legacy záležitost, a nemyslím, že to je až takový problém - zpětnou kompatibilitu potřebujeme. A i v různých localel má člověk možnost (a z hlediska zdravého rozumu povinnost :-)) použít kompatibilní kódování. Rozumný člověk dnes nebude kódování názvů souborů míchat, to je humus. Taky mě zaráží, proč ještě existuje UTF-16, ve kterém se snoubí algoritmicky velmi příjemná proměnná délka znaku z UTF-8 a úsporný formát a značně praktická závislost na endianness z UTF-32/UCS-4.
UTF-16 je kódování vhodné pro jazyky typu čínštiny, japonštiny apod. V UTF-8 se jim totiž naprostá většina znaků kóduje do tří bajtů, kdežto v UTF-16 jen do dvou. Což je samozřejmě pro, řekněme, neevropské jazyky nezanedbatelná úspora. IMHO je to docela dobrý kompromis, pokud vytváříté systém, kde se s takovými jazyky počítá.
A to se právě šeredně pletete. ;-) Pro jazyky typu čínštiny a japonštiny jsou nejvhodnější kódování ta "národní", jako je *JIS nebo BIG5. Unicode je velmi rigidní, co se týče potřeb zejména japonštiny po změnách znakové sady, a navíc panují celkem značné třenice mezi Čínany, Japonci a Unicode konzorciem, jak by vůbec měly některé znaky vypadat a co by se mělo a nemělo sjednocovat (jak čínské a japonské znaky, tak varianty znaků uvnitř čínštiny a varianty znaků uvnitř japonštiny). Navíc národní kódování jsou pro japonštinu rozhodně efektivnější než UTF-16, protože třeba v Shift-JISu jsou ASCII znaky a Hankaku Kana pouze jednobajtové. Abych parafrázoval, "což je samozřejmě nezanedbatelná úspora.". Proč myslíte, že tvůrce Ruby podporuje UTF-8, Shift-JIS a EUC-JP? Nesnažte se nám namluvit, že o potřebách kupříkladu Japonců víte víc, než on. ;-) (Přiznávám ovšem, že věci jako ISO-2022-JP mě taky docela děsí... :-)) Navíc roundtrip mezi Unicode a národními kódováními je už z principu nedostatečný, většina dat v Japonsku není v Unicode a Japonci si své databáze určitě nechtějí destruovat nějakou ztrátovou transformací.
To je opravdu pravda? Že Unicode nedokáže dobře zobrazit Japonštinu, nebo snad i Čínštinu? To by potom ale byl docela problém a selhání celého účelu Unicode.
Viz třeba http://www.jbrowse.com/text/unij.html. Vřele doporučuji celé si to důkladně přečíst. Je to poučné. :-) Tedy, není to až tak strašné, ale pro Japonce to je asi takové, jako kdybychom nám z češtiny do Unicode nevzali třeba "ř" a my museli psát "rericha".
Pravda to samozřejmě není. Jádro problému je v tom, že východoasijské znaky byly do Unicode unfikovány -- tj. pokud např. v čínštině a japonštině byly znaky se stejným významem (ale trošku odlišným vzhledem), jsou v Unicode jako jeden znak. Je to logické, protože Unicode se ve většině případů stará o význam znaku ne o jeho kresbu/vzhled.
Pro korektní zobrazení textu pak tedy ještě potřebujete znalost jazyka (a někdy i skriptu a regionu). Tyto věci neumí Unicode zrovna dobře reprezentovat, takže se typicky přenášejí o vrstvu výše, např. v XML pomocí atributu xml:lang.
Jenže někde byly poměrně necitlivě sjednoceny právě znaky s významem rozdílným, nebo alespoň nepoužitelné ve všech kontextech. Takže v Japonsku kvete trh se speciálním softwarem na správné psaní třeba vlastních jmen. :-) Navíc si nejsem jist, jestli xml:lang něco zmůže v případě variant znaků ve vlastních jménech v rámci jediného jazyka.
A chápu to správně, že abych mohl "Embedding Glyph Identifiers in XML Documents" použít třeba v MIME emailech, tak musím emaily nejprve obalit do XML? A co plaintextové soubory? To si máme všichni dávat k snídani tag soup, nebo snad XML vločky s mlékem? ;-)
Zrovna kombinovat vločky s mlékem není moc dobrý nápad, vápník se vám naváže na vločky a do těla se ho moc nedostane. Já osobně dávám přednost chlebu se sádlem nebo s jogurtem. ;-)
Pokud vám Unicode nestačí, je váš problém, jak budete ve vámi používáném formátu reprezentovat chybějící vlastnosti textu. V XML na to prostředky jsou. Pokud někdo ukládá texty ještě v jiném formátu, je to jeho boj. ;-D
Děkuji pane Kosku, vlastně jste mi jen potvrdil, že Unicode opravdu problémy má. A protože vím, jak nadnárodní komise "citlivě" řeší problémy nějakých těch "undermensch" dole - tak mi je i jasné, jak asi posuzování významu dopadlo. Z Vašeho příspěvku jsem pochopil, že asi skoro všechno bude v pořádku, ale pár maličkostí, se kterými se Japonci nemohou smířit, a kde jim komise pro vývoj Unicode nechce vyhovět. Tohle jsem si dal dohromady z toho co jste napsal mezi řádky.
Slovo význam použité Koskem a věcně špatné. Zcela odlišná význam totiž může symbol dostat v různé kombinaci znaků (symbolů) po sobě.
Možná by bylo nejlepší situaci ilustrovat na (našich) písmenek latinky pro psaní. Ty se také v různých státech i v historickém čase píší různě - a význam mají jen v kombinaci s dalšími písmeny.
A bylo by pošetilé chtít v Unicodem pojímat třeba různé způsoby psaní Š.
Ano ano, také si myslím, že hlubší rozbor by to nepřežilo. Proč je třeba v Unicode jednička normálně číslicí a pak jednička třeba v brailovém písmu, když je to významově totéž? Právě proto, že ten symbol - glyph je v Unicode také dost vyzdvihován a preferován. Osobně si myslím, že prostě některé jazyky už mají tolika symbolů, že prostě chlapíci v Unicode consorciu už se ošívali jim přidělit tolika prostoru - a nějak zakecat to museli, že ...
Dvojí výskyt písmene "mí" se zdůvodňuje ten, že jedno je řecké mí v textu a druhé je značka "mikro", ale tím chtějí jen odvést pozornost od té pravdy, že to je kvůli zpětné kompatibilitě s ISO-8859-1. ;-) BTW, ve Wikipedii má tohle téma i vlastní stránku: :-) http://en.wikipedia.org/wiki/Duplicate_characters_in_Unicode
BTW, mnou linkovaná stránka naopak tvrdí, že Unicode se stará o grafémy, nikoli o významy (ale ani o glyfy, tj. realizace grafémů). Unicode a pan Kosek jsou tedy ve sporu. ;-)
Unicode se stará o znaky. Doporučuji si přečíst standard Unicode, ne nějakou linkovanou stránku. Samozřejmě to co Unicode rozumí pod znakem je ve vetšině případů i grafém.
Nicméně jestli vás baví terminogické tahanice, přidám pár citací (The Unicode Standard 5.0, sekce 2.2):
The Unicode Standard encodes characters, not glyphs.
Psát, že "Unicode se stará a znaky" a tím že je všechno jasné, patří tak do školy ke zkoušce.
Problém přece je v tom, co se pod tím znakem třeba pro čínštinu myslí.
Koskovy definice totiž jsou krásný příklad definice kruhem. Že totiž znaky jsou to, co má reprezentaci v Unicode.
Neřekl bych věcně špatně, ale zcela v duchu standardu Unicode. Také jsme se nebavili o latince, kde jedno písmenko samo o sobě samozřejmě svůj význam nemá.
No, reagoval jsem spíš na názor, že UTF-8 je lepší než UTF-16. Národní kódování bývá samozřejmě efektivnější - z tohohle hlediska je CP1250 nebo Latin 2 pro češtinu také efektivnější než UTF-8.
Netvrdím, že o kódování japonštiny vím více než Matz (ze svého úhlu pohledu bych přístup Ruby 1.x k unicode nenazýval "podporou"), nicméně před pár lety jsem se podílel na sw projektu pro zákazníka, tuším z Honkongu, a proti použití UTF-16 nebyly, pokud si vzpomínám, žádné námitky.
Nejsem si jistý, zda problém konverze starších dokumentů se dané problematiky dotýká víc než okrajově.
Přesně tak, někteří zde diskutující zapomněli zdůraznit, že pro evropské jazyky je jsou neASCII znaky zapsané v UTF-8 na 2 byty, (běžné) znaky pro asijské jazyky na 3 byty. (A ASCII-1 znaky jen na jeden byte.)
Takže použití UTF-16 potřebu pro japonštinu na běžné znaky (myšleno znaky gramotnosti, které se učí ve škole a mohou používat v úředních textech) vždy jen 16-bitů, t.j. 2 byty.
No a když tam mermomocí potřebujete napsat něco dalšího, tak se teprve používá převod těchto delších Unicodových znaků do UTF-16.
P.S.
Hlavně by si někteří diskutující měli rozmyslet, jak by se bez použití UTF-16 poznal konec řetězce bitů (toto právě Unicode zásadním způsobem nedomyslel - takže je vlastně neimplementovatelný). Ledaže by každý znak všude na světě byl vždy na 4byty.
A na to jste přišel kde? Třeba v UTF-8 to bez problémů poznáte a to dokonce i když začnete uprostřed řetězce. Poznáte i jestli jste na začátku znaku, nebo uprostřed znaku tvořící několik bajtů a jste schopen bez problémů určit kolik že bajtů ten znak bude mít.
Jenže já myslím, že doba, kdy se počet bajtíků považoval za nejlepší kritérium už je naštěstí doufám za námi.
UTF-8 zvládne mnohem širší rozsah znaků, než UTF-16. UTF-8 je schopno zobrazit celou 32-bitovou sadu, UTF-16 jen 21 bitovou sadu. UTF-8 je kompletně přenositelné a multiplatformní, nejsou u něho problémy s endianitou, jako u UTF-16. Konec řetězce poznáte v UTF-8 snadno.
Já osobně nevidím vůbec důvod proč někde preferovat UTF-16, opravdu jediný důvod je v tom, že (a to jen ještě v některých případech, spíše v menšině) je UTF-16 dokument o nějaké bajtíky kratší, ve většině případů je UTF-8 kratší, než v UTF-16. Ono i v těch asijských zemích často mixují latinku se svým písmem, a pak už vytváří UTF-8 výrazně kratší dokumenty, než v UTF-16.
Záleží, co nazýváte "pár bajtíky". Pokud se např. většina bežných japonských či čínských textů kóduje v UTF-8 na tři bajty a v UTF-16 na dva, tak prostě tyto dokumenty kódované v UTF-8 jsou o zhruba 50 % delší, než v UTF-16 (s tím mixováním s latinkou bych to neviděl tak horké). Existuje spousta oblastí, kde to má může mít svůj význam. Unicode a jeho kódování je prostě kompromis - u některých aplikací může vadit vůbec kódování UTF, u jiných se snažíme o kompaktní uložení informací nebo o něco jiného a až na řídké výjimky jde opět o kompromis. Pamatuju projekty, kdy jsme prostě nemohli kvůli paměťovým nárokům použít UCS-4.
Stěžovat si na špatný design Unicode také nejde - design závisí i na kontextu dané doby. Když to přeženu, tak bych mohl na Vámi propagovaných 32 bitů namítnout, že je málo - lépe by bylo použít 64bitové kodování znaků, protože až navážeme kontakt s tisíci a milióny dalších civilizací ve vesmíru, těch 32 bitů určitě nebude stačit (nehledě na to, že třeba ani nemají písmo v našemm slova smyslu a pro přenositelné "dokumenty" bychom měli záběr Unicode rozšířit). Copak 8 bajtů na znak je pro současnou techniku a 64bitové CPU tolik?
Co nazývám pár bajtíků? Je to označení toho, když se někdo primárně rozhoduje podle velikosti. Neříkám, že se to ovšem nemá brát v úvahu, a že to dokonce občas nemůže hrát klíčovou roli.
Osobně si myslím, že v mnoha případech prostě velikost nehraje podstatnou roli, pokud se samozřejmě neliší několikanásobkem. Proč třeba Unix tolik preferuje lidsky čitelné textové soubory třeba na konfigurace, na /proc věci na řadu dalších účelů? Vždyť třeba binárně kódované soubory by zcela určitě byly velmi výrazně kratší! Proč se tolik propaguje XML, když je to skoro vždy velmi rozvláčný formát pro ukládání dat? A tak bych mohl pokračovat.
Unicode je podle mě velmi dobrá cesta - lepší nikdo nevymyslel. A UTF-16 je prostě zoufalý kompromis, nad kterým zoufale láme rukama příliš mnoho lidí.
Pokud děláte obrovské věci a pracujete s ohromnými texty, ale opravdu ohromnými, pak lze výběr znakového kódování sice s mizernými vlastnostmi, ale paměťovou úsporou asi tolerovat a je možná na místě. Ale jinak to nemá smysl.
Ono je vždycky něco za něco - a skoro vždycky soustředění se na paměťové úspory za každou cenu (tím nenabádám k neopodstatněnému plýtvání místem!) většinou znamená zhoršení mnoha desítek jiných parametrů celého sw projektu.
Žijete 4 let postaru. RFC2279 z roku 1998 popisující princip UTF-8 (mimochodem připouštělo jen 31bitové řetězce Unicodu) bylo v roce 2003 aktualizováno (RFC3629).
Nově se také povolují do UTF-8 převádět jen 21-ti bitové řetězce.
Do UTF-8 se povolují jen 21 bitové řetězce, ale UTF-8 bez problémů zapíše beze změny implementace celý 32 bitový prostor. Ba dokonce UTF-8 je schopno pojmout i více, než 32 bitový prostor aniž byste cokoli na algoritmu čtení/zápisu/procházení UTF-8 musel změnit jen čárku.
Omezení na 21 bitů je proto umělé, a nic to na UTF-8 nemění. Je to děláno proto, že současný Unicode pracuje ve 21 bitovém prostoru.
Ale třeba W3C standardy běžně ohledně XML třeba, nebo v DOM běžně pracují s 32 bitovým prostorem Unicode.
Ono se to jednou bude hodit, až Unicode bude muset překročit 21 bitový prostor (to je jenom otázkou času) a bude se moc hodit, že UTF-8 to umí.
Ne, W3C standardy rozhodně nepracují s 32bitovým prostorem. Buď používají zcela abstraktní definici znaku dle Unicode/ISO 10646 nebo v případě DOMu mluví o reprezentaci pomocí řetězců pomocí UTF-16.
Toho, že by Unicode měl přesáhnout 21bitový prostor, bych se opravdu nebál. Nebo snad očekáváte, že záhy objevíme nějakou dosud neznámou civilizaci někde na pustém ostrově nebo v podzemí, která používá několik set tisíc znaků a bude je chtít přidat do Unicode? Nebo, že by snad přilétli mimozemšťani? Ale to pak asi budeme díky jejich technologické převaze v jiných oblastech nuceni převzít i jejich znakovou sadu.
Myslím, že to zbytečně hrotíte. Unicode je jako každý standard kompromis, a jeho některé nedostatky v 99% bohatě převáží výhody jednotné znakové sady.
Proč bych to hrotil? Mluvím snad o tom, že Unicode je špatný standard? A kde prosím, citujte mě. Předem děkuji.
Nikoli, já hlavně říkám, že UTF-8 bez problémů dosáhne celý 32 bitový prostor (ve skutečnosti ještě větší), a že omezení na 21 bitů je jen právnické, nikoli technické, či implementační.
Toho, že něco bude stačit - takových výroků už bylo - od světoznámého "640 KB bude stačit každému" od Billa Gatese přes problém Y2K, který vzniknul tím, že taky něco mělo stačit a nemělo až po mnoho a mnoho dalších. Takových výroků najdete všude. Evidentně pokud se někdo dívá do křišťálové koule a vyjde mu, že v IT něco něčeho bude stačit - skoro vždy se jedná o fatální omyl. Historie učitelkou života.
W3C standardy dnes pracují s UTF-16, protože se to stalo standardem, protože W3C hodně spolupracuje s Javou, která ani jiné stringy neumí. Ale kdesi v prvních verzích jsem našel i poznámku o využití znaků nad 21 bitovým prostorem, pokud jsou znaky kódovány jako 4 bajty. Dnes už je to samozřejmě upraveno.
Nerad opakuji, co už jsem psal, ale 21 bitů je více než dost. Proč to tvrdím? Množství produkovaných a skladovaných informací s časem roste exponenciálně (podle výrobců storage). Proto 640kB jeden den stačilo každému (Bill to prý neřekl, ale což), a druhý den potřebuje každé PDA 100x tolik paměti. Ale předpokládáte exponenciální růst počtu abeced (či obecně symbolických způsobů zápisu jazyka)? Takový předpoklad se jeví naprosto nereálný. Pokud se za pár desítek či stovek let dostaneme s Unicode nad 21 bitů, holt přejdeme na 32-bitové, 64-bitové, nebo nějaké jiné kódování. Dnes se nezdá, že by k tomu kdy došlo.
Nerad se opakuji, ale vyfoťte mi prosím Váš záznam z křišťálové koule - ideálně nějakou pasáž třeba z roku 2020 :-)
Ale beze srandy, je jedno, jestli 21 bitů bude, nebo nebude stačit - podstatné je, že UTF-8 není na tomto limitu závislý. Stejně tak je podstatné, že limit 21 bitů je umělý, a dělaný pro kompatibilitu s UTF-16. Vyškrtněte UTF-16 a všechny technologie kolem Unicode jsou schopny okamžitě operovat ve 32 bitovém prostoru znaků - s výjimkou těch, které použily 2 bajtové uložení. Omezení na 21 bitů je umělé (prívnické), nikoli technologické, nebo implementační - bylo stanoveno pro kompatibilitu s 16 bitovými kódováními.
Pokud by se Unicode dostal nad 21 bitů, použije se UTF-32. Už u dnešních systémů (namátkou .NET, Qt) to vyústí pouze ve změnu definice třídy string, a nějakou konverzi pro starší aplikace. Samozřejmě unixy s libc takové možnosti nemají.
Nejde o délku. Jde o to, že v případě UCS-2 platí, že co 16-bit hodnota, to code point (tedy znak). UTF-16 (tedy UCS-2 se surrogate pairs) se používá minimálně, a je otázkou, zda se kdy prosadí.
Unicode není 32-bit, tedy není důvod pro kódování, které popisuje 32 bitů. Samozřejmě u dnešních systémů není technicky problém předefinovat string třeba na UTF-32, ale zatím není ta potřeba.
Mnou popisovaný problém nebyl ani tak o tom, jeslti je lepší UTF-8 nebo UTF-16, ale o tom, že při použití string API a ignorování informace o tom zda je string v Unicode dochází k nejednoznačnosti. Mnoho věcí, včetně názvů souborů na disku, se tam může poškodit.
Šeredně se pletete vy. JIS má řadu problémů. Například jsou znaky kódovány různě dlouhými sekvencemi, a pravidla pro určení délky sekvence nejsou tak "hezká", jako u UTF-8 (nemluvě o UCS-2). Navíc uprostřed streamu nelze poznat, jestli je následující znak počátkem sekvence, nebo ne. Efektivně 0x41 může být A, nebo část sekvence. Dále JIS popisuje jen poměrně malé procento nejběžnějších znaků.
Většina dat v Japonsku je dnes v Unicode. Je to důsledkem toho, že Windows dávno migrovaly na Unicode, a MS Office také. Samozřejmě jako u nás umíme do Unicode převádět PC Latin 2, 8859-2 a Kameníky, oni umějí převádět *JIS*.
Mimochodem problém s rozpoznáváním prvního znaku sekvence je důvodem, proč asiaté odmítají (nebo odmítali) UTF-16, a trvali na UCS-2. A to přesto, že znaky s code points 0x10000 a výše nekolidují se zbytkem Unicode znaků. Chtějí se vyhnout problémům, které měli s *JIS*.
Fakt? Tak opravte wikipedii, která tvrdí, že "most Japanese e-mails are in JIS encoding and web pages in Shift-JIS and yet mobile phones in Japan usually use some form of EUC".
Ale houby. UTF-16 je pomník nedomyšlenosti návrhu Unicode a je to to nejhorší kódování Unicode, kde se nabalily snad všechny nevýhody, které snad mohou vůbec existovat.
Problém je ten, že Unicode začínalo jako 16-bitové kódování znaků. Už tehdy jsem si říkal, jestli to není málo, a proč neudělají rovnou 32 bitů. Ale prostě tak se rozhodli, a nastal problém blbého návrhu. Až všichni vzali Unicode jako 16 bitové znaky (Java, Windows, atd..), pak se zjistilo, že 16 bitů nestačí a je nutné 32 bitů a bylo nutné nějak řešit kompatibilitu se systémy, které natvrdo zadrátovaly Unicode jako 16 bitů a vymyslelo se UTF-16 - nejhorší myslitelné kódování co šlo vymyslet, ale bohužel jiné řešení asi neexistuje.
Bohužel jako relikt špatně trefeného návrhu Unicode a kdysi pokusu udělat ho na 16 bitech vznikly v Unicode hodně ošklivé relikty, které si jako jizvy a šrámy nese Unicode sebou. Jeden z nich je kódování UTF-16, asi to nejhorší co pro Unicode se dá použít. Kromě toho je Unicode teď omezeno na 21 bitů, namísto na 32, a to proto, aby vůbec obskurní kódování UTF-16 nějak fungovalo.
Jak říkám, v UTF-18 se snoubí algoritmicky velmi příjemná proměnná délka znaku z UTF-8 a úsporný formát a značně praktická závislost na endianness z UTF-32/UCS-4. ;-)
> pak se zjistilo, že 16 bitů nestačí a je nutné 32 bitů
Opravdu je nutne 32 bitu? AFAIK v BMP jsou prakticky vsechny pouzivane znaky a do beznych programu neni treba implementovat podporu fenictiny nebo staroreckych hudebnich symbolu :-).
Přesně analogickou otázku si v roce 1990 a o pár let později lidé kladli také. Opravdu je nutné ukládat v roce i století a počítat s nějakým dalším stoletím? A kolik miliard se pak muselo investovat do problému Y2K už všichni víme.
Ne, 16 bitů nestačí ani náhodou - a rozhodně nebude už vůbec stačit v budoucnu.
> 16 bitů nestačí ani náhodou - a rozhodně nebude už vůbec stačit v budoucnu
:-)
Jo, v budoucnu bude urcite pribyvat spoustu novych jazyku s novymi znakovymi sadami. Nebo se vlivem velkeho rozsireni grafickych uzivatelskych rozhrani s ikonami zapis anglictiny zmeni na obrazkove pismo.
Už poslední verze Uncode 5.0 obsahuje cca 70 tisíc znaků - nacpete to do 16 bitů? A to jsme v současnosti - a to ještě mnoho znaků bylo zjednodušeno, viz například výše problém s japonštinou. A kde máte budoucí znaky?
Mám rád takové rejpaly, kteří zesměšňují bez znalosti věci, aniž by o tom něco věděli. Je takový problém, abyste nastrtoval na www.unicode.com a zjistil si fakta, když už chcete zlehčovat?
To byl muj puvodni prispevek tak nepochopitelny? Na unicode jsem se dival a nenasel jsem mimo BMP (zakladni 16bitovy rozsah) zadnou sadu znaku, kterou je treba podporovat v obecnem software - mimo BMP jsem nasel pouze znakove sady mtrvych jazyku ci jeste obskurnejsi veci. Tedy prispevek navrhoval se v nespecializovanych aplikacich omezit na znaky z BMP a nekomplikovat si software kvuli nekolika obskurnim a nevyznamnym znakovym sadam. Nebo jsem prehledl nejake dostatecne zivy jazyk, jehoz znaky jsou v unicode mimo BMP?
Za prvé: V Unicode nejsou jen znaky abeced jazyků, ale také třeba matematické symboly (jejichž část je právě v plain 1, tedy nad 16 bitovým rozsahem), notové značky, symboly peněžních měn, brailovo písmo pro slepé, různé technické symboly, a řada dalších věcí.
Za druhé: Unicode se snaží všechny potřebné a používané znaky nechat v nulté rovině, tedy v 16 bitovém rozsahu. Méně potřebné věci vyhazuje výše. Nicméně v nulté rovině už je pekně plno a tak je otázka jak dlouho to ještě bude takto fungovat.
Za třetí: Naopak, je bezvadné od Unicode, že tam jsou i mrtvé jazyky, protože tak lze konečně jednotně kódovat každý symbol na světě, který se kdy alespoň trochu používal. V 32 bitovém prostoru je velmi mnoho místa a nemusíte ani moc šetřit (i když Unicode tvrdí, že zatím používá 21 bitový prostor - nejspíše kvůli debilnímu UTF-16, který víc nakódovat nedokáže). Pokud chcete běžné jazyky, klidně zůstaňte v 16 bitovém prostoru, zatím s ním vystačíte (ale slovo zatím je v sw inženýrství dost ošemetné slovo - a bývají z toho miliónové škody).
Ja by som len podotkol, ze napriek podla vas zlemu kodovaniu UTF16, je vyhoda UTF16 prave v efektivnosti spracovania. Test na surrogates je myslim si efektivnejsi ako spracovanie utf8 streamu (tot moj skromny odhad, metodou pozriem - vidim, na zdrojovom kode). Kazdopadne ak by bol zaujem, mozem spravit zopar testov v onigurume, ktora sa myslim pouziva aj v ruby.
Analogicky lze tvrdit, že 4-místné císlo pro zápis data nestačí, a měli bychom už dnes používat 16-místné. Nesmysl? Ano, stejně jako rutinní používání UTF-32. Důležité je, že pokud to bude třeba, budeme schopni na UTF-32 přejítt.
> Rozumný člověk dnes nebude kódování názvů souborů míchat, to je humus
To povidej programatorum GTK, kteri se rozhodli, ze bez ohledu na zazitou konvenci, ze jmena souboru se interpretuji vzhledem k aktualnimu locale, oni budou vsechna jmena souboru interpretovat jako v UTF-8. Takze ruzne programy pak generuji jmena souboru v ruznych kodovanich.
Nebo jiny priklad - pri vzdalenem pristupu k systemu musis mit nastavene locale v souladu s nastavenim sveho lokalniho terminalu, coz muze byt ruzne (a z tve pozice nemenitelne) kdyz pristupujes z ruznych systemu.
Jenže jak byste to udělal jinak? Máte filesystém s osmibitovými názvy, které cokoliv ostatní interpretují jako osmibitové stringy v aktuálním locale. A vy jako tvůrce GTK chcete nabídnout rozhraní v Unicode?
Stejný problém řešily Windows a vyřešily jej naprosto stejně - a možná mám malou fantazii, ale jiné řešení aspoň trochu funkční mě ani moc nenapadá.
No jestli je triviální, že mte na disku soubory, které UTF-8 based aplikace nepřečte, nebo to, že se string při volání Qt API v důsledku mnohokrát přeloží, tak máme o pojmu trivialita dost odlišné představy. Windows se podobné problémy netýkají, protože je veškeré API primárně v Unicode UCS-2. Pokud aplikace nejede v Unicode, její volání se do Unicode převádí, a výsledek se převede zpět (týká se to samozřejmě jen starých, ne-Unicode aplikací). Názvy souborů jsou na NTFS v Unicode, na FAT také. Funkce API typu CreateFile, FindFirstFileEx, CopyFileEx, a samozřejmě TextOut, DrawTextEx (a všechna další API používající jakýmkoliv způsobem stringy) žerou Unicode UCS-2.
Jak zabráníte míchání kódování názvů souborů? Stáhnete si dokumentaci ke KDE, a už máte soubor s UTF-8 v názvu. Přimontujete si klíčenku nebo disketu s názvy v 8859-2, a už máte soubory s 8859-2 v názvu. Nedej bože pokud máte na síti soubory s názvy v ruštině v 8859-5, nebo hebrejštinou ve visual oder (8859-8).
Obecně tomu můžete zabránit takto:
1. Názvy souborů ukládat na disk vždy v Unicode (UTF-cokoliv-si-jednou-vyberete), a volání z aplikací jedoucích v code pages překládat do Unicode.
2. Názvy souborů ukládat v UTF-8 včetně informace o code page, nebo alespoň s informací o tom, zda jsou v Unicode. K tomu stačí 16-bit příznak u souboru, nebo Byte Order Mark u Unicode názvů.
3. Můžete na všechno kašlat, a nechat to na disku vyhnít, protože se vám nechce do stávajícího systému zasahovat.
Unixy před lety zvolily ten třetí způsob.
Unicode měl od první verze 16-bit kódování. UTF-16 je použitelné jen pro velmi omezený subset znaků, a je otázkou, jestli se kdy prosadí. Napíšu o tom více.
> Windows se podobné problémy netýkají, protože je veškeré API primárně v Unicode UCS-2.
Hypoteticky priklad - psal bych FTP klienta pod Windows. Vylistuji jmena souboru a nejaky chci ulozit. Informaci o kodovani danych jmen obecne nemam. V unixech proste ulozim dany soubor pod stejnou sekvenci bytu, cimz urcite nic nepokazim a pokud nahodou klientsky system pouziva stejne kodovani jako server (ne az tak neobvykla situace), tak je kodovani v poradku. Jak ale takovou posloupnost znaku prevedu do UCS-2, abych mohl zalozit soubor pomoci Windows API?
Pokud stáhnete název "školní čítanka.pdf" zapsaný v 8859-2, a na systému běžícím primárně v UTF-8 ho uložíte jako stejnou sekvenci bytů, tak jste si právě zadělal na problém. Tím problémem bude jméno souboru s neplatnou UTF-8 sekvencí (takové jméno souboru ani nemá platnou reprezentaci v UTF-16 a UTF-32).
Pro ilustraci Windows file servery drží jména souborů v Unicode. Klienti je zobrazují buď v Unicode, nebo (u Win9x) se po cestě provádí konverze do code page klienta.
V popisovaném hypotetickém případě s FTP by se pro konverzi použila default code page (v té se i zobrazují ne-Unicode stringy), pokud by si aplikace nevyžádala jinak. V důsledku budete na disku (ve všech aplikacích) vidět ten samý název, jaký FTP klient vypsal. Pokud klient na příkaz LIST vypíše "školní čítanka.pdf", stáhnete soubor by default (poměrně logicky) pod tímto názvem. Pokud se název souboru vypíše jako "ÿkoln½ ètanka.pdf", uloží se tak i na disk.
Jak to říkal kdosi nepojmenovaný: "Špatně, zkus to znova. :-)"
Zřejmě jste nikdy v UNIXu nepracoval a nepřimountovával filesystém. Protože by jste zjistil, že při mountování se uvádí codepage a charset. Tudíž vy si můžete přimountovat fs kde jsou soubory v JIT(japonštinu) a zkopírovat do svého fs, který máte pod UTF-8. Nebo se dá bez problémů přimountovat cp1250 (windows) na iso8859-2. Dokonce by to šlo i naopak. Přimountovat UTF-8 na iso8859-2. Ale pak riskujete, že narazíte na nějaký hebrejský, nebo tak něco. Ale s tím asi počítáte, když jste zvolil takový postup.
Je možné, že to windows umí také. Ale stalo se mi, že jsem se přihlásil po síti k disku, kde byli soubory v řecké alfabetě. WindowsXP-windowsXP. Ale že by to bylo bez problémů říci nemohu. Nic nefungovalo. Ale jak říkám. Snad na to mají Win nějaký nástroj.
Prosím, neuvádějte argumenty které jdou tak snadno ověřit.
Ano, v Linuxu si od jisté doby můžete nastavit konverzi code page na názvech přimontovaného FS. Bohužel to neřeší fakt, že na FS můžete mít uložené názvy ve více různých code pages. Samozřejmě nejdrsnější situace nastane, když přimontujete UTF-8 disk s překladem na 8859-2, a místo názvu v 8859-2 na něj pošlete název v UTF-8, případně jiné obdobné příhody :)
Ve Windows není problém s přístupem k diskům, které mají názvy v Unicode (je to naopak nativní, a vše co není v Unicode se do něj překládá). Hádám, že pokud jste měl nějaký problém, tak nebyl s Windows, ale s nějakou předpotopní aplikací, která neumí Unicode (a je tedy psaná pro Windows 9x bez Unicode layer, případně pro Windows 3.x). Bohužel autory takových aplikací nelze trestat ;). Můžete si ale pomoci tak, že nastavíte code page systému na řeckou; poté budou fungovat ne-Unicode aplikace v řecké code page.
Jak vidíte, mé argumenty lze ověřit, a jsou správné. Vaše neznalost pravda může vést ke špatné interpretaci fakt.
Jen bych trochu opravil Vaši formulaci, aby byla trochu objektivnější:
Ano, v Linuxu si od jisté doby můžete nastavit konverzi code page na názvech přimontovaného FS. *Velice dobře to řeší* fakt, že na FS můžete mít uložené názvy ve více různých code pages.
Ve Windows to podle Vašeho vyjádření jde také. Ale zřejmě až od verze XP, protože na 2000kách se mi to nepodařilo (má potřeba byla ta konzole). Ale třeba zde jen hraje roli, že je tak dobře neznám.
Ve Windows ani v Linuxu není problém s přístupem k diskům, které mají Unicode. Ostatně jsou to oba vyzrále OS. Rozdíl je zde snad jen v tom, že Windows to tvrdě vyžadují (s případnou možností nastavení) a překládá to pomocí API, zatímco Linux tento překlad provádí na úrovni namountování (dejme tomu také určitá forma API) a podporuje širokou škálu kódování, přičemž volba není nijak omezovaná.
Co se týče mého problému, tak ta předpotopní aplikace byl Explorel (trefil jste se). Já jsem spíše (snad tak nějak zmlsán z Linuxu) předpokládal, že si na síti nastavím, že tento a tento počítač má tento přimountovaný systém v tom a tom kódování. A on mi to transparentně tam i zpět přeloží. Přeci jenom abych si já u sebe nastavil řecký codepage určitě nemyslíte vážně.
> strchr nemůže vyhledat znak, protože Unicode znak je v UTF-8 reprezentován více byte
Coz je ale zcela v poradku - strchr ma vyhledavat vyskyt charu (jako datoveho typu) v retezci char *. Viz specifikace C99. Ne nadarmo C99 zavadi wchar_t.
No jo, jenže glibc řadu funkcí nemá pro wchar_t implementovanou :((. A když už jí má glibc, mnohdy jí nemá libc. Jak jsem psal výše, ve Windows jsou stringy vždy wchar_t (a pokud nejsou, API udržující zpětnou kompatibilitu je převede při volání).
> scandir a open sice najdou i založí soubor, ale netuší, jestli je jeho název v Unicode
Tento unixovy pristup (jmena souboru jsou posloupnosti bytu ukoncene nulovym bytem bez ohledu na jejich interpretaci) ma sve nedostatky (ktere zminuji jinde), ale opacny pristup (jmena souboru jsou znaky v unicode) ma take sve nedostatky, casto jeste horsi. Napriklad to, ze spohlehlive funguje jen za predpokladu, ze lokalni i sitove filesystemy a protokoly jsou kodovani-aware. Coz mnohe nejsou. Oproti tomu unixovy pristup funguje i na takovych protokolech.
Osobně bych také raději, aby vše probíhalo v Unicode. Cokoli jiného je jen z nouze ctnost. A nemyslím si, že problémy s unicodovými názvy by byly až tak podstatné, výhody z toho plynoucí by mnohonásobně převážily případné problémy.
Ve světě Windows nás to netrápí, protože je v Unicode prakticky všechno. Co není v Unicode, interpretuje se v určené code page (typicky default code page, pro ČR ANSI 1250, pro DOS aplikace PC Latin2), a do Unicode se to převede. Naopak unixový přístup vede k tomu, že v aplikaci používající UTF-16 (nebo UTF-32) stringy nemůžete uložit název souboru, protože UTF-8 string může obsahovat vadné sekvence (typicky pokud to není UTF-8).
Jestli máte pravdu, tak mi jistě poradíte jak nastavit například utf-8 pro konzoli. Stalo se tuhle jsem potřeboval. Jde to? Nápověda mi prozradila jen omezené možnosti kódování bez tohoto. Tak jak zporovozním ten automatický převod?
Konzole ve Windows pracuje v UCS-2, stejně jako zbytek systému. Můžete nastavit, že ne-Unicode stringy jsou v UTF-8, ale není to nijak dále podporováno (například se nepodporuje BOM, aplikace pro DOS budou zřejmě UTF-8 ignorovat či mršit atd). Stačí mít nainstalované převodní tabulky pro UTF-8 (v XP v Control Panels, Regional Options, Advanced, zde musí být zaškrtnuto Unicode-UTF 8). Poté použijte příkaz chcp s číslem code page. UTF-8 používá tuším něco jako 65535, 65000, nebo tak nějak (viz výše Control Panels).
Mám české 2000ky. Nepodařilo se mi. Existuje k tomu nějaká dokumentace? V případě MSDN prosím bližší odkaz. Přeci jen tato knihovna je jako sám internet před vynalezením vyhledávačů.
s=u"ΑαΒβΓγΔδΕεΖζΗηΘθΙιΚκΛλΜμΝνΞξΟοΠπΡρΣσΤτΥυΦφΧχΨψΩω"
>>> print s.lower()
ααββγγδδεεζζηηθθιικκλλμμννξξοοππρρσσττυυφφχχψψωω
>>> print s.upper()
ΑΑΒΒΓΓΔΔΕΕΖΖΗΗΘΘΙΙΚΚΛΛΜΜΝΝΞΞΟΟΠΠΡΡΣΣΤΤΥΥΦΦΧΧΨΨΩΩ
Co je s tymi grekmi v pythone? Ved mne sa to zda OK?
No zda sa mi to sice OK, ale tusim prispevok to nezvladol :-) Ale ked som dal teraz reagovat, tak to vyzera opat dobre ...
Proste s su vsetky grecke pismena na preskacku velke male, lower vypise pekne vsetky male a upper vsetky velke ...
Zrovna tohle je v pohodě. Ale co pravopisné pravidlo pro koncové malé sigma, které jsem se snažil ilustrovat? I přesto, že jsem si nasavil řeckou locale? Hmmm. A to je jen jeden jazyk z mnoha. Dalo by se namítnout, že to je "vysokoúrovňová" záležitost, a že si to musejí řešit aplikace, stejně jako holandské IJ, nebo nějaké ty gruzínské paznaky, nebo "ch" uvnitř slova ve slovenském abecedním řazení ("viachodnotový") a já nevím co ještě. Jenže to znamená, že Unicode nemá šanci splnit ambice typu "uděláme jednotnou znakovou sadu a jednotné kódování a všem budou automaticky dokonale fungovat všechny jazykové věci podle pravidel i cizích jazyků". Obávám se, že v tomhle smyslu na tom nejsou Java a Python o moc líp, než Ruby. Jestli Ruby splňuje tak 10 % i18n ideálu, tak Python a Java mají tak možná 30-40 %. Ruby 2 bych viděl tak na 20-50 (20 v základu, 50 s knihovnami, které lidé udělají a které půjdou nahodit nad nové m17n stringy)... Takže si nejsem jistý, jestli výkřiky pythonistů typu "Ruby je sračka, my máme skvěle fungující Unicode" mají vůbec nějaký základ, protože z praktického hlediska to pořád může být situace tzv. "z deště pod okap".
Nejlépe je na tom momentálně asi .NET Framework, ač i ten myslím že zrovna tohle moc nezvládá (implementuje jen tzv. "basic case conversion", nikoli "full case conversion"). Musím se podívat, jak dobré je ICU (to je standardně pro C, C++ a Javu, což už je dobý základ.).
Já nevím. Já být Řek, tak logicky čekám, že u"ΣΟΦΟΣ".lower() -> u"σοφος". A teď ještě jak to zapnu. :-) Unicode na to háček má, v podmínce Final_Sigma v datech SpecialCasing.txt, a je to zmíněno i v implementation guidelines.
Prijde me to jako silne poruseni logickeho rozvrstveni funkci. Takovato pravidla IMHO patri o vrstvu vys, do nejake spravy jazyku, protoze jde o pravidlo rectiny, nikoliv recke znakove sady. Oproti tomu toupper, tolower funkce chapu jako operace v ramci znakovych sad (ktere vnimam ciste jako enumerace znaku plus nekolik elementarnich zobrazeni a rozkladu nad danou sadou bez dalsich jazykovych pravidel).
Obávám ze, že to takhle úplně vydělit nelze. Zrovna lowercase/titlecase/uppercase (třeba pro sigmu nebo holandské ij) se v Unicode řeší, ale Ty říkáš, že to tam nemá co dělat. Kdyby takhle jazyky a pravopisy fungovaly, neměli bychom pro ně humanitní lingvistiku, ale jen exaktní matematiku. :-)
Vážený pane, Unicode je průmyslový standard, který má (nebo je to jeho cíl) vyřešit jednotně kódvání znaků a práci s mezinárodními texty. Jako takový to tedy musí řešit komplexně a se vším všudy včetně třídění, převodu na malá/velká písmena, a řady dalších věcí. Ony průmyslové standardy mívají tu vlastnost, že zcela řeší problém (nebo se alespoň o to snaží) - nikoli jen přidávají další systetickou věc napůl použitelnou.
Dokonce ani Unicode není jeden standard - existuje Unicode a ISO 10646, máte tedy Unicode skupinu a ISO skupinu a samozřejmě z toho vyplývající další věci.
> Unicode je průmyslový standard, který má (nebo je to jeho cíl) vyřešit jednotně kódvání znaků a práci s mezinárodními texty.
Ano, ale kdyz to bude resit na nevhodne urovni abstrakce, tak to proste vyresit nepujde a nadela to vice skody nez uzitku. Nelze na urovni znakovych sad implementovat jazykova pravidla, protoze software na dane urovni abstrakce nema nezbytne informace. Napr. knihovni funkce toupper nevi nic o vyznamu dane posloupnosti řeckych znaku. Netusi, zda se jedna o slovo v rectine, o nasobeni nekolika promennych v matematice ci neco zcela jineho. V prvnim pripade by mohlo mit smysl, aby toupper upravil znak uprostred dane posloupnosti jinak nez na konci slova, v druhem pripade je to krajne nevhodne.
Já bych se k tomu taky přikláněl, aby se to vyřelišo nějakou vyšší vrstvou, i pokud jde o standardizaci. Hodně věcí v Unicode mi nedává kvůli tomuhle smysl - casing, UCA...zase je ale otázka, jestli ty vyšší funkce občas nepotřebují podporu nízkoúrovňové reprezentace. Ty hranice budou místy dost fuzzy... :-/
Jenže Unicode má několik vrstev. Prostě Unicode je základní znaková sada (bohužel okořeněná několika nejednoznačnými věcmi, což bych taky rád odboural).
A převod na malá/velká písmena přeci provádět nemusíte, stejně tak jako třídění a pod.. - ale když už jej provádíte, tak je to stejně závislé na jazyce tak jako tak. Nemusíte hned při práci s Unicode implem,entovat naprosto všechno co v Unicode a ISO standardech najdete.
Písmenka a jazyková pravidla bohužel vymýšleli lidi a nijak nepočítali s tím, že jej někdo bude chtít digitálně používat a zpracovávat. To bude asi ten pravý důvod. Pak se prostě tím balastem pravidel v mnoha jazycích nějak srovnat musíte - a je zase velmi dobré, že ty pravidla někdo určuje jednotně - a dokonce považte ten luxus, že jej všechna najdete na jednom místě.
Knihovní funkce toupper prostě už principu je závislá na jazyce a znakové sadě (na obojím naráz). Bez znalosti těchto dvou věcí jí nelze korektně implementovat. Ve starém C se to řešilo tak, že toupper prostě převáděla anglické znaky (vidíte, už tam - byť implicitně máte znalost jazyka). Převody mezi malými a velkými písmeny nelze vůbec bez znalosti jazyka nijak vyřešit. To znamená, že pokud toupper netuší nic o tom, že je to třeba řečtina, nemůže korektně převést znaky na velké písmo.
Navíc se takhle ztrácí například rozumná možnost konvertovat velké soubory po částech. Nebo co se stane při spojování řetězců? Mají se funkce typu strcat(), strncpy() apod. (o memcpy() nemluvě) vůbec starat o to, co v řetězci zrovna je?
strcat, strnpcy se už dnes stará o to co v řetězci je - minimálně musí najít koncovou nulu. a třeba dva řetězce v UTF-8 lze bez problémů spojit funkcí strcat, či jinými funkcemi pro zpracování osmibitových řetězců
funkce memcpy je dělaná pro binární data - té už je tuplem zcela jedno co máte v řetězci
No jasně, to byl příklad hnaný do absurdity. Chtěl jsem tím říct, že zkrátka ty funkce nemohou vědět, kde začíná nebo končí slovo, věta atd. a že by to podle mě neměl být ani jejich úkol.
Vysvětlení je triviální. Unicode má některé znaky předdefinované (třeba č). Vyjma toho má samotný háček, a je možné zapsat sekvenci háček-c. No a teď si představte, že v češtině máme možnost psát každý znak s háčkem, čárkou, přehláskou, a jakoukoliv jejich kombinací. Potom sekvenci háček-přehláska-c nemůžete rastrovat tak, že přehlásku a háček dáte přes sebe - je třeba další processing. A například arabské znaky mají jiný tvar samostatně, a jiný pohromadě (obdoba našich ligatur).
Když už autoři OpenType (pokračovatele TrueType a PS1 fontů) implementovali tyhle složitosti, dali fontům možnot nést třeba stylistické alternativy apod. Naštěstí tohle všechno dostáváme ve Windows zabalené v API, a nemusíme to řešit.
Mně to nemusíte vysvětlovat, nějaké ty znalosti paleografie a lingvistiky ve mně i po deseti letech ze školy zůstaly. ;-) Člověk s touhou po jednoduchosti se ovšem ptá, proč jazyková evoluce vyplodila takovéhle věci. (BTW, my na to samozřejmě taky máme API, takže to taky nemusíme řešit. Jak prosté! :-))
OpenType toho neumí mnohem víc, je to značně polovičaté řešení v případě jazyků, pro které není ve Windows vestavěná podpora. Sice jde o minoritní kultury, ale i tak - spousta jazykových věcí je v Uniscribe a spol. natvrdo zadrátovaná. Mně se přístup Graphite docela líbí, koneckonců SIL asi ani jinou možnost nemá než poskytnout hooky k implementaci vlastních jazykových pravidel. (Ten koncept, že výrobce operačního systému ani vykreslovací knihovny není vševědoucí lingvistický bůh, svědčí o jisté pokoře, která je mi sympatická. :-))