gimchi 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module Gimchi
4
- class Korean
5
- # Class representing each Korean character. Its three components,
3
+ class Gimchi
4
+ # Class representing each Korean character. Its three components,
6
5
  # `chosung', `jungsung' and `jongsung' can be get and set.
7
6
  #
8
7
  # `to_s' merges components into a String. `to_a' returns the three components.
@@ -14,13 +13,13 @@ class Korean
14
13
  # @return [String] Jongsung component of this character.
15
14
  attr_reader :jongsung
16
15
 
17
- # @param [Gimchi::Korean] kor Gimchi::Korean instance
16
+ # @param [Gimchi] gimchi Gimchi instance
18
17
  # @param [String] kchar Korean character string
19
- def initialize kor, kchar
20
- raise ArgumentError.new('Not a korean character') unless kor.korean_char? kchar
18
+ def initialize gimchi, kchar
19
+ raise ArgumentError.new('Not a korean character') unless gimchi.korean_char? kchar
21
20
 
22
- @kor = kor
23
- if @kor.complete_korean_char? kchar
21
+ @gimchi = gimchi
22
+ if @gimchi.complete_korean_char? kchar
24
23
  c = kchar.unpack('U').first
25
24
  n = c - 0xAC00
26
25
  # '가' ~ '깋' -> 'ㄱ'
@@ -29,14 +28,14 @@ class Korean
29
28
  n = n % (21 * 28)
30
29
  n2 = n / 28;
31
30
  n3 = n % 28;
32
- self.chosung = @kor.chosungs[n1]
33
- self.jungsung = @kor.jungsungs[n2]
34
- self.jongsung = ([nil] + @kor.jongsungs)[n3]
35
- elsif @kor.chosungs.include? kchar
31
+ self.chosung = @gimchi.chosungs[n1]
32
+ self.jungsung = @gimchi.jungsungs[n2]
33
+ self.jongsung = ([nil] + @gimchi.jongsungs)[n3]
34
+ elsif @gimchi.chosung? kchar
36
35
  self.chosung = kchar
37
- elsif @kor.jungsungs.include? kchar
36
+ elsif @gimchi.jungsung? kchar
38
37
  self.jungsung = kchar
39
- elsif @kor.jongsungs.include? kchar
38
+ elsif @gimchi.jongsung? kchar
40
39
  self.jongsung = kchar
41
40
  end
42
41
  end
@@ -44,42 +43,32 @@ class Korean
44
43
  # Recombines components into a korean character.
45
44
  # @return [String] Combined korean character
46
45
  def to_s
47
- if chosung.nil? && jungsung.nil?
48
- ""
49
- elsif chosung && jungsung
50
- n1, n2, n3 =
51
- n1 = @kor.chosungs.index(chosung) || 0
52
- n2 = @kor.jungsungs.index(jungsung) || 0
53
- n3 = ([nil] + @kor.jongsungs).index(jongsung) || 0
54
- [ 0xAC00 + n1 * (21 * 28) + n2 * 28 + n3 ].pack('U')
55
- else
56
- chosung || jungsung
57
- end
46
+ @gimchi.compose chosung, jungsung, jongsung
58
47
  end
59
48
 
60
49
  # Sets the chosung component.
61
- # @param [String]
50
+ # @param [String]
62
51
  def chosung= c
63
52
  raise ArgumentError.new('Invalid chosung component') if
64
- c && @kor.chosungs.include?(c) == false
65
- @chosung = c && c.dup.extend(Component).tap { |e| e.kor = @kor }
53
+ c && @gimchi.chosung?(c) == false
54
+ @chosung = c && c.dup.extend(Component).tap { |e| e.kor = @gimchi }
66
55
  end
67
56
 
68
57
  # Sets the jungsung component
69
- # @param [String]
58
+ # @param [String]
70
59
  def jungsung= c
71
60
  raise ArgumentError.new('Invalid jungsung component') if
