+require 'rexml/document'
+LINES_PER_PAGE = 10
+LINE_REGEX = /w[0-9ab]{4}([0-9]{2})([0-9]{2})/
+SISHENG = {'sp' => '上平聲', 'xp' => '下平聲', 's' => '上聲', 'q' => '去聲', 'r' => '入聲'}
+
+class SbgyController < ApplicationController
+ layout "main"
+ caches_page :index
+ caches_action :index
+
+ # def index
+ # c = params[:char]
+ # return nil unless c
+ # (ucs, char) = process_char(c)
+ # @chars = Array.new
+ # wordheads = Wordhead.find(:all, :conditions => ["word = ?", char])
+ # wordheads.each do |wordhead|
+ # voice = Voice.find(:first, :conditions => ["id = ?", wordhead.voice_id])
+ # rhyme = Rhyme.find(:first, :conditions => ["id = ?", voice.rhyme_id])
+ # @chars.push([wordhead, voice, rhyme])
+ # end
+ # end
+ def index
+ @volumes = Volume.find(:all)
+ @rhymes = Array.new
+ @volumes.each do |volume|
+ rhymes = Rhyme.find(:all, :conditions => ["volume_id = ?", volume.id])
+ @rhymes.push(rhymes)
+ end
+ end
+ def rhyme
+ rhyme_id = params[:id]
+ @rhyme = Rhyme.find(:first, :conditions => ["id = ?", rhyme_id])
+ @volume = Volume.find(:first, :conditions => ["id = ?", @rhyme.volume_id])
+ @voices = Voice.find(:all, :conditions => ["rhyme_id = ?", rhyme_id])
+ end
+ # TODO: piece -> leaf
+ def show
+ @vol = params[:vol]
+ @piece = params[:piece]
+ @plane = params[:plane]
+ return nil unless @piece
+ return nil if @piece.empty?
+ @regex = wordid_regex(@vol, @piece, @plane)
+ wordheads = Wordhead.find(:all, :conditions => ["xmlid like ?", @regex])
+ @chars = get_matrix(wordheads)
+ (@previous_piece, @previous_plane) = previous_page(@piece, @plane)
+ (@next_piece, @next_plane) = next_page(@piece, @plane)
+ end
+ def xiaoyun
+ fanqie = params[:fanqie]
+# return nil unless id
+ if fanqie != nil then
+ f = format("<fanqie>%s</fanqie>", fanqie)
+ @voice = Voice.find(:first, :conditions => ["fanqie = ?", f])
+ else
+ id = params[:id]
+ @voice = Voice.find(:first, :conditions => ["id = ?", id])
+# elsif not(xiaoyun.empty?) then
+# @voice = Voice.find(:first, :conditions => ["name = ?", xiaoyun])
+ end
+ return nil unless @voice
+ @rhyme = Rhyme.find(:first, :conditions => ["id = ?", @voice.rhyme_id])
+ @volume = Volume.find(:first, :conditions => ["id = ?", @rhyme.volume_id])
+ @wordheads =
+ Wordhead.find(:all, :conditions => ["voice_id = ?", @voice.id])
+ end
+ def setup
+ @wordheads = 0
+ @voices = 0
+ @rhymes = 0
+ setup_wordheads
+ setup_voices
+ setup_rhymes
+ setup_volumes
+ end
+ private
+ def previous_page(piece, plane)
+ return [nil, nil] if piece == "0" and plane == "a"
+ if plane == "a" then
+ return [(piece.to_i - 1).to_s, "b"]
+ else
+ return [piece, "a"]
+ end
+ end
+ def next_page(piece, plane)
+ if plane == "b" then
+ return [(piece.to_i + 1).to_s, "a"]
+ else
+ return [piece, "b"]
+ end
+ end
+ def get_matrix(wordheads)
+ page = get_empty_page(LINES_PER_PAGE)
+ wordheads.each do |wordhead|
+ wordhead.xmlid =~ LINE_REGEX
+ line = $1
+ num = $2
+ push_to_page(page, line, num, wordhead)
+ end
+ return page
+ end
+ def get_empty_page(lines_nums)
+ page = Array.new
+ (0..(lines_nums - 1)).each do |line|
+ page[line] = Array.new
+ end
+ return page
+ end
+ def push_to_page(page, line, num, wordhead)
+ i = line.to_i - 1
+ j = num.to_i - 1
+ page[i][j] = wordhead
+ end
+ def setup_wordheads
+ wordheads = Wordhead.find(:all)
+ wordheads.each do |wordhead|
+ word = wordhead.word.to_s
+ wordhead.name = get_rewrite_word(word)
+ @wordheads += 1
+ wordhead.save!
+ end
+ end
+ def setup_voices
+ voices = Voice.find(:all)
+ voices.each do |voice|
+ word = Wordhead.find(:first, :conditions => ["id = ?", voice.wordhead_id])
+ voice.name = word.word
+ # TODO: Fanqie mixed
+ note = "<n>" + word.note.to_s + "</n>"
+ doc = REXML::Document.new note
+# fanqie = doc.elements.to_a("//fanqie")[0].text
+ doc.root.each_child do |child|
+ if child.node_type == :element and child.name == "fanqie" then
+ fanqie = child.to_s
+ voice.fanqie = get_rewrite_text(fanqie)
+ end
+ end
+ @voices += 1
+ voice.save!
+ end
+ end
+ def setup_rhymes
+ rhymes = Rhyme.find(:all)
+ rhymes.each do |rhyme|
+ voice = Voice.find(:first, :conditions => ["id = ?", rhyme.voice_id])
+ sisheng = get_sisheng(rhyme.xmlid)
+# rhyme.name = sisheng + rhyme.num + voice.name 変更 <24 Mar>
+ rhyme.name = rhyme.num + voice.name
+ rhyme.save!
+ @rhymes += 1
+ end
+ end
+ def setup_volumes
+ volumes = Volume.find(:all)
+ volumes.each do |volume|
+ if volume.title =~ /^廣韻(.+聲)/u then
+ volume.name = $1
+ end
+ volume.save!
+ end
+ end
+ def get_sisheng(xmlid) # Rhyme
+ xmlid =~ /([spxqr]+)[0-9]+/
+ sisheng_id = $1
+ return SISHENG[sisheng_id]
+ end
+ # TODO: Rewrite a child node
+ def get_rewrite_word(word)
+ string = "<w>" + word + "</w>"
+ doc = REXML::Document.new string
+ original = doc.elements.to_a("//original_word")
+ if original.size > 0 then
+ rewrite = original[0].elements.to_a("//rewrite_word")
+ if rewrite.size > 0 then
+ name = rewrite[0].text
+ else
+ name = original[0].text
+ end
+ else
+ name = word
+ end
+ return name
+ end
+ def get_rewrite_fanqie(fanqie)
+ ftext = ""
+ fanqie.each_child do |child|
+ if child.node_type == :text then
+ ftext += child.to_s
+ elsif child.name == "original_word" then
+ otext = child.text
+ child.elements.each("rewrite_word") do |rewrite|
+ ftext += rewrite.text
+ end
+ else
+ ftext += child.to_s
+ end
+ end
+ return ftext
+ end
+ def get_rewrite_text(text)
+ return "" unless text
+ string = "<t>" + text + "</t>"
+ doc = REXML::Document.new string
+ original = doc.elements.to_a("//original_text")
+ if original and original.size > 0 then
+ rtext = doc.elements.to_a("//rewrite_text")[0].text
+ else
+ rtext = text
+ end
+ return rtext
+ end
+ def wordid_regex(vol, piece, plane)
+ fpiece = sprintf("%02d", piece.to_i)
+ return "w#{vol}#{fpiece}#{plane}%%%%"
+ end
+end