1 # ***************************************************************************
3 # * Copyright (C) 2004-2016, International Business Machines
4 # * Corporation; Unicode, Inc.; and others. All Rights Reserved.
6 # ***************************************************************************
11 # note: a global filter is more efficient, but MUST include all source chars
12 #:: [\u0000-\u007E 、。 \u3099-゜ ァ-ー 。-゚ [:Latin:][:Katakana:] [:nonspacing mark:]] ;
13 # MINIMAL FILTER GENERATED FOR: Latin-Katakana
14 ### WARNING -- must add width filter, both here and below!!! ###
15 :: [[ᄀ-ᄒᄚᄡ\u1160-ᅵᆪᆬ-ᆭᆰ-ᆵ←-↓│■○\u3000-。「-」\u3099-\u309Aァ-ロワヲ-ヴヷヺ-ー!-~¢-₩][',.A-Za-z~À-ÖØ-öø-ďĒ-ĥĨ-İĴ-ķĹ-ľŃ-ňŌ-őŔ-ťŨ-žƠ-ơƯ-ưǍ-ǜǞ-ǣǦ-ǭǰǴ-ǵǸ-țȞ-ȟȦ-ȳ\u0304Ӣ-ӣӮ-ӯḀ-ẙẠ-ỹᾱᾹῑῙῡῩK-Å]] ;
16 :: [:Latin:] fullwidth-halfwidth ();
18 :: Lower (); # whenever transliterating from cased to uncased script, include this
19 # :: NFD () ; # this would catch the odd cases where a lowercase is not in NFD, but none are important for Japanese
20 # Uses modified Hepburn. Small changes to make unambiguous.
21 # | Kunrei-shiki: Hepburn/MHepburn
22 # | ------------------------------
39 # | For foreign words:
60 # Most small forms are generated, but if necessary
61 # explicit small forms are given with ~a, ~ya, etc.
62 #------------------------------------------------------
65 $consonant = [bcdfghjklmnpqrstvwxyz] ;
67 # Variables used for doubled-consonants with tsu
70 $semivoice = [\u309A゜];
71 $k_start = [カキクケコかきくけこ] ;
72 $s_start = [サシスセソさしすせそ] ;
73 $j_start = [シし] $voice ;
74 $t_start = [タチツテトたちつてと] ;
75 $n_start = [ナニヌネノンなにぬねの] ;
76 $h_start = [ハヒヘホはひへほ] ;
78 $m_start = [マミムメモまみむめも] ;
80 $r_start = [ラリルレロらりるれろ] ;
81 $w_start = [ワヰヱヲわゐゑを] ;
82 $v_start = [ワヰヱヲ]\u3099 ;
83 $voweled_basekana = [ァ-オカキクケコサシスセソタチッツテトナ-ノハヒフヘホマ-ヲヵヶ] ;
84 # if ン is followed by $n_quoter, then it needs an
85 # apostrophe after its romaji form to disambiguate it.
86 # e.g., ン ア ! = ナ, so represent as "n'a", not "na".
87 $n_quoter = [ア イ ウ エ オ ナ ニ ヌ ネ ノ ヤ ユ ヨ ン] ;
90 #------------------------------------------------------
95 # ' ' } [a-z] → ; # delete spaces before latin
96 # ' ' ← [^' '゠-ヿ] {} ['゠-ヿ] ; #insert spaces before hiragana
98 # Copy previous letter § marks
100 # | $1 $1 ← ($kana [[:M:]$voice$semivoice]?) $iteration
101 # Specials for katakana -- not shared with hiragana
108 # ~~~ begin shared rules ~~~
117 b | '~' ← ヒ \u3099} $small_y ;
118 by } $vowel → ヒ\u3099 | '~y' ;
133 dji'~i' ← チ\u3099ィ ; # liu
138 dj } $vowel → チ\u3099 | '~y' ;
139 # TODO: QUESTION: use ĵĴżŻ instead of dj, dz
146 ch } $vowel → チ | '~y' ;
148 g | '~' ← キ\u3099} $small_y ;
149 gy } $vowel → キ\u3099 | '~y' ;
156 # j } $vowel → シ\u3099 | '~y' ;
158 ji'~i' ← シ\u3099ィ ; # liu
163 k | '~' ← キ} $small_y ;
164 ky } $vowel → キ | '~y' ;
170 m | '~' ← ミ} $small_y ;
171 my } $vowel → ミ | '~y' ;
178 n | '~' ← ニ } $small_y ;
179 ny } $vowel → ニ | '~y' ;
186 p | '~' ← ヒ\u309A } $small_y ;
187 py } $vowel → ヒ\u309A | '~y' ;
193 h | '~' ← ヒ } $small_y ;
194 hy } $vowel → ヒ | '~y' ;
200 # f | '~' ← フ } $small_y ;
201 # f } $vowel → フ | '~' ;
207 r | '~' ← リ } $small_y ;
208 ry } $vowel → リ | '~y' ;
230 sh } $vowel → シ | '~y' ;
237 # v } $vowel → ウ\u3099 | '~' ;
238 #'v~a' ← ウ\u3099ァ ; # liu
239 #'v~i' ← ウ\u3099ィ ; # liu
240 #'v~e' ← ウ\u3099ェ ; # liu
241 #'v~o' ← ウ\u3099ォ ; # liu
244 # w } $vowel → ウ | '~' ;
260 j } j ↔ ッ } $j_start ;
261 b } b ↔ ッ } [$h_start$f_start] $voice;
262 d } d ↔ ッ } $t_start $voice;
263 g } g ↔ ッ } $k_start $voice;
264 p } p ↔ ッ } [$h_start$f_start] $semivoice;
265 # v } v ↔ ッ } [ワヰウヱヲう] $voice ;
266 z } z ↔ ッ } $s_start $voice;
267 v } v ↔ ッ } $v_start;
269 k } k ↔ ッ } $k_start ;
270 m } m ↔ ッ } $m_start ;
271 n } n ↔ ッ } $n_start ;
272 h } h ↔ ッ } $h_start ;
273 f } f ↔ ッ } $f_start ;
274 r } r ↔ ッ } $r_start ;
275 t } t ↔ ッ } $t_start ;
276 s } s ↔ ッ } $s_start ;
277 w } w ↔ ッ } $w_start;
278 y } y ↔ ッ } $y_start;
288 # prolonged vowel mark. this indicates a doubling of
289 # the preceding vowel sound
310 # TODO: make more accurate
311 j $1 ← sh (y* $vowel) {ヽ$voice ;
312 dj $1 ← ch (y* $vowel) {ヽ$voice ;
313 dz $1 ← ts (y* $vowel) {ヽ$voice ;
314 g $1 ← k (y* $vowel) {ヽ$voice ;
315 z $1 ← s (y* $vowel) {ヽ$voice ;
316 d $1 ← t (y* $vowel) {ヽ$voice ;
317 h $1 ← b (y* $vowel) {ヽ$voice ;
318 v $1 ← w (y* $vowel) {ヽ$voice ;
319 sh $1 ← sh (y* $vowel) {ヽ$voice ;
320 j $1 ← j (y* $vowel) {ヽ$voice ;
321 ch $1 ← ch (y* $vowel) {ヽ$voice ;
322 dj $1 ← dj(y* $vowel) {ヽ$voice ;
323 ts $1 ← ts (y* $vowel) {ヽ$voice ;
324 dz $1 ← dz (y* $vowel) {ヽ$voice ;
325 $1 ← ($consonant y* $vowel) {ヽ$voice? ;
326 $1 ← (.) {ヽ $voice? ; # otherwise repeat last character
327 ← ヽ $voice? ; # delete if no characters found
328 # h- rule: lengthens vowel if not followed by a vowel.
329 # At the point this is applied, latin [cons]?vowel sequences
330 # have been converted to katakana in NFD form.
331 $voweled_basekana [\u3099 \u309A]? { h → ー ;
332 # one-way latin- → kana rules. these do not occur in
333 # well-formed romaji representing actual japanese text.
334 # their purpose is to make all romaji map to kana of
336 # the following are not really necessary, but produce
337 # slightly more natural results.
345 # isolated consonants listed here so as not to mask
346 # longer rules above.
356 n'' ← ン } $n_quoter ;
373 # simple substitutions using backup
378 # ~~~ END shared rules ~~~
379 #------------------------------------------------------
381 '~' → ; # delete stray tildes between letters
382 [:Katakana:] { '' } [:Latin:] → ; # delete stray quotes between letters
383 # [ʾ[:Nonspacing Mark:]-[\u3099-゜]] → ; # delete any non-spacing marks that we didn't use
385 :: ([[:Katakana:][\u309B\u309C\u30A0\u30FC\uFF70\uFF9E\uFF9F]] halfwidth-fullwidth);
386 # note: a global filter is more efficient, but MUST include all source chars!!
387 #:: ([\u0000-\u007E 、。 \u3099-゜ ァ-ー 。-゚ [:Latin:][:Katakana:] [:nonspacing mark:]]);
388 # MINIMAL FILTER GENERATED FOR: Latin-Katakana BACKWARD
389 :: ( [[\ -~¢-£¥-¦¬\u0304₩。-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ│-○][~、-。がぎぐげござじずぜぞだぢづでどば-ぱび-ぴぶ-ぷべ-ぺぼ-ぽゔ\u3099-゛ゞァ-ヺー-ヾ][\u309B\u309C\u30A0\u30FC\uFF70\uFF9E\uFF9F]] ) ;