Fixer les problèmes d'encodage
5 septembre, 2008 - 10:42 | Ulhume | Formats et Standards Tutoriel

Aujourd'hui la majorité des grandes distributions est passée à l'encodage UTF-8, permettant l'affichage propre d'un large panel de symboles linguistiques. Maintenant lorsqu'il s'agit de vieux systèmes mis à jour, ou quant l'on en vient à utiliser des fichiers provenant notamment du monde Windows, il peut être utile de savoir comment unifier les encodages de sorte à garder un système de fichier propre.

Régler l'encodage du système

La première chose à vérifier est que le système est bien en UTF. Certains système que l'on a mis à jour à la main, sans passer par un ré-installation complète restent encore en ISO-8859-15. C'était mon cas pour une vielle configuration que j'avais fait progresser de Mandriva 7.2 jusqu'à aujourd'hui (on ne rigole pas ;-).

Sous Mandriva, il faut vérifier le fichier /etc/sysconfig/i18n qui doit contenir quelque chose comme cela :

LC_TELEPHONE=fr_FR.UTF-8
LC_CTYPE=fr_FR.UTF-8
LANGUAGE=fr_FR.UTF-8:fr
LC_MONETARY=fr_FR.UTF-8
LC_ADDRESS=fr_FR.UTF-8
LC_COLLATE=fr_FR.UTF-8
LC_PAPER=fr_FR.UTF-8
LC_NAME=fr_FR.UTF-8
LC_NUMERIC=fr_FR.UTF-8
SYSFONT=lat0-16
LC_MEASUREMENT=fr_FR.UTF-8
LC_TIME=fr_FR.UTF-8
LANG=fr_FR.UTF-8
LC_IDENTIFICATION=fr_FR.UTF-8
LC_MESSAGES=fr_FR.UTF-8

Après cela, on fait comme pour Windows, on reboot ;-) et le système passe tout seul en UTF-8. Une chose de faite...

SI même après cela vous êtes toujours en ISO en tant qu'utilisateur (pour savoir cela, lancez la commande locale dans une console non-root, vous devriez voir des fr_FR.UTF-8 apparaître), c'est sûrement que vous avez une configuration locale à votre compte. Regardez si vous n'auriez pas un fichier ~/.i18n et si c'est le cas, supprimez-le, déconnectez-vous et reconnectez-vous.

Sous un Windows XP récent, les systèmes de fichiers sont je crois maintenant encodés en UTF-8, de même que les partages. En revanche, il y a un hic avec Java qui persiste pour des raisons historiques à rester en ISO. Du coup, un environnement de développement comme Eclipse est spontanément ISO ce qui est loin d'être une idée de génie. Pour changer cela, il faut aller dans le paramétrage d'Eclipse, section Workspace, et changer l'encodage global de l'espace de travail. Cela ne va cependant pas modifier les fichiers déjà écrits en ISO mais juste assurer que l'encodage des prochains seront en UTF.

Les noms de fichiers

Une fois que le système est clairement en UTF-8, le point suivant sont les noms de fichiers. Soit, comme pour le point précédent, il s'agit d'un "vieux" système de fichier, soit plus régulièrement, c'est un Windowsien qui vous envoie une archive type Zip qui contient des encodages ISO et qui se décompresse tel-quel sur votre système de fichiers UTF-8.

Dans un cas, comme dans l'autre, il nous faut donc convertir chaque noms de fichier (pas leur contenu) en les renommant ce qui serait un peu fastidieux. Heureusement, une bonne âme a construit un outil qui remplis parfaitement cette tâche, convmv. Soit vous pouvez directement installer le paquet (ex. sous Mandriva, par un urpmi convmv), soit par les sources. Ensuite, la syntaxe est la suivante :

cd mon_dossier_a_convertir
convmv --notest -r -f iso-8859-15 -t utf-8 *

Les options -f et -t représentent respectivement l'encodage source (iso-8859-15) et cible (utf-8). L'option notest indique à l'outil que ce n'est pas une simulation (enlever cette option si vous voulez vérifier que tout se passe bien). L'option -r demande à traiter le dossier ainsi que tous les sous-dossier (récursif), à enlever donc si vous ne souhaiter traiter que le dossier courant. Enfin * indique qu'il fait traiter tout les fichiers, et il peut être remplacé par le nom d'un fichier unique à convertir.

