Tuesday, June 2, 2009

O diabo da acentuação (2)

Com a explosão da Internet, ficou sem sentido continuar usando sistemas de codificação de caracteres diferentes em cada parte do mundo. Mas para unificar, seria preciso uma codificação que não ia caber em um byte. Então a primeira tentativa foi usar dois bytes, o que permite códigos de \x0000 a \xFFFF, ou seja, 65536 caracteres distintos. Era o que propunham as primeiras versões do padrão Unicode. E assim várias linguagens, inclusive Java, adotaram uma representação interna de strings onde cada caractere equivale a dois bytes.

Outra idéia errada: 1 caractere == 2 bytes



Eu aprendi o que era Unicode estudando Java, e sempre achei normal que um caractere Unicode fosse representado por dois bytes em Java, numa codificação chamada UCS2. Até que em 2006 eu comecei a estudar a linguagem Ruby, e constatei que o suporte a Unicode em Ruby era mais primitivo que em Python. Fiquei surpreso porque o criador de Ruby, Yukihiro Matsumoto, é japonês, e a linguagem é muito popular no Japão.

Mas a propaganda aqui no ocidente é que o Unicode veio para resolver o problema das línguas orientais, então porque faltava um bom suporte em Ruby? Quem pesquisar um pouco o assunto vai descobrir que as primeiras versões do Unicode foram rejeitadas pelo chineses, japoneses e coreanos! Os principais motivos foram (1) a unificação de certos ideogramas que embora visualmente parecidos queriam dizer coisas diferentes e (2) a falta de uma especificação de como estender a codificação para além dos 2 bytes. O segundo ponto é interessante: quando se usa um alfabeto, uma nova palavra é apenas um novo arranjo das mesmas letras; mas em chinês, uma nova palavra pode ser um novo ideograma.

Para resolver este problema, é preciso abstrair um pouco mais...

Unicode é uma tabela de codepoints



O foco do padrão Unicode não é estabelecer uma relação entre caracteres e bytes, e sim uma relação entre caracteres e códigos numéricos chamados codepoints. Como estes codepoints serão representados na memória ou em um arquivo é uma questão secundária, até porque diferentes aplicações vão exigir diferentes representações: um formato bom para transmitir pode ser ruim para processar, por exemplo.

Na documentação do Unicode, os codepoints são identificados por números hexadecimais com o prefixo 'U+'. Veja uma pequena amostra de codepoints e caracteres:

U+6C23 氣 CJK UNIFIED IDEOGRAPH-6C23

U+06BF ڿ ARABIC LETTER TCHEH WITH DOT ABOVE

U+2620 ☠ SKULL AND CROSSBONES

U+0D0B ഋ MALAYALAM LETTER VOCALIC R

U+4DF1 ䷱ HEXAGRAM FOR THE CAULDRON

O texto eu caixa alta em cada linha acima é o atributo "name" do caractere, segundo a tabela Unicode. Além de letras de vários idiomas, o Unicode inclui também símbolos matemáticos, naipes do baralho e até hexagramas do I-Ching.

Vale a pena explorar o site oficial do Unicode, em particular as code charts (tabelas de código) onde os milhares de caracteres aparecem agrupados por idioma ou assunto.

No comments: