OVH Cloud OVH Cloud

Convertir un fichier de Mac Roman en UTF-8

19 réponses
Avatar
Sebastien
Bonjour à tous,

Je dois exploiter un fichier issu d'une Bas de données sous Mac. Je
reçois un fichier type CSV qui est très probablement codé en MAC OS
ROMAN, du moins il n'est pas en Latin-1, Windows-1252, ni UTF-8, car il
produit des caractères non reconnus.

Je passe sur le pourquoi, disons que je dois m'efforcer d'afficher ce
contenu dans des pages web qui seront en UTF-8.

J'ai touuvé (dans les contributions de http://fr3.php.net/htmlentities)
cette fonction qui encode en ISO-8859-1 :

<?php
/**
* Converts MAC OS ROMAN encoded strings to the ISO 8859-1 charset.
*
* @param string the string to convert.
* @return string the converted string.
*/
function mac_roman_to_iso($string)
{
return strtr($string,
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa1\xa4\xa6\xa7\xa8\xab\xac\xae\xaf\xb4\xbb\xbc\xbe\xbf\xc0\xc1\xc2\xc7\xc8\xca\xcb\xcc\xd6\xd8\xdb\xe1\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf1\xf2\xf3\xf4\xf8\xfc\xd2\xd3\xd4\xd5Ð",
"\xc4\xc5\xc7\xc9\xd1\xd6\xdc\xe1\xe0\xe2\xe4\xe3\xe5\xe7\xe9\xe8\xea\xeb\xed\xec\xee\xef\xf1\xf3\xf2\xf4\xf6\xf5\xfa\xf9\xfb\xfc\xb0\xa7\xb6\xdf\xae\xb4\xa8\xc6\xd8\xa5\xaa\xba\xe6\xf8\xbf\xa1\xac\xab\xbb\xa0\xc0\xc3\xf7\xff\xa4\xb7\xc2\xca\xc1\xcb\xc8\xcd\xce\xcf\xcc\xd3\xd4\xd2\xda\xdb\xd9\xaf\xb8\x22\x22\x27\x27-");
}
?>

Ensuite j'utilise quelque chose comme :

mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1');

pour passer en UTF-8.

Cela fonctionne assez bien mais le problème est qu'il reste des
caractères non reconnus, ou plutôt mal reconnus. Je suppose que la
focntion ne convertit pas tous les caractères problématiques, mais je
n'ai pas réussi à la modifier correctement (lorsque je rajoute des
caractères j'obtiens de résultats inattendus alors que je suis le
tableau de http://en.wikipedia.org/wiki/Mac_OS_Roman).

J'ai essayé de reproduire une fonction qui convertirait directement en
UTF-8 (avec les infos trouvées sur :
http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT) mais ça
ne fonctionne pas. De nombreuses subtilités doivent m'échapper.

PHP peut-il encoder directement du MAC ROMAN en ISO ? Connaissez-vous
une méthode efficace pour pallier le manque éventuel des fonctions
natives de PHP ?

Merci de votre aide,

Sébastien

9 réponses

1 2
Avatar
Sebastien
Je ne sais pas si tu le connais déjà, mais voici un autre lien
indispensable quand on veut y comprendre quelque chose à Unicode et
UTF-8 (entre autres choses, tu y comprendras la fonction code2utf) :
<http://www.cl.cam.ac.uk/~mgk25/unicode.html>.


Non je ne connaissais pas. Ca va prendre du temps à digérer...

Tout d'abord, s'il est correct de considérer æ, Æ, ½ et ¼ comme des
caractères à part entière, je pense que ce n'est pas le cas des
ligatures fi et fl (qui ne sont que graphiques). Du coup, pour faire
des recherches en mode texte, un besoin que tu as exprimé, il serait
peut-être préférable de les « dé-lier » plutôt que d'aller chercher des
caractères dans la zone « Alphabetic Presentation Forms ».


Oui et je pense que personne ne s'amuse à entrer des "æ" sous Windows
avec ALT + xxxx dans les champs de cherche et donc je vais aussi les
délier. Je pense à ajouter un argument à la fonction pour rendre le
choix optionnel.

Quant au logo
Apple, tu peux peut-être le supprimer ou le transformer en espace (comme
tu fais avec le vertical tab).


Exact, rien ne t'échappe ! Pour le logo Apple j'hésite entre une chaîne
vide et un espace. Je ne sais pas ce qui se justifie le plus.
Probablement une chaîne vide.

Tant que tu y es, tu peux aussi transformer en espace tout ce qui n'est
pas "x09" (tabulation), "x0A" (line feed) et "x0D" (carriage return).


Encore dans le mille. Ca donne donc en plus de la fonction précédente :

