i18n
Soporte de internacionalización (i18n) y localización (i10n) en adJ
Comparación con OpenBSD
- Desde adJ 5.5 la librería de C soporta formatos para fecha y hora
particulares para cada país (categoria
LC_TIMEdel locale) y tablas para todos los países de latinoamérica y otros soportados por OpenBSD. También soporta xlocale completo. La mejora deLC_TIMEse aportó a OpenBSD desde que preparaba la versión 5.6, pero no ha sido integrada. - Desde adJ 5.4 la librería de C soporta formatos numéricos particulares de
cada país (categoria
LC_NUMERICdel locale) y tablas para todos los países de latinoamérica y otros soportados por OpenBSD. También soporta las funciones de xlocale relacionadas. Esta mejora se aportó a OpenBSD desde que preparaba la versión 5.5, pero no ha sido integrada. - Desde adJ 5.4 la librería de C soporta cantidades monetarias particulares
de cada país (categoria
LC_MONETARYdel locale) y tablas para todos los países de latinoamérica y otros soportados por OpenBSD. También soporta las funciones de xlocale relacionadas. Esta mejora se aportó a OpenBSD desde cuando se preparaba la versión 5.5, pero no ha sido integrada. - Desde adJ 5.2 la librería de C soporta cotejación (collation o categoria
LC_COLLATE) o ordenamiento alfabético en el idioma nativo con base en la implementación de FreeBSD, así como el programacolldefpara generar tablas de cotejación. Esta mejora se ha aportado a OpenBSD y se espera que en futuras versiones la integre (desde OpenBSD 5.3 no la incluyen aunque ayudamos desde esa versión y algunas posteriores para que las incluyeran).
Agradecemos una revisión para OpenBSD por parte de Stephan Sperling –todas sus sugerencias se incluyeron desde adJ 5.3. - Desde adJ 5.5 implementa todas las funciones del API xlocale para la librería de C. Esta mejora se ha aportado a cada versión que se prepara de OpenBSD.
- Desde adJ 5.2 en las funciones
strcasecmpywcscasecmpemplea la categoriaLC_CTYPEdel locale actual (como POSIX 2008 lo requiere aunque de forma ambigua), por lo que operan mejor para español y otros idiomas diferente al inglés –por ejemplo ñ y Ñ con estas funciones son equivalentes en adJ 5.2 mientras que no lo son en OpenBSD 5.4. Agradecemos una revisión por parte de Stephan Sperling y Matthew Dempsky, desarrolladores de OpenBSD. - Desde adJ 5.2 replica el locale (identificaciones culturales y de idioma
para un área geográfica) para España de OpenBSD y la tabla de cotejación
para España de FreeBSD para todos los paises de Latinoamérica y de habla
hispana. Esta mejora se aportó a OpenBSD y generó expectativa de la
comunidad que trajo solución en OpenBSD 5.4 (con especial atención a paises
hispanohablantes en la utilidad
locale). - Desde adJ 5.2 está configurado por defecto para emplear el locale
es_CO.UTF-8y la zona horaria America/Bogota, e incluye zonas horarias más recientes. - Desde adJ 5.2 incluye un porte de PostgreSQL que soporta cotejaciones en idioma nativo, con este por ejemplo sus consultas a la base de datos ordenando por nombre podrán estar ordenadas en español (y no con las palabras que comienzan con tilde o ñ al final que ocurre si usa cotejación en inglés). Esta mejora podrá aportarse al porte oficial una vez OpenBSD incluya cotejación (podría ser en 5.6 o posterior).
- Desde adJ 5.2 incluye un porte de xfe modificado para soportar cotejación en el idioma nativo (y mostrar listados de archivos en el orden correcto de acuerdo al locale), así como una nueva traducción a es_CO. Esta mejora se ha aportado a xfe y fue integrada en 1.37.
- Desde adJ 5.3 incluye tablas ctype actualizadas de NetBSD para varios locales (incluyendo los basados en UTF-8) –no ha sido posible la integración de esta mejora en OpenBSD propuesta desde que se preparaba la versión 5.4.
- Hemos aportados correcciones a fallas relacionadas con el locale a OpenBSD,
por ejemplo
!MB_CUR_MAXen OpenBSD 5.4 (resuelta en adJ 5.3).
Comparación con FreeBSD
- La implementación de xlocale de FreeBSD es segura en programas con hilos –multi-thread–, esto debido a que la implementación de pthreads en OpenBSD no soporta _Thread_local.
- La implementación de xlocale en FreeBSD no soporta en strcoll ni en
strxfrmcodificaciones multibyte, mientras que la implementación en adJ 5.2 parcialmente (por ahora UTF-8 cuando se codifica ISO-8859-1). Esta mejora se aportó a OpenBSD desde que se preparaba la versión 5.4 - La implementación de cotejación basada en la de FreeBSD fue enviada y auditada en la lista de OpenBSD. Agradecemos a Stephan Sperling con cuya ayuda prácticamente se reescribió. adJ emplea las tablas de cotejación de FreeBSD, pero la de español es mejorada pues en FreeBSD la ñ y la n son equivalentes, mientras que en adJ la ñ está entre la n y la o.
- Desde adJ 5.2 se prepararon pruebas de regresión para las implementaciones
de LC_COLLATE y de
xlocale, y desde adJ 5.4 para `LC_MONETARY y LC_NUMERIC. Esta mejora se aportó a OpenBSD desde que se preparaba la versión 5.4. - FreeBSD sólo incluye tablas con formatos monetarios, numéricos y de tiempo
para España pero no para los demás países de habla hispana.
En adJ hemos incluido estos datos para todos los paises de habla hispana con base en Unicode ( http://unicode.org/cldr/trac/browser/tags/release-1-9/posix/ ) , Wikipedia, glibc (particularmente el locale de Cuba que no está en POSIX), y hemos hecho consultas privadas a personas de otros paises y públicas en listas de correo de Internet. - En OpenBSD cada categoria para un locale de la forma
idioma_territorio.codificacion(e.ges_CO.UTF-8) se busca primero comoidioma_territorio.codificacion, después comoidioma.codificacióny después comocodificacion. En FreeBSD sólo se buscaidioma_territorio.codificacion. Esto permite que adJ (y OpenBSD en el caso deLC_CTYPE) tengan menos enlaces entre locales iguales y de valores por defecto más aproximados cuando no cuenta con datos de algún territorio o idioma. - FreeBSD incluye una extensión en
nl_langinfo!D_MD_ORDERque retorna"dm"si en el locale el día va antes del mes o"md"si primero va el mes. Para soportarla incluye en las tablas deLC_TIMEy en la estructuralc_time_Tde libc un campomd_orderque incluye esta cadena.
Consideramos que esto es redundante por cuanto las mismas tablas incluyenx_fmtque para todo locale tiene%d(o%e) y%m(o%b) y el orden en el que aparecen definen si va primero el dia o el mes.
En esta lógica consideramos que hay errores en las tablas de FreeBSD parahe_IL.UTF-8.srcylv_LV.UTF-8.srcque definenx_fmten%d/%m/%ypero definenmd_orderenmd. Aunque nos parece buena la extensión!D_MD_ORDERennl_langinfo, para evitar redundancia y errores en adJ preferimos eliminar de las tablas deLC_TIMEel campomd_order.
Otras Innovaciones
- Desde adJ 5.3 se incluyen las funciones
strcasecoll,strcasecoll_l,wcscasecollywcscasecoll_lpara comparar con cotejación de acuerdo al locale e ignorando mayúsculas y minúsculas. Se trata de una extensión a POSIX 2008, incluida con otros nombres en otros sistemas operativos, aunque se propuso para OpenBSD no fue aceptada.
En adJ muchos programas populares (e.g. chrome, pidgin, libreoffice)
emplean el locale que haya configurado para presentar información ordenada,
así que notará la diferencia. Por ejemplo en la captura de pantalla
siguiente puede ver el ordenamiento correcto en canales de Pidgin (note
primero á), en el diálogo para guardar una página de chrome (note la á
antes de la D) y en el PostgreSQL incluido en adJ 5.2 (note ACHÍ antes de
ACHIOTE). En las otras 2 terminales notará caracteres en griego en
vim y una forma fresca de ver el spam desde mutt :)
[http://aprendiendo.pasosdejesus.org/sites/APRENDIENDO.PASOSDEJESUS.ORG/spages/cotejaci%C3%B3n.png]
Así como se adaptó el porte de PostgreSQL, otros portes pueden requerir
activar el soporte de locale_t, así mismo muchas utilidades del sistema
base (empezando por ls) aún no emplean las funciones de cotejación.
Puede ayudar aportando parches para las fuentes y dialogando en
https://groups.google.com/forum/?fromgroups#!forum/OpenBSD-Colombia
Resumen del Uso
Un locale define una codificación y formas de presentar información
típicas de una región geográfica (números, valores monetarios, fechas,
horas, idioma y cotejación u ordenamiento lexicográfico del mismo).
adJ viene configurado por defecto con el locale es-CO.UTF-8 es decir en
español, para Colombia y con codificación UTF-8.
Puede examinar otros locales con
% locale -a
Los paises iberoaméricanos y sus respectivos locale que opera en adJ son (en lugar de UTF-8 también puede usar ISO-8859-1 e ISO-8859-15).
| País | locale |
| Argentina | es_AR.UTF-8 |
| Brazil | pt_BR.UTF-8 |
| Bolivia | es_BO.UTF-8 |
| Chile | es_CL.UTF-8 |
| Colombia | es_CO.UTF-8 |
| Costa Rica | es_CR.UTF-8 |
| Ecuador | es_EC.UTF-8 |
| El Salvador | es_SV.UTF-8 |
| España | es_ES.UTF-8 |
| Guinea Ecuatorial | es_GQ.UTF-8 |
| Guatemala | es_GT.UTF-8 |
| Hispanohablantes de Estados Unidos | es_US.UTF-8 |
| Honduras | es_HN.UTF-8 |
| México | es_MX.UTF-8 |
| Nicaragua | es_NI.UTF-8 |
| Panama | es_PA.UTF-8 |
| Perú | es_PE.UTF-8 |
| Puerto Rico | es_PR.UTF-8 |
| Paraguay | es_PY.UTF-8 |
| República Dominicana | es_DO.UTF-8 |
| Uruguay | es_UY.UTF-8 |
| Venezuela | es_VE.UTF-8 |
En UTF-8 puede codificarse UNICODE, que a su vez permite representar todos los
lenguajes escritos –la mayoría de lenguajes occidentales, incluyendo el
español, también puede codificarse con ISO8859-1, ISO8859-15 (con euro).
Elija el locale más apropiado para su país. Recomendamos que emplee
codificación UTF-8 y que establezca el locale en sus archivos
~/.fluxbox/startup y ~/.profile agregando o cambiando la línea:
export LANG=es_CO.UTF-8
Los programas estándares emplearan esta variable (y otras asociadas) para determinar el locale y modificaran la forma de presentar:
- Los mensajes, menús y ayudas para que sean en su idioma.
En adJ esto se soporta via el portegettext. - La codificación de caracteres para que sea la que prefiere.
En adJ se emplea el soporte de
LC_CTYPEde OpenBSD que entre otros es suficiente para ISO-8859-1/15 y UTF-8. - Los ordenamientos alfabéticos serán apropiados para su idioma (por ejemplo
en español la
álexicograficamente equivale a laa, y lañestá entre lany lao). En adJ se emplea una implementación mejorada sobre la de FreeBSD que es suficiente para el español en codificaciones ISO-8859-1, ISO-8859-15 y UTF-8 (aunque no basta para otros lenguajes soportados por UNICODE). - La forma de presentar números será la particular de la región geográfica elegida. Por ejemplo el número 1000000.2 de acuerdo al país se presenta así:
| Países | Número |
| Argentina, Bolivia, Brazil, Chile, Colombia, Ecuador, España, Guatemala, Honduras, Nicaragua, Panama, Paraguay, Peru, Republica Dominicana, Uruguay, Venezuela | 1.000.000,2 |
| Costa Rica, El Salvador, Honduras, México, Puerto Rico e hispanohablantes de Estados Unidos | 1,000,000.2 |
| Cuba | 1 000 000,2 |
- Los valores monetarios se presentan con las convenciones de la categoría
LC_MONETARYdel locale desde adJ 5.4. Por ejemplo el número -3456.78 como cantidad monetaria en cada locale de iberoamérica es:
| locale | Cantidad | Observaciones |
| es_AR | -$ 3.456,78 | |
| es_BO | -$b 3.456,78 | |
| es_CL | -$ 3.456,78 | |
| es_CO | -$ 3.456,78 | |
| es_CR | -₡ 3 456,78 | Con ISO8859-1 se usa ¢ en lugar de ₡ |
| es_DO | -RD$ 3,456.78 | |
| es_EC | -$ 3.456,78 | |
| es_ES | -3.456,78 € | Con ISO8859-1 se usa Eu en lugar de € |
| es_GQ | -FCFA 3.457 | |
| es_GT | -Q 3,456.78 | |
| es_HN | -L 3,456.78 | |
| es_MX | -$ 3,456.78 | |
| es_NI | -C$ 3,456.78 | |
| es_PA | -B/. 3,456.78 | |
| es_PE | -S/. 3,456.78 | |
| es_PR | -$ 3,456.78 | |
| es_PY | -Gs 3.456,78 | |
| es_SV | -US$ 3,456.78 | |
| es_UY | -$ 3.456,78 | |
| es_US | -$3,456.78 | |
| es_VE | -Bs 3.456,78 | |
| pt_BR | -R$3.456,78 |
- También la forma de presentar fecha y hora se ve afectada por el locale así
como por la zona horaria. La zona horaria se establece enlazando
/etc/localtimecon una de las zonas del directorio/usr/share/zoneinfo, en adJ se establece por defecto enAmerica/Bogota. El formato de fecha presentado por el comandodatevaría al cambiar el locale –aunque es común para todos los países de habla hispana:
| locale | date |
| es | mié oct 1 18:17:34 COT 2014 |
| pt_BR | Qua Out 1 18:18:54 COT 2014 |
| zh | 三 10 1 18:19:38 COT 2014 |
| ja | 水 10月 1 18:20:25 COT 2014 |
| ru | ср окт 1 18:20:45 COT 2014 |
| he | ד’ אוק 1 18:21:11 COT 2014 |
xterm
Puede iniciar una terminal que soporte codificación UTF-8 y que lea la
configuración de .profile con:
xterm -en utf8 -e /bin/ksh -l
tmux
Soporta la codificación de la terminal.
vim
Puede establecerse el idioma de los mensajes que vim presenta con el comando
:language, por ejemplo para establecer español de Colombia:
:language es_CO
Puede establecer esta configuración por defecto agregando el comando al
archivo ~/.vimrc.
vim puede emplear codificaciones diferentes para la terminal y para los
archivos, ambos se establecen con la variable encoding (o enc) y cada
uno en particular con termencoding (o tenc) y fileencoding (o fenc).
La forma recomendada es hacer que vim emplee la variable de ambiente
LANG (o LC_ALL y los tipos particulares), agregando esta configuración a
su archivo ~/.vimrc:
set encoding& " terminal charset: follows current locale but still not working so:
set termencoding=
set fileencodings= " charset auto-sensing: disabled
set fileencoding& " auto-sensed charset of current buffer
mutt
Si la terminal lo soporta, mutt puede emplear codificación UTF-8, y
enviar correos con esta codificación, agregando las siguientes líneas a
su archivo ~/.muttrc (que se espera codificado en UTF-8):
set config_charset=utf-8
set locale=es_CO.UTF-8
my_hdr Content-Type: text/plain\; charset=UTF-8\; format=flowed
my_hdr Content-Transfer-Encoding: 8bit
PostgreSQL
En la versión 9.1, puede examinar las cotejaciones disponibles ingresando al interprete psql y ejecutando:
SELECT * FROM pg_collation;
Puede crear una cotejación (digamos es_co_utf_8 pues deben ser nombres en
minúsculas) para un locale soportado por el sistema operativo (digamos
es_CO.UTF-8) con:
CREATE COLLATION es_co_utf_8 (LOCALE='es_CO.UTF-8');
Una vez creada puede realizar operaciones empleándola por ejemplo:
SELECT 'Á' < 'B' COLLATE "es_co_utf_8";
?column?
----------
t
(1 row)
...
SELECT nombre FROM clase ORDER BY nombre COLLATE "es_co_utf_8";
...
Puede crear columnas de tablas especificando el tipo de cotejación por defecto para operaciones con esa columna.
CREATE TABLE ejc (
nombre VARCHAR(100) COLLATE "es_co_utf_8"
);
o cambiar las existentes:
ALTER TABLE clase ALTER nombre TYPE VARCHAR(500) COLLATE "es_co_utf_8";
También podrá renombrar cotejaciones que haya creado asi como borrarlas, ver más en http://www.postgresql.org/docs/9.1/static/collation.html
Variables de entorno relacionadas con el locale
El locale consta de varias categorias, todas ellas se establecen en conjunto
con la variable de entorno LANG o bien con LC_ALL. Puede establecer unas
particulares con:
LC_MESSAGEidioma y codificación de mensajes, menús y en general todo escrito que un programa presente al usuarioLC_NUMERICvalores numéricosLC_MONETARYvalores monetariosLC_COLLATEcotejamientoLC_CTYPECodificación y clasificación (e.g minúsuclas, mayúsculas)LC_TIMEhora y fecha
En lenguaje de programación C
LC_NUMERIC: La bandera ‘ de la función printf presentará valores numéricos
de acuerdo a la categoria LC_NUMERIC del locale. Por ejemplo
setlocale(LC_ALL, "es_CO.UTF-8");
printf("%'f", 1000000.2)
Establece todas las categorias de locale, incluyendo LC_NUMERIC en
es_CO.UTF-8 e imprime el número como: 1.000.000,200000.
Puede examinar el locale numérico con la función localeconv y nl_langinfo.
LC_MONETARY: La función strfmon dará formato a un número como cantidad
monetaria de acuerdo a la categoria LC_MONETARY del locale. Por ejemplo
llamando el siguiente programa como ejfmon.c:
#include <locale.h>
#include <monetary.h>
#include <stdio.h>
int main() {
char col![512];
setlocale(LC_ALL, "es_CO.UTF-8");
strfmon(col, sizeof(col), "%n", -3456.781);
printf("%s\n", col);
return 0;
}
Y compilando con
% cc -o ejfmon ejfmon.c
Al ejecutarlo con ./ejfmon establecerá todas las categorias de locales,
incluyendo LC_MONETARY, en es_CO.UTF-8 e imprimirá -$ 3.456,78.
Puede examinar el locale monetario con la función localeconv.
LC_TIME: define como la función date interpreta sus especificadores de
conversión, así como la operación de las funciones strftime, wcsftime,
strptime y nl_langinfo.
Su operación puede verificarse con el comando date.