split chise.rb to db.rb and ids.rb
authoreto <eto>
Tue, 18 Mar 2003 06:21:39 +0000 (06:21 +0000)
committereto <eto>
Tue, 18 Mar 2003 06:21:39 +0000 (06:21 +0000)
src/chise.rb
src/kage.rb
src/kageserver.rb
src/kanjilist.rb
src/stroke.rb
t/tc_char.rb

index d81a9d5..35191da 100755 (executable)
@@ -4,6 +4,9 @@
 require 'bdb'
 require 'uconv'
 require 'singleton'
+require 'rbchise'
+require 'db'
+require 'ids'
 
 $KCODE = 'u' #今のところこれ以外では動かない。String.splitが影響大。inspectも影響。
 $debug = false #これはテスト用
@@ -19,8 +22,8 @@ class String #==================================================================
   def char_at(n) to_a()[n] end
   def char() Character.get(to_a[0]) end
   #alias to_c char #悩み中
-  def char_id() char.char_id() end
-  def get_char_attribute(a) char.get_char_attribute(a) end
+  #def char_id() char.char_id() end #なんとなく廃止
+  #def get_char_attribute(a) char.get_char_attribute(a) end #なんとなく廃止
   #def ucs() char.ucs() end
   def to_utf8()
     return to_a.map {|ch|
@@ -151,8 +154,10 @@ module CHISE #==================================================================
   module_function :windows?
   if windows?()
     DB_DIR = 'd:/work/chise/char-db' #この後に/sysmtem-char-id/ucsという感じに続く
+    IDS_DB_DIR = 'd:/work/chise/ids/' #この後にIDS-JIS-X0208-1990.txtという感じに続く
   else
     DB_DIR = '/usr/local/lib/xemacs-21.4.10/i686-pc-linux/char-db' #この後に/sysmtem-char-id/ucsという感じに続く
+    IDS_DB_DIR = '/home/eto/work/chise/ids/' #この後にIDS-JIS-X0208-1990.txtという感じに続く
   end
 
   class EntityReference #======================================================================
@@ -256,11 +261,6 @@ module CHISE #==================================================================
   end
 
   class Character #=============================================================== 文字オブジェクト
-    BASIC_KANJI = "人子女母父王口耳手足力目首毛心犬牛鳥貝角羽虫馬魚羊肉皮米竹木麦豆山川雨風水土石金田穴日月火音糸刀舟門戸衣矢弓車皿一二三四五六七八九十百千万寸尺上中下本玉立回食行止交向歩考入示走生出来書言大小白青多少高長"
-    def is_basic_kanji?
-      BASIC_KANJI.include?(self.to_s)
-    end
-
     def initialize(char_id=nil)
       @char_id = Character.parse_char_id(char_id)
       @attributes = Hash.new
@@ -478,6 +478,11 @@ module CHISE #==================================================================
       alist.to_a.sort.each {|a, v| ar << "#{a}:#{v}" }
       return ar.join(',')+">"
     end
+    def dump_all()
+      ar = [inspect]
+      alist.to_a.sort.each {|a, v| ar << "#{a}:#{v}" }
+      return ar.join('\n')+'\n'
+    end
     def get_attributes()
       str = ""
       alist.to_a.sort.each {|a, v|
@@ -569,875 +574,6 @@ module CHISE #==================================================================
     end
   end
 
-  class DBS #======================================================================複数のDBを集めたclass、未完成
-  end
-
-  class ADB < BDB::Hash #======================================================================一つのDB
-    def initialize(*args)
-      super
-      @modified = false
-      at_exit {
-       if @modified
-         self.close #これがないと、うまくデータベースがセーブされないのです。
-       end
-      }
-    end
-    def self.open_create(filename)
-      ADB.open(filename, nil, BDB::CREATE | BDB::EXCL) #上書きはしない
-    end
-    def mykey(key)
-      if key.is_a?(String)
-       if key.char_length == 1
-         return '?'+key  #Stringだったら引く前に?を足す
-       end
-      end
-      #key = key.to_s if key.is_a?(Numeric) #NumberだったらStringにする。
-      #ここで && key ! =~ /^\?/ をいれると、?自身を検索できなくなってしまう。
-      return key
-    end
-    def myvalue(v)
-      return v if v == nil
-      return v.to_i if v =~ /^\d+$/ #数字だったらここで変換しておく
-      return v.sub(/^\?/, '') if v =~ /^\?/ #冒頭の?は取り除く
-      return $1 if v =~ /^"(.+)"$/ #最初と最後に"がついていたら、取り除く
-      #p ['get', v, t, key, db]
-      #return parse_sexp(v) if v =~ /^\(.+\)$/ #最初と最後が()の時は、S式にparseする
-      return v #それ以外って何?
-    end
-    def myget(key) #keyキーを引いて返す
-      key = mykey(key)
-      v = get(key) #存在しなかったらnilを返すことになる
-      return myvalue(v)
-    end
-    def myput(key, v) #keyにvをいれる
-      key = mykey(key)
-      put(key, v) #putする
-      @modified = true
-    end
-  end
-
-  class DB #======================================================= データベース群のabstract class
-    def self.unix_to_win(unix) #Windowsファイル名制限のため、変換する
-      win = unix.gsub(/</, '(')
-      win.gsub!(/>/, ')')
-      win.gsub!(/\*/, '+')
-      win.gsub!(/\?/, '!')
-      return win
-    end
-    def self.win_to_unix(win)
-      unix = win.gsub(%r|\)|, '>')
-      unix.gsub!(%r|\(|, '<')
-      unix.gsub!(%r|!|, '?')
-      unix.gsub!(%r|\+|, '*')
-      return unix
-    end
-    def get_filename(t)
-      return @pre + DB.unix_to_win(t) + @post if windows?
-      return @pre + t + @post
-    end
-    def get_dirname(t) File.dirname(get_filename(t)) end
-    def open_dbs()
-      @dbs = Hash.new
-      keys = find_keys()
-      keys.each {|key| open_db(key) }
-    end
-    def find_keys()
-      files = []
-      Dir.glob(@glob){|f|
-       next if ! File.file?(f)
-       next if f =~ /.txt$/
-       files << f
-      }
-      keys = []
-      files.each {|f|
-       t = DB.win_to_unix(f)
-       t.sub!(%r|^#{@pre}|, '')
-       t.sub!(%r|#{@post}$|, '') if @post != ""
-       keys << t
-      }
-      return keys
-    end
-    def close_db(t)
-      db = get(t)
-      return nil if db.nil?
-      db.close
-      @dbs.delete(t)
-    end
-    def open_db(t)
-      return nil if get(t) #すでにopenしていたら再openはしない。
-      begin
-       bdb = ADB.open(get_filename(t), nil, 0)
-       @dbs[t] = bdb if bdb != nil
-      rescue
-       p ["open error", get_filename(t)]; return nil
-      end
-      return true
-    end
-    def make_db(t, h=nil) #tという名前でhという中身のデータベースを作る
-      return nil if get(t) #すでにある場合はreturn
-      Dir.mkdir(get_dirname(t)) unless FileTest.exist?(get_dirname(t))
-      db = nil
-      begin
-       db = ADB.open_create(get_filename(t)) #上書きはしない
-       if h != nil
-         h.each {|k, v|
-           k = '?'+k if k.is_a?(String)
-           db[k] = v
-         }
-       end
-       db.close
-      rescue
-       p ["make error", get_filename(t)]; return nil
-      end
-      return true
-    end
-    def make_db_no_question_mark(t, h=nil) #tという名前でhという中身のデータベースを作る
-      return nil if get(t) #すでにある場合はreturn
-      Dir.mkdir(get_dirname(t)) unless FileTest.exist?(get_dirname(t))
-      db = nil
-      begin
-       db = ADB.open_create(get_filename(t)) #上書きはしない
-       if h != nil
-         h.each {|k, v|
-           #        k = '?'+k if k.is_a?(String)
-           db[k] = v
-         }
-       end
-       db.close
-      rescue
-       p ["make error", get_filename(t)]; return nil
-      end
-      return true
-    end
-    def remove_db(t) #tという名前のデータベースを消去する
-      db = get(t)
-      if db
-       db.close
-       @dbs.delete(t)
-      end
-      begin
-       File.unlink(get_filename(t)) if FileTest.file?(get_filename(t))
-      rescue
-       p ["unlink error", get_filename(t)]; return nil
-      end
-      dn = get_dirname(t)
-      Dir.rmdir(dn) if FileTest.directory?(dn) && Dir.entries(dn).length <= 2 #空directoryだったら消す
-      return true
-    end
-    def to_num(s)
-      return s.to_i if s =~ /^\d+$/
-      return s
-    end
-    def dump_db(t)
-      db = get(t)
-      return nil unless db
-      file = get_filename(t)
-      open("#{file}.txt", "w"){|out|
-       #        out.binmode.sync = true
-       ar = db.to_a
-       ar.map! {|k, v| [to_num(k), to_num(v)] }
-       ar.sort.each {|k, v|
-         out.printf("%s\t%s\n", k, v)
-       }
-      }
-      return true
-    end
-    def each_db()  @dbs.to_a.sort.each {|t, db| yield(t, db) } end
-    def dump_all()  each_db {|t, db| dump_db(t) } end
-    def close_all() each_db {|t, db| db.close   } end
-    def keys() @dbs.keys end
-    def each(t)
-      return unless block_given?
-      db = @dbs[t]
-      return nil unless db
-      db.each {|k, v|
-       k = to_num(k)
-       v = to_num(v)
-       k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
-       vv = get(t, k)  #p ['each', t, k, v, vv]
-       yield(k, vv)
-      }
-    end
-    def each_sort(t)
-      return unless block_given?
-      db = @dbs[t]
-      return nil unless db
-      ar = db.to_a
-      ar.map! {|k, v| [to_num(k), to_num(v)] }
-      ar.sort.each {|k, v|
-       k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
-       vv = get(t, k)  #p ['each', t, k, v, vv]
-       yield(k, vv)
-      }
-    end
-    #----------------------------------------------------------------------
-    def get(t, key=nil) #tというデータベースのkeyキーを引いて返す
-      db = @dbs[t]
-      return db if key.nil?
-      return nil unless db
-      return db.myget(key)
-    end
-    def put(t, key, v) #tというデータベースのkeyにvをいれる
-      db = @dbs[t]
-      if db == nil
-       db = make_db(t) 
-       db = open_db(t) 
-       db = @dbs[t]
-      end
-      db.myput(key, v) #putする
-    end
-  end
-
-  class CharDB < DB #------------------------------------ MCS-UTF8をキーとした属性へのデータベース
-    include Singleton
-    def initialize()
-      super
-      @glob, @pre, @post = "#{DB_DIR}/system-char-id/*", "#{DB_DIR}/system-char-id/", ""
-      open_dbs()
-    end
-    def get_all(u8) #全データベースのu8キーを引いてHashにまとめて返す
-      atrs = Hash.new
-      @dbs.each {|t, db|
-       v = get(t, u8)
-       atrs[t] = v if v != nil
-      }
-      return atrs
-    end
-  end
-
-  class CodesysDB < DB #----------------------------------------------------------------------
-    include Singleton
-    def initialize()
-      super
-      @glob, @pre, @post = "#{DB_DIR}/*/system-char-id", "#{DB_DIR}/", "/system-char-id"
-      open_dbs()
-    end
-    #def keys() @dbs.keys.sort end #どんなCodesysの情報を持っているかの一覧
-    def keys() @dbs.keys end #どんなCodesysの情報を持っているかの一覧
-    def get_codesys(t)
-      db = get(t)
-      return nil unless db
-      return Codesys.new(t)
-    end
-  end
-
-  class Codesys < DB #======================================================================
-    def initialize(name)
-      #       super
-      @name = name
-      @dbs = CodesysDB.instance
-    end
-    def keys() #どんなコードポイントの情報を持っているかの一覧
-      ks = @dbs.get(@name).keys
-      if @name =~ /jisx0208/ #特別処理
-       n = @dbs.get('=jis-x0208').keys 
-       #        p ['keys', @name, ks, n]
-       ks += n
-      end
-      ks.map! {|k| to_num(k) }
-      ks
-    end
-    def get(key)
-      v = @dbs.get(@name, key)
-      return v if v
-      if @name =~ /jisx0208/ #jisx0208が含まれている場合だけ特別処理する
-       return @dbs.get('=jis-x0208', key)
-      end
-      return nil
-    end
-    def each()
-      return unless block_given?
-      db = @dbs.get(@name)
-      return nil unless db
-      db.each {|k, v|
-       k = to_num(k)
-       v = to_num(v)
-       k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
-       vv = @dbs.get(@name, k) #p ['each', t, k, v, vv]
-       yield(k, vv)
-      }
-    end
-    def each_sort()
-      return unless block_given?
-      db = @dbs.get(@name)
-      return nil unless db
-      ar = db.to_a
-      ar.map! {|k, v| [to_num(k), to_num(v)] }
-      ar.sort.each {|k, v|
-       k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
-       vv = @dbs.get(@name, k) #p ['each', t, k, v, vv]
-       yield(k, vv)
-      }
-    end
-  end
-
-  class JISX0208
-    def initialize
-      db = CodesysDB.instance
-      @common = db.get_codesys('=jis-x0208')
-      @newest = db.get_codesys('japanese-jisx0208-1990')
-    end
-    def get_char(code)
-      char = @common.get(code)
-      return char unless char.nil?
-      char = @newest.get(code)
-      return char unless char.nil?
-      return nil
-    end
-  end
-
-  class IDS_TEXT_DB < DB #======================================================================
-    include Singleton
-    if CHISE.windows?()
-      IDS_DB_DIR = 'd:/work/chise/ids/' #この後にIDS-JIS-X0208-1990.txtという感じに続く
-    else
-      IDS_DB_DIR = '/home/eto/work/chise/ids/' #この後にIDS-JIS-X0208-1990.txtという感じに続く
-    end
-    IDS_LIST = "
-IDS-UCS-Basic.txt
-#IDS-UCS-Compat-Supplement.txt
-#IDS-UCS-Compat.txt
-IDS-UCS-Ext-A.txt
-IDS-UCS-Ext-B-1.txt
-IDS-UCS-Ext-B-2.txt
-IDS-UCS-Ext-B-3.txt
-IDS-UCS-Ext-B-4.txt
-IDS-UCS-Ext-B-5.txt
-IDS-UCS-Ext-B-6.txt
-IDS-JIS-X0208-1990.txt
-IDS-Daikanwa-01.txt
-IDS-Daikanwa-02.txt
-IDS-Daikanwa-03.txt
-IDS-Daikanwa-04.txt
-IDS-Daikanwa-05.txt
-IDS-Daikanwa-06.txt
-IDS-Daikanwa-07.txt
-IDS-Daikanwa-08.txt
-IDS-Daikanwa-09.txt
-IDS-Daikanwa-10.txt
-IDS-Daikanwa-11.txt
-IDS-Daikanwa-12.txt
-IDS-Daikanwa-dx.txt
-IDS-Daikanwa-ho.txt
-IDS-CBETA.txt
-".split
-    def initialize()
-      super
-      @ids_list = IDS_LIST
-      @chars = []
-      @glob, @pre, @post = "#{IDS_DB_DIR}/db/*", "#{IDS_DB_DIR}/db/", ""
-      dir = File.dirname(@pre)
-      Dir.mkdir(dir) unless FileTest.exist?(dir)
-      open_dbs()
-    end
-    def each_file()
-      return unless block_given?
-      @ids_list.each {|file|
-       next if file =~ /^#/
-       yield(IDS_DB_DIR+file)
-      }
-    end
-    def each_line(file)
-      open(file){|f|
-       while line = f.gets
-         next if line =~ /^;/ #コメントはとばす
-         line.chomp!
-         code, char, ids = line.split
-         yield(code, char, ids)
-       end
-      }
-    end
-    def dump_text_all
-      each_file {|file|
-       dir = File.dirname(file) + '/../ids-new/'
-       Dir.mkdir(dir) if ! FileTest.directory?(dir)
-       newfile = dir + File.basename(file)
-       p [file, newfile]
-       open(newfile, "w"){|out|
-         out.binmode.sync = true
-         each_line(file){|code, ch, ids|
-           char = Character.get(ch)
-           ids = char.decompose
-           out.print "#{code}  #{ch}   #{ids}\n"
-         }
-       }
-      }
-    end
-    def make_ids_error
-      each_file {|file|
-       dir = File.dirname(file) + '/../ids-error'
-       Dir.mkdir(dir) unless FileTest.exist?(dir)
-       errfile = dir + '/' + File.basename(file)
-       #       p [file, errfile]
-       open(errfile, "w"){|out|
-         out.binmode.sync = true
-         each_line(file){|code, ch, ids|
-           char = Character.get(ch)
-           ids_error = char['ids-error']
-           next if ids_error.nil?
-           out.print "#{code}  #{ch}   #{ids}  #{ids_error}\n"
-         }
-       }
-      }
-    end
-  end
-
-  class IDS_DB < DB #======================================================================BDB化したIDS DBを扱う
-    include Singleton
-    def initialize
-      @dbs = CharDB.instance
-    end
-    def make_ids_db
-      db = IDS_TEXT_DB.instance
-      db.each_file {|file|
-       @char_counter = 0
-       @same_ids_counter = 0
-       @good_ids_counter = 0
-       @conflict_ids_counter = 0
-       db.each_line(file){|code, ch, ids|
-         @char_counter += 1
-
-         ids = "" if ids == nil
-         next if ids == "" #IDSが定義されていない場合は、さっくりと無視するべしよ。
-
-         charimg = Character.get(ch) #実体参照である可能性がある
-
-         next if code =~ /'$/ || code =~ /"$/ #大漢和番号のダッシュ付きは無視する
-         char = Character.get("&"+code+";") #code表記を元に実体参照を作って解釈する
-         if char.nil? || char.to_s == "" #うまく文字にならなかった
-           print "char == null #{char.inspect} #{code} #{ch}   #{ids}\n" unless code =~ /^M-/ || code =~ /^CB/
-           #大漢和、CBETA以外の場合は、エラーメッセージ。
-           next
-         end
-         if char != charimg #code表記と文字が一致していない?
-           unless code =~ /^M-/ || code =~ /^MH-/ || code =~ /^CB/ #食い違っていて当然であるので何もしない
-             print "unknown char       #{char.inspect} #{code} #{ch}   #{ids}\n"
-             next #それ以外の場合はエラーメッセージをだして、次へ。
-           end
-         end
-         #next if !char.has_attribute? #isolated characterはまぎれこませない。
-
-         ids.de_er! #実体参照を解除する
-         next if ids == char.to_s #もし文字とまったく一緒なら、意味が無いので情報を持たない
-         next if ids.char_length == 1
-
-         idstree = IDS_Tree.new(ids)
-         c = idstree.check_integrity
-         c = "contains self" if ids.include?(char.to_s)
-         if c #ちょっとでもエラーがある場合は、
-           char['ids-error'] = c #エラーを記録して、データとしては保持しない
-           next
-         end
-
-         if char['ids'].nil? || char['ids'] == "" #元々IDSが無かった場合は、
-           char['ids'] = ids #普通に代入すればそれでいいです。
-           @good_ids_counter += 1
-         else #しかしいままでにすでにIDSが定義されていた場合は?
-           if char['ids'] == ids #新しいIDSと古いIDSが完全に一致するなら無視しましょう。
-             @same_ids_counter += 1
-           else #しかしいままでのIDSと新しいIDSが食い違った場合は?
-             @conflict_ids_counter += 1
-             #       print "conflict   #{char.inspect} #{code} #{ids}  #{char['ids']}\n"
-           end
-         end
-       }
-       print "#{file}  #{@char_counter}        #{@same_ids_counter}    #{@conflict_ids_counter}        #{@good_ids_counter}\n"
-       CharacterFactory.instance.reset()
-      }
-      @dbs.dump_db('ids-error') #テキスト化する
-      @dbs.dump_db('ids') #テキスト化する
-    end
-    def make_ids_reverse
-      h = Hash.new
-      @dbs.each('ids') {|k, v|
-       char = k.char
-       ids = char.decompose
-       h[ids] = "" if h[ids].nil?
-       h[ids] += k #追加する
-      }
-      h.each {|k, v|
-       h[k] = char_sort(v) #文字の順番を、よく使うっぽいものからの順番にする
-      }
-      h.delete_if {|k, v| #h[k]が""になる可能性もあるが、それはkeyとして入れないことにする。
-       v == ""
-      }
-      print "length    #{h.length}\n"
-      cdb = CodesysDB.instance
-      cdb.make_db_no_question_mark('ids', h)
-      cdb.open_db('ids') #これが無いと、dump_dbされません。
-      cdb.dump_db('ids')
-    end
-    def char_sort(composed)
-      return composed if composed.char_length == 1
-      ar = composed.to_a
-      arorg = ar.dup
-      ar2 = []
-      ar.dup.each {|ch|
-       char = ch.char
-       if char.char_id < 0xfffff #Unicodeっぽい?
-         ar2 << ch
-         ar.delete(ch)
-       end
-      }
-      if 0 < ar.length
-       EntityReference.each_codesys{|codesys, er_prefix, keta, numtype|
-         ar.each {|ch|
-           char = ch.char
-           v = char[codesys]
-           #       p [codesys, v] if v
-           if v #EntityReferenceの順番に準拠する。
-             ar2 << ch
-             ar.delete(ch)
-           end
-         }
-       }
-      end
-      if 0 < ar.length
-       #       p ['yokuwakaran character', ar, ar[0].inspect_all, arorg]
-       EntityReference.each_codesys{|codesys, er_prefix, keta, numtype|
-         ar.dup.each {|ch|
-           char = ch.char
-           v = char[codesys]
-           #       p [codesys, v] if v
-         }
-       }
-      end
-      return ar2.join("")
-    end
-    def dump_ids_duplicated
-      open('ids-duplicated.txt', 'w'){|out|
-       #out.binmode
-       CodesysDB.instance.each('ids') {|k, v|
-         if v.nil?
-           out.print "nil      #{k}    #{v}\n"
-           next
-         end
-         n = v.char_length
-         next if n == 1
-         out.print "#{n}       #{k}    #{v}"
-         v.each_char {|ch|
-           char = ch.char
-           out.print " #{char.inspect}"
-         }
-         out.print "\n"
-       }
-      }
-    end
-    def make_ids_aggregated
-      @dbs.each('ids') {|k, v|
-       char = k.char
-       ids = char.decompose
-       ag = ids.aggregate
-       char['ids-aggregated'] = ag
-      }
-      @dbs.dump_db('ids-aggregated')
-    end
-    def dump_ids_aggregated
-      open('ids-aggregated.txt', 'w'){|out|
-       #out.binmode
-       @dbs.each('ids') {|k, v|
-         char = k.char
-         ids = char['ids']
-         ag  = char['ids-aggregated']
-         out.print "#{char.to_s}       #{ag}   #{ids}\n" if ids != ag
-       }
-      }
-    end
-    def make_ids_parts
-      @dbs.each('ids') {|k, v|
-       char = k.char
-       pids = char.to_s
-       ar = []
-       counter = 0
-       loop {
-         ids = pids.decompose
-         break if ids == pids #これ以上分割できないようだったら終了〜。
-         ar += ids.to_a
-         counter += 1
-         p [char.to_s, pids, ids, ar] if 10 < counter #これは何かおかしいぞと
-         pids = ids
-       }
-       ar.sort!
-       ar.uniq!
-       #やっぱりIDS文字も加えることにする. by eto 2003-02-05
-       #       ar.delete_if {|ch|
-       #         ch.char.is_ids? #IDS文字はまぎれこませない。
-       #       }
-       str = ar.join('')
-       char['ids-parts'] = str
-      }
-      @dbs.dump_db('ids-parts')
-    end
-    def make_ids_contained
-      h = Hash.new
-      @dbs.each('ids-parts') {|k, v|
-       char = k.char
-       parts = char.ids_parts
-       parts.each_char {|ch|
-         #       part = ch.char
-         h[ch] = [] if h[ch].nil?
-         h[ch] << k
-         #       h[ch] += k
-         #       part['ids-contained'] = "" if part['ids-contained'].nil?
-         #       part['ids-contained'] += k
-       }
-      }
-      h.each {|k, v|
-       char = k.char
-       v.sort!
-       char['ids-contained'] = v.join('')
-       
-      }
-      @dbs.dump_db('ids-contained')
-    end
-    def make_ids_decomposed
-      @dbs.each('ids') {|k, v|
-       char = k.char
-       de= char.decompose_all
-       char['ids-decomposed'] = de
-      }
-      @dbs.dump_db('ids-decomposed')
-    end
-  end
-
-  class Node < Array #=======================================================木構造の中の一つの枝
-    def initialize(nodeleaf=nil, nodenum=nil)
-      super()
-      @nodeleaf = nodeleaf
-      @nodenum = nodenum
-      if @nodeleaf
-       original_add(@nodeleaf)
-      end
-    end
-    attr_reader :nodenum
-    alias original_add <<
-      private :original_add
-    def <<(obj)
-      original_add(obj)
-      @nodenum -= 1 if @nodenum
-    end
-    def nodes
-      ar = []
-      ar << self.to_s
-      self.each {|n|
-       ar += n.nodes if n.is_a? Node
-      }
-      return ar
-    end
-  end
-
-  class Tree #======================================================================木構造を扱う
-    def initialize()
-      @root = Node.new()
-      @stack = [@root]
-      @leafnum = 0
-      @depth = 1 #stackの深さが最大になったところの値、木構造が無いときは1となる
-    end
-    def depth() @depth - 1 end
-    def add_node(nodeleaf=nil, nodenum=nil) #枝を追加
-      new_node = Node.new(nodeleaf, nodenum)
-      @stack.last << new_node
-      @stack << new_node
-      if @depth < @stack.length
-       @depth = @stack.length
-      end
-      self
-    end
-    def end_node() #この枝は終り
-      @stack.pop
-      self
-    end
-    def add_leaf(a) #葉を追加
-      @stack.last << a
-      end_check()
-      self
-    end
-    def end_check()
-      n = @stack.last.nodenum
-      if n && n == 0
-       end_node()
-       end_check() #再帰
-      end
-    end
-    def check_integrity
-      n = @stack.last.nodenum
-      return nil if @root.length == 0 #no tree is good tree
-      return "unmatch leaves" if n && n != 0
-      return "extra nodes" if @root.first.is_a?(Node) && @root.length != 1
-      return "extra leaves" if @root.length != 1
-      return nil
-    end
-    def nodes
-      r = @root.nodes
-      r.shift
-      r
-    end
-    def sub_nodes
-      r = nodes
-      r.shift
-      r
-    end
-    def to_s()    @root.to_s    end
-    def inspect() @root.inspect end
-  end
-
-  class IDS_Tree < Tree #======================================================================
-    def initialize(str)
-      @str = str
-      super()
-      parse()
-    end
-    def parse()
-      @str.each_char {|ch|
-       char = Character.new(ch)
-       if is_ids?(char)
-         add_node(char, ids_operator_argc(char))
-       else
-         add_leaf(char)
-       end
-      }
-    end
-    def is_ids?(obj)
-      return true if "+*".include?(obj.to_s) #テスト用ですかね
-      return true if obj.is_ids?
-      return false
-    end
-    def ids_operator_argc(obj)
-      return obj.ids_operator_argc if 0 < obj.ids_operator_argc
-      return 2 #テスト用ってことで
-    end
-    def check_integrity
-      r = super
-      return r if r #不完全がすでにわかっているならreturn
-      return "contains ques" if @str =~ /\?/ #?が含まれている?
-      return nil
-    end
-
-  end
-
-  class IDS #======================================================================IDSそのものを扱うclass
-    def initialize(str) #IDS文字列をうけとる。
-      @str = str
-    end
-    def parse
-    end
-    def parse_x #柔軟型のParse. IDSキャラクターが前にきてなくてもよい。などなど。
-    end
-  end
-
-  class Counter #======================================================================
-    #使い方
-    #counter = Counter.new(50) { exit }
-    #counter.count
-    def initialize(max)
-      @max = max
-      @count = 0
-      @proc = proc
-    end
-    def count
-      @count += 1
-      if @max <= @count
-       @proc.call
-      end
-    end
-  end
-
-  class DBS_Management #======================================================================ファイル管理
-    OBSOLETE_ATTRIBUTES = "
-cns-radical
-cns-radical?
-kangxi-radical
-daikanwa-radical
-unicode-radical
-
-cns-strokes
-kangxi-strokes
-daikanwa-strokes
-shinjigen-1-radical
-gb-original-radical
-japanese-strokes
-jis-strokes-a
-jis-strokes-b
-jisx0208-strokes
-jis-x0213-strokes
-jisx0213-strokes
-unicode-strokes
-
-totalstrokes
-cns-total-strokes
-jis-total-strokes-b
-
-non-morohashi
-
-=>ucs*
-#=>mojikyo
-#=mojikyo
-->identical
-
-ancient-ideograph-of
-ancient-char-of-shinjigen-1
-original-ideograph-of
-original-char-of-shinjigen-1
-simplified-ideograph-of
-vulgar-ideograph-of
-vulgar-char-of-shinjigen-1
-ideograph=
-ideographic-variants
-variant-of-shinjigen-1
-
-iso-10646-comment
-".split
-    def initialize
-      @odir = DB_DIR+"/system-char-id/obsolete" #直打ちしている。
-    end
-    def move_obsolete_files # 廃止予定のbdbファイルをobsoleteディレクトリーにつっこむ
-      db = CharDB.instance
-      db.close_all
-      Dir.mkdir(@odir) unless FileTest.directory? @odir
-      OBSOLETE_ATTRIBUTES.each {|attr|
-       next if attr =~ /^#/
-       filename = db.get_filename(attr)
-       move_to_obsolete(filename)
-       move_to_obsolete(filename+".txt")
-      }
-    end
-    def move_to_obsolete(file)
-      cmd = "mv #{file} #{@odir}"
-      #      p cmd
-      system cmd
-    end
-  end
-
-  class JoyoList #======================================================================
-    include Singleton
-    #JP_JOYO_FILE = DB_DIR+"/../jp-joyo.txt" #EUC-jisx0213
-    JP_JOYO_FILE = DB_DIR+"/../joyo-ucs.txt" #UCS
-    COMPOSIT_KANJI = "鳴名加品古知問間聞取兄見切分粉貧林森校東明住位好岩砂里男畑習休短空坂島倉美孝赤看光初努協解新歌語話張強忘悲答晴現正字安守灰秋秒困国医包同合舌居右左受友反道返迷花菜集机主太氷州点店庫仕帳幼防引配早直班筆重番北化比死夏後進酒福私家世内谷半原前寺思電雲気布旅衆泣"
-    #    COMPOSIT_KANJI = "鳴名加品古"
-    def initialize
-      @nchars = []
-      read_file
-    end
-    attr_reader :nchars
-    def read_file
-      open(JP_JOYO_FILE) {|f|
-       while line = f.gets
-         next if line =~ /^;/ #コメントはとばす
-         line.chomp!
-         #stroke, nchar, ochar = line.split #new char, old char, old charはnilが多い
-         stroke, nchar = line.split
-         @nchars << nchar
-       end
-      }
-    end
-    def dump_ids(ar)
-      ar.each {|ch|
-       char = ch.char
-       print char.inspect_ids(true), "\t;", char.inspect_ids(false), "\n"
-      }
-    end
-  end
-
 end
 
 #----------------------------------------------------------------------終了
index c1b9d55..315b167 100755 (executable)
@@ -70,7 +70,7 @@ module StrokeFont
       #@rend.hsv = [13, 100, 100]
       @rend.hsv = [0, 0, 100]
     end
-    attr_reader :cache_list
+    attr_reader :cache_list, :server
     def get(code)
       return @glyphs[code] if @glyphs[code]
       svg = @server.get(code)
index 69dc095..d0dc3b0 100755 (executable)
@@ -22,10 +22,10 @@ class KageServer #==============================================================
     @glyphs = []
     @use_cache = true #デフォルト: cacheに存在する場合はcacheから引き出す。
     @offline = false #テスト用
-    #@offline = true #テスト用
+    @offline = true #テスト用
     Dir.mkdir(CACHE_DIR) unless FileTest.directory?(CACHE_DIR)
   end
-  attr_accessor :url, :use_cache
+  attr_accessor :url, :use_cache, :offline
   def filename(num, type=SKELETON) sprintf("u%04x.%s", num, TYPES[type]) end
   def cache_file(num, type=SKELETON) CACHE_DIR+"/"+filename(num, type)+".svg" end
 
index 45469ee..fb07ccc 100755 (executable)
@@ -7,8 +7,11 @@ module CHISE
   class KanjiList #======================================================================
     include Singleton
 
-    AWASE_KANJI_LIST = "鳴名加品古知問間聞取兄見切分粉貧林森校東明住位好岩砂里男畑習休短空坂島倉美孝赤看光初努協解新歌語話張強忘悲答晴現正字安守灰秋秒困国医包同合舌居右左受友反道返迷花菜集机主太氷州点店庫仕帳幼防引配早直班筆重番北化比死夏後進酒福私家世内谷半原前寺思電雲気布旅衆泣
-鳴名
+    BASIC_KANJI = "人子女母父王口耳手足力目首毛心犬牛鳥貝角羽虫馬魚羊肉皮米竹木麦豆山川雨風水土石金田穴日月火音糸刀舟門戸衣矢弓車皿一二三四五六七八九十百千万寸尺上中下本玉立回食行止交向歩考入示走生出来書言大小白青多少高長"
+
+    AWASE_KANJI_LIST = "鳴名加品古知問間聞取兄見切分粉貧林森校東明住位好岩砂里男畑習休短空坂島倉美孝赤看光初努協解新歌語話張強忘悲答晴現正字安守灰秋秒困国医包同合舌居右左受友反道返迷花菜集机主太氷州点店庫仕帳幼防引配早直班筆重番北化比死夏後進酒福私家世内谷半原前寺思電雲気布旅衆泣"
+
+    TEST_KANJI_LIST = "鳴名
 鳴名加知医短男畑秋居古灰
 加知医短男畑秋居古灰
 品問間聞取兄見切分粉貧林森校東明住位好岩砂里習休空坂島
@@ -62,9 +65,11 @@ module CHISE
 
     JINMEI_KANJI_LIST = "丑丞乃之也亘亥亦亨亮伊伍伎伶伽佑侃侑倖倭偲允冴冶凌凜凪凱勁匡卯叡只叶吾呂哉唄啄喬嘉圭尭奈奎媛嬉孟宏宥寅峻崚嵐嵩嵯嶺巌巳巴巽庄弘弥彗彦彪彬怜恕悌惇惟惣慧憧拳捷捺敦斐於旦旭旺昂昌昴晃晋晏晟晨智暉暢曙朋朔李杏杜柊柚柾栗栞桂桐梓梢梧梨椋椎椰椿楊楓楠榛槙槻樺橘檀欣欽毅毬汀汐汰沙洲洵洸浩淳渚渥湧滉漱澪煕熊燎燦燿爽爾猪玖玲琢琳瑚瑛瑞瑠瑶瑳璃甫皐皓眉眸睦瞭瞳矩碧碩磯祐禄禎秦稀稔稜穣竣笙笹紗紘紬絃絢綜綸綺綾緋翔翠耀耶聡肇胡胤脩舜艶芙芹苑茉茄茅茜莉莞菖菫萌萩葵蒔蒼蓉蓮蔦蕉蕗藍藤蘭虎虹蝶衿袈裟詢誼諄諒赳輔辰迪遥遼邑那郁酉醇釆錦鎌阿隼雛霞靖鞠須頌颯馨駒駿魁鮎鯉鯛鳩鳳鴻鵬鶴鷹鹿麟麿黎黛亀"
 
-    def awase(num=0)
-      AWASE_KANJI_LIST[num]
-    end
+    JISX0208_KANJI_LIST = "亜唖娃阿哀愛挨姶逢葵茜穐悪握渥旭葦芦鯵梓圧斡扱宛姐虻飴絢綾鮎或粟袷安庵按暗案闇鞍杏以伊位依偉囲夷委威尉惟意慰易椅為畏異移維緯胃萎衣謂違遺医井亥域育郁磯一壱溢逸稲茨芋鰯允印咽員因姻引飲淫胤蔭院陰隠韻吋右宇烏羽迂雨卯鵜窺丑碓臼渦嘘唄欝蔚鰻姥厩浦瓜閏噂云運雲荏餌叡営嬰影映曳栄永泳洩瑛盈穎頴英衛詠鋭液疫益駅悦謁越閲榎厭円園堰奄宴延怨掩援沿演炎焔煙燕猿縁艶苑薗遠鉛鴛塩於汚甥凹央奥往応押旺横欧殴王翁襖鴬鴎黄岡沖荻億屋憶臆桶牡乙俺卸恩温穏音下化仮何伽価佳加可嘉夏嫁家寡科暇果架歌河火珂禍禾稼箇花苛茄荷華菓蝦課嘩貨迦過霞蚊俄峨我牙画臥芽蛾賀雅餓駕介会解回塊壊廻快怪悔恢懐戒拐改魁晦械海灰界皆絵芥蟹開階貝凱劾外咳害崖慨概涯碍蓋街該鎧骸浬馨蛙垣柿蛎鈎劃嚇各廓拡撹格核殻獲確穫覚角赫較郭閣隔革学岳楽額顎掛笠樫橿梶鰍潟割喝恰括活渇滑葛褐轄且鰹叶椛樺鞄株兜竃蒲釜鎌噛鴨栢茅萱粥刈苅瓦乾侃冠寒刊勘勧巻喚堪姦完官寛干幹患感慣憾換敢柑桓棺款歓汗漢澗潅環甘監看竿管簡緩缶翰肝艦莞観諌貫還鑑間閑関陥韓館舘丸含岸巌玩癌眼岩翫贋雁頑顔願企伎危喜器基奇嬉寄岐希幾忌揮机旗既期棋棄機帰毅気汽畿祈季稀紀徽規記貴起軌輝飢騎鬼亀偽儀妓宜戯技擬欺犠疑祇義蟻誼議掬菊鞠吉吃喫桔橘詰砧杵黍却客脚虐逆丘久仇休及吸宮弓急救朽求汲泣灸球究窮笈級糾給旧牛去居巨拒拠挙渠虚許距鋸漁禦魚亨享京供侠僑兇競共凶協匡卿叫喬境峡強彊怯恐恭挟教橋況狂狭矯胸脅興蕎郷鏡響饗驚仰凝尭暁業局曲極玉桐粁僅勤均巾錦斤欣欽琴禁禽筋緊芹菌衿襟謹近金吟銀九倶句区狗玖矩苦躯駆駈駒具愚虞喰空偶寓遇隅串櫛釧屑屈掘窟沓靴轡窪熊隈粂栗繰桑鍬勲君薫訓群軍郡卦袈祁係傾刑兄啓圭珪型契形径恵慶慧憩掲携敬景桂渓畦稽系経継繋罫茎荊蛍計詣警軽頚鶏芸迎鯨劇戟撃激隙桁傑欠決潔穴結血訣月件倹倦健兼券剣喧圏堅嫌建憲懸拳捲検権牽犬献研硯絹県肩見謙賢軒遣鍵険顕験鹸元原厳幻弦減源玄現絃舷言諺限乎個古呼固姑孤己庫弧戸故枯湖狐糊袴股胡菰虎誇跨鈷雇顧鼓五互伍午呉吾娯後御悟梧檎瑚碁語誤護醐乞鯉交佼侯候倖光公功効勾厚口向后喉坑垢好孔孝宏工巧巷幸広庚康弘恒慌抗拘控攻昂晃更杭校梗構江洪浩港溝甲皇硬稿糠紅紘絞綱耕考肯肱腔膏航荒行衡講貢購郊酵鉱砿鋼閤降項香高鴻剛劫号合壕拷濠豪轟麹克刻告国穀酷鵠黒獄漉腰甑忽惚骨狛込此頃今困坤墾婚恨懇昏昆根梱混痕紺艮魂些佐叉唆嵯左差査沙瑳砂詐鎖裟坐座挫債催再最哉塞妻宰彩才採栽歳済災采犀砕砦祭斎細菜裁載際剤在材罪財冴坂阪堺榊肴咲崎埼碕鷺作削咋搾昨朔柵窄策索錯桜鮭笹匙冊刷察拶撮擦札殺薩雑皐鯖捌錆鮫皿晒三傘参山惨撒散桟燦珊産算纂蚕讃賛酸餐斬暫残仕仔伺使刺司史嗣四士始姉姿子屍市師志思指支孜斯施旨枝止死氏獅祉私糸紙紫肢脂至視詞詩試誌諮資賜雌飼歯事似侍児字寺慈持時次滋治爾璽痔磁示而耳自蒔辞汐鹿式識鴫竺軸宍雫七叱執失嫉室悉湿漆疾質実蔀篠偲柴芝屡蕊縞舎写射捨赦斜煮社紗者謝車遮蛇邪借勺尺杓灼爵酌釈錫若寂弱惹主取守手朱殊狩珠種腫趣酒首儒受呪寿授樹綬需囚収周宗就州修愁拾洲秀秋終繍習臭舟蒐衆襲讐蹴輯週酋酬集醜什住充十従戎柔汁渋獣縦重銃叔夙宿淑祝縮粛塾熟出術述俊峻春瞬竣舜駿准循旬楯殉淳準潤盾純巡遵醇順処初所暑曙渚庶緒署書薯藷諸助叙女序徐恕鋤除傷償勝匠升召哨商唱嘗奨妾娼宵将小少尚庄床廠彰承抄招掌捷昇昌昭晶松梢樟樵沼消渉湘焼焦照症省硝礁祥称章笑粧紹肖菖蒋蕉衝裳訟証詔詳象賞醤鉦鍾鐘障鞘上丈丞乗冗剰城場壌嬢常情擾条杖浄状畳穣蒸譲醸錠嘱埴飾拭植殖燭織職色触食蝕辱尻伸信侵唇娠寝審心慎振新晋森榛浸深申疹真神秦紳臣芯薪親診身辛進針震人仁刃塵壬尋甚尽腎訊迅陣靭笥諏須酢図厨逗吹垂帥推水炊睡粋翠衰遂酔錐錘随瑞髄崇嵩数枢趨雛据杉椙菅頗雀裾澄摺寸世瀬畝是凄制勢姓征性成政整星晴棲栖正清牲生盛精聖声製西誠誓請逝醒青静斉税脆隻席惜戚斥昔析石積籍績脊責赤跡蹟碩切拙接摂折設窃節説雪絶舌蝉仙先千占宣専尖川戦扇撰栓栴泉浅洗染潜煎煽旋穿箭線繊羨腺舛船薦詮賎践選遷銭銑閃鮮前善漸然全禅繕膳糎噌塑岨措曾曽楚狙疏疎礎祖租粗素組蘇訴阻遡鼠僧創双叢倉喪壮奏爽宋層匝惣想捜掃挿掻操早曹巣槍槽漕燥争痩相窓糟総綜聡草荘葬蒼藻装走送遭鎗霜騒像増憎臓蔵贈造促側則即息捉束測足速俗属賊族続卒袖其揃存孫尊損村遜他多太汰詑唾堕妥惰打柁舵楕陀駄騨体堆対耐岱帯待怠態戴替泰滞胎腿苔袋貸退逮隊黛鯛代台大第醍題鷹滝瀧卓啄宅托択拓沢濯琢託鐸濁諾茸凧蛸只叩但達辰奪脱巽竪辿棚谷狸鱈樽誰丹単嘆坦担探旦歎淡湛炭短端箪綻耽胆蛋誕鍛団壇弾断暖檀段男談値知地弛恥智池痴稚置致蜘遅馳築畜竹筑蓄逐秩窒茶嫡着中仲宙忠抽昼柱注虫衷註酎鋳駐樗瀦猪苧著貯丁兆凋喋寵帖帳庁弔張彫徴懲挑暢朝潮牒町眺聴脹腸蝶調諜超跳銚長頂鳥勅捗直朕沈珍賃鎮陳津墜椎槌追鎚痛通塚栂掴槻佃漬柘辻蔦綴鍔椿潰坪壷嬬紬爪吊釣鶴亭低停偵剃貞呈堤定帝底庭廷弟悌抵挺提梯汀碇禎程締艇訂諦蹄逓邸鄭釘鼎泥摘擢敵滴的笛適鏑溺哲徹撤轍迭鉄典填天展店添纏甜貼転顛点伝殿澱田電兎吐堵塗妬屠徒斗杜渡登菟賭途都鍍砥砺努度土奴怒倒党冬凍刀唐塔塘套宕島嶋悼投搭東桃梼棟盗淘湯涛灯燈当痘祷等答筒糖統到董蕩藤討謄豆踏逃透鐙陶頭騰闘働動同堂導憧撞洞瞳童胴萄道銅峠鴇匿得徳涜特督禿篤毒独読栃橡凸突椴届鳶苫寅酉瀞噸屯惇敦沌豚遁頓呑曇鈍奈那内乍凪薙謎灘捺鍋楢馴縄畷南楠軟難汝二尼弐迩匂賑肉虹廿日乳入如尿韮任妊忍認濡禰祢寧葱猫熱年念捻撚燃粘乃廼之埜嚢悩濃納能脳膿農覗蚤巴把播覇杷波派琶破婆罵芭馬俳廃拝排敗杯盃牌背肺輩配倍培媒梅楳煤狽買売賠陪這蝿秤矧萩伯剥博拍柏泊白箔粕舶薄迫曝漠爆縛莫駁麦函箱硲箸肇筈櫨幡肌畑畠八鉢溌発醗髪伐罰抜筏閥鳩噺塙蛤隼伴判半反叛帆搬斑板氾汎版犯班畔繁般藩販範釆煩頒飯挽晩番盤磐蕃蛮匪卑否妃庇彼悲扉批披斐比泌疲皮碑秘緋罷肥被誹費避非飛樋簸備尾微枇毘琵眉美鼻柊稗匹疋髭彦膝菱肘弼必畢筆逼桧姫媛紐百謬俵彪標氷漂瓢票表評豹廟描病秒苗錨鋲蒜蛭鰭品彬斌浜瀕貧賓頻敏瓶不付埠夫婦富冨布府怖扶敷斧普浮父符腐膚芙譜負賦赴阜附侮撫武舞葡蕪部封楓風葺蕗伏副復幅服福腹複覆淵弗払沸仏物鮒分吻噴墳憤扮焚奮粉糞紛雰文聞丙併兵塀幣平弊柄並蔽閉陛米頁僻壁癖碧別瞥蔑箆偏変片篇編辺返遍便勉娩弁鞭保舗鋪圃捕歩甫補輔穂募墓慕戊暮母簿菩倣俸包呆報奉宝峰峯崩庖抱捧放方朋法泡烹砲縫胞芳萌蓬蜂褒訪豊邦鋒飽鳳鵬乏亡傍剖坊妨帽忘忙房暴望某棒冒紡肪膨謀貌貿鉾防吠頬北僕卜墨撲朴牧睦穆釦勃没殆堀幌奔本翻凡盆摩磨魔麻埋妹昧枚毎哩槙幕膜枕鮪柾鱒桝亦俣又抹末沫迄侭繭麿万慢満漫蔓味未魅巳箕岬密蜜湊蓑稔脈妙粍民眠務夢無牟矛霧鵡椋婿娘冥名命明盟迷銘鳴姪牝滅免棉綿緬面麺摸模茂妄孟毛猛盲網耗蒙儲木黙目杢勿餅尤戻籾貰問悶紋門匁也冶夜爺耶野弥矢厄役約薬訳躍靖柳薮鑓愉愈油癒諭輸唯佑優勇友宥幽悠憂揖有柚湧涌猶猷由祐裕誘遊邑郵雄融夕予余与誉輿預傭幼妖容庸揚揺擁曜楊様洋溶熔用窯羊耀葉蓉要謡踊遥陽養慾抑欲沃浴翌翼淀羅螺裸来莱頼雷洛絡落酪乱卵嵐欄濫藍蘭覧利吏履李梨理璃痢裏裡里離陸律率立葎掠略劉流溜琉留硫粒隆竜龍侶慮旅虜了亮僚両凌寮料梁涼猟療瞭稜糧良諒遼量陵領力緑倫厘林淋燐琳臨輪隣鱗麟瑠塁涙累類令伶例冷励嶺怜玲礼苓鈴隷零霊麗齢暦歴列劣烈裂廉恋憐漣煉簾練聯蓮連錬呂魯櫓炉賂路露労婁廊弄朗楼榔浪漏牢狼篭老聾蝋郎六麓禄肋録論倭和話歪賄脇惑枠鷲亙亘鰐詫藁蕨椀湾碗腕弌丐丕个丱丶丼丿乂乖乘亂亅豫亊舒弍于亞亟亠亢亰亳亶从仍仄仆仂仗仞仭仟价伉佚估佛佝佗佇佶侈侏侘佻佩佰侑佯來侖儘俔俟俎俘俛俑俚俐俤俥倚倨倔倪倥倅伜俶倡倩倬俾俯們倆偃假會偕偐偈做偖偬偸傀傚傅傴傲僉僊傳僂僖僞僥僭僣僮價僵儉儁儂儖儕儔儚儡儺儷儼儻儿兀兒兌兔兢竸兩兪兮冀冂囘册冉冏冑冓冕冖冤冦冢冩冪冫决冱冲冰况冽凅凉凛几處凩凭凰凵凾刄刋刔刎刧刪刮刳刹剏剄剋剌剞剔剪剴剩剳剿剽劍劔劒剱劈劑辨辧劬劭劼劵勁勍勗勞勣勦飭勠勳勵勸勹匆匈甸匍匐匏匕匚匣匯匱匳匸區卆卅丗卉卍凖卞卩卮夘卻卷厂厖厠厦厥厮厰厶參簒雙叟曼燮叮叨叭叺吁吽呀听吭吼吮吶吩吝呎咏呵咎呟呱呷呰咒呻咀呶咄咐咆哇咢咸咥咬哄哈咨咫哂咤咾咼哘哥哦唏唔哽哮哭哺哢唹啀啣啌售啜啅啖啗唸唳啝喙喀咯喊喟啻啾喘喞單啼喃喩喇喨嗚嗅嗟嗄嗜嗤嗔嘔嗷嘖嗾嗽嘛嗹噎噐營嘴嘶嘲嘸噫噤嘯噬噪嚆嚀嚊嚠嚔嚏嚥嚮嚶嚴囂嚼囁囃囀囈囎囑囓囗囮囹圀囿圄圉圈國圍圓團圖嗇圜圦圷圸坎圻址坏坩埀垈坡坿垉垓垠垳垤垪垰埃埆埔埒埓堊埖埣堋堙堝塲堡塢塋塰毀塒堽塹墅墹墟墫墺壞墻墸墮壅壓壑壗壙壘壥壜壤壟壯壺壹壻壼壽夂夊夐夛梦夥夬夭夲夸夾竒奕奐奎奚奘奢奠奧奬奩奸妁妝佞侫妣妲姆姨姜妍姙姚娥娟娑娜娉娚婀婬婉娵娶婢婪媚媼媾嫋嫂媽嫣嫗嫦嫩嫖嫺嫻嬌嬋嬖嬲嫐嬪嬶嬾孃孅孀孑孕孚孛孥孩孰孳孵學斈孺宀它宦宸寃寇寉寔寐寤實寢寞寥寫寰寶寳尅將專對尓尠尢尨尸尹屁屆屎屓屐屏孱屬屮乢屶屹岌岑岔妛岫岻岶岼岷峅岾峇峙峩峽峺峭嶌峪崋崕崗嵜崟崛崑崔崢崚崙崘嵌嵒嵎嵋嵬嵳嵶嶇嶄嶂嶢嶝嶬嶮嶽嶐嶷嶼巉巍巓巒巖巛巫已巵帋帚帙帑帛帶帷幄幃幀幎幗幔幟幢幤幇幵并幺麼广庠廁廂廈廐廏廖廣廝廚廛廢廡廨廩廬廱廳廰廴廸廾弃弉彝彜弋弑弖弩弭弸彁彈彌彎弯彑彖彗彙彡彭彳彷徃徂彿徊很徑徇從徙徘徠徨徭徼忖忻忤忸忱忝悳忿怡恠怙怐怩怎怱怛怕怫怦怏怺恚恁恪恷恟恊恆恍恣恃恤恂恬恫恙悁悍惧悃悚悄悛悖悗悒悧悋惡悸惠惓悴忰悽惆悵惘慍愕愆惶惷愀惴惺愃愡惻惱愍愎慇愾愨愧慊愿愼愬愴愽慂慄慳慷慘慙慚慫慴慯慥慱慟慝慓慵憙憖憇憬憔憚憊憑憫憮懌懊應懷懈懃懆憺懋罹懍懦懣懶懺懴懿懽懼懾戀戈戉戍戌戔戛戞戡截戮戰戲戳扁扎扞扣扛扠扨扼抂抉找抒抓抖拔抃抔拗拑抻拏拿拆擔拈拜拌拊拂拇抛拉挌拮拱挧挂挈拯拵捐挾捍搜捏掖掎掀掫捶掣掏掉掟掵捫捩掾揩揀揆揣揉插揶揄搖搴搆搓搦搶攝搗搨搏摧摯摶摎攪撕撓撥撩撈撼據擒擅擇撻擘擂擱擧舉擠擡抬擣擯攬擶擴擲擺攀擽攘攜攅攤攣攫攴攵攷收攸畋效敖敕敍敘敞敝敲數斂斃變斛斟斫斷旃旆旁旄旌旒旛旙无旡旱杲昊昃旻杳昵昶昴昜晏晄晉晁晞晝晤晧晨晟晢晰暃暈暎暉暄暘暝曁暹曉暾暼曄暸曖曚曠昿曦曩曰曵曷朏朖朞朦朧霸朮朿朶杁朸朷杆杞杠杙杣杤枉杰枩杼杪枌枋枦枡枅枷柯枴柬枳柩枸柤柞柝柢柮枹柎柆柧檜栞框栩桀桍栲桎梳栫桙档桷桿梟梏梭梔條梛梃檮梹桴梵梠梺椏梍桾椁棊椈棘椢椦棡椌棍棔棧棕椶椒椄棗棣椥棹棠棯椨椪椚椣椡棆楹楷楜楸楫楔楾楮椹楴椽楙椰楡楞楝榁楪榲榮槐榿槁槓榾槎寨槊槝榻槃榧樮榑榠榜榕榴槞槨樂樛槿權槹槲槧樅榱樞槭樔槫樊樒櫁樣樓橄樌橲樶橸橇橢橙橦橈樸樢檐檍檠檄檢檣檗蘗檻櫃櫂檸檳檬櫞櫑櫟檪櫚櫪櫻欅蘖櫺欒欖鬱欟欸欷盜欹飮歇歃歉歐歙歔歛歟歡歸歹歿殀殄殃殍殘殕殞殤殪殫殯殲殱殳殷殼毆毋毓毟毬毫毳毯麾氈氓气氛氤氣汞汕汢汪沂沍沚沁沛汾汨汳沒沐泄泱泓沽泗泅泝沮沱沾沺泛泯泙泪洟衍洶洫洽洸洙洵洳洒洌浣涓浤浚浹浙涎涕濤涅淹渕渊涵淇淦涸淆淬淞淌淨淒淅淺淙淤淕淪淮渭湮渮渙湲湟渾渣湫渫湶湍渟湃渺湎渤滿渝游溂溪溘滉溷滓溽溯滄溲滔滕溏溥滂溟潁漑灌滬滸滾漿滲漱滯漲滌漾漓滷澆潺潸澁澀潯潛濳潭澂潼潘澎澑濂潦澳澣澡澤澹濆澪濟濕濬濔濘濱濮濛瀉瀋濺瀑瀁瀏濾瀛瀚潴瀝瀘瀟瀰瀾瀲灑灣炙炒炯烱炬炸炳炮烟烋烝烙焉烽焜焙煥煕熈煦煢煌煖煬熏燻熄熕熨熬燗熹熾燒燉燔燎燠燬燧燵燼燹燿爍爐爛爨爭爬爰爲爻爼爿牀牆牋牘牴牾犂犁犇犒犖犢犧犹犲狃狆狄狎狒狢狠狡狹狷倏猗猊猜猖猝猴猯猩猥猾獎獏默獗獪獨獰獸獵獻獺珈玳珎玻珀珥珮珞璢琅瑯琥珸琲琺瑕琿瑟瑙瑁瑜瑩瑰瑣瑪瑶瑾璋璞璧瓊瓏瓔珱瓠瓣瓧瓩瓮瓲瓰瓱瓸瓷甄甃甅甌甎甍甕甓甞甦甬甼畄畍畊畉畛畆畚畩畤畧畫畭畸當疆疇畴疊疉疂疔疚疝疥疣痂疳痃疵疽疸疼疱痍痊痒痙痣痞痾痿痼瘁痰痺痲痳瘋瘍瘉瘟瘧瘠瘡瘢瘤瘴瘰瘻癇癈癆癜癘癡癢癨癩癪癧癬癰癲癶癸發皀皃皈皋皎皖皓皙皚皰皴皸皹皺盂盍盖盒盞盡盥盧盪蘯盻眈眇眄眩眤眞眥眦眛眷眸睇睚睨睫睛睥睿睾睹瞎瞋瞑瞠瞞瞰瞶瞹瞿瞼瞽瞻矇矍矗矚矜矣矮矼砌砒礦砠礪硅碎硴碆硼碚碌碣碵碪碯磑磆磋磔碾碼磅磊磬磧磚磽磴礇礒礑礙礬礫祀祠祗祟祚祕祓祺祿禊禝禧齋禪禮禳禹禺秉秕秧秬秡秣稈稍稘稙稠稟禀稱稻稾稷穃穗穉穡穢穩龝穰穹穽窈窗窕窘窖窩竈窰窶竅竄窿邃竇竊竍竏竕竓站竚竝竡竢竦竭竰笂笏笊笆笳笘笙笞笵笨笶筐筺笄筍笋筌筅筵筥筴筧筰筱筬筮箝箘箟箍箜箚箋箒箏筝箙篋篁篌篏箴篆篝篩簑簔篦篥籠簀簇簓篳篷簗簍篶簣簧簪簟簷簫簽籌籃籔籏籀籐籘籟籤籖籥籬籵粃粐粤粭粢粫粡粨粳粲粱粮粹粽糀糅糂糘糒糜糢鬻糯糲糴糶糺紆紂紜紕紊絅絋紮紲紿紵絆絳絖絎絲絨絮絏絣經綉絛綏絽綛綺綮綣綵緇綽綫總綢綯緜綸綟綰緘緝緤緞緻緲緡縅縊縣縡縒縱縟縉縋縢繆繦縻縵縹繃縷縲縺繧繝繖繞繙繚繹繪繩繼繻纃緕繽辮繿纈纉續纒纐纓纔纖纎纛纜缸缺罅罌罍罎罐网罕罔罘罟罠罨罩罧罸羂羆羃羈羇羌羔羞羝羚羣羯羲羹羮羶羸譱翅翆翊翕翔翡翦翩翳翹飜耆耄耋耒耘耙耜耡耨耿耻聊聆聒聘聚聟聢聨聳聲聰聶聹聽聿肄肆肅肛肓肚肭冐肬胛胥胙胝胄胚胖脉胯胱脛脩脣脯腋隋腆脾腓腑胼腱腮腥腦腴膃膈膊膀膂膠膕膤膣腟膓膩膰膵膾膸膽臀臂膺臉臍臑臙臘臈臚臟臠臧臺臻臾舁舂舅與舊舍舐舖舩舫舸舳艀艙艘艝艚艟艤艢艨艪艫舮艱艷艸艾芍芒芫芟芻芬苡苣苟苒苴苳苺莓范苻苹苞茆苜茉苙茵茴茖茲茱荀茹荐荅茯茫茗茘莅莚莪莟莢莖茣莎莇莊荼莵荳荵莠莉莨菴萓菫菎菽萃菘萋菁菷萇菠菲萍萢萠莽萸蔆菻葭萪萼蕚蒄葷葫蒭葮蒂葩葆萬葯葹萵蓊葢蒹蒿蒟蓙蓍蒻蓚蓐蓁蓆蓖蒡蔡蓿蓴蔗蔘蔬蔟蔕蔔蓼蕀蕣蕘蕈蕁蘂蕋蕕薀薤薈薑薊薨蕭薔薛藪薇薜蕷蕾薐藉薺藏薹藐藕藝藥藜藹蘊蘓蘋藾藺蘆蘢蘚蘰蘿虍乕虔號虧虱蚓蚣蚩蚪蚋蚌蚶蚯蛄蛆蚰蛉蠣蚫蛔蛞蛩蛬蛟蛛蛯蜒蜆蜈蜀蜃蛻蜑蜉蜍蛹蜊蜴蜿蜷蜻蜥蜩蜚蝠蝟蝸蝌蝎蝴蝗蝨蝮蝙蝓蝣蝪蠅螢螟螂螯蟋螽蟀蟐雖螫蟄螳蟇蟆螻蟯蟲蟠蠏蠍蟾蟶蟷蠎蟒蠑蠖蠕蠢蠡蠱蠶蠹蠧蠻衄衂衒衙衞衢衫袁衾袞衵衽袵衲袂袗袒袮袙袢袍袤袰袿袱裃裄裔裘裙裝裹褂裼裴裨裲褄褌褊褓襃褞褥褪褫襁襄褻褶褸襌褝襠襞襦襤襭襪襯襴襷襾覃覈覊覓覘覡覩覦覬覯覲覺覽覿觀觚觜觝觧觴觸訃訖訐訌訛訝訥訶詁詛詒詆詈詼詭詬詢誅誂誄誨誡誑誥誦誚誣諄諍諂諚諫諳諧諤諱謔諠諢諷諞諛謌謇謚諡謖謐謗謠謳鞫謦謫謾謨譁譌譏譎證譖譛譚譫譟譬譯譴譽讀讌讎讒讓讖讙讚谺豁谿豈豌豎豐豕豢豬豸豺貂貉貅貊貍貎貔豼貘戝貭貪貽貲貳貮貶賈賁賤賣賚賽賺賻贄贅贊贇贏贍贐齎贓賍贔贖赧赭赱赳趁趙跂趾趺跏跚跖跌跛跋跪跫跟跣跼踈踉跿踝踞踐踟蹂踵踰踴蹊蹇蹉蹌蹐蹈蹙蹤蹠踪蹣蹕蹶蹲蹼躁躇躅躄躋躊躓躑躔躙躪躡躬躰軆躱躾軅軈軋軛軣軼軻軫軾輊輅輕輒輙輓輜輟輛輌輦輳輻輹轅轂輾轌轉轆轎轗轜轢轣轤辜辟辣辭辯辷迚迥迢迪迯邇迴逅迹迺逑逕逡逍逞逖逋逧逶逵逹迸遏遐遑遒逎遉逾遖遘遞遨遯遶隨遲邂遽邁邀邊邉邏邨邯邱邵郢郤扈郛鄂鄒鄙鄲鄰酊酖酘酣酥酩酳酲醋醉醂醢醫醯醪醵醴醺釀釁釉釋釐釖釟釡釛釼釵釶鈞釿鈔鈬鈕鈑鉞鉗鉅鉉鉤鉈銕鈿鉋鉐銜銖銓銛鉚鋏銹銷鋩錏鋺鍄錮錙錢錚錣錺錵錻鍜鍠鍼鍮鍖鎰鎬鎭鎔鎹鏖鏗鏨鏥鏘鏃鏝鏐鏈鏤鐚鐔鐓鐃鐇鐐鐶鐫鐵鐡鐺鑁鑒鑄鑛鑠鑢鑞鑪鈩鑰鑵鑷鑽鑚鑼鑾钁鑿閂閇閊閔閖閘閙閠閨閧閭閼閻閹閾闊濶闃闍闌闕闔闖關闡闥闢阡阨阮阯陂陌陏陋陷陜陞陝陟陦陲陬隍隘隕隗險隧隱隲隰隴隶隸隹雎雋雉雍襍雜霍雕雹霄霆霈霓霎霑霏霖霙霤霪霰霹霽霾靄靆靈靂靉靜靠靤靦靨勒靫靱靹鞅靼鞁靺鞆鞋鞏鞐鞜鞨鞦鞣鞳鞴韃韆韈韋韜韭齏韲竟韶韵頏頌頸頤頡頷頽顆顏顋顫顯顰顱顴顳颪颯颱颶飄飃飆飩飫餃餉餒餔餘餡餝餞餤餠餬餮餽餾饂饉饅饐饋饑饒饌饕馗馘馥馭馮馼駟駛駝駘駑駭駮駱駲駻駸騁騏騅駢騙騫騷驅驂驀驃騾驕驍驛驗驟驢驥驤驩驫驪骭骰骼髀髏髑髓體髞髟髢髣髦髯髫髮髴髱髷髻鬆鬘鬚鬟鬢鬣鬥鬧鬨鬩鬪鬮鬯鬲魄魃魏魍魎魑魘魴鮓鮃鮑鮖鮗鮟鮠鮨鮴鯀鯊鮹鯆鯏鯑鯒鯣鯢鯤鯔鯡鰺鯲鯱鯰鰕鰔鰉鰓鰌鰆鰈鰒鰊鰄鰮鰛鰥鰤鰡鰰鱇鰲鱆鰾鱚鱠鱧鱶鱸鳧鳬鳰鴉鴈鳫鴃鴆鴪鴦鶯鴣鴟鵄鴕鴒鵁鴿鴾鵆鵈鵝鵞鵤鵑鵐鵙鵲鶉鶇鶫鵯鵺鶚鶤鶩鶲鷄鷁鶻鶸鶺鷆鷏鷂鷙鷓鷸鷦鷭鷯鷽鸚鸛鸞鹵鹹鹽麁麈麋麌麒麕麑麝麥麩麸麪麭靡黌黎黏黐黔黜點黝黠黥黨黯黴黶黷黹黻黼黽鼇鼈皷鼕鼡鼬鼾齊齒齔齣齟齠齡齦齧齬齪齷齲齶龕龜龠堯槇遙瑤凜熙"
+
+    def basic() BASIC_KANJI_LIST; end
+    def awase() AWASE_KANJI_LIST; end
+    def test(num=0) TEST_KANJI_LIST[num]; end
     def kyoiku(gakunen=nil, kubun=nil)
       return KYOIKU_KANJI_LIST if gakunen.nil?
       return gakunen.map {|nen| kyoiku(nen) }.join('') if gakunen.is_a?(Range) && kubun.nil?
@@ -75,6 +80,37 @@ module CHISE
     end
     def joyo() JOYO_KANJI_LIST; end
     def jinmei() JINMEI_KANJI_LIST; end
+    def jisx0208() JISX0208_KANJI_LIST; end
+  end
+
+  class JoyoList_nu #====================================================================== obsolete
+    include Singleton
+    #JP_JOYO_FILE = DB_DIR+"/../jp-joyo.txt" #EUC-jisx0213
+    JP_JOYO_FILE = DB_DIR+"/../joyo-ucs.txt" #UCS
+    COMPOSIT_KANJI = "鳴名加品古知問間聞取兄見切分粉貧林森校東明住位好岩砂里男畑習休短空坂島倉美孝赤看光初努協解新歌語話張強忘悲答晴現正字安守灰秋秒困国医包同合舌居右左受友反道返迷花菜集机主太氷州点店庫仕帳幼防引配早直班筆重番北化比死夏後進酒福私家世内谷半原前寺思電雲気布旅衆泣"
+    #    COMPOSIT_KANJI = "鳴名加品古"
+    def initialize
+      @nchars = []
+      read_file
+    end
+    attr_reader :nchars
+    def read_file
+      open(JP_JOYO_FILE) {|f|
+       while line = f.gets
+         next if line =~ /^;/ #コメントはとばす
+         line.chomp!
+         #stroke, nchar, ochar = line.split #new char, old char, old charはnilが多い
+         stroke, nchar = line.split
+         @nchars << nchar
+       end
+      }
+    end
+    def dump_ids(ar)
+      ar.each {|ch|
+       char = ch.char
+       print char.inspect_ids(true), "\t;", char.inspect_ids(false), "\n"
+      }
+    end
   end
 end
 
index 0d1491b..7225114 100755 (executable)
@@ -87,6 +87,9 @@ module StrokeFont
       @px, @py = x2, y2
     end
   end
+
+  class BSplineResolver
+  end
 end
 
 #----------------------------------------------------------------------end.
index f9127e2..20c9032 100755 (executable)
@@ -9,8 +9,8 @@ include CHISE
 class TC_Character < Test::Unit::TestCase
   def setup() @char = Character.get("字") end #UTF8で与えること
   def test_char(char)
-    assert_equal(23383, char.char_id, "translate to char_id")
-    assert_equal(6, char.get_char_attribute('total_strokes'), "get total strokes by XEmacs UTF-2000 like method")
+#    assert_equal(23383, char.char_id, "translate to char_id")
+#    assert_equal(6, char.get_char_attribute('total_strokes'), "get total strokes by XEmacs UTF-2000 like method")
     assert_equal(6, char['total_strokes'], "get total strokes by Hash like method") if char.is_a? Character
     assert_equal(6, char.total_strokes, "get total strokes by method")
     assert_equal(23383, char.ucs, "translate to ucs")