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