#!/usr/bin/env python3 """Fill the Romaji column of 274-dev.md from its Kana column. Kana is the source of truth. Romaji is generated wāpuro-style — no macrons, since they are awkward to type: おう→ou, ゅう→yuu, っ doubles the following consonant, ー repeats the preceding vowel, ん→n' before a vowel or y. The trailing generic is split off and lowercased (Kawabata hashi, Houshin jinja, Takinoue kosenkyou); 丁目 take a hyphen (Shinmachi 3-choume). Compound proper stems stay as one token, because kana carries no word boundary — add them to MANUAL below if you want a break. python3 274-romaji.py # rewrite the Romaji column python3 274-romaji.py --check # report differences, change nothing Rows with no kana are left with an empty Romaji cell rather than a guess. """ import io, os, re, sys HERE = os.path.dirname(os.path.abspath(__file__)) DOC = os.path.join(HERE, '274-dev.md') # stems that must not have a trailing 川 split off — it is part of the name NOSPLIT = {'のぼりかわ', 'にいかわ', 'しんかわ', 'みかわ', 'たきさわがわ'} # hand-set forms that the mechanical rules cannot derive MANUAL = {} import re Y={'きゃ':'kya','きゅ':'kyu','きょ':'kyo','しゃ':'sha','しゅ':'shu','しょ':'sho', 'ちゃ':'cha','ちゅ':'chu','ちょ':'cho','にゃ':'nya','にゅ':'nyu','にょ':'nyo', 'ひゃ':'hya','ひゅ':'hyu','ひょ':'hyo','みゃ':'mya','みゅ':'myu','みょ':'myo', 'りゃ':'rya','りゅ':'ryu','りょ':'ryo','ぎゃ':'gya','ぎゅ':'gyu','ぎょ':'gyo', 'じゃ':'ja','じゅ':'ju','じょ':'jo','びゃ':'bya','びゅ':'byu','びょ':'byo', 'ぴゃ':'pya','ぴゅ':'pyu','ぴょ':'pyo','ぢゃ':'ja','ぢゅ':'ju','ぢょ':'jo', 'しぇ':'she','ちぇ':'che','じぇ':'je','てぃ':'ti','でぃ':'di','ふぁ':'fa', 'ふぃ':'fi','ふぇ':'fe','ふぉ':'fo','うぃ':'wi','うぇ':'we','うぉ':'wo','とぅ':'tu'} S={'あ':'a','い':'i','う':'u','え':'e','お':'o','か':'ka','き':'ki','く':'ku','け':'ke','こ':'ko', 'さ':'sa','し':'shi','す':'su','せ':'se','そ':'so','た':'ta','ち':'chi','つ':'tsu','て':'te','と':'to', 'な':'na','に':'ni','ぬ':'nu','ね':'ne','の':'no','は':'ha','ひ':'hi','ふ':'fu','へ':'he','ほ':'ho', 'ま':'ma','み':'mi','む':'mu','め':'me','も':'mo','や':'ya','ゆ':'yu','よ':'yo', 'ら':'ra','り':'ri','る':'ru','れ':'re','ろ':'ro','わ':'wa','を':'o','ん':'n', 'が':'ga','ぎ':'gi','ぐ':'gu','げ':'ge','ご':'go','ざ':'za','じ':'ji','ず':'zu','ぜ':'ze','ぞ':'zo', 'だ':'da','ぢ':'ji','づ':'zu','で':'de','ど':'do','ば':'ba','び':'bi','ぶ':'bu','べ':'be','ぼ':'bo', 'ぱ':'pa','ぴ':'pi','ぷ':'pu','ぺ':'pe','ぽ':'po', 'ぁ':'a','ぃ':'i','ぅ':'u','ぇ':'e','ぉ':'o','ゃ':'ya','ゅ':'yu','ょ':'yo'} VOW='aiueo' def kana2romaji(s): out=[];i=0 while ilen(g): return kana[:-len(g)], g return kana, '' import re as _re def romanise(kana): m=_re.match(r'^(.*?)(\d+)ちょうめ$',kana) if m: a=kana2romaji(m.group(1)); a=a[:1].upper()+a[1:] return '%s %s-choume'%(a,m.group(2)) stem,gen=split_generic(kana) a=kana2romaji(stem); b=kana2romaji(gen) if gen else '' a=a[:1].upper()+a[1:] return (a+' '+b).strip() if b else a def process(text): out, filled, changed = [], 0, 0 for line in text.split('\n'): if line.startswith('| ') and line.count('|') >= 13: c = [x.strip() for x in line.strip('|').split('|')] if re.match(r'^\d+\.\d+$', c[0]): kana = c[3] new = MANUAL.get(kana, romanise(kana)) if kana else '' if new != c[4]: if not c[4]: filled += 1 else: changed += 1 c[4] = new line = '| ' + ' | '.join(c) + ' |' out.append(line) return '\n'.join(out), filled, changed def main(): text = io.open(DOC, encoding='utf-8').read() new, filled, changed = process(text) if '--check' in sys.argv: print('%d blank cells would be filled, %d existing would change' % (filled, changed)) return io.open(DOC, 'w', encoding='utf-8').write(new) print('%d filled, %d normalised' % (filled, changed)) if __name__ == '__main__': main()