Пару днів тому на форумі uanime підростаюче покоління перекладачів представило програмку для транслітерації ромаджі (англомовна транслітерація японської) в українську, на що Мінус-один влучно зауважив, що додатки такого рівня наразі пишуть під Веб, а софт тут просто overkill. Крім того, він дещо покритикував обраний підхід до створення словничка відповідностей, який містив виключення, в той час як в ідеалі всі правила транслітерації мають бути однозначними. Ну і найголовніше його побажання було – додати можливість транслітерувати кану, японський алфавіт (катакану та хірагану). Мене це зацікавило…
Передісторія
Я подумав і вирішив, що задачка взагалі-то на кілька хвилин, але тому хотів піти складнішим шляхм і зробити її на LISP. У мене така жахлива хвороба – я не можу вчити нічого пов’язаного з IT поза контекстом хоч якогось прикладного застосування. Тому хоча мені хотілося б вивчити багато речей, але із-за того, що я не можу придумати собі прикладну задачу, в результаті не можу заставити підучити щось цікаве, але на перший погляд нетривіальне. Я трохи подумав як той Лісп розгортатити у вебі і зрештою вирішив не паритись, а підійти прагматичо (за останній рік мій “mindset” суттєво змінився і став орієнтований на кінцевий результат, а не на чергову “цікаву технологію”). Тому вирішив зробити віджет на Javascript, тим паче, що і тут у мене був маленький скелет у шафі – хотів попробувати написати плагін для jQuery, щоб коли наступного разу знову доведеться щось правити я в них вже розумівся трохи краще.
В результаті за пару годин придумав простенький алгоритм (перше, що прийшло в голову, тому приймаються будь-які суттєві пропозиції для вдосконалення), що працював на простому дереві для pattern matching (надалі просто “словник”) і побудував словник для ромаджі. На форумі uanime одразу ж почали постити баги 🙂 а я нашвидкоруч поправляти словник, додаючи пропущені патерни. В той же час Мінус-один захопився ідеєю зробити словники для хірагани та катакани. Причому оновлював він їх для кани так швидко (і публікував прямо в форумні пости), що я вирішив залити скрипт в якусь систему версійного контролю, де можна було б на льоту правити та оцінювати зміни і не зловживати форумом. До речі, в цьому плані github виявився дуже крутим зі своїм on-site редагуванням файлів та автопублікацією у веб через github pages; bitbucket там близько не валявся. Варто зазнчаити, що більшу частину роботи тут зробив Мінус-один, бо словники з певних технічних міркувань містять все-таки багато повторень і я просто в шоці як йому вдалось так швидко і з мінімумом помилок наповнити дерево для двох алфавітів.
Результат
Вийшла ось така формочка, яка транслітерує японську (увага! на сайтах, де цей допис кроспоститься скрипт не працюватиме, тому перевірити можна лише тут):
В сухому залишку: єдиний і неповторний транслітератор японського алфавіту в українську для неофіційної японсько-української транслітерації (прибічники Поліванова та інших можуть прийняти участь у створенні відповідних словників при бажанні).
Для мене ж профіт: вперше попрацював з git’ом та github’ом (з останнім я раніше лише пару раз скачував початкові коди якихось модулів та плагіни для redmine) та зробив свій перший екстеншн для jQuery.
Куточок лінгвістичного маньяка
Ще раз повторюся, що транслітерація ведеться виключно на словнику, який відповідає цій статті Мінус-одного на уаніме. Правила транслітерації зроблені там на основі здоровго глузду і не мають офіційного аналогу. Ці правила (майже) не використовуються в офіційних перекладах (єдиний, мабуть, вийняток – це “Міцубіші” 🙂 ), але їх часто беруть за основу перекладачі-любителі, оскільки на слух вони більш точно відповідають японській вимові, аніж будь-яка з офіційних систем.
Технічний куточок для підростаючого покоління
Алгоритм жадібний (матчить найдовший можливий патерн) і рекурсивний (найбільша глибина рекурсії дорівнює довжині вхідного рядка + 1; не дуже гарно, але для того застосування де планується – вистачить). Вхідний словник – дерево шаблонів побудованих наступним чином:
В js це кодується через вкладний Object:
var k2ua = {
...
"し": {
"~": "ші",
"ゃ": "шя",
"ゅ": "шю",
"ょ": {
"~": "шьо",
"う": "шьоо",
},
},
...
};
Головний мінус цього підходу – те, що деякі правила (наприклад є символ, який подовжує попередню голосну) треба заносити шляхом дублювання солідних шматків дерева, що не дуже добре, але з іншого боку дозволяє тримати сам алгоритм дуже простим. Плюс знову ж таки прагматичний підхід – транслітерація практично не змінюється з часом, тому одного разу добре виправивши всі помилки можна далі не перейматись.
І все-таки про LISP
Вже потім я знайшов, що в інеті повно інтерпретаторів LISP написаних на javascript, але:
- не відомо чи вистачило б їх можливостей
- з практично-користувацької точки зору це був би ще більший оверхед на підключення інтерпретатора
Але оригінальна ідея не відкинута, а відкладена… на невідомий термін.