"x01"=>"x20", "x02"=>"x20", "x03"=>"x20", "x04"=>"x20",
"x05"=>"x20", "x06"=>"x20", "x07"=>"x20", "x08"=>"x20",
"x0B"=>"x20", "x0C"=>"x20", "x0E"=>"x20", "x0F"=>"x20",
"x10"=>"x20", "x11"=>"x20", "x12"=>"x20", "x13"=>"x20",
"x14"=>"x20", "x15"=>"x20", "x16"=>"x20", "x17"=>"x20",
"x18"=>"x20", "x19"=>"x20", "x1A"=>"x20", "x1B"=>"x20",
"x1C"=>"x20", "1D"=>"x20", "x1E"=>"x20", "x1F"=>"x20",
"xF0"=>"x20"

Sinon, question de présentation, j'aurais écrit "x0B"=>" " plutôt que
"xB"=>"x20" (les goûts et les couleurs, toussa).


Adopté, c'est plus cohérent.

Précision : ces caractères sont légaux en UNICODE mais pas autorisés en
SGML/HTML, sauf sous forme d'appel de caractère (&#xb; ou &#11;). La
forme "littérale" est interdite en HTML.


Je doute que ce soit très légal sous forme d'appel de caractère...
Mais je n'ai pas trouvé de doc explicite.


Je ne me prononcerai pas pour le SGML/HTML dans l'absolu, mais on peut
tester avec le validateur.
Caractère "littéral"
http://validator.w3.org/check?uriÚta%3Atext%2Fhtml%3Bcharset%3Dutf-8%2C%253C%21DOCTYPE%2520HTML%2520PUBLIC%2520%2522-%252F%252FW3C%252F%252FDTD%2520HTML%25204.01%252F%252FEN%2522%253E%250D%250A%253Ctitle%253Enon%2520SGML%2520character%2520number%2520146%253C%252Ftitle%253E%250D%250A%253Cp%253E%25C2%2592&charset=%28detect+automatically%29&doctype=Inline&ss=1&verbose=1

Appel numérique de caractère
http://validator.w3.org/check?uriÚta%3Atext%2Fhtml%3Bcharset%3Dutf-8%2C%253C%21DOCTYPE%2520HTML%2520PUBLIC%2520%2522-%252F%252FW3C%252F%252FDTD%2520HTML%25204.01%252F%252FEN%2522%253E%250D%250A%253Ctitle%253Ereference%2520to%2520non-SGML%2520character%253C%252Ftitle%253E%250D%250A%253Cp%253E%2526%2523146%253B&charset=%28detect+automatically%29&doctype=Inline&ss=1&verbose=1

Pour le validateur le premier est invalide alors que le second est
valide, bien que générant un avertissement.

Je posterai ma fonction complète demain, il est tard...

Merci encore,

Sébastien


Avatar
Olivier Miakinen

Tout d'abord, s'il est correct de considérer æ, Æ, ½ et ¼ comme des
caractères à part entière, je pense que ce n'est pas le cas des
ligatures fi et fl (qui ne sont que graphiques). Du coup, pour faire
des recherches en mode texte, un besoin que tu as exprimé, il serait
peut-être préférable de les « dé-lier » plutôt que d'aller chercher des
caractères dans la zone « Alphabetic Presentation Forms ».


Oui et je pense que personne ne s'amuse à entrer des "æ" sous Windows
avec ALT + xxxx dans les champs de cherche


Je le faisais, jusqu'à ce que je découvre ceci :
http://www.langue-fr.net/d/maj_accent/windows.htm#Liegeois

AltGr + a z o p = æ Æ ½ ¼

