Кодируем помаленьку
Автор: Алексей Федорчук, 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 для экранного вывода .
Впрочем, последняя проблема, сложившись исторически, решена также в историческом масштабе времени: во FreeBSD путем загрузки карт перекодирования (screenmap), в современных отечественных (или исконно интернациональных) дистрибутивах Linux – использованием фрагментарного Unicode .
Однако пользователи Unix-систем живут не в безвоздушном пространстве – время от времени им требуется читать документы, созданные на иных платформах (пользователи которых, как уже говорилось, подчас даже не подозревают, что кроме их кодировок существуют какие-либо иные). Причем – чем дальше, тем больше: как я уже говорил, даже в исконную Unix-вотчину проникло тлетворное влияние Microsoft [3].
Первое напрашивающееся решение при этом – использование перекодировщиков. И действительно, таковых создано немало. Самый простой из них – программка iconv. Она являет собой компонент общесистемной библиотеки libc (glibc) и потому гарантированно присутствует в любом дистрибутиве Linux или BSD-клоне. Формат ее предельно прост: iconv -f [исходная_кодировка] -t [целевая кодировка] имя_файла
Она выводит результат своей работы на стандартный вывод, поэтому для сохранения его в файле следует прибегнуть к операции перенаправления вывода: iconv -f enc1 -t enc2 source_file > target_file
Ну а список доступных перекодировок (а заодно и правильное их наименование) можно посмотреть посредством команды iconv --list
Есть и более развитые средства, позволяющие в один присест перекодировать несколько файлов (и даже целый каталог). Среди них – rusconv Олега Паращенко, о которой я некогда писал в своей книжке . Она позволяет перекодировать произвольное количество файлов (в том числе и по маске), с сохранением в текущем или любом другом каталоге. И при этом не только между большинством распространенных кодировок кириллицы (DOS, Windows, KOI, Mac), но и превратить латинскую транслитерацию в читабельный русский текст (или наоборот). Большое достоинство программы – ее прекрасная документированность, руководство пользователя для нее (на русском языке) составляет несколько десятков страниц. Это избавляет меня от описания ее работы – интересующихся отсылаю к сайту автора .
Еще более удобной представляется мне программа 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-диск или сменный винчестер), позволяя делать это парой-тройкой несложных скриптов. Правда, она не позволяет рекурсивного перекодирования вложенных подкаталогов – но такой возможности я пока не видел ни в одной программе-перекодировщике .
Однако перекодировщики не решают всех проблем обмена документами – достаточно скучно перекодировать все, что потребуется впредь (или, напротив, нужно только сиюминутно). А уж если нужно поправить пару символов в 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 входит прекрасная их коллекция . Для этого Linux'овый шрифт сначала разархивируется, а затем дается команда типа dd if=linux_font.psf of=bsd_font.fnt bs=1 skip=4 count=4096
где значение count приведено для шрифта стандартного (80x25) разрешения размером 8x16. Однако теоретически можно сделать и шрифт для высокого разрешения – 8x8. А если исходный шрифт – Unicode (а в дистрибутивах Linux есть и такие), то, вычислив смещение, можно изготовить буковки в любой кириллической кодировке. Впрочем, каюсь, я в вычислениях запутался – нормально у меня получились только фонты 8x16 для CP866 .
С клавиатурными раскладками – несколько хуже: во FreeBSD они имеют место быть только для KOI8 и CP866, но не для CP1251. В Сети последних для Free (а по формату они немного другие, чем для Linux) я тоже не нашел. Осталось изготовить эту раскладку собственноручно – заодно и с переопределением всяких Win-клавиш по собственному разумению .
Наконец, если нет желания менять экранные шрифты, той же командой 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, которые заполняются соответствиями символов «кто -> во что преобразуется» (очевидно, что содержание секций представляет собой зеркальное отражение). При этом и исходный, и преобразуемый символы могут быть заданы почти любым образом – восьмеричными, шестнадцатеричными или десятичными их кодами, а то и просто символами, заключенными в одинарные кавычки (и даже без оных). Для удобочитаемости символы могут разделяться пробелами (а могут и не разделяться).
Иными словами, берутся любые требуемые кодовые таблицы и перекраиваются требуемым образом. Если же и это лениво – map-файлы для случая Windows и DOS на KOI-терминале можно взять у меня . И вызывать их указанным выше образом при необходимости.
[1] О причинах этого явления написано столько, что повторяться не буду. Отмечу только, что и здесь есть исключение – в OpenBSD штатно предусмотрена только кодировка KOI8 и для вывода.
[2] Хотя и в Linux никто не запрещает применения карт перекодировки – насколько я знаю, именно так по сию пору делается и в Slackware, и Debian.
[3] О чем можно судить хотя бы по тому, что все больше бесплатных web-хостов безальтернативно требуют Windows-кодировки для размещаемых на них страниц.
[4] Офис, web, графика в Linux. СПб: БХВ-Питер, 2001.
[5] http://beta.math.spbu.ru/~prof/w_re/. Правда, последнее время на него очень нелегко попасть.
[6] Архитектурных излишеств типа кодировок Mac и ISO8859-5 не предусмотрено, что, на мой взгляд, ценности программы отнюдь не снижает.
[7] Вроде бы в Tot-Recode для Windows такое было, или память мне изменяет?
[8] Большое спасибо Стасу Гобунову за подсказку, как именно это сделать.
[9] Заинтересованные могут посмотреть результаты на
[10] Результаты – см. предыдущее примечание.
[11] См. прим. [9]. [обратно к тексту]
Вниманию вебмастеров: использование данной статьи возможно только в соответствии
с (http://www.softerra.ru/site/rules/)