72
- c && @kor.jungsungs.include?(c) == false
73
- @jungsung = c && c.dup.extend(Component).tap { |e| e.kor = @kor }
61
+ c && @gimchi.jungsung?(c) == false
62
+ @jungsung = c && c.dup.extend(Component).tap { |e| e.kor = @gimchi }
74
63
  end
75
64
 
76
65
  # Sets the jongsung component
77
66
  #
78
- # @param [String]
67
+ # @param [String]
79
68
  def jongsung= c
80
69
  raise ArgumentError.new('Invalid jongsung component') if
81
- c && @kor.jongsungs.include?(c) == false
82
- @jongsung = c && c.dup.extend(Component).tap { |e| e.kor = @kor }
70
+ c && @gimchi.jongsung?(c) == false
71
+ @jongsung = c && c.dup.extend(Component).tap { |e| e.kor = @gimchi }
83
72
  end
84
73
 
85
74
  # Returns Array of three components.
@@ -105,22 +94,21 @@ class Korean
105
94
  end
106
95
 
107
96
  private
108
- # Three components of Korean::Char are extended to support #vowel? and #consonant? method.
97
+ # Three components of Gimchi::Char are extended to support #vowel? and #consonant? method.
109
98
  module Component
110
99
  # @return [Korean] Hosting Korean instance
111
100
  attr_accessor :kor
112
101
 
113
102
  # Is this component a vowel?
114
103
  def vowel?
115
- kor.jungsungs.include? self
104
+ kor.jungsung? self
116
105
  end
117
106
 
118
107
  # Is this component a consonant?
119
108
  def consonant?
120
- self != 'ㅇ' && kor.chosungs.include?(self)
109
+ self != 'ㅇ' && kor.chosung?(self)
121
110
  end
122
111
  end#Component
123
112
  end#Char
124
- end#Korean
125
113
  end#Gimchi
126
114
 
@@ -1,10 +1,10 @@
1
- $KCODE = 'U'
1
+ if RUBY_VERSION =~ /^1\.8\./
2
+ $KCODE = 'U'
2
3
 
3
- module Gimchi
4
- class Korean
5
- private
6
- def str_length str
7
- str.scan(/./mu).length
8
- end
9
- end#Korean
10
- end#Gimchi
4
+ class Gimchi
5
+ private
6
+ def str_length str
7
+ str.scan(/./mu).length
8
+ end
9
+ end#Gimchi
10
+ end
@@ -1,23 +1,23 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module Gimchi
4
- class Korean
3
+ class Gimchi
5
4
  # Private class.
6
5
  # Partial implementation of Korean pronouncement pronunciation rules specified in
7
6
  # http://http://www.korean.go.kr/
7
+ # @private
8
8
  class Pronouncer
9
9
  private
10
- def initialize korean
11
- @korean = korean
12
- @pconfig = korean.config['pronouncer']
10
+ def initialize gimchi
11
+ @gimchi = gimchi
12
+ @pconfig = gimchi.config[:pronouncer]
13
13
  end
14
14
 
15
15
  def pronounce! str, options = {}
16
- @sequence = @pconfig['transformation']['sequence for ' +
17
- (options[:pronounce_each_char] ? '1' : '2')] - options[:except]
16
+ @sequence = @pconfig[:transformation][
17
+ "sequence_for_#{options[:each_char] ? '1' : '2'}".to_sym] - options[:except]
18
18
 
19
19
  # Dissecting
20
- @chars = @korean.convert str
20
+ @chars = str.each_char.map { |c| @gimchi.kchar(c) rescue c }
21
21
  @orig_chars = @chars.dup
22
22
 
23
23
  # Padding
@@ -35,9 +35,9 @@ class Korean
35
35
  # Transform one by one
36
36
  applied += (0...@chars.length).inject([]) { | arr, i | arr + transform(i); }
37
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]
38
+ # Post-processing (actually just for :each_char option)
39
+ @chars.select { |c| c.is_a?(Gimchi::Char) && c.jongsung }.each do | c |
40
+ c.jongsung = @pconfig[:jongsung_sound][c.jongsung]
41
41
  end
42
42
 
43
43
  break unless options[:slur]
@@ -52,20 +52,20 @@ class Korean
52
52
  kc = @chars[@cursor]
