Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

HTML::Element::as_text(), UTF-8, setlocale() et Encode

6 réponses
Avatar
Andre Majorel
Depuis quelque temps, HTML::Element::as_text(), retourne de
l'UTF-8 au lieu d'ISO-8859-1, d'où "Wide character in print" et
un certain manque de lisibilité, puisque mon système est en
ISO-8859-1.

Il va falloir soit
(1) convaincre as_text() de convertir les entités HTML dans le
l'encodage kivabien (dans mon cas, ISO-8859-1), soit
(2) le faire moi-même.

Si (1) est possible, rien dans la doc de HTML::Element ne le
laisse supposer.

Pour faire (2), je suppose qu'il faut utiliser
Encode::decode_utf8(). Chez moi, cette sub n'a aucun effet :
elle produit de l'UTF-8.

Il faut sans doute utiliser Encode::from_to(). Mais comment
récupérer l'encodage destination ? setlocale(LC_CTYPE) donne
"en_US", pas le "iso-8859-1" que from_to() attend.

--
André Majorel <URL:http://www.teaser.fr/~amajorel/>
"No meetings were held, nor secret handshakes created, to allow a Seria-
list Elite to disenfranchise the (tonal) non conformist. None had to be."
-- Wendy Carlos

6 réponses

Avatar
espie
In article ,
Andre Majorel wrote:
Depuis quelque temps, HTML::Element::as_text(), retourne de
l'UTF-8 au lieu d'ISO-8859-1, d'où "Wide character in print" et
un certain manque de lisibilité, puisque mon système est en
ISO-8859-1.

Il va falloir soit
(1) convaincre as_text() de convertir les entités HTML dans le
l'encodage kivabien (dans mon cas, ISO-8859-1), soit
(2) le faire moi-même.

Si (1) est possible, rien dans la doc de HTML::Element ne le
laisse supposer.

Pour faire (2), je suppose qu'il faut utiliser
Encode::decode_utf8(). Chez moi, cette sub n'a aucun effet :
elle produit de l'UTF-8.



Perso, j'ai cradouillement fait ca, et ca marche:
use Encode;
sub tolatin1
{
return encode("latin1", decode("utf-8", $_[1]));
}

($_[1] parce que c'est de l'objet, et que je fais un Util->tolatin1($element))
Avatar
Andre Majorel
On 2009-01-09, Marc Espie wrote:
In article ,
Andre Majorel wrote:
Depuis quelque temps, HTML::Element::as_text(), retourne de
l'UTF-8 au lieu d'ISO-8859-1, d'où "Wide character in print" et
un certain manque de lisibilité, puisque mon système est en
ISO-8859-1.

Il va falloir soit
(1) convaincre as_text() de convertir les entités HTML dans le
l'encodage kivabien (dans mon cas, ISO-8859-1), soit
(2) le faire moi-même.

Si (1) est possible, rien dans la doc de HTML::Element ne le
laisse supposer.

Pour faire (2), je suppose qu'il faut utiliser
Encode::decode_utf8(). Chez moi, cette sub n'a aucun effet :
elle produit de l'UTF-8.



Perso, j'ai cradouillement fait ca, et ca marche:
use Encode;
sub tolatin1
{
return encode("latin1", decode("utf-8", $_[1]));
}



