cw 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|