Une fois l'opération terminé, vos noms fichiers doivent être lisibles.

Conversion des contenus

Là, nous sortons un peu du cadre de l'OS car les contenus textes sont très logiquement géré par les applications idoines. Pour convertir un contenu ISO en UTF, la commande magique est iconv utilisable comme ceci :

iconv --from-code=ISO-8859-1 --to-code=UTF-8 ancien_fichier.java -o ./nouveau_fichier.java

iconv est globalement moins sympa que convmv :

  • Pas de mode récursif.
  • Impossible d'écrire le fichier sur lui-même que ce soit par une redirection ou un -o, la sanction serait un fichier vide ;-)
  • Aucune vérification sur le fait que le fichier source soit effectivement codé en ISO.

Au fond, le vrai point problématique est le dernier, mais là, iConv n'y est pour rien. En effet, il n'y a aucun moyen fiable de savoir avec quel format est encodé un fichier texte. Il existe tout au plus des algorithmes permettant de le "deviner" mais plus le texte est cours, moins l'algorithme fonctionnera.

En somme, si vous avez un fichier ISO parmi une série d'UTF à convertir, utilisez la syntaxe précédente, quitte à gommer les deux premiers points par un petit script que vous pouvez par exemple coller dans les scripts Nautilus pour les avoir sur un click-droit :

#! /bin/sh

logger $PWD $1
iconv  --from-code=ISO-8859-1 --to-code=UTF-8 "$1" >  ~/tmp/iconv
mv ~/tmp/iconv "$1"
/.gnome2/nautilus-scripts/ISO to UTF

Maintenant si vous tenez à convertir un lot de fichier, cela peut être fait ainsi :

for fichier in $(find -type f . -name "*.java") do iconv --from-code=ISO-8859-1 --to-code=UTF-8 $fichier -c >> ~/tmp/iconv rm $fichier mv ~/tmp/iconv $fichier done

Conclusion

Avec ces deux trois astuces, vous devriez couvrir l'ensemble des cas de figures permettant d'importer chez vous des fichiers non-ISO ou de convertir en UTF des fichiers qui devrait l'être.

Si l'impact UTF/ISO est assez faible pour un utilisateur standard, il est beaucoup plus critique s'agissant par exemple d'un développeur. Dans ce cas, l'UTF devient un encodage commun à tous, quel que soit le pays ou la plateforme utilisée. Et c'est encore plus vrai dans le monde open source.

Commentaires

tuxce, le 5 septembre, 2008 - 13:21

pour ce qui est du redémarrage, il est meilleur pour avoir la totalité du système en utf8, mais se reconnecter ou relancer un service suffit à passer l'utilisateur ou le service en utf8, /etc/sysconfig/i18n étant lu par le fichier /etc/profile.

Dab, le 5 septembre, 2008 - 14:15

Et pour la route une petite fonction Perl d'encode en utf8:

sub enc2utf8 {
  my $text = shift;

  utf8::decode($text);
  $text = encode('utf-8', $text);

  return $text;
}

Ulhume, le 5 septembre, 2008 - 14:46

@tuxce s'était un peu l'idée, je veux dire d'avoir l'ensemble du système fonctionnel. Ceci dit, sous Mandriva, il ne semble pas que ce soit /etc/profile qui gère cet aspect des choses. Quant à pouvoir dire qui le fait...

Ulhume, le 5 septembre, 2008 - 14:46

@Dab attention, je vais te mettre la même en java sinon ;-)

Dab, le 5 septembre, 2008 - 15:10

Chiche ;)

tuxce, le 5 septembre, 2008 - 16:46

ben si normalement, c'est /etc/profile.d/*lang.csh (me rappelle plus du numéro)
mais c'était juste pour indiquer que le redémarrage n'est pas nécessaire ;-)

Ulhume, le 5 septembre, 2008 - 16:51

Je me fais chercher là, bon, ok :

function byte[] toUtf8(byte[] whatever, String from, string to) {
  String src = new String(whatever, from);
  return str.getBytes(to);
}

Vala :) en fait le truc en java c'est que les chaînes sont codées, en interne, en java. Donc de manière plus générale, si j'ai par exemple une volée de bytes codant une chaîne ISO, j'obtiens la chaîne UTF par un

