lib/ting/conversions/hanyu.rb

Summary

Maintainability
A
1 hr
Test Coverage
# 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