lib/ting/conversions/hanyu.rb
# coding: utf-8
module Ting
module Conversions
class Hanyu
def initialize(tone = :numbers, options = {})
@options = options
@options[:preprocess] ||= lambda {|s| s.gsub(/u:|Ü/, 'ü').downcase }
if Class === tone
@tone = tone
else
@tone = Ting::Tones.const_get(Ting.camelize(tone.to_s))
end
end
def valid_character_regexp
@valid_character_regexp ||= valid_character_regexp!
end
def valid_character_regexp!
valid_chars = []
Ting.valid_combinations do |i,f|
1.upto(5) do |tone|
valid_chars += @tone.add_tone(Conversions.unparse(:hanyu,Syllable.new(i,f)), tone).chars.to_a
end
end
valid_chars.sort!.uniq!
Regexp.new(valid_chars.map{|ch| Regexp.escape(ch)}.join('|'))
end
def parse(string)
result = []
looking_at = []
string.chars.each do |ch|
head, syll = parse_tail(looking_at)
looking_at << ch
if syll && !parse_tail(looking_at)
puts "-> #{syll.inspect}"
result << head.to_s unless head.empty?
result << syll
looking_at = [ch]
end
end
result
end
def parse_tail(chars)
7.downto(1) do |i|
head = chars[0...-i]
tail = chars[-i..-1]
syll = parse_syllable( tail )
return head, syll if syll
end
nil
end
def parse_syllable(tone_syll)
tone_syll = tone_syll.to_s
tone_syll = @options[:preprocess].call(tone_syll) if @options[:preprocess]
tone, syll = @tone.pop_tone(tone_syll)
if tone && syll
ini_fini = Conversions.parse(:hanyu,syll)
if ini_fini
p tone, syll, ini_fini
ini, fini = ini_fini.initial, ini_fini.final
end
return Syllable.new(ini, fini, tone) if tone && ini && fini
end
end
end
end
end