=head1 Russian doc for L<CCCP::Encode>

=encoding utf-8

=head1 NAME

B<CCCP::Encode> - модуль perl для корректной перекодировки строк из utf-8 в любую кирилицу (например: koi8-r, windows-1251, и т.д.)

=head1 Документация на английском

L<CCCP::Encode>

=head1 SYNOPSIS
    
    use CCCP::Encode;
    
    my $str = "если в слове 'хлеб' поменять 4 буквы, то получится — ПИВО";
         
    print CCCP::Encode->utf2cyrillic($str,'koi8-r');
    # output in koi8-r:
    # если в слове &#39;хлеб&#39; поменять 4 буквы, то получится &mdash; ПИВО 
	 
    $CCCP::Encode::ToText = 1;
    print CCCP::Encode->utf2cyrillic($str,'koi8-r');
    # output in koi8-r:
    # если в слове 'хлеб' поменять 4 буквы, то получится -- ПИВО  
    
    $CCCP::Encode::CharMap = {"\x{2014}" => '-'};
    print CCCP::Encode->utf2cyrillic($str,'koi8-r');
    # output in koi8-r:
    # если в слове 'хлеб' поменять 4 буквы, то получится - ПИВО  
    
    $CCCP::Encode::ToText = 0;
    $str = "Иероглифы: 牡 マ キ グ ナ ル フ";
    print CCCP::Encode->utf2cyrillic($str,'windows-1251');
    # output in windows-1251:
    # Иероглифы: &#x7261; &#x30DE; &#x30AD; &#x30B0; &#x30CA; &#x30EB; &#x30D5;

=head1 DESCRIPTION

Перекодировка возможна в двух режимах:

=over 4

=item *

в строку кирилицы с html entites

=item *

в строку кирилицы в текстовом формате 

=back

По умолчанию, для символов utf-8 не имеющих аналогов в кирилической таргет-кодировке (например, символ '—' или иероглифов)
в режиме "с html-entities" будет использоваться модуль B<HTML::Entities>, а в режиме "только текст" - B<Text::Unidecode>.

Вы можете переопределить карту перекодировки символов своими значениями.

Более того, Вам доступно изменить регулярное выражение поиска и замены символов в исходной строке.

=head2 INTRODUCTION

Если на frontend Вы используете ajax, то давно заметили, что данные отправляются на сервер в utf-8.
На стороне сервера Вы "ловите" эти данные перекодируете за счёт B<Encode> и, всё хорошо. 
Но, что если юзер поменял кодировку отображения страницы прямо в браузере, или (более вероятно) сделал copy-paste 
с внешнего сайта в одно из полей формы на Вашем сайте. Вот здесь-то и попадает utf-8 в обработку.
Это очень актуально для раздела "комментарии".

Вы ловите такие данные, перекодируете за счёт B<Encode>, но юзер вместо своего "красивого" комментария видит строку со знаками "?". 

    use Encode;
    ...
    my $data = $post->param('any');
    # $data = "если в слове 'хлеб' поменять 4 буквы, то получится — ПИВО";
    Encode::from_to($data,'utf-8','koi8-r');
    print $data;
    # output:
    # если в слове 'хлеб' поменять 4 буквы, то получится ? ПИВО

А шутка юмора в том, что если символ из utf-8 не имеет аналога в таргет-кодировке (будь то C<koi8-r> или C<windows-1251> или ещё какая),
то метод B<from_to> из B<Encode> заменяет его на знаки вопроса.

В большинстве случаев, на всех бекендах с базой данных а-ля mysql с default charset отличным от utf, пишется костыль.
И, здесь у каждого своё решение.

Ещё кейс:

С подобного рода проблемами (при перекодировке utf в кириллицу) можно столкнуться, если вы скачиваете и храните данные rss
каналов в своей "русской" базе.

B<CCCP::Encode> создан для решения этой небольшой, но деликатной проблемы.

=head2 METHODS

=head3 utf2cyrillic($str,$to)

И<$str> строка для перекодировки. C<$to> название кодировки, в которую нужно перекинуть строку.
По аналогии с C<$to> в C<Encode::from_to($str,'utf-8',$to)>

Возвращает перекодированную строку. 

=head2 PACKAGE VARIABLES

=head3 $CCCP::Encode::ToText

Default is false. 

Если C<$CCCP::Encode::ToText> ложь, то C<utf2cyrillic>
перекодирует строку и, встречая символ не имеющий аналога, заменяет его на соотвествующий из определённых Вами в B<$CCCP::Encode::CharMap>
или используя B<HTML::Entities>.

Если C<$CCCP::Encode::ToText> имеет истинное значение, то C<utf2cyrillic> 
перекодирует строку в формат plain/text и, встречая символ не имеющий аналога, 
заменяет его на соотвествующий из определённых Вами в B<$CCCP::Encode::CharMap>
или использует карты замены символов модуля B<Text::Unidecode>. 

=head3 $CCCP::Encode::CharMap

Default is empty hashref. 

Здесь вы можете определить своё значение для любого символа. Это очень гибкий инструмент, особенно когда требуется
осуществить замену символа на вариант отличный от C<HTML::Entities> или C<Text::Unidecode> (в зависимости от режима работы).

Более того, вы можете поставить в соответствие символу некое слово.  

Пример:

    $CCCP::Encode::CharMap = {
    	"\x{2014}" => '-',
    	"\x{2015}" => 'foo'
    };

=head3 $CCCP::Encode::Regexp

Значение по умолчанию B<[^\p{Cyrillic}|\p{IsLatin}]>  

т.е. заменять все символы, которые не соответствуют кирилице или латинице.
Вы можете заменить это значнение на своё (скаляр). 

Более подробно ознакомиться с возможными вариантами можно здесь: L<http://www.regular-expressions.info/unicode.html>

=head1 SEE ALSO

=over 4

=item *

L<Encode>

=item *

L<HTML::Entities>

=item *

L<Text::Unidecode>

=back

=head1 AUTHOR

Ivan Sivirinov

=head1 COPYRIGHT AND LICENSE

Типа бесплатно и вне очереди

=cut