Note par ailleurs que certains logiciels de traitement de texte font
automatiquement les ligatures en fonction de leur dictionnaire (utilisé
aussi comme correcteur d'orthographe).

et donc je vais aussi les délier.


... et donc ça me semble une mauvaise idée, mais tout dépend en fait de
ce que fait ton application.

Je pense à ajouter un argument à la fonction pour rendre le
choix optionnel.


Ça en revanche, pourquoi pas. Mais ne pas rendre le traitement des
ligatures æ Æ ½ ¼ dépendant de celui des ligatures fi et fl. Si vraiment
tu veux une option aussi pour fi et fl, cela peut être un champ à trois
états :
- ne rien délier
- ne délier que fi et fl, pas æ Æ ½ ¼
- tout délier


--
Olivier


Avatar
dwojylac.nospam
Sebastien wrote:

Ton fichier si je comprends bien tu peux le convertir en local sur ta
machine avant de le télécharger ou de l'exploiter...


Si seulement ! Merci beaucoup pour ces suggestsions, mais...

Il s'agit en fait d'un fichier qui sera uploadé par la personne qui
exporte ledit fichier depuis l'application sur son Mac. L'upload se fait
donc sur le Mac à travers un formulaire web HTML.

L'objectif est que cette personne ait un minimum de manipulations
"techniques" à faire. Exporter au bon format et uploader est donc en
quelque sorte le max. que je puisse exiger...


Tu peux demander à cette personne de faire cette conversion avant son
upload.
textEdit est installé en standard sur tous les Mac (c'est un traitement
de texte simple qui ouvre même les .doc et .rtf).

Il suffit de lui indiquer qu'elle fait "Fichier > Ouvrir" et de choisir
en face de "Codage format texte" "Mac Os Roman" dans le menu local en
bas de la zone de dialogue.

Son fichier s'ouvre en format texte. Si ce n'est pas le cas (mais je ne
vois pas pourquoi) un coup de menu "Format" > "Convertir au format
texte"

puis "enregistrer sous..." et de choisir en face de "codage format
texte" "Windows latin 1" ou "UTF8" (à toi de lui préciser) dans le
dialogue d'enregistrement en bas de la fenêtre...

je ne vois pas ce qui complique et qui soit hors de portée d'un macounet
moyen...

On doit même pouvoir faire un apple script qui fait ça pour elle
automatiquement et qu'elle lance avant l'upload...

Quelle appli utilise-t-elle sur mac pour gérer sa base ?

--
Dominique Wojylac http://wojylac.free.fr
Un proverbe chinois dit que lorsqu'on a rien à dire
on cite généralement un proverbe chinois.


Avatar
Sebastien
Oui et je pense que personne ne s'amuse à entrer des "æ" sous Windows
avec ALT + xxxx dans les champs de cherche


Je le faisais, jusqu'à ce que je découvre ceci :
http://www.langue-fr.net/d/maj_accent/windows.htm#Liegeois


Ca a l'air excellent, je vais essayer. (oh l'ironie du "Ca" !)

et donc je vais aussi les délier.


... et donc ça me semble une mauvaise idée, mais tout dépend en fait de
ce que fait ton application.


Je sais que ce n'est pas correct dans de nombreux cas (cf.
http://fr.wikipedia.org/wiki/Ligature_(typographie) ), mais je ne sais
pas si j'ai envie de rentrer à ce niveau de détail. Il faudrait une
liste de mots à conserver, mais en français et en anglais, voir d'autres
langues...

J'ai déjà repéré des "choeurs" avec ligature dans le fichier source.
L'application étant destinée au web, je m'attends à trouver
(éventuellement) des recherches sur ce mot sans ligature. J'ai fait le
test et lorsque je conserve la ligature, MySQL ne retourne pas les
enregistrements lors d'une recherche sur choeurs (sans ligature donc).

Ça en revanche, pourquoi pas. Mais ne pas rendre le traitement des
ligatures æ Æ ½ ¼ dépendant de celui des ligatures fi et fl. Si vraiment
tu veux une option aussi pour fi et fl, cela peut être un champ à trois
états :
- ne rien délier
- ne délier que fi et fl, pas æ Æ ½ ¼
- tout délier


Voir fonction plus bas.
Je ne suis pas satisfait de la logique de la fonction dans le traitement
des cas (précision : je ne suis pas progammeur de formation).

En fait le cas 'none' (ne rien délier) n'est jamais exploité en tant que
tel. Je ne sais pas si c'est correct/bien comme approche.
D'autre part il peut y avoir 2 passages, dans les cas
$break_ligatures='fifl' et $break_ligatures='all', ce qui peut être
lourd, mais je ne sais pas comment faire autrement.

J'ai testé a fonction avec les différents paramètres et pour le fichier
test (limité), elle fonctionne correctement. Malheureusement je n'ai pas
de Mac mais si quelqu'un (Dominique ?) pouvait me fournir un fichier
avec tous les caractères ce serait très apprécié (Je ne connais pas de
moyen de générer du MacRoman autrement, sous Windows ou sur le web...)

Sébastien