53
53
 
54
54
  # Not korean
55
- return [] unless kc.is_a? Korean::Char
55
+ return [] unless kc.is_a? Gimchi::Char
56
56
 
57
57
  # Setting up variables for fast lookup
58
58
  @kc = kc
59
- @next_kc = (nkc = @chars[@cursor + 1]).is_a?(Korean::Char) ? nkc : nil
59
+ @next_kc = (nkc = @chars[@cursor + 1]).is_a?(Gimchi::Char) ? nkc : nil
60
60
  @kc_org = @initial_chars[@cursor]
61
- @next_kc_org = (nkco = @initial_chars[@cursor + 1]).is_a?(Korean::Char) ? nkco : nil
61
+ @next_kc_org = (nkco = @initial_chars[@cursor + 1]).is_a?(Gimchi::Char) ? nkco : nil
62
62
 
63
63
  # Cannot properly pronounce
64
64
  return [] if @kc.chosung.nil? && @kc.jungsung.nil? && @kc.jongsung.nil?
65
65
 
66
66
  applied = []
67
67
  not_todo = []
68
- blocking_rule = @pconfig['transformation']['blocking rule']
68
+ blocking_rule = @pconfig[:transformation][:blocking_rule]
69
69
  @sequence.each do | rule |
70
70
  next if not_todo.include?(rule)
71
71
 
@@ -78,7 +78,7 @@ class Korean
78
78
  end
79
79
 
80
80
  def pad c
81
- return unless c.is_a? Korean::Char
81
+ return unless c.is_a? Gimchi::Char
82
82
 
83
83
  c.chosung = 'ㅇ' if c.chosung.nil?
84
84
  c.jungsung = 'ㅡ' if c.jungsung.nil?
@@ -86,12 +86,12 @@ class Korean
86
86
 
87
87
  # shortcut
88
88
  def fortis_map
89
- @korean.config['structure']['fortis map']
89
+ @gimchi.config[:structure][:fortis_map]
90
90
  end
91
91
 
92
92
  # shortcut
93
93
  def double_consonant_map
94
- @korean.config['structure']['double consonant map']
94
+ @gimchi.config[:structure][:double_consonant_map]
95
95
  end
96
96
 
97
97
  # 제5항: ‘ㅑ ㅒ ㅕ ㅖ ㅘ ㅙ ㅛ ㅝ ㅞ ㅠ ㅢ’는 이중 모음으로 발음한다.
@@ -193,7 +193,7 @@ class Korean
193
193
  'ㄱ' => 'ㅋ',
194
194
  'ㄷ' => 'ㅌ',
195
195
  'ㅈ' => 'ㅊ' }
196
- if %w[ㅎ ㄶ ㅀ].include?(@kc.jongsung)
196
+ if %w[ㅎ ㄶ ㅀ].include?(@kc.jongsung)
197
197
  # 12-1
198
198
  if map_12_1.keys.include?(@next_kc.chosung)
199
199
  @next_kc.chosung = map_12_1[@next_kc.chosung]
@@ -277,7 +277,7 @@ class Korean
277
277
 
278
278
  if false && %w[ㅏ ㅓ ㅗ ㅜ ㅟ].include?(@next_kc.jungsung) &&
279
279
  %[ㅆ ㄲ ㅈ ㅊ ㄵ ㄻ ㄾ ㄿ ㄺ].include?(@kc.jongsung) == false # PATCH
280
- @next_kc.chosung = @pconfig['jongsung sound'][ @kc.jongsung ]
280
+ @next_kc.chosung = @pconfig[:jongsung_sound][ @kc.jongsung ]
281
281
  @kc.jongsung = nil
282
282
 
283
283
  true
@@ -299,7 +299,7 @@ class Korean
299
299
 
300
300
  word = @kc.to_s + @next_kc.to_s
301
301
  if map.keys.include? word
302
- new_char = @korean.kchar(map[word].scan(/./mu)[1])
302
+ new_char = @gimchi.kchar(map[word].scan(/./mu)[1])
303
303
  @next_kc.chosung = new_char.chosung
