Discussion:
php yaml et encodage
(trop ancien pour répondre)
Une Bévue
2012-02-16 14:19:45 UTC
Permalink
je lis un fichier "setup.yaml" écrit par ruby, il est encodé en UTF-8 NO
BOM.

pour lire son contenu, depuis PHP, je fais :
$setup=yaml_parse_file('../setup.yaml');
$parameters_a=$setup['parameters_a'];
// $parameters_a est une array de hashes :
print_r($parameters_a);
echo "<br />";
foreach ($parameters_a as $key => $value) {
echo "$key => $value<br />";
foreach ($value as $cle => $valeur){
echo "$cle => $valeur<br />";
echo utf8_decode ($cle) . " => " . utf8_decode ($valeur) . "<br />";
}
echo "<br />";
}
echo "<br /><br />";

ce que j'obtiens, par exemple :
group => Médical // correspond à echo "$cle => $valeur<br />";
group => Médical // correspond à echo utf8_decode ($cle) . " => " .
utf8_decode ($valeur) . "<br />";

mon fichier php a le header :
header("Content-Type: text/html;charset=utf-8");
et mon butineur (Google Chrome 16 et Firefox 10) voient bien ce fichier
comme étant en UTF-8

la doc d'utf8_decode() dit qu'utf8_decode() décode la chaîne data, en
supposant qu'elle est au format UTF-8, et la convertit au format ISO-8859-1.

donc le flux parsé par yaml_parse_file('../setup.yaml')
est mal décodé ??? je ne comprends pas pourquoi utf8_decode me donne de
l'UTF-8, ce que j'espérais obtenir dès le départ...

sur la doc :
<http://www.php.net/manual/fr/function.yaml-emit-file.php>
il y a bien une option, à l'écriture correspondant à l'encodage.
mais sur la doc de yaml_parse_file :
<http://www.php.net/manual/fr/function.yaml-parse-file.php>
il n'y est pas fait mention d'une option spécifiant l'encodage...

