Для систем обработки текстов на множестве языков важное значение имеет (1) унифицированные механизмы для множества языков и, (2) возможность подстраивать и расширять функции, существующие в системе. В этой работе мы объясним, как эти вопросы решаются в системе Mule (MULtilingual Enhancement to GNU Emacs, т.е. Многоязычное приложение к GNU Emacs). Mule является экранным редактором, ориентированным на работу с простыми текстами в различных операционных системах (UNIX, DOS, Windows и OS/2 на многих платформах). Он дает пользователю разнообразные возможности обработки текстов на многих языках, и распространяется не только на простое редактирование текстов, но и на написание/прочтение сообщений и новостей Internet, просмотр страниц Web и т.д. Все эти функции управляются унифицированным механизмом и свободно могут настраиваться и расширяться пользователями.
Благодаря ощутимому развитию компьютерных технологий мы можем, использовать компьютер для работы не только с английским, но и многими другими языками. Во многих странах уже умеют работать на компьютерах, используя свой национальный язык. Большинство из них основывается на локальных продуктах, которые не вызывают никаких проблем, пока каждый компьютер остается в собственных локальных пределах. Но, по мере того, как Internet, связывает мир все более и более тесно, необходимость обеспечить стыковку между различными территориями/странами/языками становится все ощутимее и сейчас мы стоим перед проблемой работы с несколькими языками одновременно. Возникла она из-за того, что каждая локальная система развивалась независимо, без учета других локальных систем.
Для решения проблемы работы с несколькими языками одновременно, мы создали Mule, многоязычный редактор простых текстов на основе GNU Emacs. GNU Emacs является одним из наиболее известных и широко применяемых редакторов в мире UNIX. Наибольшее достоинство Emacs заключается в том, что он снабжен переводчиком Emacs Lisp, и большая часть функций выполняется именно Emacs Lisp. Это означает, что возможности GNU Emacs можно увеличить просто модифицируя и добавляя программы Emacs Lisp. Emacs можно использовать не только для редактирования, но и для почти всех видов обработки текстов, включая написание/прочтение сообщений и новостей Internet, просмотр страниц Web, запрос инструкций, работа со словарями в режиме реального времени, и т.д. Все эти возможности реализуются программами Emacs Lisp, и благодаря этому, могут быть полностью подстроены под требования конкретного пользователя.
Все вышеописанные функции существует и в Mule и он может использовать их для работы в многоязычной среде. Например, пользователи Mule могут обмениваться почтовыми сообщениями и читать страницы Web на всех языках, которые поддерживаются Mule.
Разрабатывая Mule, мы исходили из соображений необходимости двух вещей:
Наиболее сложным и важным вопросом обработки текстов в многоязычной среде является вопрос сохранения в унифицированном механизме, работающим с разными языками, всех тех удобств и преимуществ, которые были созданы в каждой локальной языковой среде. Работа с текстом в разных языках может отличаться во многих аспектах: в используемом наборе символов, в способе вывода текста на экран, в способе ввода текста через клавиатуру, в механизме кодирования, используемом в файлах. Чтобы работать с множеством различных языков необходимо иметь унифицированный механизм, включающий в себя все местные различия.
Другим важным вопросом является настраиваемость и расширяемость среды, другими словами, то, насколько легко добавлять функции и подстраивать их под требования конкретного пользователя. Почти невозможно разработать и представить все функциональные возможности для всех поддерживаемых языков заранее. Само количество поддерживаемых языков может меняться в будущем. В развивающихся странах может меняться даже стандартная среда государственного языка. Любая система, которой не хватает гибкости, чтобы добавить новые функции или модифицировать старые, скоро станет бесполезной, в лучшем случае добавление новых языков окажется неизмеримо тяжелой задачей.
Таким образом, даже когда мы видим, что для работы с каким-то языком нужна новая функция, мы не будем добавлять ее немедленно. Сначала мы проверим, не нужна ли аналогичная функция какому-либо другому языку, какая часть функции может быть обобщена для применения для всех языках, и какую часть функции нужно зарезервировать для будущих модификаций.
Обработка текста является комплексной задачей. Она включает в себя, как минимум, ввод текста, хранение, восстановление и вывод на дисплей. Когда мы говорим, что Mule поддерживает какой-нибудь язык, это означает, что Mule может по меньшей мере:
Здесь мы используем слово "стандартный" для обозначения не только "официального" стандарта, но и стандарта "де-факто". Более того, обрабатывая текст, мы должны обращаться с буквами, словами и строками в соответствии со стандартными требованиями каждого языка. Все эти возможности управляются унифицированным механизмом, контролирующим наборы символов, системы кодирования, методов ввода и процедуры вывода на дисплей.
Последующие разделы посвящены следующему:
Набор символом представляет собой группу символов, используемых в каком-либо региональном языке (т.е. в текстах на английском языке, в текстах на японском языке). Хотя каждый разработчик мечтает о едином наборе символов для всех языков, пока что эти мечты далеки от осуществления. ISO-10646 (или Unicode) в настоящий момент не может применяться, особенно для китайских иероглифов, из-за несовместимости при работе с CJK-унификаторами. Вот почему мы решили использовать в Mule ряд наборов символов.
Большинство наборов символов, применяемых в Mule, соответствует один к одному наборам символов, зарегистрированным в ISO (т.е. ISO-8859-1, JIS X0208). Хотя каждый набор символов ISO идентифицируется по своему типоразмеру (количеству символов, включенных в него) и последнему символу (однобайтовый код для различения наборов символов одного типоразмера), Mule идентифицирует каждый набор символов своим собственным идентификационным номером. Таким образом, чтобы задать в Mule какой-либо набор символов, необходимо установить соответствие между идентификационным номером набора и соответствующим набором символов ISO и ввести в Mule несколько параметров набора символов. Параметрами, которые используются при редактировании, являются ширина отображения, направление набора текста и т.д. В Таблице 1 приводятся примеры набора символов.
| Набор символов ISO | параметры, используемые в Mule | ||||||
| название | типоразмер | последний символ | идентификационный номер | байты | ширина | направление | |
| ASCII | 94 | 'B' | 0 | 1 | 1 | left-to-right | |
| ISO8859-1 | (Latin1) | 96 | 'A' | 129 | 2 | 1 | left-to-right |
| ISO8859-8 | (Hebrew) | 96 | 'H' | 136 | 2 | 1 | right-to-left |
| TIS620 | 96 | 'T' | 133 | 2 | 1 | left-to-right | |
| GB2312 | 94 X 94 | 'A' | 145 | 3 | 1 | left-to-right | |
| JISX0208 | 94 X 94 | 'B' | 146 | 3 | 1 | left-to-right | |
| CNS11643-1 | 94 X 94 | 'G' | 149 | 4 | 1 | left-to-right | |
| CNS11643-3 | 94 X 94 | 'I' | 246 | 4 | 1 | left-to-right | |
Можно задать и набор символов, не зарегистрированных в ISO. В этом случае Mule использует последний символ, зарезервированный ISO для индивидуального применения. Если исходный набор символов не соответствует техническим требованиям ISO-2022, его нужно организовать заново путем разбивки на несколько маленьких наборов символов или изменением точек кодирования символов, чтобы привести в соответствие с требованиями. Наиболее типичным примером является набор символов вьетнамского языка, который будет подробно описан в следующем разделе.
Чаще всего, чтобы самым простым способом удержать текст в памяти компьютера, каждый символ представляют в виде структуры из элементов фиксированной длины (от одного до четырех байтов). Когда речь идет о текстах на многих языках, использование одного или двух байтов для каждого символа, будет, очевидно, недостаточно, так как эти языки включают огромное количество символов. Использование элементов по четыре байта будет достаточно, но при работе с текстами на английском языке это будет впустую перегружать память. Поэтому, вместо представления с фиксированной длиной, мы используем многобайтовую форму изменяемой длины (дальше мы будем называть ее многобайтовой формой) для представления символов в буфере Mule; это позволяет эффективно использовать память и, одновременно, дает возможность расширения. (Эта идея была предложена Штальманом).
В многобитовой форме каждый символ представляется головными одним или двумя байтами, передающими идентификационный номер, и хвостовыми одним или двумя байтами, передающими код символа. Единственным исключением являются символы ASCII, представляемые так, как они есть, а идентификационный номер будет равен 0. В Таблице 2 дается более формальное определение внутреннего представления символов в Mule.
CHARACTER := ASCII_CHAR | MULTIBYTE_CHAR
MULTIBYTE_CHAR := PRIMARY_CHAR_1 | PRIMARY_CHAR_2
| SECONDARY_CHAR_1 | SECONDARY_CHAR_2
PRIMARY_CHAR_1 := LEADING_CODE_PRI C1
PRIMARY_CHAR_2 := LEADING_CODE_PRI C1 C2
SECONDARY_CHAR_1 := LEADING_CODE_SEC LEADING_CODE_EXT C1
SECONDARY_CHAR_2 := LEADING_CODE_SEC LEADING_CODE_EXT C1 C2
ASCII_CHAR := 0 | 1 | ... | 127
LEADING_CODE_PRI := 129 | 130 | ... | 153
LEADING_CODE_SEC := 154 | 155 | 156 | 157
C1, C2, LEADING_CODE_EXT := 160 | 161 | ... | 255
В этой таблице PRIMARY_CHAR и SECONDARY_CHAR отличаются только объемом памяти, требующейся для каждого символа, при редактировании различий между ними нет. Идентификационный номер представлен одним LEADING_CODE_PRI (в этом случае идентификационный номер будет находиться в пределах от 129 до 154) или последовательностью одним LEADING_CODE_SEC и одним LEADING_CODE_EXT (в этом случае идентификационный номер будет больше 160). Набор символов из одного байта может содержать максимум 96 символов и представляется последовательностью двух или трех байтов, набор символов из двух байтов может содержать до 9216 (96x96) символов и представляется последовательностью трех или четырех байтов. Наиболее часто используемые наборы символов мы называем PRIMARY (первичные). Все наборы символов, созданные пользователями, мы называем SECONDARY. Например в серии набора символов китайского языка (тайваньского диалекта) CNS11643 первые два уровня являются ПЕРВИЧНЫМИ, а остальные уровни являются ВТОРИЧНЫМИ (см. Таблицу 1). На Рисунке 1 показано использование однобайтовой зоны кодирования.
| 0x00--0x7f | character code of ASCII_CHAR |
| 0x80--0x99 | LEADING_CODE_PRI |
| 0x9a--0x9f | LEADING_CODE_SEC |
| 0xa0--0xff | 1st and 2nd charactercodes of MULTIBYTE_CHAR or LEADING_CODE_EXT |
Система кодирования или механизм кодирования, это способ, которым кодируется текст. В компьютере используется большое количество систем кодирования. В разных странах применяются различные системы кодирования. По этому Mule автоматически производит конверсию кодов из различных репрезентационных форматов текста во внутреннюю многобайтовую форму во всех случаях, когда Mule взаимодействует с внешним миром путем прочтения/записи файлов, общения с другими операциями, общения через сеть, принятия данных с терминала или вывода данных на терминал.
Чтобы сделать процесс кодирования настраиваемым и расширяемым, мы не стали встраивать в Mule жестко кодируемую процедуру преобразования. Вместо этого мы применили общую модель системы кодирования с рядом настраиваемых параметров. К счастью большая часть систем кодирования, применяющихся в настоящее время в мире, соответствует требованиям ISO-2022. Поэтому мы подразделяем системы кодирования на тип, соответствующий ISO-2022, и на тип не соответствующий ISO-2022. Для первого типа мы создали общий для всего ISO-2022 переводчик. Для второго типа мы разработали простой язык программирования CCL (Code Conversion Language) и создали переводчик CCL.
Когда пользователь собирается применить ту или иную систему кодирования для какой-либо операции (например, чтение файла или отправка почты), Mule автоматически обращается к переводчику ISO- 2022 или к переводчику CCL в соответствии с необходимой системой кодирования.
Хотя ISO-2022 допускает применение большого числа вариантов кодирования одного и того же текста, в действительности используются лишь некоторые из них. Таким образом для того, чтобы определить вид кодирования, достаточно небольшого количества параметров, перечисленных в Таблице 3. Например, китайский, японский и корейский варианты EUC (Extended UNIX Code) и вся серия ISO-8859 (раздел с 1-го по 10-ый) различаются только в параметрах "начальные обозначения" и "резервные обозначения". Еще один пример - 7-битовые серии ISO-2022, такие, как ISO-2022-JP, ISO-2022-JP-2, ISO-2022-KR и ISO-2022-CN. Все они используют 7-битовую среду. Разница между ними заключается только в резервных обозначениях и locking shift. В первых двух не применяется функция locking shift, а в остальных она есть.
| параметр | значение | смысл |
| исходное обозначение | список идентификационных номеров | Какой из наборов символов исходно назначается для каждого графического регистра. |
| резервное обозначение | список идентификационных номеров | Какой из наборов символов назначается исключительно для кодирования по каждому графическому регистру. |
| 7-битовая среда | истинно/ложно | Используйте кодирование только по нижним 7 битам или по всем 8 битам. |
| locking shift | истинно/ложно | Задействовать или нет функцию locking shift. |
| single shift | истинно/ложно | Задействовать или нет функцию single shift. |
| обозначение направления | истинно/ложно | Использовать последовательность для выхода согласно ISO-6429 для указания направления записи при кодировании. |
Таблица 4 показывает, как легко задать систему кодирования, соответствующую ISO-2022 в Mule. После того как система кодирования задана, ее можно использовать во всех случаях когда необходима конверсия кода. Например, после назначения системы кодирования, как указано в Таблице 4, пользователь может читать/создавать файлы GB и выводить китайские иероглифы на терминал GB и обмениваться почтовыми сообщениями в GB.
(*euc-china* ;; Название системы кодирования
2 ;; Тип, "2" означает тип, соответствующий ISO-2022
?C ;; Мнемонический символ системы кодирования
t ;; автоматическое определение типа
;; обозначения конца строки (CR, CRLF, LF)
(список lc-ascii lc-cn ;; G0 соответствует ASCII, G1 соответствует
;; китайскому GB2312
nil nil ;; G2 и G3 никогда не используются.
Примерами систем кодирования, не соответствующих ISO-2022 служат российская KOI-8 и вьетнамская VISCII. Хотя KOI-8 отвечает техническим требованиям ISO-2022, точки кодирования символов отличаются от стандарта ISO-8859-5 (латинский алфавит/кириллица), который является набором символов по умолчанию для символов кириллицы в Mule.
VISCII использует полные 8-ми битовые коды для 134 специфических вьетнамских символа, не отвечающих требованиям ISO-2022. Таким образом, в Mule вьетнамский набор символов разделяется на символы нижнего регистра и символы верхнего регистра; каждому из них присвоен собственный идентификационный номер.
Так как общий для ISO-2022 переводчик не может быть использован для кодирования и декодирования этих наборов символов, программа CCL выполняет конверсию в Mule. CCL является простым, но эффективным языком программирования, хорошо подходящим для написания алгоритма кода конверсии; это означает, что, теоретически, используя соответствующую программу CCL, Mule может работать с любой системой кодирования. Таблица 5 посвящена программе CCL, предназначенной для кодирования KOI-8.
(define-ccl-program ccl-write-koi8
'(1
((read r0)
(loop (if (r0 != 140) (write-read-repeat r0)
((read r0) (r0 -= 160)
(write-read-repeat r0
[ 32 179 32 32 32 32 32 32 32 32 32 32 32 32 32 32
225 226 247 231 228 229 246 250 233 234 235 236 237 238 239 240
242 243 244 245 230 232 227 254 251 253 255 249 248 252 224 241
193 194 215 199 196 197 214 218 201 202 203 204 205 206 207 208
210 211 212 213 198 200 195 222 219 221 223 217 216 220 192 209
32 163 32 32 32 32 32 32 32 32 32 32 32 32 32 32])
)))))
"CCL program to write KOI8.")
Мы исследовали существующие методы введения информации с использованием символов различных языков и разделили их на четыре типа.
Например, при введении японского текста сначала набираются символы хираганы (японский фонетический алфавит), затем эта последовательность символов преобразуется специальной конверсионной программой в соответствующую комбинацию иероглифов и символов хираганы. Существует несколько конверсионных программ таких, как Wnn, Canna, SJ3 (все они предназначены для японского языка) и cWnn (для китайского языка), которые могут работать в Mule. Обычно они используют очень большие словари и грамматические справочники по каждом языку, для создания соответствующих последовательностей символов.
В Mule методы введения первых трех типов используют вводную переводческую систему под названием Quail. Quail получает один набор правил перевода (называемый "Quail package") за один раз и переводит вводимое пользователем, основываясь на этих правилах. Каждое правило перевода состоит из последовательности клавиш и соответствующего переведенного текста. Каждое правило может иметь несколько вариантов переведенного текста; в этом случае пользователь должен выбрать один из них.
Подстроить Quail package под требования пользователя довольно легко. Достаточно добавить новые правила перевода или модифицировать существующие. Quail package строится по модульному принципу, что облегчает создание новых правил для новых языков. Это можно сделать простым созданием нового варианта Quail package с соответствующим именем и заданием любого количества правил перевода для этого варианта. В Таблице 6 показано как сделать новый вариант Quail package, симулирующий фиксацию верхнего регистра (в этом случае все буквы нижнего регистра будут автоматически превращаться в буквы верхнего регистра).
;; Сначала задайте новый вариант Quail package.
(quail-define-package "caps-lock"
"Caps-Lock" nil "Simulate Caps-Lock")
;; Затем задайте правила перевода.
(quail-defrule "a" "A")
...
Методы введения последнего типа реализованы в системе под названием Тамаго. Здесь нажатие клавиш переводится в фонетические коды (хирагана в японском языке и пинъин или чжуин в китайском языке), которые отправляются через сеть во внешнюю конверсионную программу. На первом этапе можно использовать систему Quail. Однако, Тамаго был разработан независимо от Quail и располагает собственной системой выработки фонетических кодов . Так как эти преобразования не могут выполняться полностью автоматически, пользователь должен работать с системой в интерактивном режиме. В настоящее время Тамаго может использовать Wnn и cWnn в качестве конверсионного сервера.
Обработка текста - это процесс более сложный, чем простой ввод символов. Для выполнения этой задачи Mule располагает многими возможностями. В качестве примеров можно привести категории символов и компилятор стандартных выражений, который позволяет вести быстрый поиск стандартных выражений.
При редактировании текста можно сгруппировать ряд символов и использовать группу в командах редактирования. Например, пользователь может пожелать отыскать какой-бы то ни было символ кириллицы, но не хочет указывать все символы и сочетать их с операторами OR. Для этой цели исходная версия GNU Emacs назначает синтаксический код для каждого символа. Синтаксический код, однако, имеет некоторые ограничения. Каждый символ может иметь максимум один синтаксический код и пользователи не могут задавать новый синтаксис.
В Mule существует еще одни способ группировки символов. Он называется категория символов. Пользователь может назначить новую категорию символа и задать любому символу столько категорий, сколько ему нужно. В Таблице 7 показаны категории символов, применяющиеся по умолчанию в Mule. Редактирование часто связано с пословной обработкой текста, но в разных языках могут быть различные понятия слова. В Mule пользователи дают определение слову, основываясь на этих категориях символов, тем самым создавая свои собственные команды редактирования.
| 'b' | Арабские символы |
| 'c' | Китайские 2-х байтовые символы |
| 'g' | Греческие символы |
| 'h' | Корейские 2-х байтовые символы |
| 'j' | Японские 2-х байтовые символы |
| 'k' | Японские 1-байтовые символы катаканы |
| 'r' | Японские 1- байтовые символы ромадзи |
| 'l' | Латинские символы |
| 'w' | Символы иврита |
| 'y' | Символы кириллицы |
| Символы тайваньского диалекта китайского языка |
При визуальном отображении многоязычного текста применяется два возможных варианта действия: Mule можно запускать с какого-либо терминала (или эмулятора терминала, такого как "xterm", "kterm", "cxterm" и д.р.), либо Mule может работать в окне.
В первом случае Mule просто посылает соответственно закодированный текст на терминалы, а задача вывода их на дисплей выполняется уже ими самими. Конверсия кода выполняется в соответствии с системой кодирования, принятой для данного терминала. Например, если пользователь работает с Mule через "cxterm", он может вывести на дисплей только английский либо китайский текст.
Работая в окне, Mule сам отвечает за изображение многоязычного текста. В Mule каждому набору символов назначается соответствующий шрифт. Комплект соответствия всех наборов символов шрифтам называется набором шрифтов (fontset) и служит основой для изображения каждого символа. Mule может использовать различные наборы шрифтов в зависимости от контекста. Например, когда Вы читаете почтовое сообщение, заголовок сообщения дается жирным шрифтом и в этом случае жирные шрифты используются только для заголовка сообщения.
В окне X внутренний код символов Mule обычно соответствует точкам кодирования шрифтов. Например, набор символов японского языка JISX0208 может быть правильно изображен на дисплее шрифтом, точки кодирования которого совпадают с JISX0208. Но, даже если для определенной комбинации набора символа и шрифта такого совпадения нет, мы можем преобразовать внутренние точки кодирования в соответствии со шрифтом с помощью программы CCL, описанной в предыдущем разделе. Если, например, набор символов кириллицы в Mule основывается на ISO-88595-5, а у пользователя имеется только шрифт KOI-8, мы все равно можем изменить назначения шрифта таким образом, что в наборе символов кириллицы можно будет использовать шрифт KOI-8 и привязать программу CCL к набору символов кириллицы (см. Таблицу 8).
Когда пользователь хочет обеспечить поддержку нового языка, он может просто задать соответствие между новым набором символов языка и шрифтом из существующего набора шрифтов.
;; Изменить назначение соответствия шрифта в DEFAULT-FONTSET набора шрифтов.
(set-fontset-font default-fontset lc-crl "HERE_COMES_KOI8_FONT_NAME")
(define-ccl-program ccl-x-koi8
'(0
((r1 -= 160)
(r1 = r1
[ 32 179 32 32 32 32 32 32 32 32 32 32 32 32 32 32
225 226 247 231 228 229 246 250 233 234 235 236 237 238 239 240
242 243 244 245 230 232 227 254 251 253 255 249 248 252 224 241
193 194 215 199 196 197 214 218 201 202 203 204 205 206 207 208
210 211 212 213 198 200 195 222 219 221 223 217 216 220 192 209
32 163 32 32 32 32 32 32 32 32 32 32 32 32 32 32])))
"CCL program to convert chars of lc-crl (ISO8859-5) to KOI8 font.")
;; Привязать программу CCL к кириллическому набору символов LC-CRL.
(x-set-ccl lc-crl ccl-x-koi8)
Мы описали многоязычный текстовый редактор Mule, обратив основное внимание на его гибкость и расширяемость. Mule имеет переводчик Emacs Lisp, который делает систему открытой. Простые программы Emacs Lisp могут внести все изменения, необходимые конкретному пользователю.
Mule был разработан в 1993 году. С тех пор во многих странах мира были внесены доработки, благодаря которым Mule поддерживает языки этих стран. Теперь он может работать с большинством европейских (включая русский и греческий) и восточно-азиатских (китайский, японский, корейский) языков, в дополнение к тайскому, вьетнамскому, арабскому, турецкому, ивриту и другим. Сейчас мы работаем над индийскими языками (письменность деванагали).
Помимо поддержки новых языков, Mule имеет целый ряд приложений, созданных пользователями, таких, как мини-программы для работы со словарями в режиме реального времени или кодер и декодер MIME. Все это доказывает, что Mule может быть настоящей рабочей средой для многоязычного окружения, а не только простым редактором.
Сейчас мы интегрируем Mule в исходную версию GNU Emacs в сотрудничестве с Free Software Foundation, организацией, распространяющей GNU Emacs. Новый вариант GNU Emacs будет иметь возможности работы с многоязычными текстами, используемые в Mule.
Mule распространяется бесплатно согласно условиям GNU GENERAL PUBLIC LICENSE. Версию Mule 2.3 можно получить по неформальному запросу в нижеследующих и многих других местах.