lib/kanjika/conjugator/masu.rb
require_relative "base" module Kanjika module Conjugator class Masu < Base GODAN_ENDINGS = { "う" => "い", # e.g., 会う → 会います "く" => "き", # e.g., 書く → 書きます "ぐ" => "ぎ", # e.g., 泳ぐ → 泳ぎます "す" => "し", # e.g., 話す → 話します "つ" => "ち", # e.g., 持つ → 持ちます "ぬ" => "に", # e.g., 死ぬ → 死にます "ぶ" => "び", # e.g., 飛ぶ → 飛びます "む" => "み", # e.g., 読む → 読みます "る" => "り" # e.g., 切る → 切ります } CONJUGATION_RULES = { ichidan: ->(stem) { stem + "ます" }, godan: ->(stem, last_char) { stem + GODAN_ENDINGS[last_char] + "ます" }, irregular: ->(verb) { IRREGULAR_MASU_FORMS[verb] } } def conjugate Ve.in(:ja).words(verb).flat_map do |word| word.tokens.map { |token| conjugate_token(word, token) }.join end.join end private def conjugate_token(word, token) if word.part_of_speech.name == "verb" conjugate_verb(token) else conjugate_others(token) end end def conjugate_verb(token) verb_type = determine_verb_type(token) apply_conjugation_rule(verb_type) end def determine_verb_type(token) return :ichidan if ichidan?(token) return :godan if godan?(token) :irregular if irregular?(token) end def apply_conjugation_rule(verb_type) rule = CONJUGATION_RULES[verb_type] case verb_type when :ichidan rule.call(stem) when :godan rule.call(stem, verb[-1]) when :irregular rule.call(verb) end end def conjugate_others(token) return verb + "します" if verb.kanji? if ending_in_e_or_i? CONJUGATION_RULES[:ichidan].call(stem) elsif godan_ending? CONJUGATION_RULES[:godan].call(stem, verb[-1]) end end def ichidan?(token) token[:inflection_type].match?(ICHIDAN) end def godan?(token) token[:inflection_type].match?(GODAN) end def irregular?(token) token[:inflection_type].match?(SURU) || token[:inflection_type].match?(KURU) end def ending_in_e_or_i? E_ENDINGS.include?(verb[-2]) || I_ENDINGS.include?(verb[-2]) end def godan_ending? GODAN_ENDINGS.key?(verb[-1]) end def stem verb.chop end end end end