1 TBL_DIR = File.join(File.dirname(__FILE__), '..', '..', 'config', 'table')
2 XS = File.join(TBL_DIR, 'phonetic_components.yml')
3 MAX_NUM_FOR_MATCHED = 100
5 class HanmorphController < ApplicationController
7 caches_page :xiesheng, :rime_groups
8 caches_action :xiesheng, :rime_groups
13 (@ucs, @char, @extext) = check_targets
15 if @errors.empty? then
17 main_procedure_at_home
18 rescue StandardError => bang
19 @message = bang.message
24 (@ucs, @char) = process_char(char) if char
25 main_procedure_at_home
30 volumes = Volume.find(:all)
31 groups = RimeGroup.find(:all)
32 #groups.sort! {|a,b| a.num <=> b.num}
33 groups.each do |group|
34 sisheng = Array.new(4)
35 volumes.each do |volume|
36 rhymes = Rhyme.find(:all, :conditions =>
37 ["rime_group_id = ? and volume_id = ?", group.id, volume.id])
39 if volume.name =~ /[上下]平聲/u then
40 sisheng[0] = Array.new unless sisheng[0]
42 elsif volume.name =~ /上聲/u then
44 elsif volume.name =~ /去聲/u then
46 elsif volume.name =~ /入聲/u then
50 @groups.push([group, sisheng])
54 @doc = YAML.load(File.new(XS))
55 # doc.each_key do |group|
56 # doc[group].each_key do |xs|
57 # doc[group][xs].each do |char|
61 @group = params[:group]
62 @xiesheng = params[:xiesheng]
63 doc = YAML.load(File.new(XS))
64 @chars = doc[@group][@xiesheng]
70 def main_procedure_at_home
80 rescue TooManyCandidatesError => bang
86 # Validation Input Parameters
89 extext = params[:extext]
91 if extext and extext.size == 0 then
92 @errors << "検索する説解が入力されていません"
93 elsif ! extext and c and c.size == 0 then
94 @errors << "検索する文字が入力されていません"
95 elsif c =~/[0-9A-Fa-f]+/ and not c =~ /[0-9A-Fa-f]{4,5}/ then
96 @errors << "#{c}: 正しいコードポイントではありません"
98 (ucs, char) = process_char(c)
99 return [ucs, char, extext]
105 cp = ucs2codepoint(@ucs)
106 ideograph = Ideograph.find(:first, :conditions => ["codepoint = ?", cp])
107 return nil unless ideograph
108 @sbgy = unihan_lookup(ideograph, 'kSBGY')
109 @hdz = unihan_lookup(ideograph, 'kHanYu')
110 @dkz = unihan_lookup(ideograph, 'kIRGDaiKanwaZiten')
111 @kx = unihan_lookup(ideograph, 'kIRGKangXi')
112 (@page, @appendix) = get_hdz_page(@hdz)
116 wordheads = Wordhead.find(:all, :conditions => ["name = ?", @char])
117 wordheads.each do |wordhead|
118 voice = Voice.find(:first, :conditions => ["id = ?", wordhead.voice_id])
119 rhyme = Rhyme.find(:first, :conditions => ["id = ?", voice.rhyme_id])
120 rime_group = RimeGroup.find(:first, :conditions =>
121 ["id = ?", rhyme.rime_group_id])
122 volume = Volume.find(:first, :conditions => ["id = ?", rhyme.volume_id])
123 @chars.push([wordhead, voice, rhyme, rime_group, volume])
127 @sw_chars = Array.new
128 wordheads = SwWordhead.find(:all, :conditions => ["name = ?", @char])
129 wordheads.each do |wordhead|
130 charid = wordhead.character_id
131 char = SwCharacter.find(:first, :conditions => ["id = ?", charid])
132 rad = SwRadical.find(:first, :conditions => ["id = ?", char.radical_id])
133 chap = SwChapter.find(:first, :conditions => ["id = ?", rad.chapter_id])
134 words = SwWordhead.find(:all, :conditions => ["character_id = ?", charid])
135 @sw_chars.push([chap, rad, char, words])
139 @dx_words = Array.new
140 wordheads = DxWordhead.find(:all, :conditions => ["name = ?", @char])
141 wordheads.each do |word|
143 rad = DxRadical.find(:first, :conditions => ["id = ?", word.radical_id])
144 vol = DxVolume.find(:first, :conditions => ["id = ?", rad.volume_id])
145 @dx_words.push([vol, rad, word])
149 @dxexp_words = Array.new
150 @pattern = sprintf("%%%s%%", @extext)
151 wordheads = DxWordhead.find_by_sql(["select * from dx_wordheads " +
152 "where exp like ?", @pattern])
153 searched = wordheads.size
154 if searched > MAX_NUM_FOR_MATCHED then
155 raise TooManyCandidatesError, "#{searched}件、見付かりました。検索条件を絞り込んでください。"
157 wordheads.each do |word|
159 rad = DxRadical.find(:first, :conditions => ["id = ?", word.radical_id])
160 vol = DxVolume.find(:first, :conditions => ["id = ?", rad.volume_id])
161 voltitle = get_voltitle(vol)
162 exp = hilighted_exp(word.exp, @extext)
163 @dxexp_words.push([voltitle, rad, word, exp])
168 def unihan_lookup(ideograph, field_name)
169 field = Field.find(:first, :conditions => ["name = ?", field_name])
170 property = Property.find(:first,
171 :conditions => ["field_id = ? and ideograph_id = ?", field.id, ideograph.id])
174 def get_hdz_page(property)
175 return nil unless property
176 if property.value =~ /([1-8])([0-9]{4})\.([0-3][0-9])[01]/ then
180 appendix = (volume == "8" ? true : false)
181 return [page, appendix, volume]
184 def get_voltitle(vol)
185 return vol.title.sub(/說文解字第/u, "")
187 def hilighted_exp(exp, pattern)
188 regex = pattern.gsub(/%/, ".+")
189 # BUG: マッチした文字列が異なる場合、最初のものに置換される
190 if exp =~ /#{regex}/u then
191 span = "<span style='background-color:lightpink;'>#{$&}</span>"
192 return exp.gsub(/#{regex}/u, span)
200 class TooManyCandidatesError < RuntimeError