Merci, mais ça ne marche pas mieux qu'un from_to($var, 'utf8',
'latin1') : tous les caractères non-ASCII deviennent des points
d'interrogation. Dans certains cas, la fonction déclenche une
même une exception ("Cannot decode string with wide characters
at /usr/lib/perl/5.10/Encode.pm line 162." puis exit (9)).

--
André Majorel <URL:http://www.teaser.fr/~amajorel/>
"No meetings were held, nor secret handshakes created, to allow a Seria-
list Elite to disenfranchise the (tonal) non conformist. None had to be."
-- Wendy Carlos
Avatar
espie
In article ,
Andre Majorel wrote:
On 2009-01-09, Marc Espie wrote:
In article ,
Andre Majorel wrote:
Depuis quelque temps, HTML::Element::as_text(), retourne de
l'UTF-8 au lieu d'ISO-8859-1, d'où "Wide character in print" et
un certain manque de lisibilité, puisque mon système est en
ISO-8859-1.

Il va falloir soit
(1) convaincre as_text() de convertir les entités HTML dans le
l'encodage kivabien (dans mon cas, ISO-8859-1), soit
(2) le faire moi-même.

Si (1) est possible, rien dans la doc de HTML::Element ne le
laisse supposer.

Pour faire (2), je suppose qu'il faut utiliser
Encode::decode_utf8(). Chez moi, cette sub n'a aucun effet :
elle produit de l'UTF-8.



Perso, j'ai cradouillement fait ca, et ca marche:
use Encode;
sub tolatin1
{
return encode("latin1", decode("utf-8", $_[1]));
}



Merci, mais ça ne marche pas mieux qu'un from_to($var, 'utf8',
'latin1') : tous les caractères non-ASCII deviennent des points
d'interrogation. Dans certains cas, la fonction déclenche une
même une exception ("Cannot decode string with wide characters
at /usr/lib/perl/5.10/Encode.pm line 162." puis exit (9)).



Tu as un autre souci, alors. Ca fonctionne tres bien avec un perl 5.10
chez moi.
Avatar
Paul Gaborit
À (at) Fri, 9 Jan 2009 13:38:59 +0000 (UTC),
(Marc Espie) écrivait (wrote):
In article ,
Andre Majorel wrote:
Depuis quelque temps, HTML::Element::as_text(), retourne de
l'UTF-8 au lieu d'ISO-8859-1, d'où "Wide character in print" et
un certain manque de lisibilité, puisque mon système est en
ISO-8859-1.

Il va falloir soit
(1) convaincre as_text() de convertir les entités HTML dans le
l'encodage kivabien (dans mon cas, ISO-8859-1), soit
(2) le faire moi-même.

Si (1) est possible, rien dans la doc de HTML::Element ne le
laisse supposer.

Pour faire (2), je suppose qu'il faut utiliser
Encode::decode_utf8(). Chez moi, cette sub n'a aucun effet :
elle produit de l'UTF-8.



Perso, j'ai cradouillement fait ca, et ca marche:
use Encode;
sub tolatin1
{
return encode("latin1", decode("utf-8", $_[1]));
}

($_[1] parce que c'est de l'objet, et que je fais un Util->tolatin1($element))



Cette fonction n'a de sens que si $_[1] contient une série d'octets
que Perl ne sait pas être de l'utf-8 mais que en fait en sont déjà.

Or HTML::Element::as_text retourne une chaîne en utf-8.

Première possibilité : indiquer à Perl que le flux sur lequel a lieu
le 'print' est encodé en ISO-8859-1 via un appel à 'binmode'. Si le
texte utf-8 ramené par HTML::Element ne contient que des caractères
représentables en ISO-8859-1, ça marchera. Sinon, il y aura toujours
des erreurs.

Deuxième possibilité : utiliser le module 'Encode' pour convertir
l'utf-8 en HTML. Ce qui donne :

print encode("latin1", $res_html_element_as_text, Encode::FB_HTMLCREF);

Et là, ça devrait marcher tout le temps.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>
Avatar
Andre Majorel
On 2009-01-09, Paul Gaborit wrote:
À (at) Fri, 9 Jan 2009 13:38:59 +0000 (UTC),
(Marc Espie) écrivait (wrote):
In article ,
Andre Majorel wrote:

Depuis quelque temps, HTML::Element::as_text(), retourne de
l'UTF-8 au lieu d'ISO-8859-1, d'où "Wide character in print" et
un certain manque de lisibilité, puisque mon système est en
ISO-8859-1.



use Encode;
sub tolatin1
{
return encode("latin1", decode("utf-8", $_[1]));
}



Cette fonction n'a de sens que si $_[1] contient une série d'octets
que Perl ne sait pas être de l'utf-8 mais que en fait en sont déjà.

Or HTML::Element::as_text retourne une chaîne en utf-8.



Merci, ça s'éclaircit.

Première possibilité : indiquer à Perl que le flux sur lequel a lieu
le 'print' est encodé en ISO-8859-1 via un appel à 'binmode'. Si le
texte utf-8 ramené par HTML::Element ne contient que des caractères
représentables en ISO-8859-1, ça marchera. Sinon, il y aura toujours
des erreurs.

Deuxième possibilité : utiliser le module 'Encode' pour convertir
l'utf-8 en HTML. Ce qui donne :



s/HTML/ISO-8859-1/, je pense.

print encode("latin1", $res_html_element_as_text, Encode::FB_HTMLCREF);

Et là, ça devrait marcher tout le temps.



Oui, encode("latin1", $html_element->as_text ()) fonctionne
parfaitement pour moi. Restent deux questions :

- Comment faire pour ne pas coder en dur "latin1" ? Chez moi,
setlocale(LC_CTYPE) retourne "en_US" ce qui, pour encode() est
un "Unknown encoding".

- Comment savoir si un scalaire est "wide" ou pas ?

--
André Majorel <URL:http://www.teaser.fr/~amajorel/>
"No meetings were held, nor secret handshakes created, to allow a Seria-
list Elite to disenfranchise the (tonal) non conformist. None had to be."
-- Wendy Carlos
Avatar
Nicolas George
Andre Majorel wrote in message
:
- Comment faire pour ne pas coder en dur "latin1" ? Chez moi,
setlocale(LC_CTYPE) retourne "en_US" ce qui, pour encode() est
un "Unknown encoding".



en_US est un nom de locale, pas d'encodage. Pour obtenir le nom d'encodage
correspondant à une locale LC_CTYPE, on utilise I18N::Langinfo::langinfo
avec la catégorie CODESET.