diff options
Diffstat (limited to 'lib/jcode.rb')
-rw-r--r-- | lib/jcode.rb | 160 |
1 files changed, 58 insertions, 102 deletions
diff --git a/lib/jcode.rb b/lib/jcode.rb index 5b5b80d797..0bd63cf6f2 100644 --- a/lib/jcode.rb +++ b/lib/jcode.rb @@ -1,6 +1,6 @@ # jcode.rb - ruby code to handle japanese (EUC/SJIS) string -$vsave, $VERBOSE = $VERBOSE, false +$vsave, $VERBOSE = $VERBOSE, FALSE class String printf STDERR, "feel free for some warnings:\n" if $VERBOSE @@ -12,9 +12,10 @@ class String private :original_succ def mbchar? - if $KCODE =~ /^s/i + case $KCODE[0] + when ?s, ?S self =~ /[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc]/n - elsif $KCODE =~ /^e/i + when ?e, ?E self =~ /[\xa1-\xfe][\xa1-\xfe]/n else false @@ -22,16 +23,15 @@ class String end def succ - if self[-2] && self[-2] & 0x80 != 0 + if self[-2] and self[-2, 2].mbchar? s = self.dup s[-1] += 1 - s[-1] += 1 if !s.mbchar? + s[-1] += 1 unless s[-2, 2].mbchar? return s else original_succ end end - alias next succ def upto(to) return if self > to @@ -58,12 +58,11 @@ class String return nil end - ExpandChCache = {} + private - def _expand_ch - return ExpandChCache[self] if ExpandChCache.key? self + def _expand_ch str a = [] - self.scan(/(.|\n)-(.|\n)|(.|\n)/) do |r| + str.scan(/(.|\n)-(.|\n)|(.|\n)/) do |r| if $3 a.push $3 elsif $1.length != $2.length @@ -74,36 +73,41 @@ class String $1.upto($2) { |c| a.push c } end end - ExpandChCache[self] = a a end + HashCache = {} + + def expand_ch_hash from, to = "" + key = from.intern.to_s + ":" + to.intern.to_s + return HashCache[key] if HashCache.key? key + afrom = _expand_ch(from) + h = {} + if to.length != 0 + ato = _expand_ch(to) + afrom.each_with_index do |x,i| h[x] = ato[i] || ato[-1] end + else + afrom.each do |x| h[x] = true end + end + HashCache[key] = h + end + + def bsquote(str) + str.gsub(/\\/, '\\\\\\\\') + end + + public + def tr!(from, to) return self.delete!(from) if to.length == 0 - if from =~ /^\^/ - comp=true - from = $' - end - afrom = from._expand_ch - ato = to._expand_ch - i = 0 - if comp - self.gsub!(/(.|\n)/) do |c| - unless afrom.include?(c) - ato[-1] - else - c - end - end + pattern = /[#{bsquote(from)}]/ + if from[0] == ?^ + last = /.$/.match(to)[0] + self.gsub!(pattern, last) else - self.gsub!(/(.|\n)/) do |c| - if i = afrom.index(c) - if i < ato.size then ato[i] else ato[-1] end - else - c - end - end + h = expand_ch_hash(from, to) + self.gsub!(pattern) do |c| h[c] end end end @@ -112,22 +116,8 @@ class String end def delete!(del) - if del =~ /^\^/ - comp=true - del = $' - end - adel = del._expand_ch - if comp - self.gsub!(/(.|\n)/) do |c| - next unless adel.include?(c) - c - end - else - self.gsub!(/(.|\n)/) do |c| - next if adel.include?(c) - c - end - end + pattern = /[#{bsquote(del)}]+/ + self.gsub!(pattern, '') end def delete(del) @@ -135,27 +125,13 @@ class String end def squeeze!(del=nil) - if del - if del =~ /^\^/ - comp=true - del = $' - end - adel = del._expand_ch - if comp - self.gsub!(/(.|\n)\1+/) do - next unless adel.include?($1) - $& - end + pattern = + if del + /([#{bsquote(del)}])\1+/ else - for c in adel - cq = Regexp.quote(c) - self.gsub!(/#{cq}(#{cq})+/, cq) - end + /(.|\n)\1+/ end - self - else - self.gsub!(/(.|\n)\1+/, '\1') - end + self.gsub!(pattern, '\1') end def squeeze(del=nil) @@ -164,33 +140,14 @@ class String def tr_s!(from, to) return self.delete!(from) if to.length == 0 - if from =~ /^\^/ - comp=true - from = $' - end - afrom = from._expand_ch - ato = to._expand_ch - i = 0 - c = nil - last = nil - self.gsub!(/(.|\n)/) do |c| - if comp - unless afrom.include?(c) - c = ato[-1] - next if c == last - last = c - else - last = nil - c - end - elsif i = afrom.index(c) - c = if i < ato.size then ato[i] else ato[-1] end - next if c == last - last = c - else - last = nil - c - end + + pattern = /([#{bsquote(from)}])\1+/ + if from[0] == ?^ + last = /.$/.match(to)[0] + self.gsub!(pattern, last) + else + h = expand_ch_hash(from, to) + self.gsub!(pattern) do h[$1] end end end @@ -198,18 +155,17 @@ class String (str = self.dup).tr_s!(from,to) or str end - alias original_chop! chop! - private :original_chop! - def chop! - if self =~ /(.)$/ and $1.size == 2 - original_chop! - end - original_chop! + self.gsub!(/(?:.|\n)\z/, '') end def chop (str = self.dup).chop! or str end + + def jcount(str) + self.delete("^#{str}").jlength + end + end $VERBOSE = $vsave |