The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Преобразование utf8 кода Perl на выходе в koi8-r + HTML (perl unicode charset translate)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: perl, unicode, charset, translate,  (найти похожие документы)
Date: Thu, 28 Nov 2002 19:40:56 +0500 From: Andrey Sapozhnikov <sapa@icb.chel.su> Newsgroups: ftn.ru.perl Subject: Преобразование utf8 кода Perl на выходе в koi8-r + HTML > "\x{2020}Сегодня\x{A0}\x{2014} Geschlo\x{DF}en" > > Результат может быть в любой восьмибитной кодировке, в которой нет > символов EM-DASH, BULLET и западно-европейских акцентированных букв. > Hапример, в кои-8. С неразрывным пробелом там призовая игра, ибо он в > кодировки есть. >> как \x{NNNN}. И в какой кодировке Вы хотите результат? Ибо то, что >> я вижу вообще не есть перекодировка чарсетов. > Согласен. Это гораздо более практически полезная задача ПРЕДСТАВЛЕHИЯ > строки, которая легко и естественно представляется в юникоде, средствами > 8-битной кодировки + HTML. Буде будет такое решение, я, естественно, > попробую адаптировать его к другим языкам, которые позволяют средставми > 8-битной кодировки выразить более другие символы - TeX, Perl, Tcl. > Если сложность адаптации будет соответствовать прямизне представления > этих символов в более другом языке, сделаю вывод, что в 5.8 перле > работа с кодировками сделана УДОБHО. ======================== example ========================== #!/usr/bin/perl -w use strict; BEGIN { use utf8; package Encode::myhtml; use base qw(Encode::Encoding); __PACKAGE__->Define('myhtml'); my %subst = ( '&' => '&amp;', '<' => '&lt;', '>' => '&gt;', '"' => '&quot;', "\x{00a0}" => '&nbsp;', "\x{2014}" => '&mdash;', "\x{00df}" => 'ss' ); sub encode ($$;$) { (my $str = $_[1]) =~ s/([&<">\x{0080}-\x{ffff}])/$subst{$1} || $1/ge; $_[1] = '' if $_[2]; Encode::encode('koi8-r', $str, Encode::FB_HTMLCREF); } }; use utf8; use encoding 'utf8', STDOUT => 'myhtml'; print "\x{2020}п║п╣пЁп╬п╢п╫я▐\x{A0}\x{2014} Geschlo\x{DF}en"; ======================== eof ========================== Вот, пожалуйста. Можно было описать свой UCM файл с кодировкой, но поскольку это по большей части повторение уже имеющейся koi8-r я решил (ценой некоторого падения скорости) класс с кодировкой написать на perl, а не в виде XS. Hадеюсь, что в твой экран оно влезет. Разумеется все, что обернуто в BEGIN впоследствии надо вынести в отдельный Encode/myhtml.pm который сам вызовется при необходимости. То, что стоит в print - это и есть твоя строка. К сожалению, гейт fido7 не разрешает (насколько я помню) слать письма в utf-8, посему я пишу в koi-8 и вставляю код AS IS. Если что-то поломается - открой скрипт любым редактором поддерживающим utf-8 и поправь строчку :)
From: Andrey Sapozhnikov <sapa@icb.chel.su> > AS> my $koi = find_encoding('koi8-r') or die "Encoding koi8-r not found"; > AS> my $encoded = $koi->encode($line, Encode::FB_QUIET); > > В таком варианте - работает. Только почему-то пока я задавал элементы > массива подстановок как "\x{00df}"=>'ss' > не хотело подставлять эсцет. > Как я поменял индексы хеша на ord-ы от соответствующего символа - все > заработало. perldoc perlunicode ... Unicode characters can also be added to a string by using the "\x{...}" notation. The Unicode code for the desired character, in hexadecimal, should be placed in the braces. For instance, a smiley face is "\x{263A}". This encoding scheme only works for characters with a code of 0x100 or above. ... посему строка с одним символом \xDF который может быть представлен в 8 битах с целью совместимости остается байтовой. А потом при апгрейде транслируется в уникодное представление символа \xDF которое есть не \x{00DF}. F*cking legacy. Hо в большинстве случаев это должно сказываться только при неправильно выставленном флажке utf8 (например считали из raw источника utf8 строку и не декодировали. Или при злонамеренном побайтовом сравнении вместо посимвольного). В таком случае можно строку явно пометить с помощью Encode::_utf8_on, хотя корректнее все-таки декодировать (decode('utf8', $line)). > Hо ведь что обидно - вчерашний вариант с необъектным интерфейсом я из > perldoc Encode передирал. только там в примере decode, а не encode было. :) Андрей P.S. Медитируем над результатами скрипта: #!/usr/bin/perl -w use strict; use utf8; use Encode; my $a = "\xdf"; my $b = "\x{00df}"; my $c = "\x{01df}"; my $d = chr(0xdf); my $e = pack('U', 0xdf); my $f = substr("\x{00df}", -1, 1); my $g = substr("\x{01df}\x{00df}", -1, 1); my $h = "\x{01df}\x{00df}"; Encode::_utf8_off($h); $h = substr($h, -1, 1); print '$a is ', Encode::is_utf8($a) ? "utf8\n" : "bytes\n"; print '$b is ', Encode::is_utf8($b) ? "utf8\n" : "bytes\n"; print '$c is ', Encode::is_utf8($c) ? "utf8\n" : "bytes\n"; print '$d is ', Encode::is_utf8($d) ? "utf8\n" : "bytes\n"; print '$e is ', Encode::is_utf8($e) ? "utf8\n" : "bytes\n"; print '$f is ', Encode::is_utf8($f) ? "utf8\n" : "bytes\n"; print '$g is ', Encode::is_utf8($g) ? "utf8\n" : "bytes\n"; print '$h is ', Encode::is_utf8($h) ? "utf8\n" : "bytes\n"; print "\n==== chars ====\n"; print '$a, $b -> ', $a eq $b ? "eq\n" : "ne\n"; print '$b, $f -> ', $b eq $f ? "eq\n" : "ne\n"; print '$f, $g -> ', $f eq $g ? "eq\n" : "ne\n"; print '$g, $h -> ', $g eq $h ? "eq\n" : "ne\n"; printf("ord(\$a) = %x\n", ord($a)); printf("ord(\$b) = %x\n", ord($b)); printf("ord(\$c) = %x\n", ord($c)); printf("ord(\$d) = %x\n", ord($d)); printf("ord(\$e) = %x\n", ord($e)); printf("ord(\$f) = %x\n", ord($f)); printf("ord(\$g) = %x\n", ord($g)); printf("ord(\$h) = %x\n", ord($h)); use bytes; print "\n==== bytes ====\n"; print '$a, $b -> ', $a eq $b ? "eq\n" : "ne\n"; print '$b, $f -> ', $b eq $f ? "eq\n" : "ne\n"; print '$f, $g -> ', $f eq $g ? "eq\n" : "ne\n"; print '$g, $h -> ', $g eq $h ? "eq\n" : "ne\n"; printf("ord(\$a) = %x\n", ord($a)); printf("ord(\$b) = %x\n", ord($b)); printf("ord(\$c) = %x\n", ord($c)); printf("ord(\$d) = %x\n", ord($d)); printf("ord(\$e) = %x\n", ord($e)); printf("ord(\$f) = %x\n", ord($f)); printf("ord(\$g) = %x\n", ord($g)); printf("ord(\$h) = %x\n", ord($h));

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

 Добавить комментарий
Имя:
E-Mail:
Заголовок:
Текст:




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2020 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру