update.
[chise/ruby.git] / chise / ids.rb
1 # Copyright (C) 2002-2004 Kouichirou Eto, All rights reserved.
2
3 require "chise/idstree"
4
5 module CHISE
6   IDC_0 = "\342\277\260"
7   IDC_1 = "\342\277\261"
8   IDC_2 = "\342\277\262"
9   IDC_3 = "\342\277\263"
10   IDC_4 = "\342\277\264"
11   IDC_5 = "\342\277\265"
12   IDC_6 = "\342\277\266"
13   IDC_7 = "\342\277\267"
14   IDC_8 = "\342\277\270"
15   IDC_9 = "\342\277\271"
16   IDC_A = "\342\277\272"
17   IDC_B = "\342\277\273"
18
19   IDC_LEFT_TO_RIGHT = IDC_0
20   IDC_ABOVE_TO_BELOW = IDC_1
21   IDC_LEFT_TO_MIDDLE_AND_RIGHT = IDC_2
22   IDC_ABOVE_TO_MIDDLE_AND_BELOW = IDC_3
23   IDC_FULL_SURROUND = IDC_4
24   IDC_SURROUND_FROM_ABOVE = IDC_5
25   IDC_SURROUND_FROM_BELOW = IDC_6
26   IDC_SURROUND_FROM_LEFT = IDC_7
27   IDC_SURROUND_FROM_UPPER_LEFT = IDC_8
28   IDC_SURROUND_FROM_UPPER_RIGHT = IDC_9
29   IDC_SURROUND_FROM_LOWER_LEFT = IDC_A
30   IDC_OVERLAID = IDC_B
31
32   class Nu_IDS
33     def initialize(ids)
34       @ids = ids
35       @ids.freeze
36     end
37
38     def tree() IDS_Tree.new(@ids); end
39
40     def compose(dbname="ids")
41       ids = @ids.to_ids.aggregate
42
43       cd = ChiseDB.instance
44       byidsdb = cd.get_by_ids_db(dbname)
45       cid = byidsdb.decode(ids)
46       return "" if cid.nil? # TO CHECK: why "", not nil?
47       composed = Character.get(cid).to_s
48       return "" if composed.nil?
49       return "" if composed.char_length == 0
50       return composed if composed.char_length == 1
51       composed.each_char {|ch|
52         char = ch.char
53         #return ch if char.has_attribute?
54         return ch # TO CHECK: the first character?
55       }
56       return ""
57     end
58
59     def aggregate(dbname="ids")
60       # In each sub part of IDS, search the corresponding char_id.
61       # If you could search the corresponding char_id, substitute with it.
62       tree = self.tree
63       return @ids if tree.depth <= 1 # no sub_node
64       tree.sub_nodes.each {|node|
65         c = node.to_ids.compose(dbname)
66         next if c.nil? || c == ""
67         #      print "#{@ids}   #{node} #{c}\n"
68         #      p [@ids, node, c]
69         n = @ids.gsub(node, c)
70         return n.to_ids.aggregate(dbname)
71       }
72       @ids
73     end
74   end
75
76   module StringIDS
77     def decompose
78       map_char {|ch| ch.char.decompose }
79     end
80
81     def decompose_all
82       map_char {|ch| ch.char.decompose_all }
83     end
84
85     def ids_tree() IDS_Tree.new(self); end
86
87     def compose(dbname="ids")
88       ids = self.aggregate
89       cd = ChiseDB.instance
90       byidsdb = cd.get_by_ids_db(dbname)
91       cid = byidsdb.decode(ids)
92       return "" if cid.nil? # TO CHECK: why "", not nil?
93       composed = Character.get(cid).to_s
94       return "" if composed.nil?
95       return "" if composed.char_length == 0
96       return composed if composed.char_length == 1
97       composed.each_char {|ch|
98         char = ch.char
99         return ch # TO CHECK: the first character?
100       }
101       "" # TO CHECK: why "", not nil?
102     end
103
104     def aggregate(dbname="ids")
105       # In each sub part of IDS, search the corresponding char_id.
106       # If you could search the corresponding char_id, substitute with it.
107       tree = self.ids_tree
108       return self if tree.depth <= 1 # no sub_node
109       tree.sub_nodes.each {|node|
110         c = node.compose(dbname)
111         next if c.nil? || c == ""
112         n = self.gsub(node, c)
113         return n.aggregate(dbname)
114       }
115       self
116     end
117
118     def find() # "日雲"→"曇"とかいう感じの操作
119       ar = []
120       length = char_length()
121       each_char {|ch|
122         char = ch.char
123         ar << char.ids_contained #その文字を含んでいる漢字のリスト
124       }
125       h = Hash.new(0)
126       #qp ar
127       ar.each {|list|
128         next if list.nil?
129         list.each_char {|ch|
130           h[ch] += 1
131         }
132       }
133       str = ""
134       h.each {|k, v|
135         #      p [k, v]
136         if length == v #全部に顔を出していたら
137           str += k
138         end
139       }
140       #    p str
141       str
142     end
143   end
144
145   module CharacterIDC
146     def is_idc?
147       0x2ff0 <= @char_id && @char_id <= 0x2fff
148     end
149
150     def idc_argument_number
151       return 0 unless is_idc?
152       return 3 if @char_id == 0x2ff2 || @char_id == 0x2ff3
153       return 2
154     end
155   end
156
157   module CharacterIDS
158     def decompose_by_meaning
159       k = self.to_s
160       ids = self.ids_represent
161       return ids if ids && !ids.empty? && k != ids
162       ids = self.ids_element
163       return ids if ids && !ids.empty? && k != ids
164       ids = self.ids_meaning
165       return ids if ids && !ids.empty? && k != ids
166       decompose
167     end
168
169     def decompose # by glyph
170       k = self.to_s
171       ids = self.ids
172       return ids if ids && !ids.empty? && k != ids
173       ids = self.ids_org
174       return ids if ids && !ids.empty? && k != ids
175       k
176     end
177
178     def decompose_all
179       pde = ""
180       de = self.decompose # the start point.
181       level = 0
182       while true
183         pde = de
184         de = pde.decompose # decompose it again.
185         break if pde == de # previous is same.
186         exit if 10 < level # p ["too many recursive", self] 
187         level += 1
188       end
189       de
190     end
191   end
192 end