gimchi 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +134 -0
- data/config/default.yml +5 -10
- data/lib/gimchi/char.rb +104 -104
- data/lib/gimchi/korean.rb +291 -277
- data/lib/gimchi/patch_1.8.rb +18 -18
- data/lib/gimchi/pronouncer.rb +488 -488
- data/test/test_gimchi.rb +4 -0
- metadata +14 -14
- data/README.rdoc +0 -120
data/lib/gimchi/patch_1.8.rb
CHANGED
@@ -2,28 +2,28 @@ $KCODE = 'U'
|
|
2
2
|
|
3
3
|
module Gimchi
|
4
4
|
class Korean
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
# Checks if the given character is a korean character.
|
6
|
+
# @param [String] ch A string of size 1
|
7
|
+
def korean_char? ch
|
8
|
+
raise ArgumentError.new('Lengthy input') if str_length(ch) > 1
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
complete_korean_char?(ch) ||
|
11
|
+
(chosungs + jungsungs + jongsungs).include?(ch)
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
# Checks if the given character is a "complete" korean character.
|
15
|
+
# "Complete" Korean character must have chosung and jungsung, with optional jongsung.
|
16
|
+
# @param [String] ch A string of size 1
|
17
|
+
def complete_korean_char? ch
|
18
|
+
raise ArgumentError.new('Lengthy input') if str_length(ch) > 1
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
# Range of Korean chracters in Unicode 2.0: AC00(가) ~ D7A3(힣)
|
21
|
+
ch.unpack('U').all? { | c | c >= 0xAC00 && c <= 0xD7A3 }
|
22
|
+
end
|
23
23
|
|
24
24
|
private
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def str_length str
|
26
|
+
str.scan(/./mu).length
|
27
|
+
end
|
28
28
|
end#Korean
|
29
29
|
end#Gimchi
|
data/lib/gimchi/pronouncer.rb
CHANGED
@@ -2,493 +2,493 @@
|
|
2
2
|
|
3
3
|
module Gimchi
|
4
4
|
class Korean
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
5
|
+
# Private class.
|
6
|
+
# Partial implementation of Korean pronouncement pronunciation rules specified in
|
7
|
+
# http://http://www.korean.go.kr/
|
8
|
+
class Pronouncer
|
9
|
+
private
|
10
|
+
def initialize korean
|
11
|
+
@korean = korean
|
12
|
+
@pconfig = korean.config['pronouncer']
|
13
|
+
end
|
14
|
+
|
15
|
+
def pronounce! str, options = {}
|
16
|
+
@sequence = @pconfig['transformation']['sequence for ' +
|
17
|
+
(options[:pronounce_each_char] ? '1' : '2')] - options[:except]
|
18
|
+
|
19
|
+
# Dissecting
|
20
|
+
@chars = @korean.dissect str
|
21
|
+
@orig_chars = @chars.dup
|
22
|
+
|
23
|
+
# Padding
|
24
|
+
@chars.each { |c| pad c }
|
25
|
+
|
26
|
+
# Two-phase processing
|
27
|
+
# - For `slur'
|
28
|
+
applied = []
|
29
|
+
2.times do | phase |
|
30
|
+
@chars = @chars.reject { |c| c =~ /\s/ } if phase == 1 # slur-phase
|
31
|
+
|
32
|
+
# Deep-fried...no copied backup
|
33
|
+
@initial_chars = @chars.map { |c| c.dup }
|
34
|
+
|
35
|
+
# Transform one by one
|
36
|
+
applied += (0...@chars.length).inject([]) { | arr, i | arr + transform(i); }
|
37
|
+
|
38
|
+
# Post-processing (actually just for :pronounce_each_char option)
|
39
|
+
@chars.select { |c| c.is_a?(Korean::Char) && c.jongsung }.each do | c |
|
40
|
+
c.jongsung = @pconfig['jongsung sound'][c.jongsung]
|
41
|
+
end
|
42
|
+
|
43
|
+
break unless options[:slur]
|
44
|
+
end
|
45
|
+
|
46
|
+
return @orig_chars.join, applied
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def transform idx
|
51
|
+
@cursor = idx
|
52
|
+
kc = @chars[@cursor]
|
53
|
+
|
54
|
+
# Not korean
|
55
|
+
return [] unless kc.is_a? Korean::Char
|
56
|
+
|
57
|
+
# Setting up variables for fast lookup
|
58
|
+
@kc = kc
|
59
|
+
@next_kc = (nkc = @chars[@cursor + 1]).is_a?(Korean::Char) ? nkc : nil
|
60
|
+
@kc_org = @initial_chars[@cursor]
|
61
|
+
@next_kc_org = (nkco = @initial_chars[@cursor + 1]).is_a?(Korean::Char) ? nkco : nil
|
62
|
+
|
63
|
+
# Cannot properly pronounce
|
64
|
+
return [] if @kc.chosung.nil? && @kc.jungsung.nil? && @kc.jongsung.nil?
|
65
|
+
|
66
|
+
applied = []
|
67
|
+
not_todo = []
|
68
|
+
blocking_rule = @pconfig['transformation']['blocking rule']
|
69
|
+
@sequence.each do | rule |
|
70
|
+
next if not_todo.include?(rule)
|
71
|
+
|
72
|
+
if self.send(rule)
|
73
|
+
applied << rule
|
74
|
+
not_todo += blocking_rule[rule] if blocking_rule.has_key?(rule)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
applied
|
78
|
+
end
|
79
|
+
|
80
|
+
def pad c
|
81
|
+
return unless c.is_a? Korean::Char
|
82
|
+
|
83
|
+
c.chosung = 'ㅇ' if c.chosung.nil?
|
84
|
+
c.jungsung = 'ㅡ' if c.jungsung.nil?
|
85
|
+
end
|
86
|
+
|
87
|
+
# shortcut
|
88
|
+
def fortis_map
|
89
|
+
@korean.config['structure']['fortis map']
|
90
|
+
end
|
91
|
+
|
92
|
+
# shortcut
|
93
|
+
def double_consonant_map
|
94
|
+
@korean.config['structure']['double consonant map']
|
95
|
+
end
|
96
|
+
|
97
|
+
# 제5항: ‘ㅑ ㅒ ㅕ ㅖ ㅘ ㅙ ㅛ ㅝ ㅞ ㅠ ㅢ’는 이중 모음으로 발음한다.
|
98
|
+
# 다만 1. 용언의 활용형에 나타나는 ‘져, 쪄, 쳐’는 [저, 쩌, 처]로 발음한다.
|
99
|
+
# 다만 3. 자음을 첫소리로 가지고 있는 음절의 ‘ㅢ’는 [ㅣ]로 발음한다.
|
100
|
+
def rule_5_1
|
101
|
+
if %w[져 쪄 쳐].include? @kc.to_s
|
102
|
+
@kc.jungsung = 'ㅓ'
|
103
|
+
|
104
|
+
true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def rule_5_3
|
109
|
+
if @kc.jungsung == 'ㅢ' && @kc_org.chosung.consonant?
|
110
|
+
@kc.jungsung = 'ㅣ'
|
111
|
+
|
112
|
+
true
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# 제9항: 받침 ‘ㄲ, ㅋ’, ‘ㅅ, ㅆ, ㅈ, ㅊ, ㅌ’, ‘ㅍ’은 어말 또는 자음 앞에서
|
117
|
+
# 각각 대표음 [ㄱ, ㄷ, ㅂ]으로 발음한다.
|
118
|
+
def rule_9
|
119
|
+
map = {
|
120
|
+
%w[ㄲ ㅋ] => 'ㄱ',
|
121
|
+
%w[ㅅ ㅆ ㅈ ㅊ ㅌ] => 'ㄷ',
|
122
|
+
%w[ㅍ] => 'ㅂ'
|
123
|
+
}
|
124
|
+
if map.keys.flatten.include?(@kc.jongsung) && (@next_kc.nil? || @next_kc.chosung.consonant?)
|
125
|
+
@kc.jongsung = map[ map.keys.find { |e| e.include? @kc.jongsung } ]
|
126
|
+
|
127
|
+
true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# 제10항: 겹받침 ‘ㄳ’, ‘ㄵ’, ‘ㄼ, ㄽ, ㄾ’, ‘ㅄ’은 어말 또는 자음 앞에서
|
132
|
+
# 각각 [ㄱ, ㄴ, ㄹ, ㅂ]으로 발음한다.
|
133
|
+
def rule_10
|
134
|
+
map = {
|
135
|
+
%w[ㄳ] => 'ㄱ',
|
136
|
+
%w[ㄵ] => 'ㄴ',
|
137
|
+
%w[ㄼ ㄽ ㄾ] => 'ㄹ',
|
138
|
+
%w[ㅄ] => 'ㅂ'
|
139
|
+
}
|
140
|
+
if map.keys.flatten.include?(@kc.jongsung) && (@next_kc.nil? || @next_kc.chosung.consonant?)
|
141
|
+
# Exceptions
|
142
|
+
if @next_kc && (
|
143
|
+
(@kc.to_s == '밟' && @next_kc.chosung.consonant?) ||
|
144
|
+
(@kc.to_s == '넓' && @next_kc && %w[적 죽 둥].include?(@next_kc_org.to_s))) # PATCH
|
145
|
+
@kc.jongsung = 'ㅂ'
|
146
|
+
else
|
147
|
+
@kc.jongsung = map[ map.keys.find { |e| e.include? @kc.jongsung } ]
|
148
|
+
end
|
149
|
+
|
150
|
+
true
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# 제11항: 겹받침 ‘ㄺ, ㄻ, ㄿ’은 어말 또는 자음 앞에서 각각 [ㄱ, ㅁ, ㅂ]으로 발음한다.
|
155
|
+
def rule_11
|
156
|
+
map = {
|
157
|
+
'ㄺ' => 'ㄱ',
|
158
|
+
'ㄻ' => 'ㅁ',
|
159
|
+
'ㄿ' => 'ㅂ'
|
160
|
+
}
|
161
|
+
if map.keys.include?(@kc.jongsung) && (@next_kc.nil? || @next_kc.chosung.consonant?)
|
162
|
+
# 다만, 용언의 어간 말음 ‘ㄺ’은 ‘ㄱ’ 앞에서 [ㄹ]로 발음한다.
|
163
|
+
# - 용언 여부 판단은?: 중성으로 판단 (PATCH)
|
164
|
+
if @next_kc && @kc.jongsung == 'ㄺ' &&
|
165
|
+
@next_kc_org.chosung == 'ㄱ' &&
|
166
|
+
%w[맑 얽 섥 밝 늙 묽 넓].include?(@kc.to_s) # PATCH
|
167
|
+
@kc.jongsung = 'ㄹ'
|
168
|
+
else
|
169
|
+
@kc.jongsung = map[@kc.jongsung]
|
170
|
+
end
|
171
|
+
|
172
|
+
true
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# 제12항: 받침 ‘ㅎ’의 발음은 다음과 같다.
|
177
|
+
# 1. ‘ㅎ(ㄶ, ㅀ)’ 뒤에 ‘ㄱ, ㄷ, ㅈ’이 결합되는 경우에는, 뒤 음절 첫소리와
|
178
|
+
# 합쳐서 [ㅋ, ㅌ, ㅊ]으로 발음한다.
|
179
|
+
# [붙임 1]받침 ‘ㄱ(ㄺ), ㄷ, ㅂ(ㄼ), ㅈ(ㄵ)’이 뒤 음절 첫소리 ‘ㅎ’과
|
180
|
+
# 결합되는 경우에도, 역시 두 음을 합쳐서 [ㅋ, ㅌ, ㅍ, ㅊ]으로 발음한다.
|
181
|
+
# [붙임 2]규정에 따라 ‘ㄷ’으로 발음되는 ‘ㅅ, ㅈ, ㅊ, ㅌ’의 경우에도 이에 준한다.
|
182
|
+
#
|
183
|
+
# 2. ‘ㅎ(ㄶ, ㅀ)’ 뒤에 ‘ㅅ’이 결합되는 경우에는, ‘ㅅ’을 [ㅆ]으로 발음한다.
|
184
|
+
#
|
185
|
+
# 3. ‘ㅎ’ 뒤에 ‘ㄴ’이 결합되는 경우에는, [ㄴ]으로 발음한다.
|
186
|
+
# [붙임]‘ㄶ, ㅀ’ 뒤에 ‘ㄴ’이 결합되는 경우에는, ‘ㅎ’을 발음하지 않는다.
|
187
|
+
#
|
188
|
+
# 4. ‘ㅎ(ㄶ, ㅀ)’ 뒤에 모음으로 시작된 어미나 접미사가 결합되는 경우에는, ‘ㅎ’을 발음하지 않는다.
|
189
|
+
def rule_12
|
190
|
+
return if @next_kc.nil?
|
191
|
+
|
192
|
+
map_12_1 = {
|
193
|
+
'ㄱ' => 'ㅋ',
|
194
|
+
'ㄷ' => 'ㅌ',
|
195
|
+
'ㅈ' => 'ㅊ' }
|
196
|
+
if %w[ㅎ ㄶ ㅀ].include?(@kc.jongsung)
|
197
|
+
# 12-1
|
198
|
+
if map_12_1.keys.include?(@next_kc.chosung)
|
199
|
+
@next_kc.chosung = map_12_1[@next_kc.chosung]
|
200
|
+
@kc.jongsung = (dc = double_consonant_map[@kc.jongsung]) && dc.first
|
201
|
+
|
202
|
+
# 12-2
|
203
|
+
elsif @next_kc.chosung == 'ㅅ'
|
204
|
+
@kc.jongsung = (dc = double_consonant_map[@kc.jongsung]) && dc.first
|
205
|
+
@next_kc.chosung = 'ㅆ'
|
206
|
+
|
207
|
+
# 12-3
|
208
|
+
elsif @next_kc.chosung == 'ㄴ'
|
209
|
+
if dc = double_consonant_map[@kc.jongsung]
|
210
|
+
@kc.jongsung = dc.first
|
211
|
+
else
|
212
|
+
@kc.jongsung = 'ㄴ'
|
213
|
+
end
|
214
|
+
|
215
|
+
# 12-4
|
216
|
+
elsif @next_kc.chosung == 'ㅇ'
|
217
|
+
@kc.jongsung = (dc = double_consonant_map[@kc.jongsung]) && dc.first
|
218
|
+
end
|
219
|
+
|
220
|
+
true
|
221
|
+
end
|
222
|
+
|
223
|
+
# 12-1 붙임
|
224
|
+
if @next_kc.chosung == 'ㅎ'
|
225
|
+
map_jongsung = {
|
226
|
+
# 붙임 1
|
227
|
+
'ㄱ' => [nil, 'ㅋ'],
|
228
|
+
'ㄺ' => ['ㄹ', 'ㅋ'],
|
229
|
+
'ㄷ' => [nil, 'ㅌ'],
|
230
|
+
'ㅂ' => [nil, 'ㅍ'],
|
231
|
+
'ㄼ' => ['ㄹ', 'ㅍ'],
|
232
|
+
'ㅈ' => [nil, 'ㅊ'],
|
233
|
+
'ㄵ' => ['ㄴ', 'ㅊ'],
|
234
|
+
|
235
|
+
# 붙임 2
|
236
|
+
'ㅅ' => [nil, 'ㅌ'],
|
237
|
+
#'ㅈ' => [nil, 'ㅌ'], # FIXME: 붙임2의 모순
|
238
|
+
'ㅊ' => [nil, 'ㅌ'],
|
239
|
+
'ㅌ' => [nil, 'ㅌ'],
|
240
|
+
}
|
241
|
+
if trans1 = map_jongsung[@kc.jongsung]
|
242
|
+
@kc.jongsung = trans1.first
|
243
|
+
@next_kc.chosung = trans1.last
|
244
|
+
|
245
|
+
true
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# 제13항: 홑받침이나 쌍받침이 모음으로 시작된 조사나 어미, 접미사와
|
251
|
+
# 결합되는 경우에는, 제 음가대로 뒤 음절 첫소리로 옮겨 발음한다.
|
252
|
+
def rule_13
|
253
|
+
return if @kc.jongsung.nil? || @kc.jongsung == 'ㅇ' || @next_kc.nil? || @next_kc.chosung != 'ㅇ'
|
254
|
+
@next_kc.chosung = @kc.jongsung
|
255
|
+
@kc.jongsung = nil
|
256
|
+
|
257
|
+
true
|
258
|
+
end
|
259
|
+
|
260
|
+
# 제14항: 겹받침이 모음으로 시작된 조사나 어미, 접미사와 결합되는 경우에는,
|
261
|
+
# 뒤엣것만을 뒤 음절 첫소리로 옮겨 발음한다.(이 경우, ‘ㅅ’은 된소리로 발음함.)
|
262
|
+
#
|
263
|
+
def rule_14
|
264
|
+
return if @kc.jongsung.nil? || @kc.jongsung == 'ㅇ' || @next_kc.nil? || @next_kc.chosung != 'ㅇ'
|
265
|
+
if consonants = double_consonant_map[@kc.jongsung]
|
266
|
+
consonants[1] = 'ㅆ' if consonants[1] == 'ㅅ'
|
267
|
+
@kc.jongsung, @next_kc.chosung = consonants
|
268
|
+
|
269
|
+
true
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# 제15항: 받침 뒤에 모음 ‘ㅏ, ㅓ, ㅗ, ㅜ, ㅟ’들로 시작되는 __실질 형태소__가 연결되는
|
274
|
+
# 경우에는, 대표음으로 바꾸어서 뒤 음절 첫소리로 옮겨 발음한다.
|
275
|
+
def rule_15
|
276
|
+
return if @kc.jongsung.nil? || @kc.jongsung == 'ㅇ' || @next_kc.nil? || @next_kc.chosung != 'ㅇ'
|
277
|
+
|
278
|
+
if false && %w[ㅏ ㅓ ㅗ ㅜ ㅟ].include?(@next_kc.jungsung) &&
|
279
|
+
%[ㅆ ㄲ ㅈ ㅊ ㄵ ㄻ ㄾ ㄿ ㄺ].include?(@kc.jongsung) == false # PATCH
|
280
|
+
@next_kc.chosung = @pconfig['jongsung sound'][ @kc.jongsung ]
|
281
|
+
@kc.jongsung = nil
|
282
|
+
|
283
|
+
true
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
# 제16항: 한글 자모의 이름은 그 받침소리를 연음하되, ‘ㄷ, ㅈ, ㅊ, ㅋ, ㅌ,
|
288
|
+
# ㅍ, ㅎ’의 경우에는 특별히 다음과 같이 발음한다.
|
289
|
+
def rule_16
|
290
|
+
return if @next_kc.nil?
|
291
|
+
|
292
|
+
map = {'디귿' => '디긋',
|
293
|
+
'지읒' => '지읏',
|
294
|
+
'치읓' => '치읏',
|
295
|
+
'키읔' => '키윽',
|
296
|
+
'티읕' => '티읏',
|
297
|
+
'피읖' => '피읍',
|
298
|
+
'히읗' => '히읏'}
|
299
|
+
|
300
|
+
word = @kc.to_s + @next_kc.to_s
|
301
|
+
if map.keys.include? word
|
302
|
+
new_char = @korean.dissect(map[word].scan(/./mu)[1])[0]
|
303
|
+
@next_kc.chosung = new_char.chosung
|
304
|
+
@next_kc.jongsung = new_char.jongsung
|
305
|
+
|
306
|
+
true
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
# 제17항: 받침 ‘ㄷ, ㅌ(ㄾ)’이 조사나 접미사의 모음 ‘ㅣ’와 결합되는 경우에는,
|
311
|
+
# [ㅈ, ㅊ]으로 바꾸어서 뒤 음절 첫소리로 옮겨 발음한다.
|
312
|
+
#
|
313
|
+
# [붙임] ‘ㄷ’ 뒤에 접미사 ‘히’가 결합되어 ‘티’를 이루는 것은 [치]로 발음한다.
|
314
|
+
def rule_17
|
315
|
+
return if @next_kc.nil? || %w[ㄷ ㅌ ㄾ].include?(@kc.jongsung) == false
|
316
|
+
|
317
|
+
if @next_kc.to_s == '이'
|
318
|
+
@next_kc.chosung = @kc.jongsung == 'ㄷ' ? 'ㅈ' : 'ㅊ'
|
319
|
+
@kc.jongsung = (dc = double_consonant_map[@kc.jongsung]) && dc.first
|
320
|
+
|
321
|
+
true
|
322
|
+
elsif @next_kc.to_s == '히'
|
323
|
+
@next_kc.chosung = 'ㅊ'
|
324
|
+
@kc.jongsung = (dc = double_consonant_map[@kc.jongsung]) && dc.first
|
325
|
+
|
326
|
+
true
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
# 제18항: 받침 ‘ㄱ(ㄲ, ㅋ, ㄳ, ㄺ), ㄷ(ㅅ, ㅆ, ㅈ, ㅊ, ㅌ, ㅎ), ㅂ(ㅍ, ㄼ,
|
331
|
+
# ㄿ, ㅄ)’은 ‘ㄴ, ㅁ’ 앞에서 [ㅇ, ㄴ, ㅁ]으로 발음한다.
|
332
|
+
def rule_18
|
333
|
+
map = {
|
334
|
+
%w[ㄱ ㄲ ㅋ ㄳ ㄺ] => 'ㅇ',
|
335
|
+
%w[ㄷ ㅅ ㅆ ㅈ ㅊ ㅌ ㅎ] => 'ㄴ',
|
336
|
+
%w[ㅂ ㅍ ㄼ ㄿ ㅄ] => 'ㅁ'
|
337
|
+
}
|
338
|
+
if @next_kc && map.keys.flatten.include?(@kc.jongsung) && %w[ㄴ ㅁ].include?(@next_kc.chosung)
|
339
|
+
@kc.jongsung = map[ map.keys.find { |e| e.include? @kc.jongsung } ]
|
340
|
+
|
341
|
+
true
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
# 제19항: 받침 ‘ㅁ, ㅇ’ 뒤에 연결되는 ‘ㄹ’은 [ㄴ]으로 발음한다.
|
346
|
+
# [붙임]받침 ‘ㄱ, ㅂ’ 뒤에 연결되는 ‘ㄹ’도 [ㄴ]으로 발음한다.
|
347
|
+
def rule_19
|
348
|
+
if @next_kc && @next_kc.chosung == 'ㄹ' && %w[ㅁ ㅇ ㄱ ㅂ].include?(@kc.jongsung)
|
349
|
+
@next_kc.chosung = 'ㄴ'
|
350
|
+
|
351
|
+
case @kc.jongsung
|
352
|
+
when 'ㄱ' then @kc.jongsung = 'ㅇ'
|
353
|
+
when 'ㅂ' then @kc.jongsung = 'ㅁ'
|
354
|
+
end
|
355
|
+
|
356
|
+
true
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
# 제20항: ‘ㄴ’은 ‘ㄹ’의 앞이나 뒤에서 [ㄹ]로 발음한다.
|
361
|
+
def rule_20
|
362
|
+
return if @next_kc.nil?
|
363
|
+
|
364
|
+
to = if %w[견란 진란 산량 단력 권력 원령 견례
|
365
|
+
문로 단로 원론 원료 근류].include?(@kc_org.to_s + @next_kc_org.to_s)
|
366
|
+
'ㄴ'
|
367
|
+
else
|
368
|
+
'ㄹ'
|
369
|
+
end
|
370
|
+
|
371
|
+
if @kc.jongsung == 'ㄹ' && @next_kc.chosung == 'ㄴ'
|
372
|
+
@kc.jongsung = @next_kc.chosung = to
|
373
|
+
|
374
|
+
true
|
375
|
+
elsif @kc.jongsung == 'ㄴ' && @next_kc.chosung == 'ㄹ'
|
376
|
+
@kc.jongsung = @next_kc.chosung = to
|
377
|
+
|
378
|
+
true
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
# 제23항: 받침 ‘ㄱ(ㄲ, ㅋ, ㄳ, ㄺ), ㄷ(ㅅ, ㅆ, ㅈ, ㅊ, ㅌ), ㅂ(ㅍ, ㄼ, ㄿ,ㅄ)’
|
383
|
+
# 뒤에 연결되는 ‘ㄱ, ㄷ, ㅂ, ㅅ, ㅈ’은 된소리로 발음한다.
|
384
|
+
def rule_23
|
385
|
+
return if @next_kc.nil?
|
386
|
+
if fortis_map.keys.include?(@next_kc.chosung) &&
|
387
|
+
%w[ㄱ ㄲ ㅋ ㄳ ㄺ ㄷ ㅅ ㅆ ㅈ ㅊ ㅌ ㅂ ㅍ ㄼ ㄿ ㅄ].include?(@kc.jongsung)
|
388
|
+
@next_kc.chosung = fortis_map[@next_kc.chosung]
|
389
|
+
|
390
|
+
true
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
# 제24항: 어간 받침 ‘ㄴ(ㄵ), ㅁ(ㄻ)’ 뒤에 결합되는 어미의 첫소리 ‘ㄱ, ㄷ, ㅅ, ㅈ’은 된소리로 발음한다.
|
395
|
+
# 다만, 피동, 사동의 접미사 ‘-기-’는 된소리로 발음하지 않는다.
|
396
|
+
# 용언 어간에만 적용.
|
397
|
+
def rule_24
|
398
|
+
return if @next_kc.nil? ||
|
399
|
+
@next_kc.to_s == '기' # FIXME 피동/사동 여부 판단 불가. e.g. 줄넘기
|
400
|
+
|
401
|
+
# FIXME 용언 여부를 판단. 정확한 판단 불가.
|
402
|
+
return unless case @kc.jongsung
|
403
|
+
when 'ㄵ'
|
404
|
+
%w[앉 얹].include? @kc.to_s
|
405
|
+
when 'ㄻ'
|
406
|
+
%w[젊 닮].include? @kc.to_s
|
407
|
+
else
|
408
|
+
false # XXX 일반적인 경우 사전 없이 판단 불가
|
409
|
+
end
|
410
|
+
|
411
|
+
if %w[ㄱ ㄷ ㅅ ㅈ].include?(@next_kc.chosung) &&
|
412
|
+
%w[ㄴ ㄵ ㅁ ㄻ ㄼ ㄾ].include?(@kc.jongsung)
|
413
|
+
@next_kc.chosung = fortis_map[@next_kc.chosung]
|
414
|
+
|
415
|
+
true
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
# 제25항: 어간 받침 ‘ㄼ, ㄾ’ 뒤에 결합되는 어미의 첫소리 ‘ㄱ, ㄷ, ㅅ, ㅈ’은
|
420
|
+
# 된소리로 발음한다.
|
421
|
+
def rule_25
|
422
|
+
return if @next_kc.nil?
|
423
|
+
|
424
|
+
if %w[ㄱ ㄷ ㅅ ㅈ].include?(@next_kc.chosung) &&
|
425
|
+
%w[ㄼ ㄾ].include?(@kc.jongsung)
|
426
|
+
@next_kc.chosung = fortis_map[@next_kc.chosung]
|
427
|
+
|
428
|
+
true
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
# 제26항: 한자어에서, ‘ㄹ’ 받침 뒤에 연결되는 ‘ㄷ, ㅅ, ㅈ’은 된소리로 발음한다.
|
433
|
+
def rule_26
|
434
|
+
# TODO
|
435
|
+
end
|
436
|
+
|
437
|
+
# 제27항: __관형사형__ ‘-(으)ㄹ’ 뒤에 연결되는 ‘ㄱ, ㄷ, ㅂ, ㅅ, ㅈ’은 된소리로 발음한다.
|
438
|
+
# - ‘-(으)ㄹ’로 시작되는 어미의 경우에도 이에 준한다.
|
439
|
+
def rule_27
|
440
|
+
# FIXME: NOT PROPERLY IMPLEMENTED
|
441
|
+
return if @next_kc.nil?
|
442
|
+
|
443
|
+
# 비교적 확률이 높은 경우들에 대해서만 처리. "일" 은 제외.
|
444
|
+
if %w[할 갈 날 볼 을 앨 말 힐].include?(@kc.to_s) && # @kc.jongsung == 'ㄹ' &&
|
445
|
+
%w[ㄱ ㄷ ㅂ ㅅ ㅈ].include?(@next_kc.chosung)
|
446
|
+
@next_kc.chosung = fortis_map[@next_kc.chosung]
|
447
|
+
true
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
# 제26항: 한자어에서, ‘ㄹ’ 받침 뒤에 연결되는 ‘ㄷ, ㅅ, ㅈ’은 된소리로 발음한다.
|
452
|
+
# 제28항: 표기상으로는 사이시옷이 없더라도, 관형격 기능을 지니는 사이시옷이
|
453
|
+
# 있어야 할(휴지가 성립되는) 합성어의 경우에는, 뒤 단어의 첫소리 ‘ㄱ, ㄷ,
|
454
|
+
# ㅂ, ㅅ, ㅈ’을 된소리로 발음한다.
|
455
|
+
def rule_26_28
|
456
|
+
# TODO
|
457
|
+
end
|
458
|
+
|
459
|
+
# 제29항: 합성어 및 파생어에서, 앞 단어나 접두사의 끝이 자음이고 뒤 단어나
|
460
|
+
# 접미사의 첫음절이 ‘이, 야, 여, 요, 유’인 경우에는, ‘ㄴ’ 음을 첨가하여
|
461
|
+
# [니, 냐, 녀, 뇨, 뉴]로 발음한다.
|
462
|
+
def rule_29
|
463
|
+
# TODO
|
464
|
+
end
|
465
|
+
|
466
|
+
# 제30항: 사이시옷이 붙은 단어는 다음과 같이 발음한다.
|
467
|
+
# 1. ‘ㄱ, ㄷ, ㅂ, ㅅ, ㅈ’으로 시작하는 단어 앞에 사이시옷이 올 때는 이들
|
468
|
+
# 자음만을 된소리로 발음하는 것을 원칙으로 하되, 사이시옷을 [ㄷ]으로
|
469
|
+
# 발음하는 것도 허용한다.
|
470
|
+
# 2. 사이시옷 뒤에 ‘ㄴ, ㅁ’이 결합되는 경우에는 [ㄴ]으로 발음한다.
|
471
|
+
# 3. 사이시옷 뒤에 ‘이’ 음이 결합되는 경우에는 [ㄴㄴ]으로 발음한다.
|
472
|
+
def rule_30
|
473
|
+
return if @next_kc.nil? || @kc.jongsung != 'ㅅ'
|
474
|
+
|
475
|
+
if %w[ㄱ ㄷ ㅂ ㅅ ㅈ].include? @next_kc.chosung
|
476
|
+
@kc.jongsung = 'ㄷ' # or nil
|
477
|
+
@next_kc.chosung = fortis_map[@next_kc.chosung]
|
478
|
+
|
479
|
+
true
|
480
|
+
elsif %w[ㄴ ㅁ].include? @next_kc.chosung
|
481
|
+
@kc.jongsung = 'ㄴ'
|
482
|
+
|
483
|
+
true
|
484
|
+
elsif @next_kc.chosung == 'ㅇ' &&
|
485
|
+
%w[ㅣ ㅒ ㅖ ㅑ ㅕ ㅛ ㅠ].include?(@next_kc.jungsung) &&
|
486
|
+
@next_kc.jongsung # PATCH
|
487
|
+
@kc.jongsung = @next_kc.chosung = 'ㄴ'
|
488
|
+
|
489
|
+
true
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end#Pronouncer
|
493
493
|
end#Korean
|
494
494
|
end#Gimchi
|