je suis sous :
.-(~)--------------------------------------------------------(***@D620)-
`--> uname -a
Linux D620 3.0.0-16-generic #28-Ubuntu SMP Fri Jan 27 17:44:39 UTC 2012
x86_64 x86_64 x86_64 GNU/Linux

le php utilisé :
PHP Version 5.3.6-13ubuntu3.6
les infos concernant yaml :LibYAML Support enabled
Module Version 1.0.1
LibYAML Version 0.1.4

Directive Local Value Master Value
yaml.decode_binary 0 0
yaml.decode_timestamp 0 0
yaml.output_canonical 0 0
yaml.output_indent 2 2
yaml.output_width 80 80


dans le fichier setup.yml d'origine, M"dical est codé ainsi :
M\xC3\xA9dical
Olivier Miakinen
2012-02-16 15:50:35 UTC
Permalink
Bonjour,
Post by Une Bévue
je lis un fichier "setup.yaml" écrit par ruby, il est encodé en UTF-8 NO
BOM.
$setup=yaml_parse_file('../setup.yaml');
[...]
foreach ($parameters_a as $key => $value) {
echo "$key => $value<br />";
foreach ($value as $cle => $valeur){
echo "$cle => $valeur<br />";
echo utf8_decode ($cle) . " => " . utf8_decode ($valeur) . "<br />";
}
echo "<br />";
}
echo "<br /><br />";
group => Médical // correspond à echo "$cle => $valeur<br />";
group => Médical // correspond à echo utf8_decode ($cle) . " => " .
utf8_decode ($valeur) . "<br />";
Le contenu du fichier setup.yaml ne serait-il pas « doublement encodé »
en UTF-8 ? Le caractère « é », par exemple, qui se code en principe en
deux octets C3 et A9, ne serait-il pas codé par quatre octets C3, 83,
C2 et A9 ?
Post by Une Bévue
header("Content-Type: text/html;charset=utf-8");
et mon butineur (Google Chrome 16 et Firefox 10) voient bien ce fichier
comme étant en UTF-8
Merci d'avoir ainsi écarté l'autre hypothèse qui serait un mauvais
Content-Type.
Post by Une Bévue
la doc d'utf8_decode() dit qu'utf8_decode() décode la chaîne data, en
supposant qu'elle est au format UTF-8, et la convertit au format ISO-8859-1.
donc le flux parsé par yaml_parse_file('../setup.yaml')
est mal décodé ??? je ne comprends pas pourquoi utf8_decode me donne de
l'UTF-8, ce que j'espérais obtenir dès le départ...
<http://www.php.net/manual/fr/function.yaml-emit-file.php>
il y a bien une option, à l'écriture correspondant à l'encodage.
<http://www.php.net/manual/fr/function.yaml-parse-file.php>
il n'y est pas fait mention d'une option spécifiant l'encodage...
La doc est assez sommaire, du coup je n'arrive pas à deviner ce que sont
censés faire les différents choix d'encodage.
Post by Une Bévue
Directive Local Value Master Value
yaml.decode_binary 0 0
Et ça, tu sais ce que ça veut dire ?
Post by Une Bévue
dans le fichier setup.yml d'origine, M"dical
Médical je suppose.
Post by Une Bévue
M\xC3\xA9dical
Ah. Et \xC3 est censé représenter un octet ou un caractère ?
Est-ce que ça ne fonctionnerait pas mieux en écrivant « Médical »
plutôt que « M\xC3\xA9dical » ? Tu as une doc de la syntaxe de
ce setup.yml ou setup.yaml (tu parles des deux) ?

Soit dit en passant, si le setup.yml est la même chose que le
setup.yaml dont tu parlais au début, et s'il est donc « encodé
en UTF-8 NO BOM » (je te cite), alors je ne vois pas pourquoi
s'embêter avec des \xNN illisibles au lieu de mettre les vrais
caractères ! En effet, je ne connaissais pas YAML, mais une
recherche Google m'indique que la syntaxe YAML a été conçue
spécifiquement pour être facilement lisible par les gens
plutôt que par les machines.

Cordialement,
--
Olivier Miakinen
Une Bévue
2012-02-16 17:24:17 UTC
Permalink
Post by Olivier Miakinen
Soit dit en passant, si le setup.yml est la même chose que le
setup.yaml dont tu parlais au début, et s'il est donc « encodé
en UTF-8 NO BOM » (je te cite), alors je ne vois pas pourquoi
s'embêter avec des \xNN illisibles au lieu de mettre les vrais
caractères ! En effet, je ne connaissais pas YAML, mais une
recherche Google m'indique que la syntaxe YAML a été conçue
spécifiquement pour être facilement lisible par les gens
plutôt que par les machines.
bonsoir,

oui, oui, il n'y a qu'un fichier "setup.yml" écrit par ruby 1.8.x sous
Mac OS X et lu par php 5.3.6 sous Xubuntu 11.10.

le é de "Médical" est codé \xC3\xA9 par le module yaml de ruby.

mais bon, je commence à piger ce qui se passe.

en fait "Médical" est une string provenant du carnet d'adresse, je
suppose qu'elle est en UTF-8 "à la mac OS X" c'est-à-dire quelque chose
comme :
"Me'dical", l'accent du é étant placé à côté du e.

plutôt que "bidouiller" côté php, je devrais regarder, côté ruby/yaml
comment transcoder en UTF-8 "ordinaire"...

bon côté php la doc n'est pas terrible effectivement.
il y a même une fonction non implémentée :
$res=yaml_emit_file ( 'yaml-write.yml', $data , YAML_UTF8_ENCODING);//
line 39
// Warning: yaml_emit_file(): not yet implemented in
/home/yt/Sites/php/yaml-write.php on line 39
Post by Olivier Miakinen
Post by Une Bévue
Directive Local Value Master Value
yaml.decode_binary 0 0
Et ça, tu sais ce que ça veut dire ?
oui :
yaml.decode_binary boolean
Off par défaut, si mis à on : permet le décodage des entités binaires
base64 ayant le tag explicite "tag:yaml.org,2002:binary".
cf. <http://php.net/manual/fr/yaml.configuration.php>

en tout cas, merci bien d'avoir répondu, sans avoir la solution, je sais
(devine) mieux d'où vient le problème...
Une Bévue
2012-02-16 18:18:02 UTC
Permalink
Post by Une Bévue
plutôt que "bidouiller" côté php, je devrais regarder, côté ruby/yaml
comment transcoder en UTF-8 "ordinaire"...
bon, je viens d'essayer en ligne de commande :
$ iconv -f UTF-8-MAC -t UTF-8 setup.yaml > setup-utf8.yaml
pas de chance, ça me donne tjs :
M\xC3\xA9dical
pour Médical
--
« Les conneries c'est comme les impôts,
on finit toujours par les payer. »
(Michel Audiard)
Olivier Miakinen
2012-02-16 20:35:07 UTC
Permalink
Post by Une Bévue
Post by Une Bévue
plutôt que "bidouiller" côté php, je devrais regarder, côté ruby/yaml
comment transcoder en UTF-8 "ordinaire"...
$ iconv -f UTF-8-MAC -t UTF-8 setup.yaml > setup-utf8.yaml
M\xC3\xA9dical
Haha... ça tu aurais dû t'en douter. Parce que, jusqu'à preuve du
contraire, les caractères « \ », « x », « C », « 3 », « A » et « 9 »
qui sont dans ton fichier setup.yaml, c'est de l'ASCII 7 bits, et
ils n'ont qu'une seule représentation possible en UTF-8 !

Mais plutôt que de lancer un outil tel que iconv, tu devrais essayer
d'éditer ton fichier avec un éditeur de texte, y rajouter un simple
« é », et sauver le résultat (en UTF-8 sans BOM) avant de le donner
en pâture à PHP.
Une Bévue
2012-02-16 22:56:06 UTC
Permalink
Post by Olivier Miakinen
Mais plutôt que de lancer un outil tel que iconv, tu devrais essayer
d'éditer ton fichier avec un éditeur de texte, y rajouter un simple
« é », et sauver le résultat (en UTF-8 sans BOM) avant de le donner
en pâture à PHP.
mouais, mais bon, ça ne me plait pas parce que ce fichier est généré
automatiquement.
je viens de vérifier, ça se passe du côté de yaml/ruby.
si je fais un print-out des données avant yaml, c'est bon...

pourtant je lis :
<http://stackoverflow.com/questions/488694/how-to-set-the-character-enco
ding-in-a-yaml-file>

The YAML 1.1 spec (which you link to) says that UTF-8 is implied if
there is no BOM, and that BOM's should be output only on UTF-16 docs. So
the presence of a BOM, and the BOM if it exists, are the only ways to
define the encoding.
--
« Les conneries c'est comme les impôts,
on finit toujours par les payer. »
(Michel Audiard)
Une Bévue
2012-02-16 23:10:00 UTC
Permalink
Post by Une Bévue
je viens de vérifier, ça se passe du côté de yaml/ruby.
si je fais un print-out des données avant yaml, c'est bon...
si je fais un aller/retour yaml :
yaml_obj = YAML::dump( @choosen_groups_a )

# -> "M\xC3\xA9dical"

ruby_obj = YAML::load( yaml_obj )

# -> Médical

yaml/ruby retrouve ses petits...
--
« Les conneries c'est comme les impôts,
on finit toujours par les payer. »
(Michel Audiard)
Olivier Miakinen
2012-02-16 23:52:58 UTC
Permalink
Post by Une Bévue
Post by Olivier Miakinen
Mais plutôt que de lancer un outil tel que iconv, tu devrais essayer
d'éditer ton fichier avec un éditeur de texte, y rajouter un simple
« é », et sauver le résultat (en UTF-8 sans BOM) avant de le donner
en pâture à PHP.
mouais, mais bon, ça ne me plait pas parce que ce fichier est généré
automatiquement.
Et alors ? Tu refuses de faire un test qui nous permettrait d'y voir
un peu plus clair, tant qu'on n'a pas une norme à se mettre sous la
dent ?
Une Bévue
2012-02-17 14:11:05 UTC
Permalink
Post by Olivier Miakinen
Et alors ? Tu refuses de faire un test qui nous permettrait d'y voir
un peu plus clair, tant qu'on n'a pas une norme à se mettre sous la
dent ?
Ah, le test, je l'avais fait côté php, si je remplace \xC3\xA9 par é,
c'est bon !
--
« Ne jamais se disputer avec un idiot : il te ramènerait à son
niveau et ensuite te battrait avec l'expérience. »
(Dilbert)
Une Bévue
2012-02-16 23:41:52 UTC
Permalink
Post by Olivier Miakinen
Mais plutôt que de lancer un outil tel que iconv, tu devrais essayer
d'éditer ton fichier avec un éditeur de texte, y rajouter un simple
« é », et sauver le résultat (en UTF-8 sans BOM) avant de le donner
en pâture à PHP.
À force de googler, j'ai trouvé une solution côté rub...
certains prétendent que yaml (du core ruby) utilise base64 ???

m'enfin, il y a un module externe "ya2yaml" (yet another yaml) qui
marche en utf-8.

je viens de vérifier, c'est bon côté mac/ruby et Ubuntu/php...

OUF )))

PS : des japonais ont eu des pbs d'encodage avec yaml...
--
« Les conneries c'est comme les impôts,
on finit toujours par les payer. »
(Michel Audiard)
Olivier Miakinen
2012-02-16 23:55:33 UTC
Permalink
Post by Une Bévue
À force de googler, j'ai trouvé une solution côté rub...
[...] il y a un module externe "ya2yaml" (yet another yaml) qui
marche en utf-8.
je viens de vérifier, c'est bon côté mac/ruby et Ubuntu/php...
Bravo !
Post by Une Bévue
PS : des japonais ont eu des pbs d'encodage avec yaml...
Ben ça, je veux bien le croire, vu le problème que tu as eu avec un
simple « é » ! Bon, je suis ravi que ce soit résolu pour toi.
Une Bévue
2012-02-17 14:11:06 UTC
Permalink
Post by Olivier Miakinen
Ben ça, je veux bien le croire, vu le problème que tu as eu avec un
simple « é » ! Bon, je suis ravi que ce soit résolu pour toi.
Ben, moi aussi, pour moi c'est une sorte de bug...
--
« Ne jamais se disputer avec un idiot : il te ramènerait à son
niveau et ensuite te battrait avec l'expérience. »
(Dilbert)
Olivier Miakinen
2012-02-16 20:30:17 UTC
Permalink
Post by Une Bévue
oui, oui, il n'y a qu'un fichier "setup.yml" écrit par ruby 1.8.x sous
Mac OS X et lu par php 5.3.6 sous Xubuntu 11.10.
Ok.
Post by Une Bévue
le é de "Médical" est codé \xC3\xA9 par le module yaml de ruby.
Tu n'as pas répondu à ma question, probablement parce que tu ne
connaissais pas la réponse. Est-ce que \xC3 et \xA9 sont censés
représenter des octets, auquel cas \xC3\xA9 serait le codage
d'un « é » en UTF-8, ou bien sont-ils censés représenter des
caractères, auquel cas \xC3 serait un « Ã » et \xA9 un « © » ?

Si ça se trouve, Ruby penche pour la première hypothèse et PHP
pour la seconde, ce qui expliquerait qu'ils ne puissent pas
s'entendre.

Que dit la norme YAML ? J'ai essayé de trouver l'info, mais je
n'ai pas réussi à trouver une doc que je sache lire.
Post by Une Bévue
mais bon, je commence à piger ce qui se passe.
en fait "Médical" est une string provenant du carnet d'adresse, je
suppose qu'elle est en UTF-8 "à la mac OS X" c'est-à-dire quelque chose
"Me'dical", l'accent du é étant placé à côté du e.
Non, ça c'est impossible. Selon qu'on l'interprète comme des numéros
de caractères ou de l'UTF-8, C3 A9 correspond soit aux deux caractères
é, soit au caractère précomposé é. Si c'était un e suivi d'un accent
aigu, ce serait codé soit 65 301, soit 65 CC 81 : rien à voir avec
C3 A9 !
Post by Une Bévue
plutôt que "bidouiller" côté php, je devrais regarder, côté ruby/yaml
comment transcoder en UTF-8 "ordinaire"...
Là, je suis entièrement d'accord. Si j'en crois la philosophie de YAML,
tu *dois* pouvoir obtenir un é lisible directement dans setup.y[a]ml.
Post by Une Bévue
Post by Olivier Miakinen
Post by Une Bévue
Directive Local Value Master Value
yaml.decode_binary 0 0
Et ça, tu sais ce que ça veut dire ?
yaml.decode_binary boolean
Off par défaut, si mis à on : permet le décodage des entités binaires
base64 ayant le tag explicite "tag:yaml.org,2002:binary".
cf. <http://php.net/manual/fr/yaml.configuration.php>
Ah, d'accord, c'est pour du Base64. Strictement rien à voir avec notre
problème, donc.
Post by Une Bévue
en tout cas, merci bien d'avoir répondu, sans avoir la solution, je sais
(devine) mieux d'où vient le problème...
Permets-moi d'en douter... (désolé)
Une Bévue
2012-02-16 22:56:06 UTC
Permalink
Post by Olivier Miakinen
Post by Une Bévue
le é de "Médical" est codé \xC3\xA9 par le module yaml de ruby.
Tu n'as pas répondu à ma question, probablement parce que tu ne
connaissais pas la réponse. Est-ce que \xC3 et \xA9 sont censés
représenter des octets, auquel cas \xC3\xA9 serait le codage
d'un « é » en UTF-8, ou bien sont-ils censés représenter des
caractères, auquel cas \xC3 serait un « Ã » et \xA9 un « © » ?
ben en fait comme je sais par ailleurs que ça représente un é, ce sont
deux octets.
Post by Olivier Miakinen
Si ça se trouve, Ruby penche pour la première hypothèse et PHP
pour la seconde, ce qui expliquerait qu'ils ne puissent pas
s'entendre.
ouais et, ce qui est encore plus curieux, c'est que la fonction
utf8_decode/php renvoie de l'utf-8 dans ce cas et pas de l'iso 8859-1...
Post by Olivier Miakinen
Que dit la norme YAML ? J'ai essayé de trouver l'info, mais je
n'ai pas réussi à trouver une doc que je sache lire.
UTF-8 NO BOM
ou UTF-16 AVEC BOM
Post by Olivier Miakinen
Post by Une Bévue
mais bon, je commence à piger ce qui se passe.
en fait "Médical" est une string provenant du carnet d'adresse, je
suppose qu'elle est en UTF-8 "à la mac OS X" c'est-à-dire quelque chose
"Me'dical", l'accent du é étant placé à côté du e.
Non, ça c'est impossible. Selon qu'on l'interprète comme des numéros
de caractères ou de l'UTF-8, C3 A9 correspond soit aux deux caractères
é, soit au caractère précomposé é. Si c'était un e suivi d'un accent
aigu, ce serait codé soit 65 301, soit 65 CC 81 : rien à voir avec
C3 A9 !
oui, oui, d'accord.
Post by Olivier Miakinen
Post by Une Bévue
plutôt que "bidouiller" côté php, je devrais regarder, côté ruby/yaml
comment transcoder en UTF-8 "ordinaire"...
Là, je suis entièrement d'accord. Si j'en crois la philosophie de YAML,
tu *dois* pouvoir obtenir un é lisible directement dans setup.y[a]ml.
oui, me reste à trouver comment. Je ne peux pas changer de version de
yaml côté ruby car c'est builtin.
Post by Olivier Miakinen
Post by Une Bévue
Post by Olivier Miakinen
Directive Local Value Master Value
yaml.decode_binary 0 0
Et ça, tu sais ce que ça veut dire ?
yaml.decode_binary boolean
Off par défaut, si mis à on : permet le décodage des entités binaires
base64 ayant le tag explicite "tag:yaml.org,2002:binary".
cf. <http://php.net/manual/fr/yaml.configuration.php>
Ah, d'accord, c'est pour du Base64. Strictement rien à voir avec notre
problème, donc.
non, rien à voir.
Post by Olivier Miakinen
Post by Une Bévue
en tout cas, merci bien d'avoir répondu, sans avoir la solution, je sais
(devine) mieux d'où vient le problème...
Permets-moi d'en douter... (désolé)
C'est vrai )))

En fait entretemps je me suis assuré que le problème vient de
yaml/ruby...
--
« Les conneries c'est comme les impôts,
on finit toujours par les payer. »
(Michel Audiard)
Olivier Miakinen
2012-02-16 23:48:48 UTC
Permalink
Post by Une Bévue
Post by Olivier Miakinen
Post by Une Bévue
le é de "Médical" est codé \xC3\xA9 par le module yaml de ruby.
Tu n'as pas répondu à ma question, probablement parce que tu ne
connaissais pas la réponse. Est-ce que \xC3 et \xA9 sont censés
représenter des octets, auquel cas \xC3\xA9 serait le codage
d'un « é » en UTF-8, ou bien sont-ils censés représenter des
caractères, auquel cas \xC3 serait un « Ã » et \xA9 un « © » ?
ben en fait comme je sais par ailleurs que ça représente un é, ce sont
deux octets.
C'est ce que tu aimerais, mais visiblement PHP n'est pas d'accord !
Sache que le caractère U+00C3 et le caractère U+00A9 existent tous
les deux dans Unicode, qu'ils se codent chacun en deux octets en
UTF-8 (donc quatre octets au total), et que visiblement c'est comme
ça que PHP les voit.
Post by Une Bévue
Post by Olivier Miakinen
Si ça se trouve, Ruby penche pour la première hypothèse et PHP
pour la seconde, ce qui expliquerait qu'ils ne puissent pas
s'entendre.
ouais et, ce qui est encore plus curieux, c'est que la fonction
utf8_decode/php renvoie de l'utf-8 dans ce cas et pas de l'iso 8859-1...
Non, pas du tout. À ce que je vois, tu passes à la fonction utf8_decode
un caractère à en UTF-8 qu'elle traduit en ISO-8859-1, puis un © en
UTF-8 qu'elle traduit de même en ISO-8859-1. Il se trouve que ces deux
caractères ISO-8859-1, l'un derrière l'autre, se codent de la même
façon que le caractère é en UTF-8, mais -- si je puis dire -- la
fonction utf8_encode s'en fout !
Post by Une Bévue
Post by Olivier Miakinen
Que dit la norme YAML ? J'ai essayé de trouver l'info, mais je
n'ai pas réussi à trouver une doc que je sache lire.
UTF-8 NO BOM
ou UTF-16 AVEC BOM
Ce n'est pas ma question. Que dit la norme YAML à propos des séquences
d'échappement constituées d'un antislash \, d'un x minuscule, et de
deux (ou plus ?) chiffres hexadécimaux ? Merci de trouver cette partie
de la doc si tu le peux. Tant qu'on n'aura pas cette info, il sera
impossible de savoir si le bug (car il y a visiblement un bug) se
trouve du côté de Ruby ou du côté de PHP.

Je vais continuer à chercher de mon côté, mais merci de le faire aussi.
Tu peux regarder aussi dans la doc de Ruby (je l'ai fait pour PHP, sans
résultat).
Olivier Miakinen
2012-02-17 00:08:14 UTC
Permalink
Salut !

J'ai vu que ton problème est résolu, mais par curiosité j'ai quand
même continué à chercher la réponse à ma question, et j'ai fini par
trouver.
Post by Olivier Miakinen
Post by Une Bévue
Post by Olivier Miakinen
Tu n'as pas répondu à ma question, probablement parce que tu ne
connaissais pas la réponse. Est-ce que \xC3 et \xA9 sont censés
représenter des octets, auquel cas \xC3\xA9 serait le codage
d'un « é » en UTF-8, ou bien sont-ils censés représenter des
caractères, auquel cas \xC3 serait un « Ã » et \xA9 un « © » ?
ben en fait comme je sais par ailleurs que ça représente un é, ce sont
deux octets.
C'est ce que tu aimerais, mais visiblement PHP n'est pas d'accord !
Sache que le caractère U+00C3 et le caractère U+00A9 existent tous
les deux dans Unicode, qu'ils se codent chacun en deux octets en
UTF-8 (donc quatre octets au total), et que visiblement c'est comme
ça que PHP les voit.
... et c'est PHP qui a raison, par rapport à ton premier outil Ruby.
Post by Olivier Miakinen
[...] Que dit la norme YAML à propos des séquences
d'échappement constituées d'un antislash \, d'un x minuscule, et de
deux (ou plus ?) chiffres hexadécimaux ? Merci de trouver cette partie
de la doc si tu le peux. Tant qu'on n'aura pas cette info, il sera
impossible de savoir si le bug (car il y a visiblement un bug) se
trouve du côté de Ruby ou du côté de PHP.
Je vais continuer à chercher de mon côté, mais merci de le faire aussi.
Tu peux regarder aussi dans la doc de Ruby (je l'ai fait pour PHP, sans
résultat).
En bref : <http://yaml.org/refcard.html>
<cit.>
Escape codes:
Numeric : { "\x12": 8-bit, "\u1234": 16-bit, "\U00102030": 32-bit }
</cit.>

En plus détaillé : <http://yaml.org/spec/current.html#id2517668>.


Et donc, \xC3\xA9 représente *vraiment* la séquence de deux caractères
« é » et non le caractère « é ». Ce dernier peut s'écrire sous la
forme \xE9, ou bien \u00E9, ou encore \U000000E9.

Mais surtout, comme « é » n'est pas un « non-printable character »
(caractère non imprimable), il faut surtout l'écrire tel quel et non
sous forme d'une séquence d'échappement.


Cordialement,
--
Olivier Miakinen
Une Bévue
2012-02-17 14:11:06 UTC
Permalink
Post by Olivier Miakinen
... et c'est PHP qui a raison, par rapport à ton premier outil Ruby.
oui, oui, merci, c'est ce que j'ai trouvé aussi de mon côté...
Post by Olivier Miakinen
Post by Olivier Miakinen
[...] Que dit la norme YAML à propos des séquences
d'échappement constituées d'un antislash \, d'un x minuscule, et de
deux (ou plus ?) chiffres hexadécimaux ? Merci de trouver cette partie
de la doc si tu le peux. Tant qu'on n'aura pas cette info, il sera
impossible de savoir si le bug (car il y a visiblement un bug) se
trouve du côté de Ruby ou du côté de PHP.
Je vais continuer à chercher de mon côté, mais merci de le faire aussi.
Tu peux regarder aussi dans la doc de Ruby (je l'ai fait pour PHP, sans
résultat).
En bref : <http://yaml.org/refcard.html>
<cit.>
Numeric : { "\x12": 8-bit, "\u1234": 16-bit, "\U00102030": 32-bit }
</cit.>
En plus détaillé : <http://yaml.org/spec/current.html#id2517668>.
Et donc, \xC3\xA9 représente *vraiment* la séquence de deux caractères
« é » et non le caractère « é ». Ce dernier peut s'écrire sous la
forme \xE9, ou bien \u00E9, ou encore \U000000E9.
Mais surtout, comme « é » n'est pas un « non-printable character »
(caractère non imprimable), il faut surtout l'écrire tel quel et non
sous forme d'une séquence d'échappement.
OUI, tout à fait, c'est ce que j'ai lu aussi dans le spec.

ça m'a demandé qq heures pour me renseigner et contourner le pb.

enfin, là, pour des raisons externes à ruby, je n'utilise pas la
dernière version de ruby, censée être UTF-8 compatible, mais ruby 1.8.7.

curieux que ce bug n'ait pas été corrigé...
--
« Ne jamais se disputer avec un idiot : il te ramènerait à son
niveau et ensuite te battrait avec l'expérience. »
(Dilbert)
Une Bévue
2012-02-17 14:11:06 UTC
Permalink
Post by Olivier Miakinen
Post by Une Bévue
ben en fait comme je sais par ailleurs que ça représente un é, ce sont
deux octets.
C'est ce que tu aimerais,
euh, comme ces strings correspondent à des noms de groupes dans mon
carnet d'adresse, j'en suis sûr...
Post by Olivier Miakinen
mais visiblement PHP n'est pas d'accord !
Sache que le caractère U+00C3 et le caractère U+00A9 existent tous
les deux dans Unicode, qu'ils se codent chacun en deux octets en
UTF-8 (donc quatre octets au total), et que visiblement c'est comme
ça que PHP les voit.
Post by Une Bévue
Post by Olivier Miakinen
Si ça se trouve, Ruby penche pour la première hypothèse et PHP
pour la seconde, ce qui expliquerait qu'ils ne puissent pas
s'entendre.
ouais et, ce qui est encore plus curieux, c'est que la fonction
utf8_decode/php renvoie de l'utf-8 dans ce cas et pas de l'iso 8859-1...
Non, pas du tout. À ce que je vois, tu passes à la fonction utf8_decode
un caractère à en UTF-8 qu'elle traduit en ISO-8859-1, puis un © en
UTF-8 qu'elle traduit de même en ISO-8859-1. Il se trouve que ces deux
caractères ISO-8859-1, l'un derrière l'autre, se codent de la même
façon que le caractère é en UTF-8, mais -- si je puis dire -- la
fonction utf8_encode s'en fout !
oui, mais ce que je ne pige pas est que visuellement, sur le butineur
(chrome et firefox) il n'y a pas d'artefact dans ce mélange UTF-8 et
iso-8859-1...
reconversion au vol ?
Post by Olivier Miakinen
Post by Une Bévue
Post by Olivier Miakinen
Que dit la norme YAML ? J'ai essayé de trouver l'info, mais je
n'ai pas réussi à trouver une doc que je sache lire.
UTF-8 NO BOM
ou UTF-16 AVEC BOM
Ce n'est pas ma question. Que dit la norme YAML à propos des séquences
d'échappement constituées d'un antislash \, d'un x minuscule, et de
deux (ou plus ?) chiffres hexadécimaux ? Merci de trouver cette partie
de la doc si tu le peux.
<http://yaml.org/spec/1.1/#id872840> :
All non-printable characters must be presented as escape sequences. Each
escape sequences must be parsed into the appropriate Unicode character.
The original escape sequence form is a presentation detail and must not
be used to convey content information. YAML escape sequences use the "\"
notation common to most modern computer languages. Note that escape
sequences are only interpreted in double-quoted scalars. In all other
scalar styles, the "\" character has no special meaning and
non-printable characters are not available.

dans mon cas (yaml/ruby), j'ai :
"M\xC3\xA9dical"
c'est bien doubly quoted.
mais bon, il est dit "All non-printable characters must be presented as
escape sequences" le é est printable...

plus loin :
Escaped 8-bit Unicode character:
[62] ns-esc-8-bit ::= "\" "x" ( ns-hex-digit x 2 )
Escaped 16-bit Unicode character:
[63] ns-esc-16-bit ::= "\" "u" ( ns-hex-digit x 4 )

le é est bien sur 2 fois 8 bits, si je comprends bien, il aurait du être
codé :
\uC3A9
non ?
Post by Olivier Miakinen
Tant qu'on n'aura pas cette info, il sera
impossible de savoir si le bug (car il y a visiblement un bug) se
trouve du côté de Ruby ou du côté de PHP.
oui, au moins ruby est consistant avec lui-même ie. une lecture d'un
fichier yaml redonne les bonnes strings
Post by Olivier Miakinen
Je vais continuer à chercher de mon côté, mais merci de le faire aussi.
Tu peux regarder aussi dans la doc de Ruby (je l'ai fait pour PHP, sans
résultat).
Ah, moins de doc côté php ?
--
« Ne jamais se disputer avec un idiot : il te ramènerait à son
niveau et ensuite te battrait avec l'expérience. »
(Dilbert)
Olivier Miakinen
2012-02-17 15:22:13 UTC
Permalink
Post by Une Bévue
Post by Olivier Miakinen
Post by Une Bévue
ben en fait comme je sais par ailleurs que ça représente un é, ce sont
deux octets.
C'est ce que tu aimerais,
euh, comme ces strings correspondent à des noms de groupes dans mon
carnet d'adresse, j'en suis sûr...
Dans ton carnet d'adresse, c'était un é. Mais dans le fichier
setup.yaml c'était devenu une séquence d'échappement pour un
à suivi d'une autre pour un ©.
Post by Une Bévue
Post by Olivier Miakinen
Post by Une Bévue
ouais et, ce qui est encore plus curieux, c'est que la fonction
utf8_decode/php renvoie de l'utf-8 dans ce cas et pas de l'iso 8859-1...
Non, pas du tout. À ce que je vois, tu passes à la fonction utf8_decode
un caractère à en UTF-8 qu'elle traduit en ISO-8859-1, puis un © en
UTF-8 qu'elle traduit de même en ISO-8859-1. Il se trouve que ces deux
caractères ISO-8859-1, l'un derrière l'autre, se codent de la même
façon que le caractère é en UTF-8, mais -- si je puis dire -- la
fonction utf8_encode s'en fout !
oui, mais ce que je ne pige pas est que visuellement, sur le butineur
(chrome et firefox) il n'y a pas d'artefact dans ce mélange UTF-8 et
iso-8859-1...
reconversion au vol ?
Je ne sais pas comment t'expliquer mieux que ce que j'ai déjà fait.
Pour que tu comprennes, il faudrait peut-être que tu essayes de traduire
toi-même, à la main (en jouant avec la réprésentation en base 2), des
caractères accentués en UTF-8.

Ah tiens, j'ai une idée. Au lieu d'UTF-8 que tu ne sembles pas bien
maîtriser supposons que l'encodage soit une simple traduction des
octets en hexadécimal. Au lieu de regarder le codage du é, regardons
celui du 'A'. Son code ASCII est 41 en hexadécimal. Dans un fichier,
tu auras donc un octet qui vaut 41 hexa pour représenter le A.
Supposons qu'un outil un peu neuneu, au lieu de mettre un code 41
dans le fichier, considère que le '4' vaut 34 en hexa et que le '1'
vaut 31 en hexa, et qu'il mette 34 31 au lieu de 41. Eh bien on
est dans le même cas : ton fichier setup.yaml contenait non pas
un codage pour le é, mais un codage pour des octets représentant
eux mêmes un codage pour le é.

Et donc, puisque tu avais un codage UTF-8 d'un codage UTF-8 du é,
au lieu d'un codage UTF-8 du é, il te fallait bien faire un
*décodage* UTF-8 (utf8_decode) pour obtenir quelque chose qui
était un simple codage UTF-8 du é.
Post by Une Bévue
[...]
"M\xC3\xA9dical"
c'est bien doubly quoted.
Oui. En fait tu avais un codage par caractères d'échappement du
« surcodage » UTF-8 d'un caractère... Une fois décodées les séquences
d'échappement, cette chaîne vaut "Médical" et pas "Médical".
Post by Une Bévue
mais bon, il est dit "All non-printable characters must be presented as
escape sequences" le é est printable...
[62] ns-esc-8-bit ::= "\" "x" ( ns-hex-digit x 2 )
[63] ns-esc-16-bit ::= "\" "u" ( ns-hex-digit x 4 )
le é est bien sur 2 fois 8 bits,
Non. Tant qu'il n'est pas codé selon un encodage donné (ISO-8859-1,
UTF-8, UTF-16, UTF-7 ou autre chose), le 'é' n'est pas « sur n bits ».
Il possède un numéro qui vaut 233 en décimal, et que l'on peut noter
U+00E9 dans Unicode. Vu que ce numéro est inférieur à 256, selon la
syntaxe de caractères d'échappement de YAML, tu peux donc l'écrire
sous la forme \xE9 (en hexa 5C 78 45 39) ou \u00E9 (en hexa 5C 75 30
30 45 39) ou encore \U000000E9 (en hexa 5C 55 30 30 30 30 30 30 45 39).
Post by Une Bévue
si je comprends bien, il aurait du être codé : \uC3A9
non ?
Non. Le caractère \uC3A9 (U+C3A9) fait partie des syllabes hangûl :
<http://www.unicode.org/fr/charts/PDF/UAC00.pdf>. Voir aussi
<http://www.fileformat.info/info/unicode/char/c3a9/index.htm>.
Son codage en UTF-8 est EC 8E A9.

Le é c'est \u00E9 (U+00E9) :
<http://www.unicode.org/fr/charts/PDF/U0080.pdf>.
C'est son codage en UTF-8 qui vaut C3 A9.
Post by Une Bévue
Post by Olivier Miakinen
Tant qu'on n'aura pas cette info, il sera
impossible de savoir si le bug (car il y a visiblement un bug) se
trouve du côté de Ruby ou du côté de PHP.
oui, au moins ruby est consistant avec lui-même ie. une lecture d'un
fichier yaml redonne les bonnes strings
Oui. Son interprétation de la norme était erronée, mais au moins il
avait la même en lecture qu'en écriture.
Post by Une Bévue
Post by Olivier Miakinen
Je vais continuer à chercher de mon côté, mais merci de le faire aussi.
Tu peux regarder aussi dans la doc de Ruby (je l'ai fait pour PHP, sans
résultat).
Ah, moins de doc côté php ?
Ben oui, mais ça tu l'avais déjà remarqué toi-même :
<http://www.php.net/manual/fr/book.yaml.php>
<http://www.php.net/manual/fr/intro.yaml.php>.
Une Bévue
2012-02-17 15:43:09 UTC
Permalink
Post by Olivier Miakinen
Ah tiens, j'ai une idée. Au lieu d'UTF-8 que tu ne sembles pas bien
maîtriser supposons que l'encodage soit une simple traduction des
octets en hexadécimal. Au lieu de regarder le codage du é, regardons
celui du 'A'. Son code ASCII est 41 en hexadécimal. Dans un fichier,
tu auras donc un octet qui vaut 41 hexa pour représenter le A.
Supposons qu'un outil un peu neuneu, au lieu de mettre un code 41
dans le fichier, considère que le '4' vaut 34 en hexa et que le '1'
vaut 31 en hexa, et qu'il mette 34 31 au lieu de 41. Eh bien on
est dans le même cas : ton fichier setup.yaml contenait non pas
un codage pour le é, mais un codage pour des octets représentant
eux mêmes un codage pour le é.
Et donc, puisque tu avais un codage UTF-8 d'un codage UTF-8 du é,
au lieu d'un codage UTF-8 du é, il te fallait bien faire un
*décodage* UTF-8 (utf8_decode) pour obtenir quelque chose qui
était un simple codage UTF-8 du é.
c'est tout à fait clair !
Post by Olivier Miakinen
Post by Une Bévue
[...]
"M\xC3\xA9dical"
c'est bien doubly quoted.
Oui. En fait tu avais un codage par caractères d'échappement du
« surcodage » UTF-8 d'un caractère... Une fois décodées les séquences
d'échappement, cette chaîne vaut "Médical" et pas "Médical".
Post by Une Bévue
mais bon, il est dit "All non-printable characters must be presented as
escape sequences" le é est printable...
[62] ns-esc-8-bit ::= "\" "x" ( ns-hex-digit x 2 )
[63] ns-esc-16-bit ::= "\" "u" ( ns-hex-digit x 4 )
le é est bien sur 2 fois 8 bits,
Non. Tant qu'il n'est pas codé selon un encodage donné (ISO-8859-1,
UTF-8, UTF-16, UTF-7 ou autre chose), le 'é' n'est pas « sur n bits ».
Il possède un numéro qui vaut 233 en décimal, et que l'on peut noter
U+00E9 dans Unicode. Vu que ce numéro est inférieur à 256, selon la
syntaxe de caractères d'échappement de YAML, tu peux donc l'écrire
sous la forme \xE9 (en hexa 5C 78 45 39) ou \u00E9 (en hexa 5C 75 30
30 45 39) ou encore \U000000E9 (en hexa 5C 55 30 30 30 30 30 30 45 39).
OK, ok.
Post by Olivier Miakinen
Post by Une Bévue
si je comprends bien, il aurait du être codé : \uC3A9
non ?
<http://www.unicode.org/fr/charts/PDF/UAC00.pdf>. Voir aussi
<http://www.fileformat.info/info/unicode/char/c3a9/index.htm>.
Son codage en UTF-8 est EC 8E A9.
<http://www.unicode.org/fr/charts/PDF/U0080.pdf>.
C'est son codage en UTF-8 qui vaut C3 A9.
bon.
Post by Olivier Miakinen
Post by Une Bévue
Post by Olivier Miakinen
Tant qu'on n'aura pas cette info, il sera
impossible de savoir si le bug (car il y a visiblement un bug) se
trouve du côté de Ruby ou du côté de PHP.
oui, au moins ruby est consistant avec lui-même ie. une lecture d'un
fichier yaml redonne les bonnes strings
Oui. Son interprétation de la norme était erronée, mais au moins il
avait la même en lecture qu'en écriture.
Post by Une Bévue
Post by Olivier Miakinen
Je vais continuer à chercher de mon côté, mais merci de le faire aussi.
Tu peux regarder aussi dans la doc de Ruby (je l'ai fait pour PHP, sans
résultat).
Ah, moins de doc côté php ?
<http://www.php.net/manual/fr/book.yaml.php>
<http://www.php.net/manual/fr/intro.yaml.php>.
la difficulté que j'ai eue question doc php est que l'implémentation de
yaml (comme avec ruby d'ailleurs) est variable et qu'il n'est pas tjs
évident de savoir si la page de doc correspond à l'implémentation.
--
« Ne jamais se disputer avec un idiot : il te ramènerait à son
niveau et ensuite te battrait avec l'expérience. »
(Dilbert)
Loading...