i
[chise/ruby.git] / chise / string.rb
1 # Copyright (C) 2002-2004 Kouichirou Eto, All rights reserved.
2
3 class String
4   def to_a()
5     ar = self.split(//u) # split self to chars as UTF-8
6     ar
7   end
8
9   def each_char() to_a.each {|ch| yield ch } end
10   def each_character() to_a.each {|ch| yield ch.char } end
11   def char_length() to_a.length end
12   def char_at(n) to_a()[n] end
13   def first_char() to_a[0] end
14   def char() CHISE::Character.get(to_a[0]) end
15   def to_utf8()
16     return to_a.map {|ch|
17       ch.char.to_utf8
18     }.join("")
19   end
20
21   def map_char(block = Proc.new)
22     return unless block_given?
23     return self.to_a.map {|ch| (block.call(ch)).to_s }.join("")
24   end
25
26   def map_char!(block = Proc.new)
27     return unless block_given?
28     self.replace(self.map_char {|ch| block.call(ch)})
29   end
30
31   def map_character(block = Proc.new)
32     return unless block_given?
33     return self.to_a.map {|ch| (block.call(ch.char)).to_s }.join("")
34   end
35
36   def map_character!(block = Proc.new)
37     return unless block_given?
38     self.replace(self.map_char {|ch| block.call(ch.char)})
39   end
40
41   def method_missing(mid, *args)
42     if char_length == 1 #\8fÈ\97ª\8c`\82ª\97L\8cø\82È\82Ì\82Í\81A\88ê\95\8e\9a\82Ì\8e\9e\82¾\82¯
43       char.method_missing(mid, *args)
44     else
45       raise NameError, "undefined method `#{mid.id2name}'", caller(1)
46     end
47   end
48
49   def map_utf8() map_char {|ch| ch.char.map_utf8 } end
50   alias map_ucs map_utf8
51
52   def map_ucs_er() map_char {|ch| ch.char.map_ucs_er } end
53   def to_er() map_char {|ch| ch.char.to_er } end
54
55   #put\8aÖ\8cW\81A[]\8aÖ\8cW\82Í\97p\88Ó\82µ\82È\82¢\82±\82Æ\82É\82µ\82½\81B
56   def de_er!() #EntityReference\82ð\8eæ\82è\8f\9c\82­
57     return self unless self =~ Regexp.new(EntityReference::REGEXP_PART) #\82»\82ê\82ç\82µ\82¢\82Ì\82ª\96³\82¯\82ê\82Î\89½\82à\82µ\82È\82¢
58     er = "&"+$1+";"      
59     self.sub!(Regexp.new(Regexp.escape(er)), Character.new(er).mcs_utf8) #\95Ï\8a·\8e©\91Ì\82ÍCharacter\82É\82Ü\82©\82¹\82é
60     return self.de_er! if self =~ Regexp.new(EntityReference::REGEXP_PART) #\82Ü\82¾\82 \82Á\82½\82ç\8dÄ\8bA
61     return self
62   end
63
64   def de_er() return self.dup.de_er!; end
65
66   def inspect_all() map_char {|ch| ch.char.inspect_all } end
67   def inspect_x()   map_char {|ch| ch.char.inspect_x   } end
68
69 #  def to_euc()   map_char {|ch| ch.char.to_euc   } end
70   def map_euc()  map_char {|ch| ch.char.map_euc  } end
71 #  def to_sjis()  map_char {|ch| ch.char.to_sjis  } end
72   def map_sjis() map_char {|ch| ch.char.map_sjis } end
73
74   def glyph_decompose() map_char {|ch| ch.char.glyph_decompose } end
75   def decompose() map_char {|ch| ch.char.decompose } end
76   def decompose!() self.replace(self.decompose); self; end
77
78   def nu_decompose_all(level=nil)
79     level = 0 if level.nil?
80     if 10 < level
81       p ["too many recursive", self] 
82       exit
83     end
84     de = self.decompose
85     return de.decompose_all(level+1) if de != self #\82È\82É\82©\95Ï\89»\82ª\82 \82Á\82½\82©\82ç\8dÄ\8bA
86     de #\82à\82¤\82±\82ê\88È\8fã\95Ï\89»\82Í\96³\82³\82»\82¤\82¾\82¼\82Æ\81B
87   end
88
89   def decompose_all() map_char {|ch| ch.char.decompose_all } end
90   def decompose_all!() self.replace(self.decompose_all); self; end
91
92   def find() #"\93ú\89_"\81¨"\93Ü"\82Æ\82©\82¢\82¤\8a´\82\82Ì\91\80\8dì
93     ar = []
94     length = char_length()
95     each_char {|ch|
96       char = ch.char
97       ar << char.ids_contained #\82»\82Ì\95\8e\9a\82ð\8aÜ\82ñ\82Å\82¢\82é\8a¿\8e\9a\82Ì\83\8a\83X\83g
98     }
99     h = Hash.new(0)
100     ar.each {|list|
101       next if list.nil?
102       list.each_char {|ch|
103         h[ch] += 1
104       }
105     }
106     str = ""
107     h.each {|k, v|
108       #      p [k, v]
109       if length == v #\91S\95\94\82É\8aç\82ð\8fo\82µ\82Ä\82¢\82½\82ç
110         str += k
111       end
112     }
113     #    p str
114     str
115   end
116
117   def compose()
118     db = CHISE::CodesysDB.instance
119     composed = db.get("ids", self)
120     return "" if composed.nil? #\82È\82©\82Á\82½\82æ\82Æ\81B
121     return "" if composed.char_length == 0 #\82È\82É\82²\82Æ?
122     return composed if composed.char_length == 1
123     composed.each_char {|ch|
124       char = ch.char
125       return ch if char.has_attribute? #\82Æ\82è\82 \82¦\82¸\8dÅ\8f\89\82É\82Ý\82Â\82©\82Á\82½\82à\82Ì\82ð\95Ô\82·\82Æ\82¢\82¤\83k\83\8b\82¢\8ed\97l
126     }
127     return "" #attribute\82ð\8e\9d\82Â\82à\82Ì\82ª\88ê\82Â\82à\96³\82©\82Á\82½\82ç\81A""\82É\82·\82é
128   end
129
130   def aggregate()
131     #self\82Å\82 \82é\95\8e\9a\97ñ\82ðIDS\82¾\82Æ\89¼\92è\82µ\81A\82»\82ê\82ð\8a®\91S\82Écompose\82µ\82«\82ç\82È\82¢\82Å\81A
132     #\82»\82Ì\95\94\95ª\8fW\8d\87\82¾\82¯\82ð\82Æ\82è\82¾\82µ\82Ä\81Acompose\89Â\94\\82Å\82 \82ê\82Î\82Å\82«\82é\82¾\82¯compose\82·\82é\81B
133     tree = CHISE::IDS_Tree.new(self)
134     return self if tree.depth <= 1 #sub_nodes\82ª\96³\82¢\8fê\8d\87\82Í\82±\82±\82Å\82³\82æ\82È\82ç
135     tree.sub_nodes.each {|node|
136       c = node.compose
137       next if c.nil? || c == ""
138       #      print "#{self}     #{node} #{c}\n"
139       #      p [self, node, c]
140       n = self.gsub(node, c)
141       return n.aggregate
142     }
143     return self #\82¨\82«\82©\82¦\82ç\82ê\82é\82à\82Ì\82ª\82Ü\82Á\82½\82­\82È\82©\82Á\82½\82ç\81A\8e©\95ª\82ð\82©\82¦\82·\81B
144   end
145
146 end