<?php
function MacRoman_to_utf8($str, $break_ligatures='none')
{
// $break_ligatures : 'none' | 'fifl' | 'all'
// 'none' : don't break any MacRoman ligatures, transform them into
their utf-8 counterparts
// 'fifl' : break only fi ("xDE" => "fi") and fl ("xDF"=>"fl")
// 'all' : break fi, fl and also AE ("xAE"=>"AE"), ae
("xBE"=>"ae"), OE ("xCE"=>"OE") and oe ("xCF"=>"oe")

if($break_ligatures == 'fifl')
{
$str = strtr($str, array("xDE"=>"fi", "xDF"=>"fl"));
}

if($break_ligatures == 'all')
{
$str = strtr($str, array("xDE"=>"fi", "xDF"=>"fl", "xAE"=>"AE",
"xBE"=>"ae", "xCE"=>"OE", "xCF"=>"oe"));
}

$str = strtr($str, array("x80"=>"xC3x84", "x81"=>"xC3x85",
"x82"=>"xC3x87", "x83"=>"xC3x89", "x84"=>"xC3x91",
"x85"=>"xC3x96", "x86"=>"xC3x9C", "x87"=>"xC3xA1",
"x88"=>"xC3xA0", "x89"=>"xC3xA2", "x8A"=>"xC3xA4",
"x8B"=>"xC3xA3", "x8C"=>"xC3xA5", "x8D"=>"xC3xA7",
"x8E"=>"xC3xA9", "x8F"=>"xC3xA8", "x90"=>"xC3xAA",
"x91"=>"xC3xAB", "x92"=>"xC3xAD", "x93"=>"xC3xAC",
"x94"=>"xC3xAE", "x95"=>"xC3xAF", "x96"=>"xC3xB1",
"x97"=>"xC3xB3", "x98"=>"xC3xB2", "x99"=>"xC3xB4",
"x9A"=>"xC3xB6", "x9B"=>"xC3xB5", "x9C"=>"xC3xBA",
"x9D"=>"xC3xB9", "x9E"=>"xC3xBB", "x9F"=>"xC3xBC",
"xA0"=>"xE2x80xA0", "xA1"=>"xC2xB0", "xA2"=>"xC2xA2",
"xA3"=>"xC2xA3", "xA4"=>"xC2xA7", "xA5"=>"xE2x80xA2",
"xA6"=>"xC2xB6", "xA7"=>"xC3x9F", "xA8"=>"xC2xAE",
"xA9"=>"xC2xA9", "xAA"=>"xE2x84xA2", "xAB"=>"xC2xB4",
"xAC"=>"xC2xA8", "xAD"=>"xE2x89xA0", "xAE"=>"xC3x86",
"xAF"=>"xC3x98", "xB0"=>"xE2x88x9E", "xB1"=>"xC2xB1",
"xB2"=>"xE2x89xA4", "xB3"=>"xE2x89xA5", "xB4"=>"xC2xA5",
"xB5"=>"xC2xB5", "xB6"=>"xE2x88x82", "xB7"=>"xE2x88x91",
"xB8"=>"xE2x88x8F", "xB9"=>"xCFx80", "xBA"=>"xE2x88xAB",
"xBB"=>"xC2xAA", "xBC"=>"xC2xBA", "xBD"=>"xCExA9",
"xBE"=>"xE6", "xBF"=>"xC3xB8", "xC0"=>"xC2xBF",
"xC1"=>"xC2xA1", "xC2"=>"xC2xAC", "xC3"=>"xE2x88x9A",
"xC4"=>"xC6x92", "xC5"=>"xE2x89x88", "xC6"=>"xE2x88x86",
"xC7"=>"xC2xAB", "xC8"=>"xC2xBB", "xC9"=>"xE2x80xA6",
"xCA"=>"xC2xA0", "xCB"=>"xC3x80", "xCC"=>"xC3x83",
"xCD"=>"xC3x95", "xCE"=>"xC5x92", "xCF"=>"xC5x93",
"xD0"=>"xE2x80x93", "xD1"=>"xE2x80x94", "xD2"=>"xE2x80x9C",
"xD3"=>"xE2x80x9D", "xD4"=>"xE2x80x98", "xD5"=>"xE2x80x99",
"xD6"=>"xC3xB7", "xD7"=>"xE2x97x8A", "xD8"=>"xC3xBF",
"xD9"=>"xC5xB8", "xDA"=>"xE2x81x84", "xDB"=>"xE2x82xAC",
"xDC"=>"xE2x80xB9", "xDD"=>"xE2x80xBA", "xDE"=>"xEFxACx81",
"xDF"=>"xEFxACx82", "xE0"=>"xE2x80xA1", "xE1"=>"xC2xB7",
"xE2"=>"xE2x80x9A", "xE3"=>"xE2x80x9E", "xE4"=>"xE2x80xB0",
"xE5"=>"xC3x82", "xE6"=>"xC3x8A", "xE7"=>"xC3x81",
"xE8"=>"xC3x8B", "xE9"=>"xC3x88", "xEA"=>"xC3x8D",
"xEB"=>"xC3x8E", "xEC"=>"xC3x8F", "xED"=>"xC3x8C",
"xEE"=>"xC3x93", "xEF"=>"xC3x94", "xF0"=>"xEFxA3xBF",
"xF1"=>"xC3x92", "xF2"=>"xC3x9A", "xF3"=>"xC3x9B",
"xF4"=>"xC3x99", "xF5"=>"xC4xB1", "xF6"=>"xCBx86",
"xF7"=>"xCBx9C", "xF8"=>"xC2xAF", "xF9"=>"xCBx98",
"xFA"=>"xCBx99", "xFB"=>"xCBx9A", "xFC"=>"xC2xB8",
"xFD"=>"xCBx9D", "xFE"=>"xCBx9B", "xFF"=>"xCBx87",
"x01"=>"x20", "x02"=>"x20", "x03"=>"x20", "x04"=>"x20",
"x05"=>"x20", "x06"=>"x20", "x07"=>"x20", "x08"=>"x20",
"x0B"=>"x20", "x0C"=>"x20", "x0E"=>"x20", "x0F"=>"x20",
"x10"=>"x20", "x11"=>"x20", "x12"=>"x20", "x13"=>"x20",
"x14"=>"x20", "x15"=>"x20", "x16"=>"x20", "x17"=>"x20",
"x18"=>"x20", "x19"=>"x20", "x1A"=>"x20", "x1B"=>"x20",
"x1C"=>"x20", "1D"=>"x20", "x1E"=>"x20", "x1F"=>"x20", "xF0"=>""));

return $str;
}
?>


