katsuyoujin 0.0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +674 -0
- data/README.md +3 -0
- data/Rakefile +4 -0
- data/katsuyoujin.gemspec +26 -0
- data/lib/katsuyoujin.rb +22 -0
- data/lib/katsuyoujin/analyzer.rb +44 -0
- data/lib/katsuyoujin/base.rb +37 -0
- data/lib/katsuyoujin/verb.rb +31 -0
- data/lib/katsuyoujin/version.rb +3 -0
- data/rules/godan/base.yml +70 -0
- data/rules/godan/conjugations.yml +30 -0
- data/rules/godan/iru_eru.yml +86 -0
- data/rules/ichidan/base.yml +7 -0
- data/rules/ichidan/conjugations.yml +30 -0
- data/spec/fixtures/conjugations.yml +150 -0
- data/spec/fixtures/godan/base.yml +72 -0
- data/spec/fixtures/ichidan/base.yml +24 -0
- data/spec/lib/base_spec.rb +15 -0
- data/spec/lib/conjugations_spec.rb +40 -0
- data/spec/spec_helper.rb +9 -0
- metadata +131 -0
data/README.md
ADDED
data/Rakefile
ADDED
data/katsuyoujin.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'katsuyoujin/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'katsuyoujin'
|
8
|
+
spec.version = Katsuyoujin::VERSION
|
9
|
+
spec.authors = ['LuckyThirteen']
|
10
|
+
spec.email = ['baloghzsof@gmail.com']
|
11
|
+
spec.summary = 'Japanese verb conjugator.'
|
12
|
+
spec.description = ''
|
13
|
+
spec.homepage = 'https://github.com/LuckyThirteen/katsuyoujin'
|
14
|
+
spec.license = 'GPLv3'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'mojinizer'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'rspec'
|
26
|
+
end
|
data/lib/katsuyoujin.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
require 'katsuyoujin/version'
|
4
|
+
require 'katsuyoujin/verb'
|
5
|
+
require 'katsuyoujin/base'
|
6
|
+
require 'katsuyoujin/analyzer'
|
7
|
+
|
8
|
+
module Katsuyoujin
|
9
|
+
CONJUGATIONS = { 'ichidan' => YAML.load_file('rules/ichidan/conjugations.yml'),
|
10
|
+
'godan' => YAML.load_file('rules/godan/conjugations.yml') }
|
11
|
+
|
12
|
+
def self.conjugate(word, *args, category: nil, hiragana: true)
|
13
|
+
verb = Verb.new word
|
14
|
+
|
15
|
+
vcat = category || verb.category
|
16
|
+
rules = args.inject(CONJUGATIONS[vcat]) { |conjugations, rule| conjugations[rule] || {} }
|
17
|
+
return unless rules['base']
|
18
|
+
|
19
|
+
base = Base.new(verb, rules['base']).conjugate category: category, hiragana: hiragana
|
20
|
+
base + rules['attachment']
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'kuromoji'
|
2
|
+
require 'mojinizer'
|
3
|
+
|
4
|
+
module Katsuyoujin
|
5
|
+
class Analyzer
|
6
|
+
attr_reader :word
|
7
|
+
|
8
|
+
def initialize(word)
|
9
|
+
@word = word
|
10
|
+
end
|
11
|
+
|
12
|
+
def verb
|
13
|
+
analysis.detect do |part|
|
14
|
+
part['parts_of_speech'].split(/\s*,\s*/).include? '動詞'
|
15
|
+
end || {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def base_form
|
19
|
+
verb['base_form'].to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
def base_form_hiragana
|
23
|
+
verb['reading'].to_s.hiragana
|
24
|
+
end
|
25
|
+
|
26
|
+
def verb_category
|
27
|
+
return nil unless base_form
|
28
|
+
|
29
|
+
case
|
30
|
+
when ['する'].include?(base_form_hiragana.chars.last(2).join) then 'irregular'
|
31
|
+
when 'くる' == base_form_hiragana then 'irregular'
|
32
|
+
when YAML.load_file('rules/godan/iru_eru.yml').include?(base_form_hiragana) then 'godan'
|
33
|
+
when ['iru', 'eru'].include?(base_form_hiragana.romaji.chars.last(3).join) then 'ichidan'
|
34
|
+
else 'godan'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def analysis
|
41
|
+
@analysis ||= Kuromoji::Core.new.tokenize_with_hash word
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Katsuyoujin
|
2
|
+
class Base
|
3
|
+
attr_reader :verb, :base_letter
|
4
|
+
|
5
|
+
ICHIDAN_BASE_TABLE = YAML.load_file 'rules/ichidan/base.yml'
|
6
|
+
GODAN_BASE_TABLE = YAML.load_file 'rules/godan/base.yml'
|
7
|
+
|
8
|
+
def initialize(verb, base_letter)
|
9
|
+
@verb = verb
|
10
|
+
@base_letter = base_letter
|
11
|
+
end
|
12
|
+
|
13
|
+
def conjugate(category: nil, hiragana: true)
|
14
|
+
case category || verb.category
|
15
|
+
when 'ichidan' then ichidan_base(verb, base_letter, hiragana: hiragana)
|
16
|
+
when 'godan' then godan_base(verb, base_letter, hiragana: hiragana)
|
17
|
+
when 'irregular' then irregular_base(verb, base_letter, hiragana: hiragana)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def ichidan_base(verb, base_letter, hiragana: true)
|
22
|
+
verb_root(hiragana) + ICHIDAN_BASE_TABLE[base_letter]
|
23
|
+
end
|
24
|
+
|
25
|
+
def godan_base(verb, base_letter, hiragana: true)
|
26
|
+
verb_root(hiragana) + GODAN_BASE_TABLE[base_letter][verb.ending]
|
27
|
+
end
|
28
|
+
|
29
|
+
def irregular_base(verb, base_letter, hiragana: true)
|
30
|
+
fail NotImplementedError
|
31
|
+
end
|
32
|
+
|
33
|
+
def verb_root(hiragana = true)
|
34
|
+
hiragana ? verb.hiragana_root : verb.root
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Katsuyoujin
|
2
|
+
class Verb
|
3
|
+
def initialize(word)
|
4
|
+
@analyzer = Analyzer.new word
|
5
|
+
end
|
6
|
+
|
7
|
+
def dictionary_form
|
8
|
+
@analyzer.base_form
|
9
|
+
end
|
10
|
+
|
11
|
+
def dictionary_form_hiragana
|
12
|
+
@analyzer.base_form_hiragana
|
13
|
+
end
|
14
|
+
|
15
|
+
def category
|
16
|
+
@analyzer.verb_category
|
17
|
+
end
|
18
|
+
|
19
|
+
def ending
|
20
|
+
dictionary_form[-1]
|
21
|
+
end
|
22
|
+
|
23
|
+
def root
|
24
|
+
dictionary_form.chomp ending
|
25
|
+
end
|
26
|
+
|
27
|
+
def hiragana_root
|
28
|
+
dictionary_form_hiragana.chomp ending
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
"あ":
|
2
|
+
"す": "さ"
|
3
|
+
"く": "か"
|
4
|
+
"ぐ": "が"
|
5
|
+
"ぶ": "ば"
|
6
|
+
"む": "ま"
|
7
|
+
"ぬ": "な"
|
8
|
+
"る": "ら"
|
9
|
+
"つ": "た"
|
10
|
+
"う": "わ"
|
11
|
+
"い":
|
12
|
+
"す": "し"
|
13
|
+
"く": "き"
|
14
|
+
"ぐ": "ぎ"
|
15
|
+
"ぶ": "び"
|
16
|
+
"む": "み"
|
17
|
+
"ぬ": "に"
|
18
|
+
"る": "り"
|
19
|
+
"つ": "ち"
|
20
|
+
"う": "い"
|
21
|
+
"う":
|
22
|
+
"す": "す"
|
23
|
+
"く": "く"
|
24
|
+
"ぐ": "ぐ"
|
25
|
+
"ぶ": "ぶ"
|
26
|
+
"む": "む"
|
27
|
+
"ぬ": "ぬ"
|
28
|
+
"る": "る"
|
29
|
+
"つ": "つ"
|
30
|
+
"う": "う"
|
31
|
+
"え":
|
32
|
+
"す": "せ"
|
33
|
+
"く": "け"
|
34
|
+
"ぐ": "げ"
|
35
|
+
"ぶ": "べ"
|
36
|
+
"む": "め"
|
37
|
+
"ぬ": "ね"
|
38
|
+
"る": "れ"
|
39
|
+
"つ": "て"
|
40
|
+
"う": "え"
|
41
|
+
"お":
|
42
|
+
"す": "そう"
|
43
|
+
"く": "こう"
|
44
|
+
"ぐ": "ごう"
|
45
|
+
"ぶ": "ぼう"
|
46
|
+
"む": "もう"
|
47
|
+
"ぬ": "のう"
|
48
|
+
"る": "ろう"
|
49
|
+
"つ": "とう"
|
50
|
+
"う": "おう"
|
51
|
+
"て":
|
52
|
+
"す": "して"
|
53
|
+
"く": "いて"
|
54
|
+
"ぐ": "いで"
|
55
|
+
"ぶ": "んで"
|
56
|
+
"む": "んで"
|
57
|
+
"ぬ": "んで"
|
58
|
+
"る": "って"
|
59
|
+
"つ": "って"
|
60
|
+
"う": "って"
|
61
|
+
"た":
|
62
|
+
"す": "した"
|
63
|
+
"く": "いた"
|
64
|
+
"ぐ": "いだ"
|
65
|
+
"ぶ": "んだ"
|
66
|
+
"む": "んだ"
|
67
|
+
"ぬ": "んだ"
|
68
|
+
"る": "った"
|
69
|
+
"つ": "った"
|
70
|
+
"う": "った"
|
@@ -0,0 +1,30 @@
|
|
1
|
+
"casual":
|
2
|
+
"nonpast_indicative":
|
3
|
+
"affirmative":
|
4
|
+
"base": "う"
|
5
|
+
"attachment": ""
|
6
|
+
"negative":
|
7
|
+
"base": "あ"
|
8
|
+
"attachment": "ない"
|
9
|
+
"past_indicative":
|
10
|
+
"affirmative":
|
11
|
+
"base": "た"
|
12
|
+
"attachment": ""
|
13
|
+
"negative":
|
14
|
+
"base": "あ"
|
15
|
+
"attachment": "なかった"
|
16
|
+
"polite":
|
17
|
+
"nonpast_indicative":
|
18
|
+
"affirmative":
|
19
|
+
"base": "い"
|
20
|
+
"attachment": "ます"
|
21
|
+
"negative":
|
22
|
+
"base": "い"
|
23
|
+
"attachment": "ません"
|
24
|
+
"past_indicative":
|
25
|
+
"affirmative":
|
26
|
+
"base": "い"
|
27
|
+
"attachment": "ました"
|
28
|
+
"negative":
|
29
|
+
"base": "い"
|
30
|
+
"attachment": "ませんでした"
|
@@ -0,0 +1,86 @@
|
|
1
|
+
- "あせる"
|
2
|
+
- "あざける"
|
3
|
+
- "だべる"
|
4
|
+
- "える"
|
5
|
+
- "ふける"
|
6
|
+
- "ふせる"
|
7
|
+
- "はべる"
|
8
|
+
- "へる"
|
9
|
+
- "ひねる"
|
10
|
+
- "ひるがえる"
|
11
|
+
- "ほてる"
|
12
|
+
- "かえる"
|
13
|
+
- "かげる"
|
14
|
+
- "かける"
|
15
|
+
- "ける"
|
16
|
+
- "くねる"
|
17
|
+
- "くつがえる"
|
18
|
+
- "める"
|
19
|
+
- "ねる"
|
20
|
+
- "のめる"
|
21
|
+
- "ぬめる"
|
22
|
+
- "おもねる"
|
23
|
+
- "せる"
|
24
|
+
- "せせる"
|
25
|
+
- "しゃべる"
|
26
|
+
- "しげる"
|
27
|
+
- "しける"
|
28
|
+
- "しめる"
|
29
|
+
- "そべる"
|
30
|
+
- "すべる"
|
31
|
+
- "たける"
|
32
|
+
- "てる"
|
33
|
+
- "つねる"
|
34
|
+
- "うねる"
|
35
|
+
- "うせる"
|
36
|
+
- "よみがえる"
|
37
|
+
- "あぶらぎる"
|
38
|
+
- "びびる"
|
39
|
+
- "ちぎる"
|
40
|
+
- "ちる"
|
41
|
+
- "どじる"
|
42
|
+
- "ぐちる"
|
43
|
+
- "はいる"
|
44
|
+
- "はしる"
|
45
|
+
- "ひる"
|
46
|
+
- "ほじる"
|
47
|
+
- "ほとばしる"
|
48
|
+
- "いびる"
|
49
|
+
- "いじる"
|
50
|
+
- "いきる"
|
51
|
+
- "いる"
|
52
|
+
- "かぎる"
|
53
|
+
- "かじる"
|
54
|
+
- "きる"
|
55
|
+
- "きしる"
|
56
|
+
- "こじる"
|
57
|
+
- "くびる"
|
58
|
+
- "くじる"
|
59
|
+
- "まいる"
|
60
|
+
- "まじる"
|
61
|
+
- "めいる"
|
62
|
+
- "みくびる"
|
63
|
+
- "みなぎる"
|
64
|
+
- "もぎる"
|
65
|
+
- "もじる"
|
66
|
+
- "むしる"
|
67
|
+
- "なじる"
|
68
|
+
- "ねじる"
|
69
|
+
- "にぎる"
|
70
|
+
- "にじる"
|
71
|
+
- "ののしる"
|
72
|
+
- "おちいる"
|
73
|
+
- "おもいいる"
|
74
|
+
- "おもいきる"
|
75
|
+
- "せびる"
|
76
|
+
- "しる"
|
77
|
+
- "そしる"
|
78
|
+
- "すじる"
|
79
|
+
- "たぎる"
|
80
|
+
- "たまぎる"
|
81
|
+
- "とばしる"
|
82
|
+
- "とちる"
|
83
|
+
- "やじる"
|
84
|
+
- "よぎる"
|
85
|
+
- "よじる"
|
86
|
+
- "よこぎる"
|
@@ -0,0 +1,30 @@
|
|
1
|
+
"casual":
|
2
|
+
"nonpast_indicative":
|
3
|
+
"affirmative":
|
4
|
+
"base": "う"
|
5
|
+
"attachment": ""
|
6
|
+
"negative":
|
7
|
+
"base": "あ"
|
8
|
+
"attachment": "ない"
|
9
|
+
"past_indicative":
|
10
|
+
"affirmative":
|
11
|
+
"base": "た"
|
12
|
+
"attachment": ""
|
13
|
+
"negative":
|
14
|
+
"base": "あ"
|
15
|
+
"attachment": "なかった"
|
16
|
+
"polite":
|
17
|
+
"nonpast_indicative":
|
18
|
+
"affirmative":
|
19
|
+
"base": "い"
|
20
|
+
"attachment": "ます"
|
21
|
+
"negative":
|
22
|
+
"base": "い"
|
23
|
+
"attachment": "ません"
|
24
|
+
"past_indicative":
|
25
|
+
"affirmative":
|
26
|
+
"base": "い"
|
27
|
+
"attachment": "ました"
|
28
|
+
"negative":
|
29
|
+
"base": "い"
|
30
|
+
"attachment": "ませんでした"
|
@@ -0,0 +1,150 @@
|
|
1
|
+
"食べる":
|
2
|
+
"casual":
|
3
|
+
"nonpast_indicative":
|
4
|
+
"affirmative": "たべる"
|
5
|
+
"negative": "たべない"
|
6
|
+
"past_indicative":
|
7
|
+
"affirmative": "たべた"
|
8
|
+
"negative": "たべなかった"
|
9
|
+
"polite":
|
10
|
+
"nonpast_indicative":
|
11
|
+
"affirmative": "たべます"
|
12
|
+
"negative": "たべません"
|
13
|
+
"past_indicative":
|
14
|
+
"affirmative": "たべました"
|
15
|
+
"negative": "たべませんでした"
|
16
|
+
"話す":
|
17
|
+
"casual":
|
18
|
+
"nonpast_indicative":
|
19
|
+
"affirmative": "はなす"
|
20
|
+
"negative": "はなさない"
|
21
|
+
"past_indicative":
|
22
|
+
"affirmative": "はなした"
|
23
|
+
"negative": "はなさなかった"
|
24
|
+
"polite":
|
25
|
+
"nonpast_indicative":
|
26
|
+
"affirmative": "はなします"
|
27
|
+
"negative": "はなしません"
|
28
|
+
"past_indicative":
|
29
|
+
"affirmative": "はなしました"
|
30
|
+
"negative": "はなしませんでした"
|
31
|
+
"歩く":
|
32
|
+
"casual":
|
33
|
+
"nonpast_indicative":
|
34
|
+
"affirmative": "あるく"
|
35
|
+
"negative": "あるかない"
|
36
|
+
"past_indicative":
|
37
|
+
"affirmative": "あるいた"
|
38
|
+
"negative": "あるかなかった"
|
39
|
+
"polite":
|
40
|
+
"nonpast_indicative":
|
41
|
+
"affirmative": "あるきます"
|
42
|
+
"negative": "あるきません"
|
43
|
+
"past_indicative":
|
44
|
+
"affirmative": "あるきました"
|
45
|
+
"negative": "あるきませんでした"
|
46
|
+
"泳ぐ":
|
47
|
+
"casual":
|
48
|
+
"nonpast_indicative":
|
49
|
+
"affirmative": "およぐ"
|
50
|
+
"negative": "およがない"
|
51
|
+
"past_indicative":
|
52
|
+
"affirmative": "およいだ"
|
53
|
+
"negative": "およがなかった"
|
54
|
+
"polite":
|
55
|
+
"nonpast_indicative":
|
56
|
+
"affirmative": "およぎます"
|
57
|
+
"negative": "およぎません"
|
58
|
+
"past_indicative":
|
59
|
+
"affirmative": "およぎました"
|
60
|
+
"negative": "およぎませんでした"
|
61
|
+
"呼ぶ":
|
62
|
+
"casual":
|
63
|
+
"nonpast_indicative":
|
64
|
+
"affirmative": "よぶ"
|
65
|
+
"negative": "よばない"
|
66
|
+
"past_indicative":
|
67
|
+
"affirmative": "よんだ"
|
68
|
+
"negative": "よばなかった"
|
69
|
+
"polite":
|
70
|
+
"nonpast_indicative":
|
71
|
+
"affirmative": "よびます"
|
72
|
+
"negative": "よびません"
|
73
|
+
"past_indicative":
|
74
|
+
"affirmative": "よびました"
|
75
|
+
"negative": "よびませんでした"
|
76
|
+
"飲む":
|
77
|
+
"casual":
|
78
|
+
"nonpast_indicative":
|
79
|
+
"affirmative": "のむ"
|
80
|
+
"negative": "のまない"
|
81
|
+
"past_indicative":
|
82
|
+
"affirmative": "のんだ"
|
83
|
+
"negative": "のまなかった"
|
84
|
+
"polite":
|
85
|
+
"nonpast_indicative":
|
86
|
+
"affirmative": "のみます"
|
87
|
+
"negative": "のみません"
|
88
|
+
"past_indicative":
|
89
|
+
"affirmative": "のみました"
|
90
|
+
"negative": "のみませんでした"
|
91
|
+
"死ぬ":
|
92
|
+
"casual":
|
93
|
+
"nonpast_indicative":
|
94
|
+
"affirmative": "しぬ"
|
95
|
+
"negative": "しなない"
|
96
|
+
"past_indicative":
|
97
|
+
"affirmative": "しんだ"
|
98
|
+
"negative": "しななかった"
|
99
|
+
"polite":
|
100
|
+
"nonpast_indicative":
|
101
|
+
"affirmative": "しにます"
|
102
|
+
"negative": "しにません"
|
103
|
+
"past_indicative":
|
104
|
+
"affirmative": "しにました"
|
105
|
+
"negative": "しにませんでした"
|
106
|
+
"作る":
|
107
|
+
"casual":
|
108
|
+
"nonpast_indicative":
|
109
|
+
"affirmative": "つくる"
|
110
|
+
"negative": "つくらない"
|
111
|
+
"past_indicative":
|
112
|
+
"affirmative": "つくった"
|
113
|
+
"negative": "つくらなかった"
|
114
|
+
"polite":
|
115
|
+
"nonpast_indicative":
|
116
|
+
"affirmative": "つくります"
|
117
|
+
"negative": "つくりません"
|
118
|
+
"past_indicative":
|
119
|
+
"affirmative": "つくりました"
|
120
|
+
"negative": "つくりませんでした"
|
121
|
+
"待つ":
|
122
|
+
"casual":
|
123
|
+
"nonpast_indicative":
|
124
|
+
"affirmative": "まつ"
|
125
|
+
"negative": "またない"
|
126
|
+
"past_indicative":
|
127
|
+
"affirmative": "まった"
|
128
|
+
"negative": "またなかった"
|
129
|
+
"polite":
|
130
|
+
"nonpast_indicative":
|
131
|
+
"affirmative": "まちます"
|
132
|
+
"negative": "まちません"
|
133
|
+
"past_indicative":
|
134
|
+
"affirmative": "まちました"
|
135
|
+
"negative": "まちませんでした"
|
136
|
+
"洗う":
|
137
|
+
"casual":
|
138
|
+
"nonpast_indicative":
|
139
|
+
"affirmative": "あらう"
|
140
|
+
"negative": "あらわない"
|
141
|
+
"past_indicative":
|
142
|
+
"affirmative": "あらった"
|
143
|
+
"negative": "あらわなかった"
|
144
|
+
"polite":
|
145
|
+
"nonpast_indicative":
|
146
|
+
"affirmative": "あらいます"
|
147
|
+
"negative": "あらいません"
|
148
|
+
"past_indicative":
|
149
|
+
"affirmative": "あらいました"
|
150
|
+
"negative": "あらいませんでした"
|