language_cards 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/cards/{japanese-hiragana.yml → en/japanese-hiragana.yml} +0 -0
- data/cards/en/japanese-kanji-jlpt-n5.yml +107 -0
- data/cards/{japanese-katakana.yml → en/japanese-katakana.yml} +0 -0
- data/language_cards.gemspec +12 -12
- data/lib/language_cards.rb +7 -2
- data/lib/language_cards/controllers/application_controller.rb +27 -0
- data/lib/language_cards/controllers/game.rb +51 -55
- data/lib/language_cards/controllers/main_menu.rb +14 -19
- data/lib/language_cards/helpers/view_helper.rb +8 -0
- data/lib/language_cards/language_cards.rb +11 -41
- data/lib/language_cards/user_interface.rb +19 -4
- data/lib/language_cards/version.rb +1 -1
- data/lib/language_cards/view/game.erb +1 -1
- data/lib/language_cards/view/main_menu.erb +1 -1
- data/lib/language_cards/yaml_loader.rb +49 -0
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 409fa54cd14dc132b49083d8e4a26cd768803b13aff44e822da5c23cd5898e9a
|
4
|
+
data.tar.gz: ba9fcbcf3df0a95c6b7984772c90a21560beefa4790058b277dbce27515b6924
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83285da9cb6ac703432739dc0f20ed8155bc84e73891f171b8aab07d9744b41da30ba997b5e6a8266cba55186216e31a417718ea84d45dcf9b7a8e7793568d93
|
7
|
+
data.tar.gz: b310a242bb5e3299bedbc306829becbab0f82bb602a4884bde516ad52356b833670ac9542c8433347dcdc43c7845b8403b2729bf345cc162c403debfd616cae4
|
File without changes
|
@@ -0,0 +1,107 @@
|
|
1
|
+
--- # https://www.jlptstudy.net/N5/?kanji-list
|
2
|
+
Japanese:
|
3
|
+
Kanji (JLPT Level N5):
|
4
|
+
mapping: { Kanji: [Hiragana, English] }
|
5
|
+
一: [ひと, ひとつ, one, only, even, 1]
|
6
|
+
七: [なな, seven, 7]
|
7
|
+
万: [よろず, ten thousand]
|
8
|
+
三: [さん, three, 3]
|
9
|
+
上: [うえ, above, up]
|
10
|
+
下: [した, below, down, descend, give, low, inferior]
|
11
|
+
中: [なか, in, inside, middle, mean, center]
|
12
|
+
九: [ここの, nine, 9]
|
13
|
+
二: [に, two, 2]
|
14
|
+
五: [ご, five, 5]
|
15
|
+
人: [ひと, people, person, man, human being, other people, mankind]
|
16
|
+
今: [いま, now]
|
17
|
+
休: [きゅう, rest, day off, retire, sleep]
|
18
|
+
会: [かい, gathering, meeting, meet, party, association, interview, join]
|
19
|
+
何: [なに, なん, what]
|
20
|
+
先: [さき, before, ahead, previous, future, precedence]
|
21
|
+
入: [いり, enter, insert]
|
22
|
+
八: [はち, eight, 8]
|
23
|
+
六: [ろく, six, 6]
|
24
|
+
円: [えん, circle, yen, round]
|
25
|
+
出: [で, exit, leave]
|
26
|
+
分: [ぶん, part, minute of time, segment, share, degree, one's lot, duty, understand, know, rate, 1%, chances, shaku/100]
|
27
|
+
前: [まえ, in front, before]
|
28
|
+
北: [きた, north]
|
29
|
+
十: [じゅう, ten, 10]
|
30
|
+
千: [せん, thousand, 1000]
|
31
|
+
午: [うま, noon, sign of the horse, 11AM-1PM, seventh sign of Chinese zodiac]
|
32
|
+
半: [はん, half, middle, odd number, semi-, part-]
|
33
|
+
南: [みなみ, south]
|
34
|
+
友: [とも, friend]
|
35
|
+
口: [くち, mouth]
|
36
|
+
古: [ふる, old]
|
37
|
+
右: [みぎ, right]
|
38
|
+
名: [な, name, noted, distinguished, reputation]
|
39
|
+
四: [よん, four, 4]
|
40
|
+
国: [くに, country, state, region, province, home, hometown, homeland, home country, land, earth]
|
41
|
+
土: [つち, soil, earth, ground, Turkey]
|
42
|
+
外: [そと, outside, outside of]
|
43
|
+
多: [さわ, many, frequent, much]
|
44
|
+
大: [おお, large, big]
|
45
|
+
天: [てん, heavens, sky, imperial]
|
46
|
+
女: [おんな, woman, female]
|
47
|
+
子: [こ, child, sign of the rat, 11PM-1AM, first sign of Chinese zodiac]
|
48
|
+
学: [がく, study, learning, science]
|
49
|
+
安: [あん, cheap, relax, low, quiet, rested, contented, peaceful]
|
50
|
+
小: [しょう, little, small]
|
51
|
+
少: [すくな, few, little]
|
52
|
+
山: [やま, mountain]
|
53
|
+
川: [かわ, stream, river]
|
54
|
+
左: [ひだり, left]
|
55
|
+
年: [とし, year, counter for years, age]
|
56
|
+
店: [みせ, store, shop]
|
57
|
+
後: [あと, behind, back, later]
|
58
|
+
手: [て, hand]
|
59
|
+
新: [しん, new]
|
60
|
+
日: [ひ, day, sun, Japan, counter for days, sunshine, sunlight, case, event]
|
61
|
+
時: [じ, time, hour]
|
62
|
+
書: [しょ, write]
|
63
|
+
月: [つき, month, moon]
|
64
|
+
木: [き, tree, wood]
|
65
|
+
本: [もと, book, present, main, 'true', real, counter for long cylindrical things]
|
66
|
+
来: [き, come, due, next, cause, become]
|
67
|
+
東: [ひがし, east]
|
68
|
+
校: [-こう, exam, school, printing, proof, correction]
|
69
|
+
母: [はは, mama, mother]
|
70
|
+
毎: [まい, every]
|
71
|
+
気: [いき, spirit, mind, air, atmosphere, mood]
|
72
|
+
水: [みず, water]
|
73
|
+
火: [ひ, fire]
|
74
|
+
父: [ちち, father]
|
75
|
+
生: [なま, life, genuine, birth]
|
76
|
+
男: [おとこ, male]
|
77
|
+
白: [しろ, white]
|
78
|
+
百: [もも, hundred, 100]
|
79
|
+
目: [め, eye, class, look, insight, experience, care, favor]
|
80
|
+
社: [やしろ, company, firm, office, association, shrine]
|
81
|
+
空: [そら, empty, sky, void, vacant, vacuum]
|
82
|
+
立: [たて, stand up]
|
83
|
+
耳: [みみ, ear]
|
84
|
+
聞: [きき, hear, ask, listen]
|
85
|
+
花: [はな, flower]
|
86
|
+
行: [こう, going, journey]
|
87
|
+
西: [にし, west, Spain]
|
88
|
+
見: [み, see, hopes, chances, idea, opinion, look at, visible]
|
89
|
+
言: [げん, say]
|
90
|
+
話: [はなし, tale, talk]
|
91
|
+
語: [ご, word, speech, language]
|
92
|
+
読: [よみ, read]
|
93
|
+
買: [かい, buy]
|
94
|
+
足: [あし, leg, foot, be sufficient, counter for pairs of footwear]
|
95
|
+
車: [くるま, car]
|
96
|
+
週: [しゅう, week]
|
97
|
+
道: [みち, road-way, street, district, journey, course, moral, teachings]
|
98
|
+
金: [きん, gold]
|
99
|
+
長: [なが, long, leader]
|
100
|
+
間: [ま, interval, space]
|
101
|
+
雨: [あめ, rain]
|
102
|
+
電: [でん, electricity]
|
103
|
+
食: [しょく, eat, food]
|
104
|
+
飲: [いん, drink, smoke, take]
|
105
|
+
駅: [えき, station]
|
106
|
+
高: [こう, tall, high, expensive]
|
107
|
+
魚: [さかな, fish]
|
File without changes
|
data/language_cards.gemspec
CHANGED
@@ -4,27 +4,27 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'language_cards/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'language_cards'
|
8
8
|
spec.version = LanguageCards::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Daniel P. Clark']
|
10
|
+
spec.email = ['6ftdan@gmail.com']
|
11
11
|
|
12
12
|
spec.summary = %q{Flashcard game for language learning.}
|
13
13
|
spec.description = %q{Flashcard game for language learning. Make your own cards or translations as well.}
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
14
|
+
spec.homepage = 'http://github.com/danielpclark/language_cards'
|
15
|
+
spec.license = 'MIT'
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
18
|
f.match(%r{^(test|spec|features)/})
|
19
19
|
end
|
20
20
|
|
21
21
|
spec.executables = ['language_cards']
|
22
|
-
spec.require_paths = [
|
22
|
+
spec.require_paths = ['lib','cards']
|
23
23
|
|
24
|
-
spec.add_dependency
|
25
|
-
spec.add_dependency
|
26
|
-
spec.add_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
24
|
+
spec.add_dependency 'highline', '~> 1.7'
|
25
|
+
spec.add_dependency 'i18n', '~> 0.7'
|
26
|
+
spec.add_dependency 'slop', '~> 4.6'
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
28
|
+
spec.add_development_dependency 'rake', '~> 12.3'
|
29
|
+
spec.add_development_dependency 'minitest', '~> 5.10'
|
30
30
|
end
|
data/lib/language_cards.rb
CHANGED
@@ -2,17 +2,22 @@ require 'language_cards/version'
|
|
2
2
|
require 'language_cards/language_cards'
|
3
3
|
require 'yaml'
|
4
4
|
require 'i18n'
|
5
|
+
require 'slop'
|
5
6
|
require 'highline'
|
6
|
-
require 'elixirize'
|
7
7
|
|
8
8
|
##
|
9
9
|
# TODO:
|
10
10
|
# * Implement score-keeper
|
11
11
|
# * Race against the clock
|
12
12
|
# * Weighted random for better learning
|
13
|
-
# * Value to Value is simply keyboard practice and should be clocked
|
14
13
|
|
15
14
|
module LanguageCards
|
15
|
+
OPTS = Slop.parse do |args|
|
16
|
+
args.string '-l', '--language', 'language (default: en)', default: 'en'
|
17
|
+
end
|
18
|
+
|
19
|
+
CARD_LANGUAGE = OPTS[:language]
|
20
|
+
|
16
21
|
module ESC
|
17
22
|
CLEAR = (ERASE_SCOLLBACK = "\e[3J") + (CURSOR_HOME = "\e[H") + (ERASE_DISPLAY = "\e[2J")
|
18
23
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module LanguageCards
|
2
|
+
module Controllers
|
3
|
+
class ApplicationController
|
4
|
+
include Helpers::ViewHelper
|
5
|
+
|
6
|
+
def initialize(opts = {})
|
7
|
+
@opts = opts
|
8
|
+
end
|
9
|
+
|
10
|
+
def render(_binding)
|
11
|
+
view = ERB.new IO.read File.expand_path("../view/#{snake name}.erb", __dir__)
|
12
|
+
|
13
|
+
view.result(_binding)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
attr_reader :opts
|
18
|
+
def name
|
19
|
+
self.class.name.split('::').last
|
20
|
+
end
|
21
|
+
|
22
|
+
def errors
|
23
|
+
Array(opts[:errors])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,72 +1,68 @@
|
|
1
|
+
require 'language_cards/controllers/application_controller'
|
2
|
+
|
1
3
|
module LanguageCards
|
2
4
|
module Controllers
|
3
|
-
|
4
|
-
|
5
|
-
include Helpers::ViewHelper
|
6
|
-
include Helpers::GameHelper
|
5
|
+
class Game < ApplicationController
|
6
|
+
include Helpers::GameHelper
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def render(correct:, incorrect:, title:, timer:, last:)
|
9
|
+
_score = t('Game.ScoreMenu.Score') + ": %0.2d%%" % calc_score(correct, incorrect)
|
10
|
+
_timer = [((t('Timer.Timer') + ": " + timer.ha) if timer.time?), nil, timer.h]
|
11
|
+
_mexit = t 'Menu.Exit'
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
ᐅ ERB.method :new
|
16
|
-
view.result(binding)
|
17
|
-
end
|
13
|
+
super(binding)
|
14
|
+
end
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
def process(cards, mode)
|
17
|
+
ic = struct_data.new(cards, mode)
|
18
|
+
ic.get_input
|
19
|
+
{
|
20
|
+
correct: ic.valid?,
|
21
|
+
last: ic.valid? ? ic.correct_msg : ic.incorrect_msg
|
22
|
+
}
|
23
|
+
end
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
25
|
+
def struct_data
|
26
|
+
Struct.new(:card_set, :mode) do
|
27
|
+
def input
|
28
|
+
@input
|
29
|
+
end
|
33
30
|
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
def get_input
|
32
|
+
@input ||= CLI.ask("#{I18n.t('Game.TypeThis')}: #{display}")
|
33
|
+
end
|
37
34
|
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
def card
|
36
|
+
@card ||= card_set.sample.current
|
37
|
+
end
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
def display
|
40
|
+
"#{card}"
|
41
|
+
end
|
45
42
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
43
|
+
def expected
|
44
|
+
case mode
|
45
|
+
when :translate
|
46
|
+
card.translation
|
47
|
+
when :typing_practice
|
48
|
+
"#{card}"
|
49
|
+
else
|
50
|
+
raise "Invalid mode in Game Controller!"
|
55
51
|
end
|
52
|
+
end
|
56
53
|
|
57
|
-
|
58
|
-
|
59
|
-
|
54
|
+
def correct_msg
|
55
|
+
"#{I18n.t('Game.Correct')} #{input} = #{display}"
|
56
|
+
end
|
60
57
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
58
|
+
def incorrect_msg
|
59
|
+
output = "#{I18n.t('Game.Incorrect')} #{input} != #{display}"
|
60
|
+
output << " #{I18n.t('Game.Its')} #{expected.join(', ')}" if mode == :translate
|
61
|
+
output
|
62
|
+
end
|
66
63
|
|
67
|
-
|
68
|
-
|
69
|
-
end
|
64
|
+
def valid?
|
65
|
+
card_set.match? input
|
70
66
|
end
|
71
67
|
end
|
72
68
|
end
|
@@ -1,25 +1,20 @@
|
|
1
|
+
require 'language_cards/controllers/application_controller'
|
2
|
+
|
1
3
|
module LanguageCards
|
2
4
|
module Controllers
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
_toggle = "m: " + t('Menu.ToggleGameMode')
|
15
|
-
_courses = courses.each.with_index.map {|item,index| "#{index + 1}: #{item}" }
|
16
|
-
_mexit = t 'Menu.Exit'
|
5
|
+
class MainMenu < ApplicationController
|
6
|
+
def render(courses:, mode:)
|
7
|
+
_title = t 'Menu.Title'
|
8
|
+
_select = t 'Menu.Choose'
|
9
|
+
_mode = t('Menu.GameMode') + case mode.peek
|
10
|
+
when :translate then t 'Menu.ModeTranslate'
|
11
|
+
when :typing_practice then t 'Menu.ModeTyping'
|
12
|
+
end
|
13
|
+
_toggle = "m: " + t('Menu.ToggleGameMode')
|
14
|
+
_courses = courses.each.with_index.map {|item,index| "#{index + 1}: #{item}" }
|
15
|
+
_mexit = t 'Menu.Exit'
|
17
16
|
|
18
|
-
|
19
|
-
ᐅ( IO.method :read ).
|
20
|
-
ᐅ ERB.method :new
|
21
|
-
view.result(binding)
|
22
|
-
end
|
17
|
+
super(binding)
|
23
18
|
end
|
24
19
|
end
|
25
20
|
end
|
@@ -23,6 +23,14 @@ module LanguageCards
|
|
23
23
|
def humanize string
|
24
24
|
"#{string}".split('_').map(&:capitalize).join(' ')
|
25
25
|
end
|
26
|
+
|
27
|
+
def snake string
|
28
|
+
"#{string}".gsub(/(.)([A-Z])/, '\1_\2').downcase
|
29
|
+
end
|
30
|
+
|
31
|
+
def wordwrap words
|
32
|
+
"#{words}".gsub(/(.{1,#{SUBMENUWIDTH - 7}})(\s+|\Z)/, "\\1\n\t").strip
|
33
|
+
end
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
@@ -1,55 +1,25 @@
|
|
1
1
|
require 'language_cards/menu_node'
|
2
|
-
|
2
|
+
require 'language_cards/yaml_loader'
|
3
|
+
require 'language_cards/user_interface'
|
3
4
|
|
4
5
|
module LanguageCards
|
5
6
|
class LanguageCards
|
6
7
|
def initialize
|
7
|
-
|
8
|
-
|
9
|
-
# TODO: Extract out YAML file loading behavior to methods via SRP.
|
10
|
-
File.join('..','..').
|
11
|
-
ᐅ(File.method(:expand_path), __dir__ ).
|
12
|
-
ᐅ(File.method(:join), 'cards', '*.yml').
|
13
|
-
ᐅ(Dir.method :[] ).
|
14
|
-
+(
|
15
|
-
if ENV['HOME']
|
16
|
-
File.expand_path(ENV['HOME']).
|
17
|
-
ᐅ(File.method(:join), '.language_cards', 'cards', '*.yml').
|
18
|
-
ᐅ Dir.method :[]
|
19
|
-
else
|
20
|
-
[]
|
21
|
-
end
|
22
|
-
).
|
23
|
-
each do |c|
|
24
|
-
next unless yaml_data = c.ᐅ(File.method :open).ᐅ(~:read).ᐅ(YAML.method :load)
|
25
|
-
for language in yaml_data.keys do
|
26
|
-
# Merges sub-items for languages
|
27
|
-
if @CARDS.has_key? language
|
28
|
-
@CARDS[language] = \
|
29
|
-
yaml_data[language].
|
30
|
-
ᐅ(method :Hash).
|
31
|
-
ᐅ @CARDS[language].
|
32
|
-
ᐅ(method :Hash).
|
33
|
-
method(:merge)
|
34
|
-
else
|
35
|
-
# Merges top scope languages
|
36
|
-
{ language => yaml_data[language] }.
|
37
|
-
ᐅ @CARDS.method :merge!
|
38
|
-
end
|
39
|
-
end
|
8
|
+
self.cards = builder(YAMLLoader.new.load)
|
9
|
+
end
|
40
10
|
|
41
|
-
|
11
|
+
def start
|
12
|
+
UserInterface.new(cards).start
|
13
|
+
end
|
42
14
|
|
43
|
-
|
44
|
-
|
15
|
+
private
|
16
|
+
attr_accessor :cards
|
17
|
+
def builder(cards_yaml)
|
18
|
+
cards_yaml.each_with_object([]) do |(language, values), memo|
|
45
19
|
values.each do |category_with_card_set|
|
46
20
|
memo << MenuNode.new(language, category_with_card_set)
|
47
21
|
end
|
48
22
|
end
|
49
23
|
end
|
50
|
-
|
51
|
-
def start
|
52
|
-
@CARDS.ᐅ(UserInterface.method :new).ᐅ ~:start
|
53
|
-
end
|
54
24
|
end
|
55
25
|
end
|
@@ -11,7 +11,7 @@ module LanguageCards
|
|
11
11
|
include Controllers
|
12
12
|
def initialize cards
|
13
13
|
@cards = cards
|
14
|
-
@courses = cards
|
14
|
+
@courses = process_courses(cards)
|
15
15
|
@mode = [:translate, :typing_practice].cycle
|
16
16
|
end
|
17
17
|
|
@@ -26,7 +26,7 @@ module LanguageCards
|
|
26
26
|
loop do
|
27
27
|
clear
|
28
28
|
|
29
|
-
CLI.say MainMenu.render courses: courses, mode: mode
|
29
|
+
CLI.say MainMenu.new(opts).render courses: courses, mode: mode
|
30
30
|
|
31
31
|
value = CLI.ask("")
|
32
32
|
|
@@ -40,17 +40,18 @@ module LanguageCards
|
|
40
40
|
title = "#{collection.title} (#{humanize mode.peek})"
|
41
41
|
collection = collection.mode(mode.peek) # Mode<CardSet> < Game
|
42
42
|
|
43
|
+
game = Game.new(opts)
|
43
44
|
timer = Timer.new
|
44
45
|
begin # Game Loop
|
45
46
|
loop do
|
46
47
|
clear
|
47
48
|
timer.mark
|
48
|
-
CLI.say
|
49
|
+
CLI.say game.render correct: correct,
|
49
50
|
incorrect: incorrect,
|
50
51
|
title: title,
|
51
52
|
timer: timer,
|
52
53
|
last: last
|
53
|
-
result =
|
54
|
+
result = game.process(collection, collection.mode)
|
54
55
|
result[:correct] ? correct! : incorrect!
|
55
56
|
last = result[:last]
|
56
57
|
end
|
@@ -65,6 +66,10 @@ module LanguageCards
|
|
65
66
|
|
66
67
|
private
|
67
68
|
attr_reader :mode, :cards, :correct, :incorrect, :courses
|
69
|
+
def opts
|
70
|
+
@opts ||= {}
|
71
|
+
end
|
72
|
+
|
68
73
|
def correct!
|
69
74
|
@correct = @correct.to_i + 1
|
70
75
|
end
|
@@ -72,6 +77,16 @@ module LanguageCards
|
|
72
77
|
def incorrect!
|
73
78
|
@incorrect = @incorrect.to_i + 1
|
74
79
|
end
|
80
|
+
|
81
|
+
def process_courses(cards)
|
82
|
+
courses = cards.flat_map {|i| i.label.join(' - ') }
|
83
|
+
|
84
|
+
if courses.empty?
|
85
|
+
opts[:errors] = ["No Flash Cards found for language: #{CARD_LANGUAGE}"]
|
86
|
+
end
|
87
|
+
|
88
|
+
courses
|
89
|
+
end
|
75
90
|
end
|
76
91
|
end
|
77
92
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module LanguageCards
|
2
|
+
class YAMLLoader
|
3
|
+
def initialize
|
4
|
+
@language = CARD_LANGUAGE
|
5
|
+
end
|
6
|
+
|
7
|
+
def load
|
8
|
+
cards = {}
|
9
|
+
|
10
|
+
cards_yaml.each do |c|
|
11
|
+
next unless yaml_data = YAML.load(File.open(c).read)
|
12
|
+
for language in yaml_data.keys do
|
13
|
+
# Merges sub-items for languages
|
14
|
+
if cards.has_key? language
|
15
|
+
cards[language] = Hash( cards[language] ).merge( Hash(yaml_data[language]) )
|
16
|
+
else
|
17
|
+
# Merges in new top scope languages
|
18
|
+
cards.merge!({ language => yaml_data[language] })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
cards
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
attr_reader :language
|
28
|
+
|
29
|
+
def application_path
|
30
|
+
File.expand_path(File.join('..','..'), __dir__)
|
31
|
+
end
|
32
|
+
|
33
|
+
def cards_yaml
|
34
|
+
application_path_cards_yaml + home_path_cards_yaml
|
35
|
+
end
|
36
|
+
|
37
|
+
def application_path_cards_yaml
|
38
|
+
Dir[File.join(application_path, 'cards', language, '*.yml')]
|
39
|
+
end
|
40
|
+
|
41
|
+
def home_path_cards_yaml
|
42
|
+
if ENV['HOME']
|
43
|
+
Dir[File.join(ENV['HOME'], '.language_cards', 'cards', language, '*.yml')]
|
44
|
+
else
|
45
|
+
[]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: language_cards
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel P. Clark
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04-
|
11
|
+
date: 2018-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.7'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: slop
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '4.6'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '4.6'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -113,10 +113,12 @@ files:
|
|
113
113
|
- bin/console
|
114
114
|
- bin/language_cards
|
115
115
|
- bin/setup
|
116
|
-
- cards/japanese-hiragana.yml
|
117
|
-
- cards/japanese-
|
116
|
+
- cards/en/japanese-hiragana.yml
|
117
|
+
- cards/en/japanese-kanji-jlpt-n5.yml
|
118
|
+
- cards/en/japanese-katakana.yml
|
118
119
|
- language_cards.gemspec
|
119
120
|
- lib/language_cards.rb
|
121
|
+
- lib/language_cards/controllers/application_controller.rb
|
120
122
|
- lib/language_cards/controllers/game.rb
|
121
123
|
- lib/language_cards/controllers/main_menu.rb
|
122
124
|
- lib/language_cards/grapheme_builder.rb
|
@@ -134,6 +136,7 @@ files:
|
|
134
136
|
- lib/language_cards/version.rb
|
135
137
|
- lib/language_cards/view/game.erb
|
136
138
|
- lib/language_cards/view/main_menu.erb
|
139
|
+
- lib/language_cards/yaml_loader.rb
|
137
140
|
- locales/en.yml
|
138
141
|
homepage: http://github.com/danielpclark/language_cards
|
139
142
|
licenses:
|