Avatar
Olivier Miakinen

Je le faisais, jusqu'à ce que je découvre ceci :
http://www.langue-fr.net/d/maj_accent/windows.htm#Liegeois


Ca a l'air excellent, je vais essayer. (oh l'ironie du "Ca" !)


« Ça ! »

(Étonnant, non ? À toi d'en faire autant, si le c½ur t'en dit...)

Je sais que ce n'est pas correct dans de nombreux cas (cf.
http://fr.wikipedia.org/wiki/Ligature_(typographie) ), mais je ne sais
pas si j'ai envie de rentrer à ce niveau de détail. Il faudrait une
liste de mots à conserver, mais en français et en anglais, voir d'autres
langues...


Une autre possibilité consisterait à stocker en base deux versions de
chaque texte : la version originale, et la version en ascii pur (avec ½
remplacé par oe, mais aussi é par e, À par A, Ñ par N, etc.).

[...]
Je ne suis pas satisfait de la logique de la fonction dans le traitement
des cas (précision : je ne suis pas progammeur de formation).


Ben dis donc, chapeau alors, vu la rapidité avec laquelle tu as
implémenté chacune des idées que je te proposais.

J'ai testé a fonction avec les différents paramètres et pour le fichier
test (limité), elle fonctionne correctement. Malheureusement je n'ai pas
de Mac mais si quelqu'un (Dominique ?) pouvait me fournir un fichier
avec tous les caractères ce serait très apprécié (Je ne connais pas de
moyen de générer du MacRoman autrement, sous Windows ou sur le web...)


Hahaha... ça c'est trivial !

<?php
header("Content-Type: text/plain; charset=macintosh");

// On affiche directement les 128 derniers caractères
for ($idx8; $idx<256; $idx++) {
echo chr($idx);
}

// Là on passe par une chaîne, pour stocker *tous* les
// caractères, y compris les caractères de contrôle,
// et même x00.
$result ="";
for ($idx = 0; $idx < 256; $idx++) {
if ($idx % 16 == 0) {
$result .= "n";
}
$result .= "<" . chr($idx) . ">";
}
echo $result;
?>

Résultat ici :
<http://www.miakinen.net/tmp/allchars.php>

Note que dans ton cas tu n'as pas besoin du charset "macintosh" puisque
tu vas transformer les caractères en UTF-8, mais la boucle pour $idx
allant de 0 (inclus) à 256 (exclu) te donnera la liste de tous les
caractères possibles.

[...]
// 'all' : break fi, fl and also AE ("xAE"=>"AE"), ae


Alors ça c'est extraordinaire. Je ne sais pas s'ils l'ont fait exprès,
mais mettre le caractère AE à la position AE, c'est grandiose.
Note au passage que tu as oublié un dans le commentaire ("xAE").

$str = strtr($str, array("xDE"=>"fi", "xDF"=>"fl", "xAE"=>"AE",
"xBE"=>"ae", "xCE"=>"OE", "xCF"=>"oe"));


Tiens, tu l'as oublié ici aussi, ce qui est plus gênant.

[...]
"x01"=>"x20", "x02"=>"x20", "x03"=>"x20", "x04"=>"x20",
"x05"=>"x20", "x06"=>"x20", "x07"=>"x20", "x08"=>"x20",
"x0B"=>"x20", "x0C"=>"x20", "x0E"=>"x20", "x0F"=>"x20",
"x10"=>"x20", "x11"=>"x20", "x12"=>"x20", "x13"=>"x20",
"x14"=>"x20", "x15"=>"x20", "x16"=>"x20", "x17"=>"x20",
"x18"=>"x20", "x19"=>"x20", "x1A"=>"x20", "x1B"=>"x20",
"x1C"=>"x20", "1D"=>"x20", "x1E"=>"x20", "x1F"=>"x20", "xF0"=>""));


Tu peux rajouter "x00" => "" et "x7F"=>"x20". Le premier parce que
contrairement au C tu peux avoir un caractère nul dans une chaîne PHP,
le second parce que c'est aussi un caractère de contrôle (DEL).

--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)


Avatar
Sebastien

Tu peux demander à cette personne de faire cette conversion avant son
upload.
[...]

je ne vois pas ce qui complique et qui soit hors de portée d'un macounet
moyen...



