Meniu

O scurta introducere in UTF8

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.

0x00000000 - 0x0000007F: 0xxxxxxx
0x00000080 - 0x000007FF: 110xxxxx 10xxxxxx
0x00000800 - 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
0x00010000 - 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0x00200000 - 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0x04000000 - 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
Caracterele romanesti sunt serializate pe doi octeti in UTF8 dupa cum urmeaza:
a - 0xc3, 0xa2; a - 0xc3, 0x82;
a - 0xc4, 0x83; A - 0xc4, 0x82;
i - 0xc3, 0xae; I - 0xc3, 0x8e;
s - 0xc5, 0x9f; S - 0xc5, 0x9e;
t - 0xc5, 0xa3; T - 0xc5, 0xa2;

Exista trei lucruri despre care trebuie sa discutam in ceea ce priveste o setare de caractere diacritice romanesti sub Linux: setarea tastaturii, setarea fonturilor si setarea variabilei "locale".

Setare tastatura- Majoritatea tastaturilor comercializate in Romania sunt tastaturi de tip US. Aceasta se datoreste pretului dar si modului in care ne-am obisnuit sa avem literele asezate. Pe o asemenea tastatura putem mapa caracterele diacritice dupa cum urmeaza: cu tasta Alt din partea dreapta a barei de spatiu apasata, tastele a, s, t, i devin diacritice, iar tasta q devine a.

Pentru a obtine acest efect incepem prin a copia fisierul .Xmodmap in directorul home/user curent:
#cp /usr/lib/X11/etc/xmodmap.std .Xmodmap

Apoi, intr-un program de editare modificam .Xmodmap (sau cut&paste de aici). Rezultatul este urmatorul:
!
! $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:

FontPath "/usr/share/fonts/misc:unscaled"
FontPath "/usr/share/fonts/100dpi:unscaled"
FontPath "/usr/share/fonts/75dpi:unscaled"
FontPath "/usr/share/fonts/ttf-bitstream-vera"
FontPath "/usr/share/fonts/corefonts"
FontPath "/usr/share/fonts/Type1"
FontPath "/usr/share/fonts/TTF"
FontPath "/usr/share/fonts/freefont"
FontPath "/usr/share/fonts/artwiz"
FontPath "/usr/share/fonts/sharefonts"
FontPath "/usr/share/fonts/terminus"
FontPath "/usr/share/fonts/unifont"
Din anumite motive, programele de genul xterm au nevoie sa fie informate in mod exact care din fonturile din xorg sa le foloseasca. Adaugam/modificam urmatoarea linie in fisierul .Xresources in directorul home curent (daca este nevoie, creem un fisier nou cu acest nume):
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

Cu aceste modificari este timpul sa pornim xorg pentru ca setarea de tastatura si setarea de fonturi sa aiba efect. Presupunand ca totul a mers bine, deschidem o fereastra xterm iar in aceasta ferestra introducem:
# 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 test
Scopul 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 test
tocmai ati cheltuit o sumã indecentã de bani, si care "by default" nu stie
# sed s/stie/vrea/ test
Scopul 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:

// file test.c
#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!
#

Andreea

"Rome wasn't built in a day" !
  • | 120 articole

Nici un comentariu inca. Fii primul!
  • powered by Verysign