304
304
  @next_kc.jongsung = new_char.jongsung
305
305
 
@@ -331,8 +331,8 @@ class Korean
331
331
  # ㄿ, ㅄ)’은 ‘ㄴ, ㅁ’ 앞에서 [ㅇ, ㄴ, ㅁ]으로 발음한다.
332
332
  def rule_18
333
333
  map = {
334
- %w[ㄱ ㄲ ㅋ ㄳ ㄺ] => 'ㅇ',
335
- %w[ㄷ ㅅ ㅆ ㅈ ㅊ ㅌ ㅎ] => 'ㄴ',
334
+ %w[ㄱ ㄲ ㅋ ㄳ ㄺ] => 'ㅇ',
335
+ %w[ㄷ ㅅ ㅆ ㅈ ㅊ ㅌ ㅎ] => 'ㄴ',
336
336
  %w[ㅂ ㅍ ㄼ ㄿ ㅄ] => 'ㅁ'
337
337
  }
338
338
  if @next_kc && map.keys.flatten.include?(@kc.jongsung) && %w[ㄴ ㅁ].include?(@next_kc.chosung)
@@ -395,7 +395,7 @@ class Korean
395
395
  # 다만, 피동, 사동의 접미사 ‘-기-’는 된소리로 발음하지 않는다.
396
396
  # 용언 어간에만 적용.
397
397
  def rule_24
398
- return if @next_kc.nil? ||
398
+ return if @next_kc.nil? ||
399
399
  @next_kc.to_s == '기' # FIXME 피동/사동 여부 판단 불가. e.g. 줄넘기
400
400
 
401
401
  # FIXME 용언 여부를 판단. 정확한 판단 불가.
@@ -441,7 +441,7 @@ class Korean
441
441
  return if @next_kc.nil?
442
442
 
443
443
  # 비교적 확률이 높은 경우들에 대해서만 처리. "일" 은 제외.
444
- if %w[할 갈 날 볼 을 앨 말 힐].include?(@kc.to_s) && # @kc.jongsung == 'ㄹ' &&
444
+ if %w[할 갈 날 볼 을 앨 말 힐].include?(@kc.to_s) && # @kc.jongsung == 'ㄹ' &&
445
445
  %w[ㄱ ㄷ ㅂ ㅅ ㅈ].include?(@next_kc.chosung)
446
446
  @next_kc.chosung = fortis_map[@next_kc.chosung]
447
447
  true
@@ -467,7 +467,7 @@ class Korean
467
467
  # 1. ‘ㄱ, ㄷ, ㅂ, ㅅ, ㅈ’으로 시작하는 단어 앞에 사이시옷이 올 때는 이들
468
468
  # 자음만을 된소리로 발음하는 것을 원칙으로 하되, 사이시옷을 [ㄷ]으로
469
469
  # 발음하는 것도 허용한다.
470
- # 2. 사이시옷 뒤에 ‘ㄴ, ㅁ’이 결합되는 경우에는 [ㄴ]으로 발음한다.
470
+ # 2. 사이시옷 뒤에 ‘ㄴ, ㅁ’이 결합되는 경우에는 [ㄴ]으로 발음한다.
471
471
  # 3. 사이시옷 뒤에 ‘이’ 음이 결합되는 경우에는 [ㄴㄴ]으로 발음한다.
472
472
  def rule_30
473
473
  return if @next_kc.nil? || @kc.jongsung != 'ㅅ'
@@ -490,5 +490,4 @@ class Korean
490
490
  end
491
491
  end
492
492
  end#Pronouncer
493
- end#Korean
494
493
  end#Gimchi
@@ -1,3 +1,4 @@
1
+ $VERBOSE = true
1
2
  require 'rubygems'
2
3
  require 'bundler'
3
4
  begin
@@ -2,76 +2,75 @@
2
2
 
3
3
  $LOAD_PATH.unshift File.dirname(__FILE__)
4
4
  require 'helper'
5
+ require 'yaml'
6
+ require 'ansi'
7
+
5
8
 
