# NAME Octets::To::Unicode - модуль и утилиты ru-perltidy и ru-utf8 для распознавания кодировки текста (в том числе в файлах) и его декодирования. # VERSION 0.01 # SYNOPSIS use Octets::To::Unicode; my $unicode = decode "Стар Трек"; my ($unicode, $encoding) = decode "Стар Трек"; my $unicode = decode $octets_in_cp1251_or_maybe_in_utf8, [qw/cp1251 utf-8/]; my $encoding = detect $octets; my $encoding = detect $octets, [qw/cp1251 utf-8/]; my ($file_text_in_unicode, $encoding) = file_decode "path/to/file", ["cp1251", "koi8-r"]; file_encode "path/to/file2", "koi8-r", $file_text_in_unicode; Использование утилит: # Отформатировать указанные файлы perltidy: $ ru-perltidy file1 file2 # Указать кодировку: $ ru-perltidy file1 file2 -e utf-8,cp1251 # Форматирует только изменённые файлы в репозитории git: $ ru-perltidy # Форматирует изменённые файлы в ветке (на случай, если забыл отформатировать перед комитом): $ ru-perltidy --in-branch # Указать расширения файлов: $ ru-perltidy --ext 'pl,pm,' # Обработать файлы в директориях: $ ru-perltidy --in-dir .,/tmp/mydir # Выполнить операцию с файлами: $ ru-utf8 file1 file2 -c 'perltidy $f -st > $o' # Переменные, которые можно использовать: $ ru-utf8 file1 file2 -c 'echo $f $o $e $x' $ ru-utf8 file1 file2 -o -c 'echo $f1 $o1 $e1 $x1 - $f2 $o2 $e2 $x2' # Кроме команды шелла можно использовать ещё код perl: $ ru-utf8 file1 file2 -s 'print "$f $o $e $x -- $unicode\n"' $ ru-utf8 file1 file2 -o -s 'print "@f @o @e @x"' # Определить кодировку файлов и перекодировать их в koi8-r: $ ru-encoding -t koi8-r # DESCRIPTION Пакет включает в себя утилиты: - **ru-perltidy** — форматирует файлы через perltidy c определением их кодировки; - **ru-utf8** — переводит файлы во временные (в кодировке utf-8), выполняет указанную команду и переписывает обратно в определённой кодировке; - **ru-encoding** — перекодирует файлы в указанную кодировку. и модуль perl: - **Octets::To::Unicode** — модуль c функциями определения кодировки текста и его конвертирования между кодировками. **Octets::To::Unicode** предоставляет необходимое множество утилит для определения кодировки текста и его декодирования, а так же — работы с файлами. В 2000-х определилась тенденция переводить проекты в национальных кодировках в utf-8. Однако не везде их перевели одним махом, а решили рубить собаке хвост постепенно. В результате во многих проектах часть файлов c кодом в utf-8, а часть — в национальной кодировке (cp1251, например). Ещё одной проблемой могут служить урлы с эскейп-последоваительностями. Например, https://ru.wikipedia.org/wiki/Молчание#Золото преобразуется в мессенджере, куда эту ссылку можно скопировать, в https://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%BB%D1%87%D0%B0%D0%BD%D0%B8%D0%B5#%D0%97%D0%BE%D0%BB%D0%BE%D1%82%D0%BE. Причём один мессенджер переведёт русские символы в utf-8, другой — в cp1251, третий — в koi8-r. Чтобы решить эти две проблемы в приложениях и был написан этот модуль. # SUBROUTINES/METHODS ## bohemy $num = bohemy $unicode; Возвращает числовую характеристику похожести текста на русский. Алгоритм основан на наблюдении, что в русском языке слово начинается на прописную или строчную букву, а затем состоит из строчных букв. Таким образом, числовая характеристика, это сумма длин русско-похожих слов с разницей суммы длин русско-непохожих. Принимает параметр: - **$unicode** Текст в юникоде (с взведённым флажком utf8). ## decode $unicode = decode $octets, $encodings; ($unicode, $encoding) = decode $octets, $encodings; Возвращает декодированный текст в скалярном контексте, а в списочном, ещё и определённую кодировку. Если ни одна из кодировок не подошла, то вместо юникода в первом параметре возвращаются октеты, а вместо кодировки - `undef`: ($octets, $encoding_is_undef) = decode $octets, []; Принимает параметры: - **$unicode** Текст в юникоде (с взведённым флажком utf8). - **$encodings** Cписок кодировок, которыми предлагается попробовать декодировать текст. Необязательный. Значение по умолчанию: `[qw/utf-8 cp1251 koi8-r/]`. ## detect $encoding = detect $octets, $encodings; Возвращает определённую кодировку или `undef`. Параметры такие же как у ["decode"](#decode). ## file\_find @files = file_find $path_to_directory; Ищет файлы в директориях рекурсивно и возвращает список путей к ним. Принимает параметр: - **$path\_to\_directory** Путь к файлу или директории. Если путь не ведёт к директории, то он просто возвращается в списке. ## file\_read $octets = file_read $path; Считывает файл. Возвращает текст в октетах. Выбрасывает исключение, если открыть файл не удалось. Принимает параметр: - **$path** Путь к файлу. ## file\_write file_write $path, $octets_or_unicode; Перезаписывает файл строкой. Ничего не возвращает. Выбрасывает исключение, если открыть файл не удалось. Принимает параметры: - **$path** Путь к файлу. - **$octets\_or\_unicode** Новое тело файла в октетах или юникоде. ## file\_decode $unicode = file_decode $path, $encodings; ($unicode, $encoding) = file_decode $path, $encodings; Возвращает декодированный текст из файла в скалярном контексте, а в списочном, ещё и определённую кодировку. Если ни одна из кодировок не подошла, то вместо юникода в первом параметре возвращаются октеты, а вместо кодировки - `undef`: ($octets, $encoding_is_undef) = file_decode $path, []; Принимает параметры: - **$path** Путь к файлу. - **$encodings** Cписок кодировок, которыми предлагается попробовать декодировать текст. Необязательный. Значение по умолчанию: `[qw/utf-8 cp1251 koi8-r/]`. ## file\_encode file_encode $path, $encoding, $unicode; Переписывает текст в файле в указанной кодировке. Принимает параметры: - **$path** Путь к файлу. - **$encoding** Кодировка в которую следует перевести параметр `unicode` перед записью в файл. - **$unicode** Новый текст файла в юникоде (с установленным флажком utf8). ## test\_file $is_file = test_file $file, $exts, $interpreters; Тестирует файл на соответствие указанным расширениям, а если расширения нет, то на соответсвие интерпретаторов к указанному в первой строке файла начинающейся на `#!`. Принимает параметры: - **$file** Путь к файлу. Обязательный. - **$exts** Список расширений для сопоставления, если он пуст, то подходит любое. Необязательный. Значение по умолчанию: `[]`. - **$interpreters** Список интерпретаторов для сопоставления, если он пуст, то подходит любой, главное, чтобы строка начиналась на `#!`. Необязательный. Значение по умолчанию: `[]`. ## test\_files @files = test_files $files, $exts, $interpreters; Тестирует файлы на соответствие указанным расширениям или интерпретаторам. Принимает параметры: - **$files** Список файлов. Обязательный. - **$exts** Такой же как в **test\_file**. - **$interpreters** Такой же как в **test\_file**. ## change\_files @files = change_files(); Возвращает изменённые файлы в репозитории git. ## change\_files @files = change_files_in_branch(); Возвращает изменённые файлы в ветке. # INSTALL Установить можно любым менеджером `perl` со **CPAN**, например: $ sudo cpm install -g Octets::To::Unicode # DEPENDENCIES Зависит от модулей: - Getopt::Long - Encode - List::Util - Pod::Usage - Term::ANSIColor и от **perltidy** опционально: - Perl::Tidy # RELEASE Релиз на **CPAN** осуществляется так: - Обновить исходники: $ git pull - Отредактировать файл _Changes_. В файле _Changes_ нужно написать список изменений, которые вошли в этот релиз. Изменения записываются в виде списка, одно изменение — один элемент списка. Элементы списка обозначаются символами тире \`-\`. Список с изменениями нужно разместить между строкой \`{{$NEXT}}\` и строкой с предыдущим релизом. Допустим, предыдущий релиз был 1.71. Тогда описание изменений нового релиза будет выглядеть так: {{$NEXT}} - RU-5 Какой-то тикет, который вошел в релиз. - RU-6 Ещё один тикет, вошедший в релиз. 1.71 2021-05-07T08:52:18Z - RU-4 Какой-то предыдущий тикет. Обратите внимание — у нового релиза пока нет версии. Версия будет вычислена Миниллой при выполнении релиза и автоматически вписана в файл _Changes_ вместо метки `{{$NEXT}}`. - Активировать локальную библиотеку: $ cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib) Это нужно, чтобы не выполнять релиз под рутом. - Выполнить релиз: $ minil release В процессе Минилла задаст несколько вопросов, в частности предложит выбрать номер новой версии. Обычно на все вопросы нужно отвечать кнопкой "enter". Иначе лучше прервать процесс и внести изменения в конфигурационные файлы. # LINKS - perltidy и cp1251 / [https://habr.com/ru/post/664308/](https://habr.com/ru/post/664308/). # AUTHOR Yaroslav O. Kosmina # LICENSE ⚖ **GPLv3**