gimchi 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Junegunn Choi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,116 @@
1
+ # encoding: UTF-8
2
+
3
+ = gimchi
4
+
5
+ == 개요
6
+
7
+ Gimchi는 한글 스트링을 다롭니다.
8
+ 국립 국어원 어문 규정에 정의된 한글의 표준 발음법과
9
+ 로마자 표기법을 (일부) 구현한 것이 주요 기능입니다.
10
+
11
+ 또한 다음의 기능들을 제공합니다.
12
+ - 주어진 캐릭터가 한글인지 판단
13
+ - 한글을 초성, 중성, 종성으로 분리하고, 이를 다시 합치는 기능
14
+ - 숫자 표기를 한글 표현으로 변환
15
+
16
+ == 사용법
17
+
18
+ === Gimchi::Korean 인스턴스의 생성
19
+ ko = Gimchi::Korean.new
20
+
21
+ === 한글 캐릭터 여부 판단
22
+ ko.korean_char? 'ㄱ' # true
23
+ ko.complete_korean_char? 'ㄱ' # false
24
+
25
+ ko.korean_char? 'ㅏ' # true
26
+ ko.complete_korean_char? 'ㅏ' # false
27
+
28
+ ko.korean_char? '가' # true
29
+ ko.complete_korean_char? '가' # true
30
+
31
+ === Gimchi::Korean::Char
32
+ arr = ko.dissect '이것은 한글입니다.'
33
+ # [이, 것, 은, " ", 한, 글, 입, 니, 다, "."]
34
+
35
+ arr[4].class # Gimchi::Korean::Char
36
+
37
+ arr[4].chosung # "ㅎ"
38
+ arr[4].jungsung # "ㅏ"
39
+ arr[4].jongsung # "ㄴ"
40
+ arr[4].to_a # ["ㅎ", "ㅏ", "ㄴ"]
41
+ arr[4].to_s # "한"
42
+
43
+ arr[4].chosung = 'ㄷ'
44
+ arr[4].jongsung = 'ㄹ'
45
+ arr[4].to_s # "달"
46
+ arr[4].complete? # true
47
+ arr[4].partial? # false
48
+
49
+ arr[4].chosung = nil
50
+ arr[4].jongsung = nil
51
+ arr[4].complete? # false
52
+ arr[4].partial? # true
53
+
54
+ === 숫자 읽기
55
+ ko.read_number(1999) # "천 구백 구십 구"
56
+ ko.read_number(- 100.123) # "마이너스 백점일이삼"
57
+ ko.read_number("153,101,202,333.321")
58
+ ko.read_number("153,191,100,678.3214")
59
+ # "천 오백 삼십 일억 구천 백 십만 육백 칠십 팔점삼이일사"
60
+
61
+ # 나이, 시간 ( -살, -시 )
62
+ ko.read_number("20살") # "스무살"
63
+ ko.read_number("13 살") # "열세 살"
64
+ ko.read_number("7시 30분") # "일곱시 삼십분"
65
+
66
+ === 표준 발음 (부분 구현)
67
+ str = "됐어 됐어 이제 그런 가르침은 됐어 매일 아침 7 시 30 분까지 우릴 조그만 교실로 몰아넣고"
68
+ ko.pronounce str
69
+ # "돼써 돼써 이제 그런 가르치믄 돼써 매일 아침 일곱 시 삼십 분까지 우릴 조그만 교실로 모라너코"
70
+
71
+ ko.pronounce str, :slur => true
72
+ # "돼써 돼써 이제 그런 가르치믄 돼써 매이 라치 밀곱 씨 삼십 뿐까지 우릴 조그만 교실로 모라너코"
73
+
74
+ ko.pronounce str, :pronounce_each_char => true
75
+ # "됃어 됃어 이제 그런 가르침은 됃어 매일 아침 일곱 시 삼십 분까지 우릴 조그만 교실로 몰아너고"
76
+
77
+ ko.pronounce str, :number => false
78
+ # "돼써 돼써 이제 그런 가르치믄 돼써 매일 아침 7 시 30 분까지 우릴 조그만 교실로 모라너코"
79
+
80
+ === 로마자 표기 (부분 구현)
81
+ str = "됐어 됐어 이제 그런 가르침은 됐어 매일 아침 7 시 30 분까지 우릴 조그만 교실로 몰아넣고"
82
+
83
+ ko.romanize str
84
+ # "Dwaesseo dwaesseo ije geureon gareuchimeun dwaesseo mae-il achim ilgop si samsip bunkkaji uril jogeuman gyosillo moraneoko"
85
+ ko.romanize str, :slur => true
86
+ # "Dwaesseo dwaesseo ije geureon gareuchimeun dwaesseo mae-i rachi milgop ssi samsip ppunkkaji uril jogeuman gyosillo moraneoko"
87
+ ko.romanize str, :as_pronounced => false
88
+ # "Dwaet-eo dwaet-eo ije geureon gareuchim-eun dwaet-eo mae-il achim ilgop si samsip bunkkaji uril jogeuman gyosillo mol-aneogo"
89
+ ko.romanize str, :number => false
90
+ # "Dwaesseo dwaesseo ije geureon gareuchimeun dwaesseo mae-il achim 7 si 30 bunkkaji uril jogeuman gyosillo moraneoko"
91
+
92
+ == 구현의 한계
93
+
94
+ 표준 발음법과 로마어 표기법을 모두 구현하기 위해서는 형태소 분석과 충분한
95
+ 사전, 그리고 문맥의 의미 분석이 필요합니다. 이 모든 것이 준비된다고 할 지라도
96
+ 완벽한 결과를 얻는 것은 불가능합니다.
97
+ 이는 현재 gimchi가 목표로 하는 것이 아니며 gimchi는 간단한 구현으로 어느 수준
98
+ 이상의 결과를 얻는 것을 목표로 합니다. 현재 구현의 한계 내에서 정확도를 올리기
99
+ 위해 Ad-hoc한 patch 등이 코드에 상당량 포함된 상태인데 이를 정제하고 체계화하는
100
+ 노력이 필요합니다.
101
+
102
+ == Contributing to gimchi
103
+
104
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
105
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
106
+ * Fork the project
107
+ * Start a feature/bugfix branch
108
+ * Commit and push until you are happy with your contribution
109
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
110
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
111
+
112
+ == Copyright
113
+
114
+ Copyright (c) 2011 Junegunn Choi. See LICENSE.txt for
115
+ further details.
116
+
@@ -0,0 +1,118 @@
1
+ # encoding: UTF-8
2
+
3
+ = gimchi
4
+
5
+ Gimchi is a simple Ruby gem which knows how to handle Korean strings. It knows
6
+ how to dissect Korean characters into its 3 components, namely chosung,
7
+ jungsung and optional jongsung. It knows how Korean sentences are pronounced
8
+ and how they're written in roman alphabet.
9
+
10
+ Gimchi (only partially) implements the following rules dictated by
11
+ The National Institute of The Korean Language (http://www.korean.go.kr)
12
+ * Korean Standard Pronunciation
13
+ * Korean romanization
14
+
15
+ == Usage
16
+
17
+ === Creating Gimchi::Korean instance
18
+ ko = Gimchi::Korean.new
19
+
20
+ === Checks if the given character is in Korean alphabet
21
+ ko.korean_char? 'ㄱ' # true
22
+ ko.complete_korean_char? 'ㄱ' # false
23
+
24
+ ko.korean_char? 'ㅏ' # true
25
+ ko.complete_korean_char? 'ㅏ' # false
26
+
27
+ ko.korean_char? '가' # true
28
+ ko.complete_korean_char? '가' # true
29
+
30
+ === Usage of Gimchi::Korean::Char
31
+ arr = ko.dissect '이것은 한글입니다.'
32
+ # [이, 것, 은, " ", 한, 글, 입, 니, 다, "."]
33
+
34
+ arr[4].class # Gimchi::Korean::Char
35
+
36
+ arr[4].chosung # "ㅎ"
37
+ arr[4].jungsung # "ㅏ"
38
+ arr[4].jongsung # "ㄴ"
39
+ arr[4].to_a # ["ㅎ", "ㅏ", "ㄴ"]
40
+ arr[4].to_s # "한"
41
+
42
+ arr[4].chosung = 'ㄷ'
43
+ arr[4].jongsung = 'ㄹ'
44
+ arr[4].to_s # "달"
45
+ arr[4].complete? # true
46
+ arr[4].partial? # false
47
+
48
+ arr[4].chosung = nil
49
+ arr[4].jongsung = nil
50
+ arr[4].complete? # false
51
+ arr[4].partial? # true
52
+
53
+ === Reading numbers in Korean
54
+ ko.read_number(1999) # "천 구백 구십 구"
55
+ ko.read_number(- 100.123) # "마이너스 백점일이삼"
56
+ ko.read_number("153,101,202,333.321")
57
+ ko.read_number("153,191,100,678.3214")
58
+ # "천 오백 삼십 일억 구천 백 십만 육백 칠십 팔점삼이일사"
59
+
60
+ # Age, Time ( -살, -시 )
61
+ ko.read_number("20살") # "스무살"
62
+ ko.read_number("13 살") # "열세 살"
63
+ ko.read_number("7시 30분") # "일곱시 삼십분"
64
+
65
+ === Standard pronunciation (partially implemented)
66
+ str = "됐어 됐어 이제 그런 가르침은 됐어 매일 아침 7 시 30 분까지 우릴 조그만 교실로 몰아넣고"
67
+ ko.pronounce str
68
+ # "돼써 돼써 이제 그런 가르치믄 돼써 매일 아침 일곱 시 삼십 분까지 우릴 조그만 교실로 모라너코"
69
+
70
+ ko.pronounce str, :slur => true
71
+ # "돼써 돼써 이제 그런 가르치믄 돼써 매이 라치 밀곱 씨 삼십 뿐까지 우릴 조그만 교실로 모라너코"
72
+
73
+ ko.pronounce str, :pronounce_each_char => true
74
+ # "됃어 됃어 이제 그런 가르침은 됃어 매일 아침 일곱 시 삼십 분까지 우릴 조그만 교실로 몰아너고"
75
+
76
+ ko.pronounce str, :number => false
77
+ # "돼써 돼써 이제 그런 가르치믄 돼써 매일 아침 7 시 30 분까지 우릴 조그만 교실로 모라너코"
78
+
79
+ === Romanization (partially implemented)
80
+ str = "됐어 됐어 이제 그런 가르침은 됐어 매일 아침 7 시 30 분까지 우릴 조그만 교실로 몰아넣고"
81
+
82
+ ko.romanize str
83
+ # "Dwaesseo dwaesseo ije geureon gareuchimeun dwaesseo mae-il achim ilgop si samsip bunkkaji uril jogeuman gyosillo moraneoko"
84
+ ko.romanize str, :slur => true
85
+ # "Dwaesseo dwaesseo ije geureon gareuchimeun dwaesseo mae-i rachi milgop ssi samsip ppunkkaji uril jogeuman gyosillo moraneoko"
86
+ ko.romanize str, :as_pronounced => false
87
+ # "Dwaet-eo dwaet-eo ije geureon gareuchim-eun dwaet-eo mae-il achim ilgop si samsip bunkkaji uril jogeuman gyosillo mol-aneogo"
88
+ ko.romanize str, :number => false
89
+ # "Dwaesseo dwaesseo ije geureon gareuchimeun dwaesseo mae-il achim 7 si 30 bunkkaji uril jogeuman gyosillo moraneoko"
90
+
91
+ == Limitation of the implementation
92
+
93
+ Unfortunately in order to implement the complete specification of Korean
94
+ pronunciation and romanization, we need NLP, hugh Korean dictionaries and even
95
+ semantic analysis of the given string. And even with all those complex
96
+ processing, we cannot guarantee 100% accuracy of the output. So yes, that is
97
+ definitely not what this gem tries to achieve. Gimchi tries to achieve "some"
98
+ level of accuracy with relatively simple code.
99
+
100
+ Currently, Gimchi code containts a lot of ad-hoc (possibly invalid) patches
101
+ that try to improve the quality of the output, which should better be
102
+ refactored anytime soon.
103
+
104
+ == Contributing to gimchi
105
+
106
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
107
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
108
+ * Fork the project
109
+ * Start a feature/bugfix branch
110
+ * Commit and push until you are happy with your contribution
111
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
112
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
113
+
114
+ == Copyright
115
+
116
+ Copyright (c) 2011 Junegunn Choi. See LICENSE.txt for
117
+ further details.
118
+
@@ -0,0 +1,156 @@
1
+ ---
2
+ structure:
3
+ chosung: [ㄱ, ㄲ, ㄴ, ㄷ, ㄸ, ㄹ, ㅁ, ㅂ, ㅃ, ㅅ, ㅆ, ㅇ, ㅈ, ㅉ, ㅊ, ㅋ, ㅌ, ㅍ, ㅎ]
4
+ jungsung: [ㅏ, ㅐ, ㅑ, ㅒ, ㅓ, ㅔ, ㅕ, ㅖ, ㅗ, ㅘ, ㅙ, ㅚ, ㅛ, ㅜ, ㅝ, ㅞ, ㅟ, ㅠ, ㅡ, ㅢ, ㅣ]
5
+ jongsung: [ㄱ, ㄲ, ㄳ, ㄴ, ㄵ, ㄶ, ㄷ, ㄹ, ㄺ, ㄻ, ㄼ, ㄽ, ㄾ, ㄿ, ㅀ, ㅁ, ㅂ, ㅄ, ㅅ,
6
+ ㅆ, ㅇ, ㅈ, ㅊ, ㅋ, ㅌ, ㅍ, ㅎ]
7
+
8
+ fortis map:
9
+ ㄱ: ㄲ
10
+ ㄷ: ㄸ
11
+ ㅂ: ㅃ
12
+ ㅅ: ㅆ
13
+ ㅈ: ㅉ
14
+
15
+ double consonant map:
16
+ ㄳ: [ㄱ, ㅅ]
17
+ ㄵ: [ㄴ, ㅈ]
18
+ ㄶ: [ㄴ, ㅎ]
19
+ ㄺ: [ㄹ, ㄱ]
20
+ ㄻ: [ㄹ, ㅁ]
21
+ ㄼ: [ㄹ, ㅂ]
22
+ ㄽ: [ㄹ, ㅅ]
23
+ ㄾ: [ㄹ, ㅌ]
24
+ ㄿ: [ㄹ, ㅍ]
25
+ ㅀ: [ㄹ, ㅎ]
26
+ ㅄ: [ㅂ, ㅅ]
27
+
28
+ pronouncer:
29
+ jongsung sound:
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
+ transformation:
58
+ # changing the order affects the quality of the transformation
59
+ sequence:
60
+ - rule_16
61
+ - rule_17
62
+ - rule_18
63
+ - rule_19
64
+ - rule_5_1
65
+ - rule_5_3
66
+ - rule_30
67
+ - rule_23
68
+ - rule_24
69
+ - rule_25
70
+ - rule_12
71
+ - rule_20
72
+ - rule_10
73
+ - rule_27
74
+ - rule_9
75
+ - rule_11
76
+ - rule_14
77
+ - rule_13
78
+ - rule_15
79
+ blocking rule:
80
+ rule_16: [rule_30]
81
+
82
+ number:
83
+ negative: 마이너스
84
+ decimal point: 점
85
+ units: ["", 만, 억, 조, 경, 해, 자, 양, 구, 간, 정, 재, 극, 항하사, 아승기, 나유타, 불가사의, 무량대수]
86
+ digits: [영, 일, 이, 삼, 사, 오, 육, 칠, 팔, 구]
87
+
88
+ # 정수형일 때 또다른 표현법 (나이, 시간)
89
+ alt notation:
90
+ when suffix:
91
+ 살:
92
+ max:
93
+ 시:
94
+ max: 12
95
+ tenfolds: [열, 스물, 서른, 마흔, 쉰, 예순, 일흔, 여든, 아흔, 백]
96
+ digits: ["", 한, 두, 세, 네, 다섯, 여섯, 일곱, 여덟, 아홉]
97
+ post substitution:
98
+ 물살: 무살
99
+ 물시: 무살
100
+
101
+ romanization:
102
+ chosung:
103
+ ㄱ: g
104
+ ㄲ: kk
105
+ ㅋ: k
106
+ ㄷ: d
107
+ ㄸ: tt
108
+ ㅌ: t
109
+ ㅂ: b
110
+ ㅃ: pp
111
+ ㅍ: p
112
+ ㅈ: j
113
+ ㅉ: jj
114
+ ㅊ: ch
115
+ ㅅ: s
116
+ ㅆ: ss
117
+ ㅎ: h
118
+ ㄴ: n
119
+ ㅁ: m
120
+ ㄹ: r
121
+ ㅇ: "-"
122
+ jungsung:
123
+ ㅏ: a
124
+ ㅓ: eo
125
+ ㅗ: o
126
+ ㅜ: u
127
+ ㅡ: eu
128
+ ㅣ: i
129
+ ㅐ: ae
130
+ ㅔ: e
131
+ ㅚ: oe
132
+ ㅟ: wi
133
+ ㅑ: ya
134
+ ㅕ: yeo
135
+ ㅛ: yo
136
+ ㅠ: yu
137
+ ㅒ: yae
138
+ ㅖ: ye
139
+ ㅘ: wa
140
+ ㅙ: wae
141
+ ㅝ: wo
142
+ ㅞ: we
143
+ ㅢ: ui
144
+ jongsung:
145
+ ㄱ: k
146
+ ㄴ: n
147
+ ㄷ: t
148
+ ㄹ: l
149
+ ㅁ: m
150
+ ㅂ: p
151
+ ㅇ: ng
152
+ post substitution:
153
+ # 제2항 [붙임 2]‘ㄹ’은 모음 앞에서는 ‘r’로, 자음 앞이나 어말에서는
154
+ # ‘l’로 적는다. 단, ‘ㄹㄹ’은 ‘ll’로 적는다.
155
+ lr: ll
156
+
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ # Junegunn Choi (junegunn.c@gmail.com)
4
+
5
+ require 'gimchi/korean'
6
+ require 'gimchi/char'
7
+ require 'gimchi/pronouncer'
8
+
@@ -0,0 +1,104 @@
1
+ # encoding: UTF-8
2
+
3
+ module Gimchi
4
+ class Korean
5
+ # Class representing each Korean character.
6
+ # chosung, jungsung and jongsung can be get and set.
7
+ #
8
+ # to_s merges components into a String.
9
+ # to_a returns the three components.
10
+ class Char
11
+ attr_reader :org
12
+ attr_reader :chosung, :jungsung, :jongsung
13
+
14
+ def initialize kor, kchar
15
+ raise ArgumentError('Not a korean character') unless kor.korean_char? kchar
16
+
17
+ @kor = kor
18
+ @cur = []
19
+ if @kor.complete_korean_char? kchar
20
+ c = kchar.unpack('U').first
21
+ n = c - 0xAC00
22
+ # '가' ~ '깋' -> 'ㄱ'
23
+ n1 = n / (21 * 28)
24
+ # '가' ~ '깋'에서의 순서
25
+ n = n % (21 * 28)
26
+ n2 = n / 28;
27
+ n3 = n % 28;
28
+ self.chosung = @kor.chosungs[n1]
29
+ self.jungsung = @kor.jungsungs[n2]
30
+ self.jongsung = ([nil] + @kor.jongsungs)[n3]
31
+ elsif (@kor.chosungs + @kor.jongsungs).include? kchar
32
+ self.chosung = kchar
33
+ elsif @kor.jungsungs.include? kchar
34
+ self.jungsung = kchar
35
+ end
36
+
37
+ @org = self.dup
38
+ end
39
+
40
+ # recombine components into korean character
41
+ def to_s
42
+ if chosung.nil? && jungsung.nil?
43
+ ""
44
+ elsif chosung && jungsung
45
+ n1, n2, n3 =
46
+ n1 = @kor.chosungs.index(chosung) || 0
47
+ n2 = @kor.jungsungs.index(jungsung) || 0
48
+ n3 = ([nil] + @kor.jongsungs).index(jongsung) || 0
49
+ [ 0xAC00 + n1 * (21 * 28) + n2 * 28 + n3 ].pack('U')
50
+ else
51
+ chosung || jungsung
52
+ end
53
+ end
54
+
55
+ def chosung= c
56
+ raise ArgumentError.new('Invalid chosung component') if
57
+ c && @kor.chosungs.include?(c) == false
58
+ @chosung = c && c.dup.extend(Component).tap { |e| e.kor = @kor }
59
+ end
60
+
61
+ def jungsung= c
62
+ raise ArgumentError.new('Invalid jungsung component') if
63
+ c && @kor.jungsungs.include?(c) == false
64
+ @jungsung = c && c.dup.extend(Component).tap { |e| e.kor = @kor }
65
+ end
66
+
67
+ def jongsung= c
68
+ raise ArgumentError.new('Invalid jongsung component') if
69
+ c && @kor.jongsungs.include?(c) == false
70
+ @jongsung = c && c.dup.extend(Component).tap { |e| e.kor = @kor }
71
+ end
72
+
73
+ # to_a returns the three components.
74
+ def to_a
75
+ [chosung, jungsung, jongsung]
76
+ end
77
+
78
+ # Check if this is a complete Korean character
79
+ def complete?
80
+ chosung.nil? == false && jungsung.nil? == false
81
+ end
82
+
83
+ # Check if this is a non-complete Korean character
84
+ # e.g. ㅇ, ㅏ
85
+ def partial?
86
+ chosung.nil? || jungsung.nil?
87
+ end
88
+
89
+ private
90
+ # nodoc #
91
+ module Component
92
+ attr_accessor :kor
93
+
94
+ def vowel?
95
+ kor.jungsungs.include? self
96
+ end
97
+
98
+ def consonant?
99
+ self != 'ㅇ' && kor.chosungs.include?(self)
100
+ end
101
+ end#Component
102
+ end#Char
103
+ end#Korean
104
+ end#Gimchi