Acest articol este o scurta introducere in UTF8 din perspectiva sistemului de operare Linux. Articolul este dedicat tuturor celor ce intampina in mod regulat dificultati in setarea caracterelor diacritice romanesti in diferite programe sub Linux. Toate exemplele de mai jos au fost incercate pe o distributie Gentoo, si se presupune ca pot fi replicate cu usurinta si pe alte tipuri de distributii.
Scopul declarat al acestui articol este de a va lasa cu impresia ca orice este posibil, inclusiv sa folositi litere precum s si t pe un calculator pe care tocmai ati cheltuit o suma indecenta de bani, si care "by default" nu stie decat engleza.
UTF-8 - Standardul ASCII (American Standard Code for Information Interchange) sta la baza seturilor de caractere folosite in toate sistemele de operare moderne. A fost adoptat in anul 1968 sub numele ANSIX3.4. Conform ASCII, caracterele limbii engleze sunt mapate in numere intregi pe 8 biti. Aceasta mapare acopera 256 de caractere literare si de control diferite. Bineinteles, 256 de caractere nu acopera toate limbile globului, asadar in decursul timpului alte forme de mapare au fost definite. Dupa o serie de iteratii s-a ajuns la Unicode.
Originile standardului Unicode pot fi trasate catre Bell Laboratories care ne-au adus in decursul timpului limbajul de programare C, sistemul de operare Unix iar mai tarziu C++. Mecanismul a fost descris mai intai de Ken Thompson si Robert Pike in anul 1993, ca stand la baza sistemului de procesare de text in noul lor sistem de operare Plan9. A fost preluat apoi de X/Open Group si inclus in ghidul de portabilitate intitulat XPG4 care sta la baza specificatie Unix98.
Adoptat de catre ISO in 1996 devine astfel standard international sub numele de ISO-10646. Acest standard este suportat sub Linux, iar unele distributii (spre exemplu Fedora) sunt setate default pentru UTF8.
Dupa cum se mentioneaza la http://www.unicode.org/, standardul Unicode prevede un cod numeric unic pentru fiecare caracter, pe orice platforma hardware, in orice program software, si in orice limba. Unicode este compatibil cu standardul ASCII astfel incat un document tiparit in ASCII poate fi interpretat corect in Unicode, dar nu si invers.
Caracterele romanesti sunt reprezentate de urmatoarele coduri Unicode:
a - U00e2; a - U00C2;
a - U0103; A - U0102;
i - U00ee; I - U00ce;
s - U015f; S - U015e;
t - U0163; T - U0162;
UTF8 este in esenta o metoda de serializare a codurilor de caractere Unicode pe mai multi octeti.
#cp /usr/lib/X11/etc/xmodmap.std .Xmodmap
! ! $XFree86: xc/programs/Xserver/hw/xfree86/etc/xmodmap.std,v 3.4 1996/02/04 09:09:12 dawes Exp $ ! ! Standard key mapping for XFree86 (for US keyboards). ! ! This file can be fed to xmodmap to restore the default mapping. ! ! $XConsortium: xmodmap.std /main/7 1996/02/21 17:48:55 kaleb $ ! ! First, clear the modifiers ! clear shift clear lock clear control clear mod1 clear mod2 clear mod3 clear mod4 clear mod5 ! ! Set the mapping for each key ! keycode 8 = keycode 9 = Escape keycode 10 = 1 exclam keycode 11 = 2 at keycode 12 = 3 numbersign keycode 13 = 4 dollar keycode 14 = 5 percent keycode 15 = 6 asciicircum keycode 16 = 7 ampersand keycode 17 = 8 asterisk keycode 18 = 9 parenleft keycode 19 = 0 parenright keycode 20 = minus underscore keycode 21 = equal plus keycode 22 = BackSpace keycode 23 = Tab keycode 24 = q Q 0x000e2 0x000c2 keycode 25 = w W keycode 26 = e E keycode 27 = r R keycode 28 = t T U00163 U00162 keycode 29 = y Y keycode 30 = u U keycode 31 = i I 0x000ee 0x000ce keycode 32 = o O keycode 33 = p P keycode 34 = bracketleft braceleft keycode 35 = bracketright braceright keycode 36 = Return keycode 37 = Control_L keycode 38 = a A U00103 U00102 keycode 39 = s S U0015f U0015e keycode 40 = d D keycode 41 = f F keycode 42 = g G keycode 43 = h H keycode 44 = j J keycode 45 = k K keycode 46 = l L keycode 47 = semicolon colon keycode 48 = apostrophe quotedbl keycode 49 = grave asciitilde keycode 50 = Shift_L keycode 51 = backslash bar keycode 52 = z Z keycode 53 = x X keycode 54 = c C keycode 55 = v V keycode 56 = b B keycode 57 = n N keycode 58 = m M keycode 59 = comma less keycode 60 = period greater keycode 61 = slash question keycode 62 = Shift_R keycode 63 = KP_Multiply keycode 64 = Alt_L Meta_L keycode 65 = space keycode 66 = Caps_Lock keycode 67 = F1 keycode 68 = F2 keycode 69 = F3 keycode 70 = F4 keycode 71 = F5 keycode 72 = F6 keycode 73 = F7 keycode 74 = F8 keycode 75 = F9 keycode 76 = F10 keycode 77 = Num_Lock keycode 78 = Multi_key keycode 79 = KP_Home KP_7 keycode 80 = KP_Up KP_8 keycode 81 = KP_Prior KP_9 keycode 82 = KP_Subtract keycode 83 = KP_Left KP_4 keycode 84 = NoSymbol KP_5 keycode 85 = KP_Right KP_6 keycode 86 = KP_Add keycode 87 = KP_End KP_1 keycode 88 = KP_Down KP_2 keycode 89 = KP_Next KP_3 keycode 90 = KP_Insert KP_0 keycode 91 = KP_Delete KP_Decimal !keycode 92 = X386Sys_Req keycode 93 = keycode 94 = keycode 95 = F11 keycode 96 = F12 ! keycodes 97-107 are not available on 84-key keyboards keycode 97 = Home keycode 98 = Up keycode 99 = Prior keycode 100 = Left keycode 101 = Begin keycode 102 = Right keycode 103 = End keycode 104 = Down keycode 105 = Next keycode 106 = Insert keycode 107 = Delete keycode 108 = KP_Enter keycode 109 = Control_R keycode 110 = Pause keycode 111 = Print keycode 112 = KP_Divide !keycode 113 = Alt_R Meta_R keycode 114 = Break ! keycodes 115-117 are only available on some extended keyboards ! (e.g., Microsoft's ergonomic keyboard). keycode 115 = Meta_L keycode 116 = Meta_R keycode 117 = Menu ! ! Set the modifiers ! add shift = Shift_L Shift_R add lock = Caps_Lock add control = Control_L Control_R add mod1 = Alt_L ! If you have ServerNumlock set in your XF86Config, you can comment out keysym Alt_R = Mode_switch add mod2 = Mode_switch ! ! ! ! If you use any of the special default key mappings in Xconfig, they should be ! duplicated in this file. Mappings should be added before the section above ! which sets the modifiers. ! ! For the key specs: ! LeftAlt => keycode 64 ! RightAlt => keycode 113 ! AltGr => keycode 113 ! ScrollLock => keycode 78 ! RightCtl => keycode 109 ! ! For the mappings: ! Meta => Alt_L Meta_L ! Alt_R Meta_R ! Compose => Multi_key ! ModeShift => Mode_switch ! ModeLock => Mode_switch X386Mode_Lock ! ScrollLock => Scroll_Lock ! Control => Control_R ! ! If you use ModeShift or ModeLock, the following modifier must be set: ! !add mod5 = Mode_switch ! ! For example, to get the equivalent of: ! ! ScrollLock ModeLock ! RightAlt ModeShift ! LeftAlt Meta ! RightCtl Compose ! ! use the following: ! !keycode 78 = Mode_switch X386Mode_Lock !keycode 113 = Mode_switch !keycode 64 = Alt_L Meta_L !keycode 109 = Multi_key ! !add mod5 = Mode_switch ! When using ServerNumLock in your XF86Config, the following codes/symbols ! are available in place of 79-81, 83-85, 87-91 !keycode 136 = KP_7 !keycode 137 = KP_8 !keycode 138 = KP_9 !keycode 139 = KP_4 !keycode 140 = KP_5 !keycode 141 = KP_6 !keycode 142 = KP_1 !keycode 143 = KP_2 !keycode 144 = KP_3 !keycode 145 = KP_0 !keycode 146 = KP_Decimal !keycode 147 = Home !keycode 148 = Up !keycode 149 = Prior !keycode 150 = Left !keycode 151 = Begin !keycode 152 = Right !keycode 153 = End !keycode 154 = Down !keycode 155 = Next !keycode 156 = Insert !keycode 157 = Delete
Setare fonturi - In marea lor majoritate, fonturile instalate de xorg suporta UTF-8. Este totusi recomandat sa incarcam o serie de alte fonturi:
emerge freetype corefonts freefonts artwiz-fonts sharefonts terminus-font ttf-bitstream-vera unifont
Apoi modificam /etc/X11/xorg.conf dupa cum urmeaza:
xterm*font: -Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO10646-1 Trebuie apoi sa adaugam la inceputul fisierului .xinitrc urmatoarele doua linii: xrdb -merge .Xresources xmodmap .Xmodmap
# xterm -u8&(xterm ruleaza default fara suport UTF8). O noua ferestra xterm se deschide, iar aceasta are suportul dorit:
# ãastiÃaSÞI
O serie de alte emulatore de terminal sub X au suport pentru UTF8, de exemplu rxvt-unicode si gnome-terminal. Majoritatea comenzilor de tip UNIX suporta utf8, iar ca editoare de text as mentiona abiword si gedit.
Setare "locale" - Pentru a facilita procesul de internationalizare a programelor de calculator, in standardul limbajului C au fost introduse asa numitele "locales". Implementate ca environment variables, fiecare dintre ele specifica o conventie privind modul in care un program trebuie sa prelucreze un anumit tip de informatie. Spre exemplu, LC_TIME este folosit pentru a formata timpul potrivit regulilor limbii respective, iar LC_MESSAGES este folosit pentru afisare textelor generate de program (cum ar fi meniurile, help, etc) in limba respectiva.
De mentionat ca acesta setare pentru locale este optionala. In cazul in care nu o facem, programele respective vor continua sa prelucreze mai departe text romanesc fara probleme, daca au suport initial pentru UTF8. Deci, daca nu ne deranjeaza meniurile de genul Open/Save/Find, putem sarii linistiti la capitolul urmator.
Incepem cu un mic experiment. Intr-o fereastra de terminal introducem comanda locale:
# locale LANG= LC_CTYPE="POSIX" LC_NUMERIC="POSIX" LC_TIME="POSIX" LC_COLLATE="POSIX" LC_MONETARY="POSIX" LC_MESSAGES="POSIX" LC_PAPER="POSIX" LC_NAME="POSIX" LC_ADDRESS="POSIX" LC_TELEPHONE="POSIX" LC_MEASUREMENT="POSIX" LC_IDENTIFICATION="POSIX" LC_ALL=
Daca arata ca mai sus, inseamna ca variabila locale nu a fost setata inca. Setarea se face in felul urmator:
# export LANG=ro_RO.UTF-8 # locale LANG=ro_RO.UTF-8 LC_CTYPE="ro_RO.UTF-8" LC_NUMERIC="ro_RO.UTF-8" LC_TIME="ro_RO.UTF-8" LC_COLLATE="ro_RO.UTF-8" LC_MONETARY="ro_RO.UTF-8" LC_MESSAGES="ro_RO.UTF-8" LC_PAPER="ro_RO.UTF-8" LC_NAME="ro_RO.UTF-8" LC_ADDRESS="ro_RO.UTF-8" LC_TELEPHONE="ro_RO.UTF-8" LC_MEASUREMENT="ro_RO.UTF-8" LC_IDENTIFICATION="ro_RO.UTF-8" LC_ALL=
O serie intreaga de programe au fost deja traduse in limba romana (AbiWord, xmms, gedit, gnome-terminal, etc). Pornite din aceasta fereastra xterm, textul romanesc din meniurile programului va fi afisat corect.
Pentru programatori - Mesajul de la Bell Labs este deosebit de clar: il lasam pe utilizator sa-si bata capul cu setarea de tastatura si setarea de fonturi, iar instantaneu o serie intreaga de programe scrise cu mult timp in urma vor functiona corect.
# cat testScopul declarat al acestui articol este de a vã lãsa cu impresia cã orice este posibil, inclusiv sã folositi litere precum s si t pe un calculator pe care tocmai ati cheltuit o sumã indecentã de bani, si care "by default" nu stie decat englezã.
# grep stie testtocmai ati cheltuit o sumã indecentã de bani, si care "by default" nu stie
# sed s/stie/vrea/ testScopul declarat al acestui articol este de a vã lãsa cu impresia cã orice este posibil, inclusiv sã folositi litere precum s si t pe un calculator pe care tocmai ati cheltuit o sumã indecentã de bani, si care "by default" nu vrea decat englezã.
Singurul lucru de care trebuie sa tinem cont este ca editorul pe care-l folosim sa suporte UTF8:
#include int main() { printf("Salut, sarpe!n"); return 0; }
gcc este alt program caruia nu-i pasa daca textul este unicode sau nu:
# gcc test.c # ./a.out Salut, sarpe! #