Module: Daidai::Conjugator

Defined in:
lib/daidai/conjugator.rb

Overview

Turns a dictionary-form word + its JMdict part-of-speech into the full conjugation paradigm. This is a faithful Ruby port of jconj’s table-driven algorithm (Stuart McGraw / EDRDG; GPL) — all the linguistic knowledge lives in the vendored tables, this just applies them.

Constant Summary collapse

QUADRANTS =

The four (negative?, polite?) quadrants every conjugation is generated in.

[ [ false, false ], [ false, true ], [ true, false ], [ true, true ] ].freeze
DIRECT =

JMdict codes whose full paradigm lives directly in conjo.csv, mapped to a coarse kind for grouping. Archaic classes (v2*, v4*) and bare nouns are deliberately absent — they simply aren’t offered for conjugation.

{
  "adj-i" => :i_adjective, "adj-ix" => :i_adjective,
  "v1" => :ichidan, "v1-s" => :ichidan,
  "v5aru" => :godan, "v5b" => :godan, "v5g" => :godan, "v5k" => :godan,
  "v5k-s" => :godan, "v5m" => :godan, "v5n" => :godan, "v5r" => :godan,
  "v5r-i" => :godan, "v5s" => :godan, "v5t" => :godan, "v5u" => :godan,
  "v5u-s" => :godan,
  "vk" => :kuru, "vs-i" => :suru, "vs-s" => :suru
}.freeze
COPULA_POS =

the copula だ — na-adjectives conjugate through it

15
SURU_POS =

vs-i (する) — ‘vs` nouns conjugate by appending する

48

Class Method Summary collapse

Class Method Details

.conjugatable?(pos) ⇒ Boolean

True if any of ‘pos` (a JMdict code or array of codes) can be conjugated.

Returns:

  • (Boolean)


33
34
35
# File 'lib/daidai/conjugator.rb', line 33

def conjugatable?(pos)
  Array(pos).any? { |code| strategy(code.to_s) }
end

.conjugate(kanji:, reading:, pos:) ⇒ Object

Conjugate ‘kanji`/`reading` (dictionary forms) according to `pos`. When `pos` is an array the first conjugatable code wins. Returns a Result, or nil when nothing is conjugatable.



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/daidai/conjugator.rb', line 40

def conjugate(kanji:, reading:, pos:)
  code = Array(pos).map(&:to_s).find { |c| strategy(c) }
  return nil unless code

  strat   = strategy(code)
  kanji   = nil if kanji.to_s.empty?
  reading = reading.to_s
  return nil if kanji.nil? && reading.empty?

  forms = build(strat, kanji, reading)
  forms.empty? ? nil : Word.new(word: kanji || reading, pos: code, kind: strat[:kind], forms: forms)
end