String ma_chaîne_utf=new String(mes_octets_iso, "ISO-8859-15");

Dab, le 5 septembre, 2008 - 17:28

Oh ben fallait pas :)
Par contre ça t'oblige à connaitre le codage de la chaine.

Ex de la fonction Perl
j'ai deux fichiers avec des codages différents:
$file -i *
iso8859-1.txt: ISO-8859 text
utf8.txt: UTF-8 Unicode text

#!/usr/bin/perl

use File::Slurp qw( read_file );
use Encode;
use utf8;

my $encoding = "utf-8";

my $iso8859 = scalar read_file( "iso8859-1.txt" );
$iso8859 = encutf8($iso8859);
print $iso8859;

my $utf8 = scalar read_file( "utf8.txt" );
$utf8 = encutf8($utf8);
print $utf8;

Ulhume, le 5 septembre, 2008 - 17:36

@Dab
certes ça t'obliges à connaître l'encodage de la chaîne mais d'un autre côté, j'ai souvent planté perl qui se trompait d'encodage en cherchant à le deviner (typiquement avec un ou deux accentués sur un paragraphe).

Dab, le 5 septembre, 2008 - 17:52

Je dois te dire que j'ai uniquement testé en iso8859 et utf8, les seuls que j'utilise, dans ces cas ça traduit correctement. C'est cette méthode que j'utilise pour la traduction des fichiers en texte sur Catapulse.

Ulhume, le 5 septembre, 2008 - 17:56

@dab non mais ça marche très bien aussi sur les autres encodages, le seul truc c'est que lorsque tu utilises cela sur une phrase courte, ne contenant qu'un ou deux accents, il n'est pas sur de lui. Ce qui est normal je pense car rien de purement rationnel lui permet de déterminer l'encodage, c'est une pure heuristique.

Dab, le 5 septembre, 2008 - 18:37

Franchement je ne sais pas du tout sa manière d'y parvenir, ni beaucoup plus sur l'encodage:) mais je viens de tester avec une courte phrase et même avec un unique caractère et ... ça fonctionne encore. Maudit Perl, veut pas se tromper :)

Ulhume, le 5 septembre, 2008 - 19:26

@Dab bein moi je veux bien le voir me deviner l'encodage entre deux ISO différents ;-)

PS: c'est pas un challenge que je lance, y'a sûrement plus intéressant à faire de son temps ;-)

Dab, le 5 septembre, 2008 - 22:17

hmmm , si tu avais un fichier en esperanto (ISO-8859-3) sous la main, je veux bien tester ;)

fredg, le 6 septembre, 2008 - 12:35

Excellent, très instructif, merci.

++

Ulhume, le 6 septembre, 2008 - 23:34

@Dab J'ai pas cela en stock, mais tu dois pouvoir faire cela facilement en sauvant un texte avec gedit ou autre.

Ulhume, le 6 septembre, 2008 - 23:34

@fredg de rien :)

DrMick, le 25 mars, 2009 - 13:01
C'était mon cas pour une vielle configuration que j'avais fait progresser de Mandriva 7.2 jusqu'à aujourd'hui

Ben c'est surement pas moi qui rigolerais, vu que ... c'est exactement mon cas et la source de mes problemes actuels (apres passage direct de Mdv 2007 à Mdv 2009).

Alors merci pour toutes ces infos, que j'ai quand même mis 3 jours à trouver :).

DrMick

Poster un nouveau commentaire

Si vous avez détecté une erreur, coquille ou bêtises du même ordre, merci de plutôt passer par le formulaire de contact
Pour vous abonner au flux des commentaires sur cet article, clickez ici.
Pour répondre à quelqu'un, utilisez plutôt le lien répondre qui se trouve en haut (ou en bas) à gauche de son commentaire.
Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement. Si vous avez un compte gravatar, l'utilisez pour afficher votre avatar.
  • To highlight piece of code, just surround them with <code type="language"> Your code &tl;/code>>. Language can be java,c++,bash,etc... Everything Geshi support.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote> <div> <p> <br>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Every instance of custom tags in the input text will be replaced with a specific tool shortcut.

Plus d'informations sur les options de formatage

Êtes-vous humain ?
Cette question est là pour déterminer si vous êtes humain ou pas...