J'espère que non, mais je veux aussi limiter le nombre d'opérations. Si
je trouve le moyen de supprimer la nécessité d'une opération (c'est y
est, globalement, grâce à la fonction de conversion) côté utilisateur,
le risque d'erreurs diminue avec le nombre d'opérations que je ne
contrôle pas (en admettant que je ne fasse pas d'erreur de mon côté :)).
Il peut aussi y avoir différentes personnes côté utilisateur et chacun
devra apprendre cette manip qui, si elle n'est pas insurmontable, ne
leur est peut-être pas naturelle...

On doit même pouvoir faire un apple script qui fait ça pour elle
automatiquement et qu'elle lance avant l'upload...



Là je ne sais pas faire, et ça reste une opération à faire (et à
laquelle il faut penser) côté utilisateur.

Quelle appli utilise-t-elle sur mac pour gérer sa base ?



FileMaker Pro 7

Avatar
Sebastien
(Étonnant, non ? À toi d'en faire autant, si le c½ur t'en dit...)


:)

C'est absolument sublime ! Enfin des guillemets français au bout des
doigts (adieu Alt + 174 / Alt + 175). Et l'apotrophe française, et
l'espace insécable, les tirets cadratin et demi-cadratin... Pourquoi
n'avais-je jamais entendu parler de cet outil !? Encore merci !

Je sais que ce n'est pas correct dans de nombreux cas (cf.
http://fr.wikipedia.org/wiki/Ligature_(typographie) ), mais je ne sais
pas si j'ai envie de rentrer à ce niveau de détail. Il faudrait une
liste de mots à conserver, mais en français et en anglais, voir d'autres
langues...


Une autre possibilité consisterait à stocker en base deux versions de
chaque texte : la version originale, et la version en ascii pur (avec ½
remplacé par oe, mais aussi é par e, À par A, Ñ par N, etc.).


En effet c'est déjà plus faisable. Mais ça reviendrait à doubler tous
les champs pouvant contenir du texte non-ASCII. Et ça implique une
deuxième conversion (macRoman_to_ascii). Ça serait quand même formidable
de pouvoir rechercher "choeur" et d'afficher "ch½ur". Je verrai si j'ai
le courage de me lancer...

Ben dis donc, chapeau alors, vu la rapidité avec laquelle tu as
implémenté chacune des idées que je te proposais.


Merci, ça fait quand même trois jours que je planche dessus, et tes
encouragements ne sont pas pour rien dans ma persévérence.

<?php
header("Content-Type: text/plain; charset=macintosh");

[...]
?>


Damned ! Ça ne m'était pas venu à l'esprit ! Mais si je ne m'abuse, on
utilise ici les capacités du serveur et non celles de PHP, celui-ci ne
gérant pas le codage Macintosh...

Résultat ici :
<http://www.miakinen.net/tmp/allchars.php>


Tiens, tiens... Mon cher Opera s'obstine à interprêter les < et > comme
des balises, malgré le "text/plain". De plus il n'affiche pas
correctement les caractères. Firefox a plus de succès.

Alors ça c'est extraordinaire. Je ne sais pas s'ils l'ont fait exprès,
mais mettre le caractère AE à la position AE, c'est grandiose.


J'avais remarqué aussi, ça ne m'étonnerait pas du tout.

Note au passage que tu as oublié un dans le commentaire ("xAE").


$str = strtr($str, array("xDE"=>"fi", "xDF"=>"fl", "xAE"=>"AE",
"xBE"=>"ae", "xCE"=>"OE", "xCF"=>"oe"));



Tiens, tu l'as oublié ici aussi, ce qui est plus gênant.


Merci, c'est corrigé. J'ai fait une recherche sur "x dans la fonction et
je n'en ai pas trouvé d'autres.

Tu peux rajouter "x00" => "" et "x7F"=>"x20". Le premier parce que
contrairement au C tu peux avoir un caractère nul dans une chaîne PHP,
le second parce que c'est aussi un caractère de contrôle (DEL).



Ajoutés. Je m'étais posé la question de x7F parce qu'il n'est pas défini
du tout dans http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT

Merci encore d'avoir décortiqué et débuggé mon travail d'amateur !

En fin de post, la fonction avec les ajouts et corrections (x7F est au
début).


Sébastien