6
9
  class TestGimchi < Test::Unit::TestCase
7
10
  def test_korean_char
8
- ko = Gimchi::Korean.new
9
- assert_equal true, ko.korean_char?('ㄱ') # true
10
- assert_equal true, ko.kchar?('') # true
11
- assert_equal true, ko.korean_char?('') # true
12
- assert_equal true, ko.korean_char?('') # true
13
- assert_equal true, ko.korean_char?('값') # true
14
- assert_equal true, ko.kchar?('값') # true
15
-
16
- assert_equal false, ko.korean_char?('a') # false
17
- assert_equal false, ko.korean_char?('1') # false
18
- assert_raise(ArgumentError) { ko.korean_char?('두자') }
19
- assert_raise(ArgumentError) { ko.kchar?('두자') }
11
+ assert_equal true, Gimchi.korean_char?('ㄱ') # true
12
+ assert_equal true, Gimchi.kchar?('ㄱ') # true
13
+ assert_equal true, Gimchi.korean_char?('') # true
14
+ assert_equal true, Gimchi.korean_char?('') # true
15
+ assert_equal true, Gimchi.korean_char?('') # true
16
+ assert_equal true, Gimchi.kchar?('값') # true
17
+
18
+ assert_equal false, Gimchi.korean_char?('a') # false
19
+ assert_equal false, Gimchi.korean_char?('1') # false
20
+ assert_raise(ArgumentError) { Gimchi.korean_char?('두자') }
21
+ assert_raise(ArgumentError) { Gimchi.kchar?('두자') }
20
22
  end
21
23
 
22
24
  def test_kchar
23
- ko = Gimchi::Korean.new
24
- # Alias
25
- [ko.kchar('한'), ko.korean_char('한')].each do |kc|
26
- assert_equal Gimchi::Korean::Char, kc.class
27
- assert_equal "", kc.chosung
28
- assert_equal "ㅏ", kc.jungsung
29
- assert_equal "", kc.jongsung
30
- assert_equal ["ㅎ", "ㅏ", "ㄴ"], kc.to_a
31
- assert_equal "한", kc.to_s
32
- assert_equal true, kc.complete?
33
- assert_equal false, kc.partial?
34
- end
35
-
36
- assert_raise(ArgumentError) { ko.kchar('한글') }
37
- assert_raise(ArgumentError) { ko.kchar('A') }
38
-
39
- assert_equal true, ko.kchar("ㅏ").partial?
25
+ kc = Gimchi::Char('한')
26
+ assert_equal Gimchi::Char, kc.class
27
+ assert_equal "ㅎ", kc.chosung
28
+ assert_equal "ㅏ", kc.jungsung
29
+ assert_equal "", kc.jongsung
30
+ assert_equal ["ㅎ", "ㅏ", "ㄴ"], kc.to_a
31
+ assert_equal "", kc.to_s
32
+ assert_equal true, kc.complete?
33
+ assert_equal false, kc.partial?
34
+
35
+ assert_raise(ArgumentError) { Gimchi::Char('한글') }
36
+ assert_raise(ArgumentError) { Gimchi::Char('A') }
37
+
38
+ assert_equal true, Gimchi::Char("ㅏ").partial?
40
39
  end
41
40
 
42
41
  def test_complete_korean_char
43
- ko = Gimchi::Korean.new
44
42
 
45
- assert_equal false, ko.complete_korean_char?('ㄱ') # false
46
- assert_equal false, ko.complete_korean_char?('ㅏ') # false
47
- assert_equal true, ko.complete_korean_char?('가') # true
48
- assert_equal true, ko.complete_korean_char?('값') # true
43
+ assert_equal false, Gimchi.complete_korean_char?('ㄱ') # false
44
+ assert_equal false, Gimchi.complete_korean_char?('ㅏ') # false
45
+ assert_equal true, Gimchi.complete_korean_char?('가') # true
46
+ assert_equal true, Gimchi.complete_korean_char?('값') # true
49
47
 
