JS/TS библиотека для транслитераций между 50 языками (2450 комбинаций)

Обычно под термином транслитерация подразумевают написание русскоязычного текста latinskimi bukvami. Однако это лишь одна сторона транслитерации - романизация (или латинизация), которая преобразовывает любую нелатинскую письменность в латиницу, например:
китайский / японский / корейский / хинди / арабский / греческий / русский > латиница / английский
Существует множество библиотек, которые романизируют различные языки. Ещё меньше библиотек, которые транслитерируют в обратную сторону (т.е. латиницу в нелатинскую письменность), например:
английский / испанский / португальский / немецкий / французский / итальянский > китайский / японский / корейский / хинди / арабский / греческий / русский
И почти нет библиотек, которые транслитерируют между самыми разнообразными письменностями и языками - например, армянский в греческий, хинди в арабский, чешский в корейский, и т.д.
Более того, существующие библиотеки часто не учитывают контекст и преобразовывают побуквенно. Результаты могут быть трудночитаемыми и нарушать всевозможные языковые правила. Например, популярная библиотека transliteration так транслитерирует Хоккайдо, написанное на японском кандзи:
北海道 > Bei Hai Dao
А так транслитерирует Багдад, написанное на арабском:
بغداد > bGdd
Такая транслитерация подойдёт, если необходимо приблизительное (порой совсем грубое) латинское представление любого нелатинского текста, например, для слагификации (преобразования текста в URL). В итоге такого латинского франкенштейна остаётся лишь использовать в URL-адресах, которые обычно никто кроме машин не читает.
Можно также использовать API от Google Translate, но есть нюансы:
в каких-то ситуациях он может переводить отдельные слова вместо того, чтобы их транслитерировать (например, Eva Green может стать Ева Зелёная);
в каких-то ситуациях он может просто неправильно транслитерировать (например, мальтийский город Marsaxlokk трансформирует на русский как Марсакслокк - правильно Марсашлокк);
результат каждый раз нужно ждать с внешнего API;
он платный.
Можно использовать ИИ для этой задачи, но и здесь есть нюансы:
может галлюцинировать, выдавая разные результаты для одного и того же текста;
результат каждый раз нужно ждать с внешнего API;
он платный.
Что, если нужна библиотека, за которую не нужно платить, которая живёт на нашем сервере, и которая каждый раз выдаёт предсказуемые результаты? Что, если нужна правильная, удобочитаемая транслитерация? Что, если нужна не только романизация, но и транслитерация между самыми разнообразными письменностями и языками?
Правильная транслитерация
Более конкретно речь пойдёт о практической транскрипции. Чистая транслитерация обычно описывает побуквенное преобразование письменностей, но не всегда описывает лингвистические правила, которые представляют звуки и буквы. Концептуальная иерархия выглядит следующим образом:
транслитерация с одной письменности на другую (побуквенно)
языковая транслитерация
фонетическая транскрипция: описание произношения (например, с помощью МФА)
практическая транскрипция: представление произношения исходного языка с использованием орфографических правил целевого языка.
Последний пункт - пункт нашего назначения. Иными словами, текст, написанный на исходном языке, должен быть конвертирован в целевой язык так, чтобы носитель языка мог его безошибочно прочитать:
исходный язык > целевой язык
На практике граница между транслитерацией и транскрипцией часто размыта, особенно когда применяется к именам собственным.
Хотя с лингвистической точки зрения термин транскрипция здесь более точен, обычно он применяется в контексте транскрибирования аудио или видео в текст. Поэтому, чтобы избежать путаницы относительно реального функционала библиотеки, отныне я буду использовать только термин транслитерация.
Экзонимы
Библиотека не поддерживает переводы, включая экзонимы - исторически устоявшиеся традиционные переводы иностранных имён собственных (например, названия городов).
Для примера возьмём греческую столицу Αθήνα. Она имеет устоявшийся русский перевод Афины, однако транслитерация с греческого на русский звучит как Атина:
Αθήνα > перевод на русский > Афины
Αθήνα > транслитерация на русский > Атина
Версия переведённая - это то, как название иностранного города известно среди русскоговорящих. Версия транслитерированная - это то, как название города произносят носители греческого языка, и как это произношение адаптировано на русский язык с учётом правил русского языка.
Если исключить исторические экзонимы, перевод имён собственных между разными языками обычно фактически представляет собой именно транслитерацию.
ICU
ICU (International Components for Unicode) - это широко используемая библиотека с открытым исходным кодом, которая обеспечивает полноценную поддержку стандарта Unicode, локализацию и интернационализацию в программных приложениях.
ICU включает в себя исключительно полезный инструмент для преобразования текста - Transforms. Он предназначен для обработки регистров, нормализации, транслитерации и двунаправленных преобразований текста. В нём также встроены наборы правил для побуквенной транслитерации из одной письменности в другую - но поскольку такая транслитерация мне не подходит, я ими не пользовался.
ICU написана на двух языках - на C/C++ и на Java. Поскольку я разрабатываю библиотеку на JavaScript, я написал на нём собственную реализацию необходимого мне функционала - Rule-Based Transliterator (RBT) - который отвечает за преобразования текста на основе правил. Эти правила и нужно нам сгенерировать для каждого языка.
ИИ
При создании большого количества правил транслитераций между различными языками логично воспользоваться помощью ИИ. Однако даже более умные и продвинутые модели грешат галлюцинациями и могут запутываться в тонкостях правил ICU (например, для определения контекста совпадения использовать } вместо { , и наоборот; или забыть использовать разделитель проходов ::Null).
Поэтому человеческая верификация всех генерируемых ИИ правил является обязательной - даже если я не владею языками, для которых они сгенерированы, ведь я могу проверить сами правила в соответствии с принципами ICU.
Для верификации сгенерированных правил в соответствии с лингвистическими принципами языков, для которых они сгенерированы, я использую список из 60 примеров (20 названий городов + 20 имён людей + 20 названий компаний - для каждого поддерживаемого языка).
Вот пошаговый процесс для генерации ICU правил:
ИИ генерирует правила.
Проверяем правила вручную, исправляем ошибки (если нужно).
Применяем правила к 60 примерам.
ИИ оценивает полученные результаты (0-100).
ИИ генерирует исправления для правил (если нужно).
Проверяем исправления вручную, исправляем ошибки (если нужно).
Применяем полученные исправления.
Повторяем шаги 3-7 до тех пор, пока оценка не достигнет 100. Если это занимает более 20-30 циклов, то любая оценка выше 95 считается приемлемой.
МФА
Генерирование правил транслитерации между двумя языками оправдано, когда эти языки исторически и/или лингвистически связаны (например, между кириллическими языками, азиатскими языками, семитскими языками, индоарийскими языками и т. д.). Однако создание прямых транслитераторов между всеми 50 языками было бы весьма трудоёмким процессом, поэтому нам необходим более универсальный подход.
Языки делятся на две основные категории: орфографические (основанные на написании) и фонетические (основанные на звучании).
Фонетические языки (часто это именно те, которые не имеют общего алфавитного предка с латынью или кириллицей) почти всегда заимствуют иностранные названия, основываясь на их звучании, полностью игнорируя их написание. К таким языкам относятся китайский, японский, корейский, хинди, бенгальский, урду, персидский, арабский и иврит. Для них я использую МФА (Международный фонетический алфавит) в качестве промежуточного звена для транслитерации. Таким образом, я сгенерировал ICU правила для преобразования всех поддерживаемых языков в МФА - для последующего преобразования МФА в фонетические языки. Транслитерация для фонетических языков выглядит следующим образом:
любой язык > МФА > китайский / японский / корейский / хинди / бенгальский / урду / персидский / арабский / иврит
Также я использую МФА при транслитерации с английского и французского. У них глубокая орфография (использование непроизносимых букв, исторические варианты написания, масштабные редукции гласных, нарушение стандартных европейских фонетических норм). Поэтому процесс транслитерации для этих языков выглядит следующим образом:
языки с глубокой орфографией > МФА > любой язык
Другие примеры использования МФА при транслитерациях:
урду / персидский / арабский / иврит / армянский / грузинский > МФА > любой язык
китайский / японский / корейский > МФА > армянский / грузинский
хинди / бенгальский > МФА > армянский / грузинский / кириллица / языки с неглубокой орфографией
Унифицированная латынь
Трансформация одних языков в МФА и последующая трансформация МФА в другие языки работает лишь для вышеперечисленных языковых комбинаций. Для остальных случаев вместо МФА будем использовать унифицированную латынь:
китайский / японский / корейский / греческий / кириллица / армянский / грузинский / языки с неглубокой орфографией > унифицированная латынь > любой язык, использующий латиницу
хинди / бенгальский > унифицированная латынь > языки с глубокой орфографией
греческий / армянский / грузинский / языки с неглубокой орфографией > унифицированная латынь > кириллица
любой язык > унифицированная латынь > греческий
греческий / кириллица / языки с неглубокой орфографией > унифицированная латынь > армянский / грузинский
Унифицированная латынь учитывает все уникальные фонетические варианты согласных, диграфов и гласных звуков, встречающиеся в исходных языках, таким образом нормализуя любой исходный язык в единый стандартный алфавит, например:
итальянское
ciстановитсяčпольское
cстановитсяtsтурецкое
cстановитсяdž
Впоследствии получившаяся унифицированная латынь преобразовывается в необходимые целевые языки, учитывая соответствующие языковые правила и нормы.
Романизация
Для романизации языков, которые не используют латиницу, существуют самые разнообразные подходы и системы, как официальные, так и неофициальные. Они могут использоваться для разных целей и задач, например, одна система может использоваться для транслитерации имён в паспортах; другая система может быть общепринятой при транслитерации географических названий.
Для каждого такого языка я использовал следующие системы романизации:
китайский: пиньинь
японский: система Хепбёрна
корейский: новая романизация корейского языка (RR)
хинди/деванагари, бенгальский, урду: система транслитерации Хантера
греческий: ELOT 743, 2-е изд.
армянский, грузинский: BGN/PCGN
украинский: утверждённая система 2010 г.
болгарский: закон о транслитерации 2009 г.
македонский: диграфовая система ICAO Doc 9303
Для романизации языков, использующих консонантную письменность (абджад), идеально подходит МФА:
арабский / персидский / иврит > МФА > английский
Кириллизация
Кириллица сильно фрагментирована: в разных языках для обозначения одних и тех же звуков используются совершенно разные буквы. Например, слово, кириллизированное для носителя русского языка, будет выглядеть ломаным, написанным с ошибками, или совершенно неправильно произноситься носителем болгарского или македонского языка.
Существуют различные языки, использующие кириллицу: некоторые из них широко распространены, некоторые используются крайне редко, а у некоторых есть официальные распространённые латинские эквиваленты:
Язык | Будем поддерживать? | Обоснование |
Русский | Да | Охватывает обширную восточнославянскую демографическую группу. Кроме России им пользуются, например, в Беларуси и Центральной Азии. |
Казахский | Да | В Казахстане по решению государства ведется переход от кириллицы к латинице. Однако сроки этого перехода постоянно переносятся, и продолжает использоваться кириллица. |
Украинский | Да | В украинском языке есть уникальные гласные (І, Ї, Є) и согласные (Ґ), которых нет в других кириллических языках. |
Белорусский | Нет | Хотя белорусский язык имеет свой собственный язык (и уникальную гласную Ў), население в подавляющем большинстве двуязычно, и русский язык является доминирующим в Беларуси. |
Болгарский | Да | Болгарский является южнославянским стандартом. Также необходимо учитывать правильное использование гласной буквы «Ъ». |
Македонский | Да | Включает в себя отдельные буквы сербского языка (Ј, Љ, Њ, Џ), но при этом содержит свои уникальные буквы (Ѓ и Ќ). |
Сербский | Да - но только латиница | Носители сербского языка свободно владеют как кириллицей, так и латиницей. Фактически, в онлайн среде гаевица часто является предпочтительным выбором, поэтому будем поддерживать только её. Также, при необходимости сербская латиница легко конвертируется в кириллицу и обратно с помощью этой библиотеки. |
При кириллизации я использую МФА или унифицированную латынь для большинства языковых комбинаций (см. выше). Однако китайский, японский и корейский языки требуют индивидуального подхода, поскольку для них существуют устоявшиеся системы кириллизации:
китайский:
на русский: система Палладия
на казахский: адаптированная версия системы Палладия
на украинский: академическая система (украинизированная система Палладия)
на болгарский: официальная болгарская система транскрипции китайского языка (создана кафедрой синологии Софийского университета в 1990-х годах)
на македонский: адаптированная версия сербской системы транскрипции
японский:
на русский: система Поливанова
на казахский: адаптированная версия системы Поливанова
на украинский: система Бондаренко
на болгарский: официальная болгарская система транскрипции (созданная кафедрой японоведения Софийского университета)
на македонский: адаптированная версия сербской системы транскрипции
корейский:
на русский: система Концевича
на казахский: адаптированная версия системы Концевича
на украинский: украинизированная система Концевича
на болгарский: официальная болгарская система транскрипции (созданная кафедрой корееведения Софийского университета)
на македонский: адаптированная версия сербской системы транскрипции
Жи-ши пиши с "и"
При транслитерации с одного языка на другой итоговый текст может содержать необычные сочетания букв, которые для носителя языка будут странными или даже неправильными. Почти в каждом языке существуют определенные запрещённые сочетания букв, и правила для их исправлений. Иногда такие правила могут применяться исключительно к транслитерированным иностранным именам собственным.
Для соответствия языковым нормам я сгенерировал такие правила исправления запрещённых буквенных сочетаний для всех языков, где они могут быть. Например, если по какой-то причине при транслитерации на русский язык мы получим жы или шы, благодаря этим правилам они будут исправлены на жи и ши.
На данный момент библиотека поддерживает 50 языков, что равно 2450 языковым комбинациям. Любой желающий может поэкспериментировать с библиотекой в своём браузере - она совместима с Chromium и WebKit, хоть изначально и разрабатывалась для Node.js.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.