cw 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/Gemfile +11 -0
- data/LICENSE +21 -0
- data/README.md +21 -0
- data/Rakefile +1 -0
- data/audio/audio_output.wav +0 -0
- data/audio/audio_output.wav0000.mp3 +0 -0
- data/audio/dash.wav +0 -0
- data/audio/dot.wav +0 -0
- data/audio/e_space.wav +0 -0
- data/audio/space.wav +0 -0
- data/cw.gemspec +18 -0
- data/daily.rb +182 -0
- data/data/text/abbreviations.txt +1 -0
- data/data/text/common_words.txt +90 -0
- data/data/text/cw_conversation.txt +1 -0
- data/data/text/most_common_words.txt +1 -0
- data/data/text/progress.txt +1 -0
- data/data/text/q_codes.txt +1 -0
- data/data/text/tom_sawyer.txt +6477 -0
- data/example.rb +139 -0
- data/lib/cw.rb +111 -0
- data/lib/cw/alphabet.rb +29 -0
- data/lib/cw/audio_player.rb +63 -0
- data/lib/cw/book.rb +239 -0
- data/lib/cw/book_details.rb +47 -0
- data/lib/cw/cl.rb +112 -0
- data/lib/cw/cw_dsl.rb +211 -0
- data/lib/cw/cw_encoding.rb +56 -0
- data/lib/cw/cw_params.rb +29 -0
- data/lib/cw/cw_threads.rb +36 -0
- data/lib/cw/file_details.rb +13 -0
- data/lib/cw/key_input.rb +53 -0
- data/lib/cw/monitor.rb +36 -0
- data/lib/cw/monitor_keys.rb +37 -0
- data/lib/cw/numbers.rb +29 -0
- data/lib/cw/print.rb +137 -0
- data/lib/cw/process.rb +11 -0
- data/lib/cw/progress.rb +27 -0
- data/lib/cw/randomize.rb +73 -0
- data/lib/cw/repeat_word.rb +91 -0
- data/lib/cw/rss.rb +71 -0
- data/lib/cw/sentence.rb +78 -0
- data/lib/cw/speak.rb +11 -0
- data/lib/cw/spoken.rb +11 -0
- data/lib/cw/str.rb +67 -0
- data/lib/cw/stream.rb +161 -0
- data/lib/cw/test_letters.rb +52 -0
- data/lib/cw/test_words.rb +59 -0
- data/lib/cw/tester.rb +221 -0
- data/lib/cw/timing.rb +92 -0
- data/lib/cw/tone_generator.rb +225 -0
- data/lib/cw/voice.rb +16 -0
- data/lib/cw/words.rb +182 -0
- data/read_book.rb +33 -0
- data/test/run_tests_continuously.rb +4 -0
- data/test/test_cw.rb +527 -0
- data/test/test_stream.rb +401 -0
- metadata +102 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class RepeatWord < FileDetails
|
4
|
+
|
5
|
+
include Tester
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super
|
9
|
+
@repeat_word = true
|
10
|
+
end
|
11
|
+
|
12
|
+
#overloaded #todo
|
13
|
+
|
14
|
+
def print_failed_exit_words
|
15
|
+
until stream.stream_empty?
|
16
|
+
word = stream.pop[:value]
|
17
|
+
print.prn_red word + ' ' unless @repeat_word
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def print_words words
|
22
|
+
timing.init_char_timer
|
23
|
+
(words.to_s + space).each_char do |letr|
|
24
|
+
process_letter letr
|
25
|
+
loop do
|
26
|
+
process_space_maybe letr
|
27
|
+
process_word_maybe
|
28
|
+
break if timing.char_delay_timeout?
|
29
|
+
end
|
30
|
+
print.prn letr if print_letters?
|
31
|
+
break if quit?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def process_input_word_maybe
|
36
|
+
if @word_to_process
|
37
|
+
stream.match_last_active_element @process_input_word.strip
|
38
|
+
@process_input_word = @word_to_process = nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def build_word_maybe
|
43
|
+
@input_word ||= empty_string
|
44
|
+
@input_word << key_chr if is_relevant_char?
|
45
|
+
move_word_to_process if complete_word?
|
46
|
+
end
|
47
|
+
|
48
|
+
def process_letter letr
|
49
|
+
current_word.process_letter letr
|
50
|
+
sleep_char_delay letr
|
51
|
+
end
|
52
|
+
|
53
|
+
def print_marked_maybe
|
54
|
+
@popped = stream.pop_next_marked
|
55
|
+
print.results(@popped, :pass_only) if(@popped && ! print_letters?)
|
56
|
+
end
|
57
|
+
|
58
|
+
#overloaded #todo
|
59
|
+
|
60
|
+
def play_words_thread
|
61
|
+
play_words_until_quit
|
62
|
+
print "\n\rplay has quit " if @debug
|
63
|
+
end
|
64
|
+
|
65
|
+
def double_words words
|
66
|
+
temp = []
|
67
|
+
words.each do |wrd|
|
68
|
+
2.times { temp.push wrd }
|
69
|
+
end
|
70
|
+
words = temp
|
71
|
+
end
|
72
|
+
|
73
|
+
def run words
|
74
|
+
temp_words = words.all
|
75
|
+
temp_words = double_words temp_words if Params.double_words
|
76
|
+
temp_words.each do |word|
|
77
|
+
loop do
|
78
|
+
@input_word, @words = '', Words.new
|
79
|
+
@quit, @failed = nil, nil
|
80
|
+
@words.add [word]
|
81
|
+
@threads = CWThreads.new(self, thread_processes)
|
82
|
+
@threads.run
|
83
|
+
break unless @failed
|
84
|
+
break if global_quit?
|
85
|
+
end
|
86
|
+
break if global_quit?
|
87
|
+
end
|
88
|
+
reset_stdin
|
89
|
+
print.newline
|
90
|
+
end
|
91
|
+
end
|
data/lib/cw/rss.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#class Rss
|
4
|
+
|
5
|
+
class Rss
|
6
|
+
|
7
|
+
def sources
|
8
|
+
{
|
9
|
+
bbc: 'http://feeds.bbci.co.uk/news/rss.xml',
|
10
|
+
reuters: 'http://feeds.reuters.com/Reuters/worldNews?format=xml',
|
11
|
+
guardian: 'http://www.theguardian.com/world/rss',
|
12
|
+
quotations: 'http://feeds.feedburner.com/quotationspage/qotd'
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def source src
|
17
|
+
sources.has_key?(src) ? sources[src] : sources[:quotations]
|
18
|
+
end
|
19
|
+
|
20
|
+
def read_rss(src, show_count = 3)
|
21
|
+
require 'feedjira'
|
22
|
+
require "htmlentities"
|
23
|
+
require 'sanitize'
|
24
|
+
coder = HTMLEntities.new
|
25
|
+
url = source(src)
|
26
|
+
feed = Feedjira::Feed.fetch_and_parse url # returns a Hash, with each url having a Feedjira::Feed object
|
27
|
+
entry_count = 0
|
28
|
+
@rss_articles = []
|
29
|
+
entry = feed.entries.each do |entry|
|
30
|
+
title = entry.title
|
31
|
+
unless(title.include?('VIDEO:') ||
|
32
|
+
title.include?('In pictures:') ||
|
33
|
+
title.include?('Morning business round-up'))
|
34
|
+
words = entry.summary
|
35
|
+
entry_count += 1
|
36
|
+
end
|
37
|
+
@rss_articles << (Sanitize.clean coder.decode words).split(',')
|
38
|
+
break if entry_count >= show_count
|
39
|
+
end
|
40
|
+
@rss_flag = true
|
41
|
+
end
|
42
|
+
|
43
|
+
def inc_article_index
|
44
|
+
@article_index += 1
|
45
|
+
end
|
46
|
+
|
47
|
+
def article_index
|
48
|
+
@article_index || @article_index = 0
|
49
|
+
end
|
50
|
+
|
51
|
+
def cw_chars chr
|
52
|
+
chr.tr('^a-z0-9\.\,+', '')
|
53
|
+
end
|
54
|
+
|
55
|
+
def exclude_non_cw_chars word
|
56
|
+
temp = ''
|
57
|
+
word.split.each do |chr|
|
58
|
+
temp += chr if letter(chr)
|
59
|
+
end
|
60
|
+
temp
|
61
|
+
end
|
62
|
+
|
63
|
+
def next_article
|
64
|
+
temp = @rss_articles[article_index]
|
65
|
+
return unless temp
|
66
|
+
inc_article_index
|
67
|
+
quote = ''
|
68
|
+
temp.map { |i| quote += i }
|
69
|
+
(quote.split.collect { |article| cw_chars(article.strip.gsub("\"", '').downcase)})
|
70
|
+
end
|
71
|
+
end
|
data/lib/cw/sentence.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Sentence
|
4
|
+
|
5
|
+
attr_accessor :index #todo
|
6
|
+
|
7
|
+
def text ; @text ||= String.new ; end
|
8
|
+
def all ; @sentences ; end
|
9
|
+
def next ; @next = true ; end
|
10
|
+
def next? ; @next ; end
|
11
|
+
def forward ; @index += 1 ; end
|
12
|
+
def previous? ; @previous ; end
|
13
|
+
def repeat? ; @repeat ; end
|
14
|
+
def change? ; next? || previous? ; end
|
15
|
+
def change_or_repeat? ; change? || repeat? ; end
|
16
|
+
def current ; @sentences[@index] ; end
|
17
|
+
def next_sentence ; @sentences[@index + 1] ; end
|
18
|
+
|
19
|
+
def change
|
20
|
+
forward if next?
|
21
|
+
rewind if previous?
|
22
|
+
end
|
23
|
+
|
24
|
+
def rewind
|
25
|
+
@index = @index <= 1 ? 0 : @index - 1
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_progress progress_file
|
29
|
+
File.open(progress_file, 'r') {|f| @index = f.readline.to_i}
|
30
|
+
end
|
31
|
+
|
32
|
+
def write_progress progress_file
|
33
|
+
File.open(progress_file, 'w') {|f| f.puts @index.to_s}
|
34
|
+
end
|
35
|
+
|
36
|
+
def read_book book
|
37
|
+
File.open(book, 'r') { |f| text.replace f.readlines(' ').join}
|
38
|
+
end
|
39
|
+
|
40
|
+
def cw_chars chr
|
41
|
+
chr.tr('^a-z0-9\,\=\!\/\?\.', '')
|
42
|
+
end
|
43
|
+
|
44
|
+
def exclude_non_cw_chars word
|
45
|
+
cw_chars(word)
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_all
|
49
|
+
@sentences = []
|
50
|
+
@text.gsub!(/\s+/, ' ').downcase!
|
51
|
+
loop do
|
52
|
+
sentence_end = @text.index('. ')
|
53
|
+
unless sentence_end
|
54
|
+
break
|
55
|
+
end
|
56
|
+
line = @text[0..sentence_end]
|
57
|
+
line = line.split.collect{|word| exclude_non_cw_chars word}.join(' ')
|
58
|
+
@sentences << line
|
59
|
+
@text.replace @text[sentence_end + 2..-1]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def check_sentence_navigation chr
|
64
|
+
@next = true if(chr == ']')
|
65
|
+
@previous = true if(chr == '[')
|
66
|
+
@repeat = true if(chr == '-')
|
67
|
+
end
|
68
|
+
|
69
|
+
def reset_flags
|
70
|
+
@next = @previous = @repeat = nil
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_array
|
74
|
+
array = @sentences[@index].split(' ')
|
75
|
+
array.collect {|x| x + ' '}
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/lib/cw/speak.rb
ADDED
data/lib/cw/spoken.rb
ADDED
data/lib/cw/str.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#class Str
|
4
|
+
|
5
|
+
class Str
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@seperator = ', '
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
delim = delim_std_str
|
13
|
+
["\n#{Params.name}\r",
|
14
|
+
"\n#{delim}",
|
15
|
+
"#{wpm_str}\n",
|
16
|
+
shuffle_str,
|
17
|
+
word_count_str,
|
18
|
+
word_size_str,
|
19
|
+
beginning_str,
|
20
|
+
ending_str,
|
21
|
+
delim].
|
22
|
+
collect{ |prm| prm.to_s }.join
|
23
|
+
end
|
24
|
+
|
25
|
+
def stringify ary
|
26
|
+
ary.join(@seperator)
|
27
|
+
end
|
28
|
+
|
29
|
+
def delim_str size
|
30
|
+
"#{'=' * size}\n\r"
|
31
|
+
end
|
32
|
+
|
33
|
+
def delim_std_str
|
34
|
+
tempsize = Params.name.size
|
35
|
+
delim_str tempsize
|
36
|
+
end
|
37
|
+
|
38
|
+
def shuffle_str
|
39
|
+
shuffle = Params.shuffle
|
40
|
+
shuffle ? "Shuffle: #{shuffle ? 'yes' : 'no'}\n\r" : nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def word_count_str
|
44
|
+
wc = Params.word_count
|
45
|
+
wc ? "Word count: #{wc}\n\r" : nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def word_size_str
|
49
|
+
size = Params.size
|
50
|
+
size ? "Word size: #{size}\n\r" : nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def beginning_str
|
54
|
+
beginning = Params.begin
|
55
|
+
beginning ? "Beginning: #{stringify beginning}\n\r" : nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def ending_str
|
59
|
+
ending = Params.end
|
60
|
+
ending ? "Ending: #{stringify ending}\n\r" : nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def wpm_str
|
64
|
+
"WPM: #{Params.wpm}\n\r"
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/lib/cw/stream.rb
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Stream
|
4
|
+
|
5
|
+
attr_accessor :active_region
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@active_region = 6
|
9
|
+
empty
|
10
|
+
end
|
11
|
+
|
12
|
+
def empty
|
13
|
+
@stream, @success, @first_element, @last_element = {},{}, 0, 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def count
|
17
|
+
@last_element - @first_element
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_word word
|
21
|
+
@stream[@last_element] = word.strip
|
22
|
+
@success[@last_element] = nil
|
23
|
+
inc_last_element
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_char char
|
27
|
+
@stream[@last_element] = char
|
28
|
+
@success[@last_element] = nil
|
29
|
+
inc_last_element
|
30
|
+
end
|
31
|
+
|
32
|
+
def inc_last_element
|
33
|
+
@last_element += 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def inc_first_element
|
37
|
+
@first_element += 1
|
38
|
+
end
|
39
|
+
|
40
|
+
def mark(element, type)
|
41
|
+
@success[element] = type
|
42
|
+
end
|
43
|
+
|
44
|
+
def mark_success element
|
45
|
+
mark element, true
|
46
|
+
end
|
47
|
+
|
48
|
+
def mark_fail element
|
49
|
+
mark element, false
|
50
|
+
end
|
51
|
+
|
52
|
+
def stream_empty?
|
53
|
+
@first_element == @last_element
|
54
|
+
end
|
55
|
+
|
56
|
+
def inactive_region
|
57
|
+
stream_empty? ? nil : @last_element - @active_region - 1
|
58
|
+
end
|
59
|
+
|
60
|
+
def fail_unmarked_inactive_elements
|
61
|
+
if(( ! stream_empty?) && (count > @active_region))
|
62
|
+
@first_element.upto(inactive_region) do |count|
|
63
|
+
@success[count] = false unless @success[count] == true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def first
|
69
|
+
@stream[@first_element]
|
70
|
+
end
|
71
|
+
|
72
|
+
def pop
|
73
|
+
unless stream_empty?
|
74
|
+
ele = @first_element
|
75
|
+
inc_first_element
|
76
|
+
success = @success.delete(ele)
|
77
|
+
success = success == nil ? false : success
|
78
|
+
{ :value => @stream.delete(ele),
|
79
|
+
:success => success
|
80
|
+
}
|
81
|
+
else
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# def pop_marked
|
87
|
+
# return_val = {}
|
88
|
+
# fail_unmarked_inactive_elements
|
89
|
+
# @first_element.upto(@last_element) do |ele|
|
90
|
+
# unless stream_empty?
|
91
|
+
# if(ele < inactive_region)
|
92
|
+
# val = pop
|
93
|
+
#
|
94
|
+
# return_val[ele] = {pop => @success[ele]}
|
95
|
+
# elsif(@success[ele] == true || @success[ele] == false)
|
96
|
+
# return_val[ele] = {pop => @success[ele]}
|
97
|
+
# else
|
98
|
+
# break
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
# end
|
102
|
+
# return_val == {} ? nil : return_val
|
103
|
+
# end
|
104
|
+
|
105
|
+
def pop_next_marked
|
106
|
+
return_val = {}
|
107
|
+
fail_unmarked_inactive_elements
|
108
|
+
unless stream_empty?
|
109
|
+
if(@first_element < inactive_region)
|
110
|
+
pop
|
111
|
+
elsif(@success[@first_element] == true || @success[@first_element] == false)
|
112
|
+
pop
|
113
|
+
end
|
114
|
+
end
|
115
|
+
# return_val == {} ? nil : return_val
|
116
|
+
end
|
117
|
+
|
118
|
+
def element type
|
119
|
+
return @last_element - 1 if type == :last
|
120
|
+
first = @last_element - @active_region - 1
|
121
|
+
first < 0 ? 0 : first
|
122
|
+
end
|
123
|
+
|
124
|
+
def match_first_active_element match
|
125
|
+
if ! stream_empty?
|
126
|
+
found = false
|
127
|
+
first = element(:first)
|
128
|
+
first.upto element(:last) do |ele|
|
129
|
+
if found
|
130
|
+
first.upto found - 1 do |failed|
|
131
|
+
@success[failed] = false # unless @success[ele]
|
132
|
+
end
|
133
|
+
break
|
134
|
+
elsif((@stream[ele] == match) && (! @success[ele]))
|
135
|
+
@success[ele], found = true, ele
|
136
|
+
else
|
137
|
+
@success[first] = false
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def match_last_active_element match
|
144
|
+
if ! stream_empty?
|
145
|
+
first = @last_element - @active_region - 1
|
146
|
+
first = 0 if(first < 0)
|
147
|
+
last = @last_element - 1
|
148
|
+
found = false
|
149
|
+
last.downto(first) do |ele|
|
150
|
+
if found
|
151
|
+
@success[ele] = false unless @success[ele]
|
152
|
+
elsif((@stream[ele] == match) && (! @success[ele]))
|
153
|
+
@success[ele], found = true, true
|
154
|
+
else
|
155
|
+
@success[first] = false
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|