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 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       cd = ChiseDB.instance
42       byidsdb = cd.get_by_ids_db(dbname)
43       cid = byidsdb.decode(@ids)
44       return "" if cid.nil? # TO CHECK: why "", not nil?
45       composed = Character.get(cid).to_s
46       return "" if composed.nil?
47       return "" if composed.char_length == 0
48       return composed if composed.char_length == 1
49       composed.each_char {|ch|
50         char = ch.char
51         #return ch if char.has_attribute?
52         return ch # TO CHECK: the first character?
53       }
54       return ""
55     end
56
57     def aggregate(dbname="ids")
58       # In each sub part of IDS, search the corresponding char_id.
59       # If you could search the corresponding char_id, substitute with it.
60       tree = self.tree
61       return @ids if tree.depth <= 1 # no sub_node
62       tree.sub_nodes.each {|node|
63         c = node.to_ids.compose(dbname)
64         next if c.nil? || c == ""
65         #      print "#{@ids}   #{node} #{c}\n"
66         #      p [@ids, node, c]
67         n = @ids.gsub(node, c)
68         return n.to_ids.aggregate(dbname)
69       }
70       @ids
71     end
72   end
73
74   module StringIDS
75     def decompose
76       map_char {|ch| ch.char.decompose }
77     end
78
79     def decompose_all
80       map_char {|ch| ch.char.decompose_all }
81     end
82   end
83
84   module CharacterIDC
85     def is_idc?
86       0x2ff0 <= @char_id && @char_id <= 0x2fff
87     end
88
89     def idc_argument_number
90       return 0 unless is_idc?
91       return 3 if @char_id == 0x2ff2 || @char_id == 0x2ff3
92       return 2
93     end
94   end
95
96   module CharacterIDS
97     def decompose # by glyph
98       decompose_internal
99     end
100
101     def decompose_by_meaning
102       decompose_internal(true)
103     end
104
105     def decompose_all
106       pde = ""
107       de = self.decompose # the start point.
108       level = 0
109       while true
110         pde = de
111         de = pde.decompose # decompose it again.
112         break if pde == de # previous is same.
113         exit if 10 < level # p ["too many recursive", self] 
114         level += 1
115       end
116       de
117     end
118
119     private
120
121     def decompose_internal(by_meaning=nil)
122       #idss = self.ids
123       #return idss if idss
124       #return k if self.is_basic_kanji?
125       #return ids if idss && 0 < ids.length && k != ids
126
127       k = self.to_s
128       if by_meaning
129         ids = self.ids_represent
130         return ids if ids && 0 < ids.length && k != ids
131         ids = self.ids_element
132         return ids if ids && 0 < ids.length && k != ids
133         ids = self.ids_meaning
134         return ids if ids && 0 < ids.length && k != ids
135       end
136       ids = self.ids
137       return ids if ids && 0 < ids.length && k != ids
138       ids = self.ids_org
139       return ids if ids && 0 < ids.length && k != ids
140       k
141
142       #return k if ids.nil? || ids.length == 0 || k == ids
143       #if ids.char_length == 2
144       #p ["What???", k, ids, k.inspect_all]
145       ##return idsx[1] #二個目だけ返すとか?
146       #return k #IDSに展開する方法が無いと。
147       #end
148       #return k if k == ids
149       #if ids.include?(k) #<C5-4C4D><C6-4A37>この二文字のBUG対策
150       ##return ids.sub(k, "")
151       #return k #IDSに展開する方法が無いと。
152       #end
153       #return ids
154     end
155
156   end
157 end