<?php
function MacRoman_to_utf8($str, $break_ligatures='none')
{
// $break_ligatures : 'none' | 'fifl' | 'all'
// 'none' : don't break any MacRoman ligatures, transforma them into
their utf-8 counterparts
// 'fifl' : break only fi ("xDE" => "fi") and fl ("xDF"=>"xEFxACx82")
// 'all' : break fi, fl and also AE ("xAE"=>"xC3x86"), ae
("xBE"=>"xE6"), OE ("xCE"=>"xC5x92") and oe ("xCF"=>"xC5x93")

if($break_ligatures == 'fifl')
{
$str = strtr($str, array("xDE"=>"fi", "xDF"=>"fl"));
}

if($break_ligatures == 'all')
{
$str = strtr($str, array("xDE"=>"fi", "xDF"=>"fl", "xAE"=>"AE",
"xBE"=>"ae", "xCE"=>"OE", "xCF"=>"oe"));
}

$str = strtr($str, array("x7F"=>"x20", "x80"=>"xC3x84",
"x81"=>"xC3x85", "x82"=>"xC3x87", "x83"=>"xC3x89",
"x84"=>"xC3x91", "x85"=>"xC3x96", "x86"=>"xC3x9C",
"x87"=>"xC3xA1", "x88"=>"xC3xA0", "x89"=>"xC3xA2",
"x8A"=>"xC3xA4", "x8B"=>"xC3xA3", "x8C"=>"xC3xA5",
"x8D"=>"xC3xA7", "x8E"=>"xC3xA9", "x8F"=>"xC3xA8",
"x90"=>"xC3xAA", "x91"=>"xC3xAB", "x92"=>"xC3xAD",
"x93"=>"xC3xAC", "x94"=>"xC3xAE", "x95"=>"xC3xAF",
"x96"=>"xC3xB1", "x97"=>"xC3xB3", "x98"=>"xC3xB2",
"x99"=>"xC3xB4", "x9A"=>"xC3xB6", "x9B"=>"xC3xB5",
"x9C"=>"xC3xBA", "x9D"=>"xC3xB9", "x9E"=>"xC3xBB",
"x9F"=>"xC3xBC", "xA0"=>"xE2x80xA0", "xA1"=>"xC2xB0",
"xA2"=>"xC2xA2", "xA3"=>"xC2xA3", "xA4"=>"xC2xA7",
"xA5"=>"xE2x80xA2", "xA6"=>"xC2xB6", "xA7"=>"xC3x9F",
"xA8"=>"xC2xAE", "xA9"=>"xC2xA9", "xAA"=>"xE2x84xA2",
"xAB"=>"xC2xB4", "xAC"=>"xC2xA8", "xAD"=>"xE2x89xA0",
"xAE"=>"xC3x86", "xAF"=>"xC3x98", "xB0"=>"xE2x88x9E",
"xB1"=>"xC2xB1", "xB2"=>"xE2x89xA4", "xB3"=>"xE2x89xA5",
"xB4"=>"xC2xA5", "xB5"=>"xC2xB5", "xB6"=>"xE2x88x82",
"xB7"=>"xE2x88x91", "xB8"=>"xE2x88x8F", "xB9"=>"xCFx80",
"xBA"=>"xE2x88xAB", "xBB"=>"xC2xAA", "xBC"=>"xC2xBA",
"xBD"=>"xCExA9", "xBE"=>"xE6", "xBF"=>"xC3xB8",
"xC0"=>"xC2xBF", "xC1"=>"xC2xA1", "xC2"=>"xC2xAC",
"xC3"=>"xE2x88x9A", "xC4"=>"xC6x92", "xC5"=>"xE2x89x88",
"xC6"=>"xE2x88x86", "xC7"=>"xC2xAB", "xC8"=>"xC2xBB",
"xC9"=>"xE2x80xA6", "xCA"=>"xC2xA0", "xCB"=>"xC3x80",
"xCC"=>"xC3x83", "xCD"=>"xC3x95", "xCE"=>"xC5x92",
"xCF"=>"xC5x93", "xD0"=>"xE2x80x93", "xD1"=>"xE2x80x94",
"xD2"=>"xE2x80x9C", "xD3"=>"xE2x80x9D", "xD4"=>"xE2x80x98",
"xD5"=>"xE2x80x99", "xD6"=>"xC3xB7", "xD7"=>"xE2x97x8A",
"xD8"=>"xC3xBF", "xD9"=>"xC5xB8", "xDA"=>"xE2x81x84",
"xDB"=>"xE2x82xAC", "xDC"=>"xE2x80xB9", "xDD"=>"xE2x80xBA",
"xDE"=>"xEFxACx81", "xDF"=>"xEFxACx82", "xE0"=>"xE2x80xA1",
"xE1"=>"xC2xB7", "xE2"=>"xE2x80x9A", "xE3"=>"xE2x80x9E",
"xE4"=>"xE2x80xB0", "xE5"=>"xC3x82", "xE6"=>"xC3x8A",
"xE7"=>"xC3x81", "xE8"=>"xC3x8B", "xE9"=>"xC3x88",
"xEA"=>"xC3x8D", "xEB"=>"xC3x8E", "xEC"=>"xC3x8F",
"xED"=>"xC3x8C", "xEE"=>"xC3x93", "xEF"=>"xC3x94",
"xF0"=>"xEFxA3xBF", "xF1"=>"xC3x92", "xF2"=>"xC3x9A",
"xF3"=>"xC3x9B", "xF4"=>"xC3x99", "xF5"=>"xC4xB1",
"xF6"=>"xCBx86", "xF7"=>"xCBx9C", "xF8"=>"xC2xAF",
"xF9"=>"xCBx98", "xFA"=>"xCBx99", "xFB"=>"xCBx9A",
"xFC"=>"xC2xB8", "xFD"=>"xCBx9D", "xFE"=>"xCBx9B",
"xFF"=>"xCBx87", "x00"=>"x20", "x01"=>"x20", "x02"=>"x20",
"x03"=>"x20", "x04"=>"x20", "x05"=>"x20", "x06"=>"x20",
"x07"=>"x20", "x08"=>"x20", "x0B"=>"x20", "x0C"=>"x20",
"x0E"=>"x20", "x0F"=>"x20", "x10"=>"x20", "x11"=>"x20",
"x12"=>"x20", "x13"=>"x20", "x14"=>"x20", "x15"=>"x20",
"x16"=>"x20", "x17"=>"x20", "x18"=>"x20", "x19"=>"x20",
"x1A"=>"x20", "x1B"=>"x20", "x1C"=>"x20", "1D"=>"x20",
"x1E"=>"x20", "x1F"=>"x20", "xF0"=>""));

return $str;
}
?>


