graywolf's lair

Inhuman being's diary…

jp2ua transliteration jQuery widget

| 7 Comments

Пару днів тому на форумі 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, але:

  • не відомо чи вистачило б їх можливостей
  • з практично-користувацької точки зору це був би ще більший оверхед на підключення інтерпретатора

Але оригінальна ідея не відкинута, а відкладена… на невідомий термін.

7 Comments

  1. Я от не до кінця зрозумів функцію traverse.
    Що означає параметр ws?
    І чому й для яких символів іноді по два варіанти?
    Символ що подовжує попередню голосну в катакані це "う"?
    Що таке "~"?

    Але найбільше мене цікавить – як ви склали словники, і як зробити щось подібне для англійської?

    • ws – індикатор початку слова (костиль), бо деякі сполучення по різному транслітеруються. Наприклад:
      "yo" в середині слова – це "ьо" (Ponyo – Поньо)
      "yo" на початку слова – це "йо" (Youkai – Йоокай)

      "う" це взагалі-то "у", але там завжди є нюанси… Це Мінус-одного треба питати.

      "~" – службовий символ. Означає, що коли наступного символу в слові немає на цьому рівні дерева, то використовувати те, що справа від нього (по суті це значення за замовчуванням для поточного рівня розбору патерну; якщо він далі матчиться, то розбір іде на наступний рівень, а якщо ні, то береться те, що напроти "~"). Тобто для того прикладу що зверху:
      しょう = шьоо (дерево пройшло всю глибину)
      ししょ = шішьо (розбір припинився на другому символі, оскільки нема гілки дерева, що відповідала б "しし", і розбір почався спочатку для хвосту "しょ")

      Для ромаджі я здебільшого просто на common sense робив і потім лише виправляв помилки, які знайшли на форумі uanime.

      Як для обох алфавітів кани Мінус-один робив – це треба його питати.

  2. результат beautiful! 🙂 інлайн гарненько виглядає теж! заберу в тебе собі потім… (зараз в мене напружена п'ятниця, фак…)

    @bunyk
    う – так, подовжує попередню О, робить її ОО. є це っ, цу маленька, вона подвоює наступну приголосну

    тут нема словників, тільки дерева символів:

    "символ":"символ-заміна"
    "s":"с"

    якщо треба "символ + 2-й символ", виникають дужки:

    "символ":{
    "~":"символ-заміна" <– те саме, що вище без дужок
    "+2-й символ":"два символи-заміни"
    "+інший 2-й символ":"два символи-заміни"

    }

    "s":{
    "~":"с"
    "a":"са"
    "i":"сі"

    }

    для трьох символів виникають ще одні вкладені дужки і т.д.

    все тут видно: http://ashenwolf.github.com/jp2ua-transliterate/w

    • Як будеш інтегрувати собі – маякуй, там у ворпрес вставити виявилось не так тривіально – добрих півгодини як не годину провозився 🙂 Але вцілому рекомендації:
      По-перше, css -файл треба буде поправити. я додавав округлення по верхньому краю для інлайн-віджета та із-заособливостей базової теми довелось прибирати бордери для таблиць.
      По-друге, в WP короткий аліас $ для jQuery не працює з якихось міркувань і треба замість $ завжди писати jQuery (можна подивитись в джерелі цієї сторінки як воно виглядає).

  3. Pingback: Віджет українсько-японської транслітерації « minus-one | мінус-один

Залишити відповідь

Required fields are marked *.