50
- assert_equal false, ko.korean_char?('a') # false
51
- assert_equal false, ko.korean_char?('1') # false
52
- assert_raise(ArgumentError) { ko.korean_char?('두자') }
48
+ assert_equal false, Gimchi.korean_char?('a') # false
49
+ assert_equal false, Gimchi.korean_char?('1') # false
50
+ assert_raise(ArgumentError) { Gimchi.korean_char?('두자') }
53
51
  end
54
52
 
55
53
  def test_dissect
56
- ko = Gimchi::Korean.new
54
+ arr = '이것은 Hangul 입니다.'.each_char.map { |ch|
55
+ (Gimchi::Char(ch) rescue [ch]).to_a
56
+ }.flatten.compact
57
57
 
58
- arr = ko.dissect '이것은 Hangul 입니다.'
59
- assert_equal ["ㅇ", "ㅣ", "ㄱ", "ㅓ", "ㅅ", "ㅇ", "ㅡ", "ㄴ", " ",
58
+ assert_equal ["ㅇ", "ㅣ", "ㄱ", "ㅓ", "ㅅ", "ㅇ", "ㅡ", "ㄴ", " ",
60
59
  "H", "a", "n", "g", "u", "l", " ", "ㅇ", "ㅣ", "ㅂ",
61
60
  "ㄴ", "ㅣ", "ㄷ", "ㅏ", "."], arr
62
61
  end
63
62
 
64
63
  def test_convert
65
- ko = Gimchi::Korean.new
66
-
67
- arr = ko.convert '이것은 한글입니다.'
64
+ arr = '이것은 한글입니다.'.each_char.map { |ch|
65
+ Gimchi::Char(ch) rescue ch
66
+ }
68
67
  # [이, 것, 은, " ", 한, 글, 입, 니, 다, "."]
69
68
 
70
69
  assert_equal 10, arr.length
71
- assert_equal Gimchi::Korean::Char, arr[0].class
72
- assert_equal Gimchi::Korean::Char, arr[1].class
73
- assert_equal Gimchi::Korean::Char, arr[2].class
74
-
70
+ assert_equal Gimchi::Char, arr[0].class
71
+ assert_equal Gimchi::Char, arr[1].class
72
+ assert_equal Gimchi::Char, arr[2].class
73
+
75
74
  ch = arr[2]
76
75
  assert_equal 'ㅇ', ch.chosung
77
76
  assert_equal 'ㅡ', ch.jungsung
@@ -108,43 +107,41 @@ class TestGimchi < Test::Unit::TestCase
108
107
  end
109
108
 
110
109
  def test_read_number
111
- ko = Gimchi::Korean.new
112
- assert_equal "", ko.read_number(0)
113
- assert_equal "", ko.read_number(1)
114
- assert_equal "구", ko.read_number(9)
115
- assert_equal " 구백 구십 구", ko.read_number(1999)
116
- assert_equal "마이너스 백점일이삼", ko.read_number(- 100.123)
110
+ assert_equal "영", Gimchi.read_number(0)
111
+ assert_equal "", Gimchi.read_number(1)
112
+ assert_equal "", Gimchi.read_number(9)
113
+ assert_equal "천 구백 구십 구", Gimchi.read_number(1999)
114
+ assert_equal "마이너스 백점일이삼", Gimchi.read_number(- 100.123)
117
115
  assert_equal "오백 삼십 일억 구천 백 십만 육백 칠십 팔점삼이일사오육칠",
118
- ko.read_number("53,191,100,678.3214567")
119
- assert_equal "영점영영영영영일이삼사오", ko.read_number("1.2345e-06")
120
- assert_equal "일해 이천 삼백 사십 오경", ko.read_number("1.2345e+20")
121
- assert_equal "플러스 일해 이천 삼백 사십 오경", ko.read_number("+ 1.2345e+20")
122
- assert_equal "마이너스 일해 이천 삼백 사십 오경", ko.read_number("- 1.2345e+20")
123
- assert_equal "만 십 이점삼", ko.read_number("100.123e+2")
124
- assert_equal "십만 십 이점삼", ko.read_number("1000.123e+2")
125
- assert_equal "백 일만 십 이점삼", ko.read_number("10100.123e+2")
126
- assert_equal "천 십 이점삼", ko.read_number("10.123e+2")
127
- assert_equal "십점영", ko.read_number("10.0")
128
- assert_equal "플러스 십점영", ko.read_number("+ 10.0")
116
+ Gimchi.read_number("53,191,100,678.3214567")
117
+ assert_equal "영점영영영영영일이삼사오", Gimchi.read_number("1.2345e-06")
118
+ assert_equal "일해 이천 삼백 사십 오경", Gimchi.read_number("1.2345e+20")
119
+ assert_equal "플러스 일해 이천 삼백 사십 오경", Gimchi.read_number("+ 1.2345e+20")
120
+ assert_equal "마이너스 일해 이천 삼백 사십 오경", Gimchi.read_number("- 1.2345e+20")
121
+ assert_equal "만 십 이점삼", Gimchi.read_number("100.123e+2")
122
+ assert_equal "십만 십 이점삼", Gimchi.read_number("1000.123e+2")
123
+ assert_equal "백 일만 십 이점삼", Gimchi.read_number("10100.123e+2")
124
+ assert_equal "천 십 이점삼", Gimchi.read_number("10.123e+2")
125
+ assert_equal "십점영", Gimchi.read_number("10.0")
126
+ assert_equal "플러스 십점영", Gimchi.read_number("+ 10.0")
129
127
 
130
128
  # 나이, 시간, 개수, 명 ( -살, -시, -개, -명 )
131
- assert_equal "나는 이십", ko.read_number("나는 20")
132
- assert_equal "나는 스무살", ko.read_number("나는 20살")
133
- assert_equal "나는 스물네살", ko.read_number("나는 24살")
134
- assert_equal "스무개", ko.read_number("20개")
135
- assert_equal "스무 명", ko.read_number("20 명")
136
- assert_equal "이십 칠점일살", ko.read_number("27.1살")
137
- assert_equal "너는 열세 살", ko.read_number("너는 13 살")
138
- assert_equal "백 서른두명", ko.read_number("132명")
139
- assert_equal "이천 오백 아흔아홉개", ko.read_number("2,599개")
140
- assert_equal "지금은 일곱시 삼십분", ko.read_number("지금은 7시 30분")
129
+ assert_equal "나는 이십", Gimchi.read_number("나는 20")
130
+ assert_equal "나는 스무살", Gimchi.read_number("나는 20살")
131
+ assert_equal "나는 스물네살", Gimchi.read_number("나는 24살")
132
+ assert_equal "스무개", Gimchi.read_number("20개")
133
+ assert_equal "스무 명", Gimchi.read_number("20 명")
134
+ assert_equal "이십 칠점일살", Gimchi.read_number("27.1살")
135
+ assert_equal "너는 열세 살", Gimchi.read_number("너는 13 살")
136
+ assert_equal "백 서른두명", Gimchi.read_number("132명")
137
+ assert_equal "이천 오백 아흔아홉개", Gimchi.read_number("2,599개")
138
+ assert_equal "지금은 일곱시 삼십분", Gimchi.read_number("지금은 7시 30분")
139
+
140
+ # No way!
141
+ assert_raise(RangeError) { Gimchi.read_number 10 ** 100 }
141
142
  end
142
143
 
143
144
  def test_pronounce
144
- require 'yaml'
145
- require 'ansi'
146
-
147
- ko = Gimchi::Korean.new
148
145
  cnt = 0
149
146
  s = 0
150
147
  test_set = YAML.load File.read(File.dirname(__FILE__) + '/pronunciation.yml')
@@ -152,8 +149,8 @@ class TestGimchi < Test::Unit::TestCase
152
149
  cnt += 1
153
150
  k = k.gsub(/[-]/, '')
154
151
 
155
- t1, tfs1 = ko.pronounce(k, :pronounce_each_char => false, :slur => true, :debug => true)
156
- t2, tfs2 = ko.pronounce(k, :pronounce_each_char => false, :slur => false, :debug => true)
152
+ t1, tfs1 = Gimchi.pronounce(k, :each_char => false, :slur => true, :debug => true)
153
+ t2, tfs2 = Gimchi.pronounce(k, :each_char => false, :slur => false, :debug => true)
157
154
 
158
155
  path = ""
159
156
  if (with_slur = v.include?(t1.gsub(/\s/, ''))) || v.include?(t2.gsub(/\s/, ''))
@@ -165,7 +162,7 @@ class TestGimchi < Test::Unit::TestCase
165
162
  r = ANSI::Code::RED + ANSI::Code::BOLD + v.join(' / ') + ANSI::Code::RESET
166
163
  t = [t1, t2].join ' | '
167
164
  end
168
- puts "#{k} => #{t} (#{ko.romanize t, :as_pronounced => false}) [#{path}] #{r}"
165
+ puts "#{k} => #{t} (#{Gimchi.romanize t, :as_pronounced => false}) [#{path}] #{r}"
169
166
  end
170
167
  puts "#{s} / #{cnt}"
171
168
  # FIXME
@@ -173,19 +170,16 @@ class TestGimchi < Test::Unit::TestCase
173
170
  end
174
171
 
175
172
  def test_romanize_preserve_non_korean
176
- ko = Gimchi::Korean.new
177
- assert_equal 'ttok-kkateun kkk', ko.romanize('똑같은 kkk')
173
+ assert_equal 'ttok-kkateun kkk', Gimchi.romanize('똑같은 kkk')
178
174
  end
179
175
 
180
176
  def test_romanize
181
- ko = Gimchi::Korean.new
182
-
183
177
  cnt = 0
184
178
  s = 0
185
179
  test_set = YAML.load File.read(File.dirname(__FILE__) + '/romanization.yml')
186
180
  test_set.each do | k, v |
187
181
  cnt += 1
188
- rom = ko.romanize k.sub(/\[.*/, '')
182
+ rom = Gimchi.romanize k.sub(/\[.*/, '')
189
183
  if rom.downcase.gsub(/[\s-]/, '') == v.downcase.gsub(/\(.*\)/, '').gsub(/[\s-]/, '')
190
184
  r = ANSI::Code::BLUE + ANSI::Code::BOLD + rom + ANSI::Code::RESET
191
185
  s += 1
@@ -198,4 +192,38 @@ class TestGimchi < Test::Unit::TestCase
198
192
  # FIXME
199
193
  assert s >= 63
200
194
  end
195
+
196
+ def test_cho_jung_jongsung?
197
+ c, j, jo = Gimchi::Char("달").to_a
198
+ assert Gimchi.chosung?(c)
199
+ assert Gimchi.jungsung?(j)
200
+ assert Gimchi.jongsung?(jo)
201
+
202
+ assert Gimchi.chosung?( 'ㄱ')
203
+ assert !Gimchi.jungsung?('ㄱ')
204
+ assert Gimchi.jongsung?('ㄱ')
205
+ assert !Gimchi.chosung?( 'ㅏ')
206
+ assert Gimchi.jungsung?('ㅏ')
207
+ assert !Gimchi.jongsung?('ㅏ')
208
+ assert !Gimchi.chosung?( 'ㄺ')
209
+ assert !Gimchi.jungsung?('ㄺ')
210
+ assert Gimchi.jongsung?('ㄺ')
211
+ end
212
+
213
+ def test_compose_decompose
214
+ ret = Gimchi.decompose("한")
215
+ assert ret.is_a?(Array)
216
+ assert_equal 'ㅎ', ret[0]
217
+ assert_equal 'ㅏ', ret[1]
218
+ assert_equal 'ㄴ', ret[2]
219
+
220
+ assert_equal '한', Gimchi.compose(*ret)
221
+
222
+ ret = Gimchi.decompose("ㅋ")
223
+ assert_equal 'ㅋ', ret[0]
224
+ assert_equal nil, ret[1]
225
+ assert_equal nil, ret[2]
226
+
227
+ assert_equal 'ㅋ', Gimchi.compose(*ret)
228
+ end
201
229
  end