Utilisateur:Ftiercel/ja-kana2API.py
ja-kana2API.py
#!/usr/bin/python # -*- coding: utf-8 -*- # Author : Fabrice TIERCELIN # Date : 2008-02-16 # Version : 1.2 # Licence : GPL import sys import re import time # kana2API returns the API pronunciation of the given word in kana (either hiragana or katakana) # # How it works : # The mecanism is based on the big characters (for instance : いらっしゃる -> いらしる) # because the pronunciations of those characters are all separated by dots. # Each iteration creates a syllable pronunciation. # Then, the pronunciation of each big character is divised into three parts (1) : # - the first consonant (if any) # - the second consonant (if any) # - the vowel # For the first consonant, there are several pronunciations, depending on different contexts (2) : # - there is a ん before # - there is a っ before # For the vowel, there are several pronunciations too (2) : # - there is a ゃ or similar after # - there is no small character around # Last, we check if there is any ん or small characters around and we choose the good pronunciation (3). def pop(kana): char = kana[0] remainingKana = kana while (kana != char + remainingKana) and (len(remainingKana) > 0): remainingKana = remainingKana[1:] if (len(remainingKana) > 0): remainingKana = kana[1:] return char, remainingKana def kana2API(kana): remainingKana = kana ## remainingKana = kana.replace(u' ', u'') pronunciation = u'' # There is no dot before the first syllable. dot = u'' while (len(remainingKana) > 0): isFinished = False hasSmallTsuBefore = False hasNBefore = False char, remainingKana = pop(remainingKana) # First, we check if there is any っ or ん before a big character. # We notice it and then we increment the remaining kana. smallChar = u'' if char in [u'っ' ,u'ッ']: hasSmallTsuBefore = True if (len(remainingKana) > 0): char, remainingKana = pop(remainingKana) else: isFinished = True elif char in [u'ん' ,u'ン']: hasNBefore = True if (len(remainingKana) > 0): char, remainingKana = pop(remainingKana) else: pronunciation = pronunciation + u'ɴ' isFinished = True if not isFinished: # 1. The big character # For the ん pronunciation if hasNBefore: if char in [u'あ' ,u'い' ,u'う' ,u'え' ,u'お' ,u'を' ,u'ア' ,u'イ' ,u'ウ' ,u'エ' ,u'オ' ,u'ヲ']: n = u'ɴ' elif char in [u'か' ,u'が' ,u'き' ,u'ぎ' ,u'く' ,u'ぐ' ,u'け' ,u'げ' ,u'こ' ,u'ご' ,u'カ' ,u'ガ' ,u'キ' ,u'ギ' ,u'ク' ,u'グ' ,u'ケ' ,u'ゲ' ,u'コ' ,u'ゴ']: n = u'ŋ̩' elif char in [u'ば' ,u'ぱ' ,u'び' ,u'ぴ' ,u'ふ' ,u'ぶ' ,u'ぷ' ,u'べ' ,u'ぺ' ,u'ぼ' ,u'ぽ' ,u'ま' ,u'み' ,u'む' ,u'め' ,u'も' ,u'バ' ,u'パ' ,u'ビ' ,u'ピ' ,u'フ' ,u'ブ' ,u'プ' ,u'ベ' ,u'ペ' ,u'ボ' ,u'ポ' ,u'マ' ,u'ミ' ,u'ム' ,u'メ' ,u'モ']: n = u'ɱ' else: n = u'n' # For the first consonant pronunciation if char in [u'あ' ,u'い' ,u'う' ,u'え' ,u'お' ,u'を' ,u'ア' ,u'イ' ,u'ウ' ,u'エ' ,u'オ' ,u'ヲ']: firstConsonant = u'' elif char in [u'か' ,u'き' ,u'く' ,u'け' ,u'こ' ,u'カ' ,u'キ' ,u'ク' ,u'ケ' ,u'コ']: firstConsonant = u'k' elif char in [u'が' ,u'ぎ' ,u'ぐ' ,u'げ' ,u'ご' ,u'ガ' ,u'ギ' ,u'グ' ,u'ゲ' ,u'ゴ']: firstConsonant = u'g' elif char in [u'さ' ,u'す' ,u'せ' ,u'そ' ,u'サ' ,u'ス' ,u'セ' ,u'ソ']: firstConsonant = u's' elif char in [u'し' ,u'シ']: firstConsonant = u'ʃ' elif char in [u'ざ' ,u'ぜ' ,u'ぞ' ,u'ザ' ,u'ゼ' ,u'ゾ']: firstConsonant = u'z' elif char in [u'じ' ,u'ず' ,u'づ' ,u'ジ' ,u'ズ' ,u'ヅ', u'だ' ,u'ぢ' ,u'で' ,u'ど' ,u'ダ' ,u'ヂ' ,u'デ' ,u'ド']: firstConsonant = u'd' elif char in [u'た' ,u'ち' ,u'つ' ,u'て' ,u'と' ,u'タ' ,u'チ' ,u'ツ' ,u'テ' ,u'ト']: firstConsonant = u't' elif char in [u'な' ,u'に' ,u'ぬ' ,u'ね' ,u'の' ,u'ナ' ,u'ニ' ,u'ヌ' ,u'ネ' ,u'ノ']: firstConsonant = u'n' elif char in [u'は' ,u'ひ' ,u'へ' ,u'ほ' ,u'ハ' ,u'ヒ' ,u'ヘ' ,u'ホ']: firstConsonant = u'h' elif char in [u'ふ' ,u'フ']: firstConsonant = u'ɸ' elif char in [u'ば' ,u'び' ,u'ぶ' ,u'べ' ,u'ぼ' ,u'バ' ,u'ビ' ,u'ブ' ,u'ベ' ,u'ボ']: firstConsonant = u'b' elif char in [u'ぱ' ,u'ぴ' ,u'ぷ' ,u'ぺ' ,u'ぽ' ,u'パ' ,u'ピ' ,u'プ' ,u'ペ' ,u'ポ']: firstConsonant = u'p' elif char in [u'ま' ,u'み' ,u'む' ,u'め' ,u'も' ,u'マ' ,u'ミ' ,u'ム' ,u'メ' ,u'モ']: firstConsonant = u'm' elif char in [u'や' ,u'ゆ' ,u'よ' ,u'ヤ' ,u'ユ' ,u'ヨ']: firstConsonant = u'j' elif char in [u'ら' ,u'り' ,u'る' ,u'れ' ,u'ろ' ,u'ラ' ,u'リ' ,u'ル' ,u'レ' ,u'ロ']: firstConsonant = u'r' elif char in [u'わ' ,u'ゐ' ,u'ゑ' ,u'ワ' ,u'ヰ' ,u'ヱ']: firstConsonant = u'w' else: firstConsonant = u'' # For the second consonant pronunciation if char in [u'ち' ,u'チ']: secondConsonant = u'ʃ' elif char in [u'つ' ,u'ツ']: secondConsonant = u's' elif char in [u'じ' ,u'ぢ' ,u'ず' ,u'づ' ,u'ジ' ,u'ヂ' ,u'ズ' ,u'ヅ']: secondConsonant = u'z' else: secondConsonant = u'' # For the vowel pronunciation if char in [u'あ' ,u'か' ,u'が' ,u'さ' ,u'ざ' ,u'た' ,u'だ' ,u'な' ,u'は' ,u'ば' ,u'ぱ' ,u'ま' ,u'や' ,u'ら' ,u'わ' ,u'ア' ,u'カ' ,u'ガ' ,u'サ' ,u'ザ' ,u'タ' ,u'ダ' ,u'ナ' ,u'ハ' ,u'バ' ,u'パ' ,u'マ' ,u'ヤ' ,u'ラ' ,u'ワ']: if hasNBefore and (char in [u'あ' ,u'ア']): vowelNormal = u'ã' else: vowelNormal = u'a' elif char in [u'い' ,u'き' ,u'ぎ' ,u'し' ,u'じ' ,u'ち' ,u'ぢ' ,u'に' ,u'ひ' ,u'び' ,u'ぴ' ,u'み' ,u'り' ,u'ゐ' ,u'イ' ,u'キ' ,u'ギ' ,u'シ' ,u'ジ' ,u'チ' ,u'ヂ' ,u'ニ' ,u'ヒ' ,u'ビ' ,u'ピ' ,u'ミ' ,u'リ' ,u'ヰ']: vowelNormal = u'i' elif char in [u'う' ,u'ゔ' ,u'く' ,u'ぐ' ,u'す' ,u'ず' ,u'つ' ,u'づ' ,u'ぬ' ,u'ふ' ,u'ぶ' ,u'ぷ' ,u'む' ,u'ゆ' ,u'る' ,u'ウ' ,u'ヴ' ,u'ク' ,u'グ' ,u'ス' ,u'ズ' ,u'ツ' ,u'ヅ' ,u'ヌ' ,u'フ' ,u'ブ' ,u'プ' ,u'ム' ,u'ユ' ,u'ル']: vowelNormal = u'ɯ' elif char in [u'え' ,u'け' ,u'げ' ,u'せ' ,u'ぜ' ,u'て' ,u'で' ,u'ね' ,u'へ' ,u'べ' ,u'ぺ' ,u'め' ,u'れ' ,u'ゑ' ,u'エ' ,u'ケ' ,u'ゲ' ,u'セ' ,u'ゼ' ,u'テ' ,u'デ' ,u'ネ' ,u'ヘ' ,u'ベ' ,u'ペ' ,u'メ' ,u'レ' ,u'ヱ' ,u'ヹ']: vowelNormal = u'e' elif char in [u'お' ,u'こ' ,u'ご' ,u'そ' ,u'ぞ' ,u'と' ,u'ど' ,u'の' ,u'ほ' ,u'ぼ' ,u'ぽ' ,u'も' ,u'よ' ,u'ろ' ,u'を' ,u'オ' ,u'コ' ,u'ゴ' ,u'ソ' ,u'ゾ' ,u'ト' ,u'ド' ,u'ノ' ,u'ホ' ,u'ボ' ,u'ポ' ,u'モ' ,u'ヨ' ,u'ロ' ,u'ヲ' ,u'ヺ']: if hasNBefore and (char in [u'お' ,u'オ']): vowelNormal = u'õ' else: vowelNormal = u'o' else: vowelNormal = u'' # For the vowel pronunciation before a small character if char in [u'い' ,u'き' ,u'ぎ' ,u'し' ,u'じ' ,u'ち' ,u'ぢ' ,u'に' ,u'ひ' ,u'び' ,u'ぴ' ,u'み' ,u'り' ,u'ゐ' ,u'イ' ,u'キ' ,u'ギ' ,u'シ' ,u'ジ' ,u'チ' ,u'ヂ' ,u'ニ' ,u'ヒ' ,u'ビ' ,u'ピ' ,u'ミ' ,u'リ' ,u'ヰ']: ## vowelBeforeSmallChar = u'j' vowelBeforeSmallChar = u'' else: vowelBeforeSmallChar = vowelNormal # 2. The following small character hasLongVowel = False hasSmallCharAfter = False hasLongSmallCharAfter = False secondVowel = u'' if (len(remainingKana) > 0): if remainingKana[0] in [u'ゃ' ,u'ゅ' ,u'ょ' ,u'ャ' ,u'ュ' ,u'ョ']: hasSmallCharAfter = True elif (char in [u'し' ,u'じ' ,u'ち' ,u'ぢ' ,u'シ' ,u'ジ' ,u'チ' ,u'ヂ']) and (remainingKana[0] in [u'ぁ' ,u'ぅ' ,u'ぇ' ,u'ぉ' ,u'ァ' ,u'ゥ' ,u'ェ' ,u'ォ']): hasSmallCharAfter = True elif remainingKana[0] in [u'ぁ' ,u'ぃ' ,u'ぅ' ,u'ぇ' ,u'ぉ' ,u'ァ' ,u'ィ' ,u'ゥ' ,u'ェ' ,u'ォ' ,u'ー']: hasLongVowel = True if hasSmallCharAfter: if remainingKana[0] in [u'ゃ' ,u'ぁ' ,u'ャ' ,u'ァ']: smallChar = u'a' elif remainingKana[0] in [u'ぃ' ,u'ィ']: smallChar = u'i' elif remainingKana[0] in [u'ゅ' ,u'ぅ' ,u'ュ' ,u'ゥ']: smallChar = u'ɯ' elif remainingKana[0] in [u'ぇ' ,u'ェ']: smallChar = u'e' elif remainingKana[0] in [u'ょ' ,u'ぉ' ,u'ョ' ,u'ォ']: smallChar = u'o' else: smallChar = u'' if hasLongVowel or hasSmallCharAfter: remainingKana = pop(remainingKana)[1] if hasSmallCharAfter and (len(remainingKana) > 0): if remainingKana[0] == u'ー': hasLongSmallCharAfter = True remainingKana = pop(remainingKana)[1] if len(remainingKana) > 0: if remainingKana[0] in [u'い' ,u'イ']: if not hasLongVowel and not hasSmallCharAfter and char in [u'え' ,u'け' ,u'げ' ,u'せ' ,u'ぜ' ,u'て' ,u'で' ,u'ね' ,u'へ' ,u'べ' ,u'ぺ' ,u'め' ,u'れ' ,u'ゑ' ,u'エ' ,u'ケ' ,u'ゲ' ,u'セ' ,u'ゼ' ,u'テ' ,u'デ' ,u'ネ' ,u'ヘ' ,u'ベ' ,u'ペ' ,u'メ' ,u'レ' ,u'ヱ' ,u'ヹ']: secondVowel = u'ː' else: secondVowel = u'j' remainingKana = pop(remainingKana)[1] # 3. Pronunciation writting # 3.1. consonants if hasNBefore: pronunciation = pronunciation + n + u'.' + firstConsonant + secondConsonant elif hasSmallTsuBefore: pronunciation = pronunciation + firstConsonant + u'.' + firstConsonant + secondConsonant else: pronunciation = pronunciation + dot + firstConsonant + secondConsonant # 3.2. vowels if hasLongSmallCharAfter: pronunciation = pronunciation + vowelBeforeSmallChar + smallChar + u'ː' + secondVowel elif hasSmallCharAfter: pronunciation = pronunciation + vowelBeforeSmallChar + smallChar + secondVowel elif hasLongVowel: pronunciation = pronunciation + vowelNormal + u'ː' + secondVowel else: pronunciation = pronunciation + vowelNormal + secondVowel # Now, we always need dot to separate syllables dot = u'.' return pronunciation if __name__ == "__main__": wordList = [] ftin =open('./japaneseWords.txt', 'r') line = ftin.readline() while (line): wordList.append(line) line = ftin.readline() ftin.close() now = time.localtime() filename = './pronunciations-' + str(now.tm_hour) + '-' + str(now.tm_min) + '-' + str(now.tm_sec) + '.txt' outputFile = open(filename, 'w') for rawWord in wordList: ## rawWord = wordList[21] word = rawWord.decode('utf-8') decodedWord = word.strip(u'\r\n ') pron = kana2API(decodedWord) encodedWord = decodedWord.encode('utf-8') encodedPron = pron.encode('utf-8') outputFile.write(encodedWord + '\t/' + encodedPron + '/') outputFile.write("\r\n") outputFile.close()