div.main {margin-left: 20pt; margin-right: 20pt}Кодируем помаленьку Автор: Алексей Федорчук, alv@newmail.ru Опубликовано:
13.04.2002 Оригинал: http://www.softerra.ru/freeos/17363/
Своеобразие исторической судьбы России
проявлялась во всем. В том числе и в том – что русский язык самый
многокодировочный язык в мире. Что создает, конечно, некоторые трудности в
повседневной жизни. Но зато – какой простор для проявления исконно народной
смекалки…
Перечисление ныне существующие (то есть
используемые) кодировки кириллических символов – уже требует изрядного
напряжения интеллекта, особенно если учесть все синонимы, псевдонимы и эпитеты.
Здесь и
классическая кодировка DOS, она же – CP866, IBM866, альтернативная (на
полноту перечня не претендую); по сию пору она есть стандарт междокументного
обмена – так, РФФИ принимает электронные версии проектов только в ней (и в
чисто текстовом формате);
и не менее традиционная KOI8-R – кодировка электронной почты и, до
недавнего времени, Рунета;
и ISO8859-5, кодировка Sun, по не вполне понятным причинам сподобившаяся
канонизации в качестве кодировки ГОСТ'а;
и CP1251, она же – кодировка Windows, не только добившаяся почти
безраздельного господства на пользовательских десктопах, но и теснящая KOI8 в
ее исконной вотчине – Интернет-серверах;
и кодировка MacOS, правда, слава богу, так и не вышедшая за пределы своей
платформы.
А еще где-то за кадром остаются «болгарская»
кодировка (как легко понять из названия, к Болгарии почти никакого отношения не
имеющая), и древняя кодировка того же Mac'а (как помнится, даже не одна), и
апокалиптический Unicode…
Легка жизнь пользователей, закосневших в чистом
«черном» DOS'е или присягнувших на верность OS/2: как бы то ни было, их CP866
признается всеми – нет, наверное, текстового процессора, не имеющего функции
сохранения документа в этом формате. Не сложнее – и мучителям Windows (или
мучимым оной): они могут позволить себе просто не знать о существовании иных
кодировок, кроме CP1251. Ну а эзотерикам от MacOS – им, подозреваю, ничего,
кроме собственной кодировки и не нужно. Не знаю уж, как обходятся Solaris'ты –
но и от них сетований как-будто не слышно.
А вот те, кто связал судьбу с открытыми и
свободными Unix-подобными системами, обязаны учитывать все изобилие
кириллических кодировок. Хотя бы потому, что большинство из них даже не
поднимаясь из-за своего десктопа, используют две из них – KOI8 для клавиатурного
ввода и CP866 для экранного вывода [1].
Впрочем, последняя проблема, сложившись
исторически, решена также в историческом масштабе времени: во FreeBSD путем
загрузки карт перекодирования (screenmap), в современных отечественных (или
исконно интернациональных) дистрибутивах Linux – использованием фрагментарного
Unicode [2].
Однако пользователи Unix-систем живут не в
безвоздушном пространстве – время от времени им требуется читать документы,
созданные на иных платформах (пользователи которых, как уже говорилось, подчас
даже не подозревают, что кроме их кодировок существуют какие-либо иные). Причем
– чем дальше, тем больше: как я уже говорил, даже в исконную Unix-вотчину
проникло тлетворное влияние Microsoft [3].
Первое напрашивающееся решение при этом –
использование перекодировщиков. И действительно, таковых создано немало. Самый
простой из них – программка iconv. Она являет собой компонент общесистемной
библиотеки libc (glibc) и потому гарантированно присутствует в любом
дистрибутиве Linux или BSD-клоне. Формат ее предельно прост: iconv -f [исходная_кодировка] -t [целевая кодировка] имя_файла
Она выводит результат своей работы на
стандартный вывод, поэтому для сохранения его в файле следует прибегнуть к
операции перенаправления вывода: iconv -f enc1 -t enc2 source_file > target_file
Ну а список доступных перекодировок (а заодно и
правильное их наименование) можно посмотреть посредством команды iconv --list
Есть и более развитые средства, позволяющие в
один присест перекодировать несколько файлов (и даже целый каталог). Среди них –
rusconv Олега Паращенко, о которой я некогда писал в своей книжке [4]. Она позволяет
перекодировать произвольное количество файлов (в том числе и по маске), с
сохранением в текущем или любом другом каталоге. И при этом не только между
большинством распространенных кодировок кириллицы (DOS, Windows, KOI, Mac), но и
превратить латинскую транслитерацию в читабельный русский текст (или наоборот).
Большое достоинство программы – ее прекрасная документированность, руководство
пользователя для нее (на русском языке) составляет несколько десятков страниц.
Это избавляет меня от описания ее работы – интересующихся отсылаю к сайту автора
[5].
Еще более удобной представляется мне программа
d1489 (автор – Андрей Чернов, известный, помимо прочего, и своими трудами по
русификации Unix'ов), доступная во FreeBSD в виде порта и пакета (в
дистрибутивах Linux она мне не попадалась, может быть, просто не обращал
внимания). В отличие от rusconv, она не документирована вообще – с ней нет ни
man-, ни info-страниц, лишь очень краткая справка по использованию. Впрочем – ни
в чем более она и не нуждается, предоставляя, однако, вполне достаточные
возможности.
Пакет d1489 включает в себя две пары утилит –
fromwin/towin и fromdos/todos, назначение которых вполне ясно из их имен: это
перекодирование между KOI8 и Windows/DOS, соответственно [6]. Есть в ней и
еще одна утилитка – a2kfcnv, для трансформации экранных консольных шрифтов из
CP866 в KOI8, что может оказаться отнюдь не лишним.
Используется каждая из парных утилит одинаково,
хотя и разнообразно (о чем мы узнаем посредством запуска любой команды с опцией
-h или -?). Можно дать команду fromwin имя_файла
в результате чего исходный файл в кодировке
CP1251 будет замещен им же, но в KOI8. Можно перенаправить результат
перекодировки в другой файл – fromwin < Win-файл > KOI-файл
А можно перекодировать и множество файлов, в том
числе и по маске (например, все текстовые или html-документы каталога) с записью
результатов в другой каталог, скажем fromwin -o output_dir ~/*.html
По умолчанию при перекодировании из KOI8 в
DOS/Windows и обратно программа заодно преобразует и символы конца строк в вид,
принятый в целевой системе. Что при желании можно подавить опцией -b. Ну а опция
-p по возможности пытается сохранить такие атрибуты файлов, как время
модификации (насколько это осуществимо при переносе между DOS/Windows и Unix).
Короче говоря, пакет очень удобен, если
требуется регулярно переносить большие объемы данных на фиксированные носители
(например, Zip-диск или сменный винчестер), позволяя делать это парой-тройкой
несложных скриптов. Правда, она не позволяет рекурсивного перекодирования
вложенных подкаталогов – но такой возможности я пока не видел ни в одной
программе-перекодировщике [7].
Однако перекодировщики не решают всех проблем
обмена документами – достаточно скучно перекодировать все, что потребуется
впредь (или, напротив, нужно только сиюминутно). А уж если нужно поправить пару
символов в Windows или DOS-документе…
Так что очень желательной видится возможность
переключения кодировок терминала, что называется, на лету (или на бегу?). К
счастью, и такое не запрещается – благодаря механизму загрузки клавиатурных
раскладок и экранных шрифтов (да и карт соответствия, буде потребуется – также).
В Linux можно сделать разными способами, в зависимости от того, какой пакет
управления консолью – kkb или console-tools, принят в данном дистрибутиве. И
потому скажу пока только за FreeBSD.
Там эти функции возложены на две штатные
программы из пакета системной консоли (syscons), одна из которых называется
vidcontrol, другая – kbdcontrol. Посредством первой можно подгрузить шрифт в
любой кодировке, например vidcontrol -f 8x16 cp1251-8x16.fnt
А второй – задать соответствующую ему
клавиатурную раскладку: kbdcontrol -l ru.cp1251.kbd
Разумеется, для того, чтобы сварить суп из
курицы, нужно как минимум иметь курицу. То есть, применительно к случаю –
соответствующие экранные шрифты и клавиатурные раскладки. Благо с первыми
проблем нет – в комплект FreeBSD входят консольные шрифты для всех трех главных
кодировок русского языка (хотя эстетически, да и эргономически, все они далеки
от совершенства).
Для тех, которые с претензиями (как ваш покорный
слуга, например) – шрифты для консоли FreeBSD можно изготовить из таковых для
Linux-консоли, в отечественные дистрибутивы типа Altlinux входит прекрасная их
коллекция [8]. Для этого
Linux'овый шрифт сначала разархивируется, а затем дается команда типа dd if=linux_font.psf of=bsd_font.fnt bs=1 skip=4 count=4096
где значение count приведено для шрифта
стандартного (80x25) разрешения размером 8x16. Однако теоретически можно сделать
и шрифт для высокого разрешения – 8x8. А если исходный шрифт – Unicode (а в
дистрибутивах Linux есть и такие), то, вычислив смещение, можно изготовить
буковки в любой кириллической кодировке. Впрочем, каюсь, я в вычислениях
запутался – нормально у меня получились только фонты 8x16 для CP866 [9].
С клавиатурными раскладками – несколько хуже: во
FreeBSD они имеют место быть только для KOI8 и CP866, но не для CP1251. В Сети
последних для Free (а по формату они немного другие, чем для Linux) я тоже не
нашел. Осталось изготовить эту раскладку собственноручно – заодно и с
переопределением всяких Win-клавиш по собственному разумению [10].
Наконец, если нет желания менять экранные
шрифты, той же командой vidcontrol в форме vidcontrol -l *.scm
можно подгрузить и требуемую карту соответствия.
Опять же, если таковая имеется – а штатно она есть только для KOI8 -> CP866.
Но и тут принципиальных сложностей не предвидится – с помощью толики терпения и
чьей-то матери нужную карту можно склепать вручную.
Однако и средства syscons – не панацея от всех
бед. Главный их недостаток – переключение шрифта, раскладки и таблицы
соответствия между ними действует на все виртуальные консоли сразу. И потому
мечта – сочинять текст в KOI8, время от времени просматривая документы,
сохраненные в CP1251, – имеет шанс так и остаться мечтой. А уж о том, чтобы
таскать между ними фрагменты, казалось бы, можно забыть.
Можно – если бы не открытие на сайте винницкой
фирмы Крон
замечательной программки mapchan, позволяющей (цитирую README) «произвольным
образом преобразовывать терминальный ввод-вывод». И дающей, таким образом,
возможность работать на различных виртуальных консолях с документами в любых
кодировках (в общем случае – не только кириллицы, и не только на локальной
машине, но и с удаленных терминалах, но этот аспект я затрагивать не буду).
Программа (автор ее представляется как Yura
Kalinichenko) являет собой модернизацию одноименной утилиты из SCO Unix и
написана, судя по всему, под Linux. Однако ничего Linux-специфичного не содержит
и потому должна работать под любым Unix'ом. За любой – не скажу, но под FreeBSD
она устанавливается без проблем и работает прекрасно.
Установка ее – стандартна, распаковывается архив
и от имени root'а даются команды make
make install
Правда, при этом свой исполнимый файл (mapchan
же) записывается непосредственно в каталог /bin, а дополнительные компоненты (в
частности, собственно таблицы перекодировки ввода/вывода – map-файлы)
предлагается руками положить в каталог /etc/mapchan. Если это почему-либо не
устраивает – можно обойтись без make install и вручную расписать их куда угодно
(например, как $HOME/bin/mapchan и т.д.). Далее программа запускается следующим
образом mapchan -s [shell] -f /path/file.map
после чего в текущей консоли грузится указанная
опцией -s оболочка, в которой можно наслаждаться чтением и писанием русских
текстов в той кодировке, которая определена заданным через опцию -f map-файлом,
вне зависимости от того, какая кодировка определена для системы в целом. При
этом не затрагиваются ни клавиатурные раскладки (все буквы находятся на тех же
местах, что и раньше), ни их переключатели (кириллица/латиница переключаются тем
же способом), ни экранные шрифты (вид их остается неизменным). Боле того, все
прочие консоли сохраняют общесистемную кодировку. И выделенный мышью фрагмент в
консоли с KOI8 в правильном виде вставляется на консоль с Win- или
DOS-кодировкой.
Красота, да и только… Дело за малым –
обзавестись достаточным количеством map-файлов для всех требуемых случаев. В
комплекте таковые имеются для работы с DOS-кодировкой в KOI'шном терминале, и с
кодировкой KOI8-U при терминалах с альтернативным DOS (он же – CP866) и с
кодировкой ГОСТ'а. Есть и вариант для некоего терминала СМ7238 – я с таким не
сталкивался.
А вот самый актуальный ныне случай – для работы
с CP1251 при KOI-терминале, – не представлен. Изготовлением соответствующего
map-файла следует озадачиться самостоятельно. Благо вследствие формата map-файла
это просто: определяются две секции – input и output, которые заполняются
соответствиями символов «кто -> во что преобразуется» (очевидно, что
содержание секций представляет собой зеркальное отражение). При этом и исходный,
и преобразуемый символы могут быть заданы почти любым образом – восьмеричными,
шестнадцатеричными или десятичными их кодами, а то и просто символами,
заключенными в одинарные кавычки (и даже без оных). Для удобочитаемости символы
могут разделяться пробелами (а могут и не разделяться).
Иными словами, берутся любые требуемые кодовые
таблицы и перекраиваются требуемым образом.
|