Avatar
Olivier Miakinen

C'est absolument sublime ! Enfin des guillemets français au bout des
doigts (adieu Alt + 174 / Alt + 175). Et l'apotrophe française, et
l'espace insécable, les tirets cadratin et demi-cadratin... Pourquoi
n'avais-je jamais entendu parler de cet outil !? Encore merci !


Attention quand même que l'apostrophe et les tirets ne font pas partie
d'ISO-8859-1 ni d'ISO-8859-15 : aucun problème pour le web, mais
inutilisable pour écrire dans les groupes de nouvelles.

Une autre possibilité consisterait à stocker en base deux versions de
chaque texte : la version originale, et la version en ascii pur (avec ½
remplacé par oe, mais aussi é par e, À par A, Ñ par N, etc.).


En effet c'est déjà plus faisable. Mais ça reviendrait à doubler tous
les champs pouvant contenir du texte non-ASCII.


Oui.

Et ça implique une deuxième conversion (macRoman_to_ascii).


Tu peux à la place faire une conversion utf8_to_ascii, qui resterait
utilisable le jour où tu auras des utilisateurs sur d'autres systèmes
que MacRoman.

<?php
header("Content-Type: text/plain; charset=macintosh");

[...]
?>


Damned ! Ça ne m'était pas venu à l'esprit ! Mais si je ne m'abuse, on
utilise ici les capacités du serveur et non celles de PHP, celui-ci ne
gérant pas le codage Macintosh...


Eh bien tu t'abuses ! Il s'agit exclusivement des capacités du
navigateur, le serveur quant à lui ne gérant que des octets sans
se préoccuper le moins du monde de savoir si c'est du MacRoman, de
l'UTF-8 ou de l'EBCDIC.

Tiens, tiens... Mon cher Opera s'obstine à interprêter les < et > comme
des balises, malgré le "text/plain". De plus il n'affiche pas
correctement les caractères. Firefox a plus de succès.


J'ai essayé avec Internet Explorer, c'est encore pire (preuve que c'est
bien le navigateur qui attache une signification à ces octets).

D'ailleurs, quel que soit le charset déclaré (voire si tu n'en mets
aucun), tu peux demander à Firefox de changer sa façon d'interpréter ces
mêmes octets grâce au menu « Affichage / Encodage des caractères ».
En choisissant ISO-8859-5 tu verras du cyrillique, avec ISO-8859-6 de
l'arabe, du grec moderne avec ISO-8859-7, de l'hébreu pour ISO-8859-8,
etc. Et pourtant, le contenu est strictement le même : un octet de
valeur 128, un autre de valeur 129, etc. jusqu'à 255, puis rebelote à
partir de 0.


Avatar
dwojylac.nospam
Sebastien wrote:

Quelle appli utilise-t-elle sur mac pour gérer sa base ?
FileMaker Pro 7



Dans la version 6 et sur Mac on ne peut pas choisir le format d'encodage
des fichiers exportés alors que dans la version Windows il me semble que
oui. (en tout cas c'est dit dans la doc)

Dans la version 8 cela a été implémenté (dans le dialogue de choix des
champs exportés, en bas, après avoir donné le type et le nom du fichier
d'export) et Latin 1 et UTF8 sont bien présents.

Je ne sais pas ce qu'il en est dans la version 7 macintosh, mais cela
vaudrait peut-être la peine de vérifier.

--
Dominique Wojylac http://wojylac.free.fr
Un proverbe chinois dit que lorsqu'on a rien à dire
on cite généralement un proverbe chinois.


1 2