4b695ce40316f33d4569fc05d501fdf87b6725bf
[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
41       ids = @ids
42       cd = ChiseDB.instance
43       ct = cd.get_by_ids_db("ids")
44       cid = ct.decode(ids)
45       return "" if cid.nil?
46       composed = Character.get(cid).to_s
47       return "" if composed.nil?
48       return "" if composed.char_length == 0
49       return composed if composed.char_length == 1
50       composed.each_char {|ch|
51         char = ch.char
52         #return ch if char.has_attribute?
53         return ch
54       }
55       return ""
56     end
57
58     def aggregate
59       # Take each sub part of String.
60       # If you can aggregate the sub part, aggregate it.
61       #tree = IDS_Tree.new(@ids)
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
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
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   end
85
86   module CharacterIDC
87     def is_idc?
88       0x2ff0 <= @char_id && @char_id <= 0x2fff
89     end
90
91     def idc_argument_number
92       return 0 unless is_idc?
93       return 3 if @char_id == 0x2ff2 || @char_id == 0x2ff3
94       return 2
95     end
96   end
97
98   module CharacterIDS
99     def decompose # by glyph
100       decompose_internal
101     end
102
103     def decompose_by_meaning
104       decompose_internal(true)
105     end
106
107     def decompose_all
108       pde = ""
109       de = self.decompose # the start point.
110       level = 0
111       while true
112         pde = de
113         de = pde.decompose # decompose it again.
114         break if pde == de # previous is same.
115         exit if 10 < level # p ["too many recursive", self] 
116         level += 1
117       end
118       de
119     end
120
121     private
122
123     def decompose_internal(by_meaning=nil)
124       #idss = self.ids
125       #return idss if idss
126       #return k if self.is_basic_kanji?
127       #return ids if idss && 0 < ids.length && k != ids
128
129       k = self.to_s
130       if by_meaning
131         ids = self.ids_represent
132         return ids if ids && 0 < ids.length && k != ids
133         ids = self.ids_element
134         return ids if ids && 0 < ids.length && k != ids
135         ids = self.ids_meaning
136         return ids if ids && 0 < ids.length && k != ids
137       end
138       ids = self.ids_aggregated
139       return ids if ids && 0 < ids.length && k != ids
140       ids = self.ids
141       return ids if ids && 0 < ids.length && k != ids
142       k
143
144       #return k if ids.nil? || ids.length == 0 || k == ids
145       #if ids.char_length == 2
146       #p ["What???", k, ids, k.inspect_all]
147       ##return idsx[1] #二個目だけ返すとか?
148       #return k #IDSに展開する方法が無いと。
149       #end
150       #return k if k == ids
151       #if ids.include?(k) #<C5-4C4D><C6-4A37>この二文字のBUG対策
152       ##return ids.sub(k, "")
153       #return k #IDSに展開する方法が無いと。
154       #end
155       #return ids
156     end
157
158   end
159 end