cw 0.2.4 → 0.3.0

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.cw_config +18 -0
  3. data/.gitignore +10 -1
  4. data/LICENSE +2 -1
  5. data/README.md +212 -96
  6. data/Rakefile +15 -2
  7. data/VERSION +1 -1
  8. data/Vagrantfile +45 -0
  9. data/cw.gemspec +6 -1
  10. data/data/text/book_to_read.txt +4 -0
  11. data/data/text/english.txt +10000 -0
  12. data/example.rb +172 -106
  13. data/lib/cw.rb +10 -126
  14. data/lib/cw/alphabet.rb +53 -46
  15. data/lib/cw/audio_player.rb +83 -72
  16. data/lib/cw/book.rb +160 -185
  17. data/lib/cw/book_details.rb +38 -49
  18. data/lib/cw/cl.rb +101 -95
  19. data/lib/cw/common_words.rb +76 -0
  20. data/lib/cw/config.rb +50 -0
  21. data/lib/cw/current_word.rb +23 -24
  22. data/lib/cw/cw_dsl.rb +264 -131
  23. data/lib/cw/cw_encoding.rb +63 -69
  24. data/lib/cw/cw_stream.rb +86 -82
  25. data/lib/cw/cw_threads.rb +132 -22
  26. data/lib/cw/element.rb +60 -54
  27. data/lib/cw/file_details.rb +26 -11
  28. data/lib/cw/key_input.rb +53 -35
  29. data/lib/cw/numbers.rb +26 -19
  30. data/lib/cw/os.rb +13 -0
  31. data/lib/cw/play.rb +92 -0
  32. data/lib/cw/print.rb +102 -100
  33. data/lib/cw/process.rb +3 -0
  34. data/lib/cw/progress.rb +20 -17
  35. data/lib/cw/randomize.rb +56 -52
  36. data/lib/cw/repeat_word.rb +59 -66
  37. data/lib/cw/reveal.rb +32 -31
  38. data/lib/cw/rss.rb +52 -48
  39. data/lib/cw/sentence.rb +83 -76
  40. data/lib/cw/speak.rb +8 -4
  41. data/lib/cw/spoken.rb +8 -4
  42. data/lib/cw/str.rb +62 -30
  43. data/lib/cw/test_letters.rb +20 -28
  44. data/lib/cw/test_words.rb +25 -31
  45. data/lib/cw/tester.rb +219 -226
  46. data/lib/cw/text_helpers.rb +19 -15
  47. data/lib/cw/timing.rb +63 -67
  48. data/lib/cw/tone_generator.rb +176 -153
  49. data/lib/cw/tone_helpers.rb +15 -23
  50. data/lib/cw/voice.rb +12 -8
  51. data/lib/cw/words.rb +136 -106
  52. data/run_script_tests.rb +165 -0
  53. data/test/my_words.txt +1 -0
  54. data/test/test_common_words.rb +71 -0
  55. data/test/test_config.rb +98 -0
  56. data/test/test_current_word.rb +62 -0
  57. data/test/test_cw.rb +87 -120
  58. data/test/test_cw_threads.rb +123 -0
  59. data/test/test_filtering.rb +439 -0
  60. data/test/test_params.rb +28 -0
  61. data/test/test_play.rb +51 -0
  62. data/test/test_stream.rb +83 -83
  63. data/test/test_tester.rb +9 -27
  64. data/test/test_timing.rb +212 -0
  65. metadata +94 -12
  66. data/lib/cw/config_file.rb +0 -69
  67. data/lib/cw/monitor_keys.rb +0 -37
  68. data/lib/cw/params.rb +0 -104
@@ -1,73 +1,79 @@
1
- module Element
1
+ # encoding: utf-8
2
2
 
3
- def element type
4
- return @last_element - 1 if type == :last
5
- first = @last_element - @active_region - 1
6
- first < 0 ? 0 : first
7
- end
3
+ module CWG
8
4
 
9
- def match_first_active_element match
10
- if ! stream_empty?
11
- found = false
12
- first = element(:first)
13
- first.upto element(:last) do |ele|
14
- if found
15
- first.upto found - 1 do |failed|
16
- @success[failed] = false # unless @success[ele]
5
+ module Element
6
+
7
+ def element type
8
+ return @last_element - 1 if type == :last
9
+ first = @last_element - @active_region - 1
10
+ first < 0 ? 0 : first
11
+ end
12
+
13
+ def match_first_active_element match
14
+ if ! stream_empty?
15
+ found = false
16
+ first = element(:first)
17
+ first.upto element(:last) do |ele|
18
+ if found
19
+ first.upto found - 1 do |failed|
20
+ @success[failed] = false # unless @success[ele]
21
+ end
22
+ break
23
+ elsif((@stream[ele] == match) && (! @success[ele]))
24
+ @success[ele], found = true, ele
25
+ else
26
+ @success[first] = false
17
27
  end
18
- break
19
- elsif((@stream[ele] == match) && (! @success[ele]))
20
- @success[ele], found = true, ele
21
- else
22
- @success[first] = false
23
28
  end
24
29
  end
25
30
  end
26
- end
27
31
 
28
- def match_last_active_element(match)
29
- process_last_active_element(match) unless stream_empty?
30
- end
32
+ def match_last_active_element(match)
33
+ process_last_active_element(match) unless stream_empty?
34
+ end
31
35
 
32
- def process_last_active_element(match)
33
- first = get_first
34
- last = get_last
35
- check_last_element_success(match, first, last)
36
- end
36
+ def process_last_active_element(match)
37
+ first = get_first
38
+ last = get_last
39
+ check_last_element_success(match, first, last)
40
+ end
37
41
 
38
- def check_last_element_success(match, first, last)
39
- found = false
40
- last.downto(first) do |element|
41
- if found
42
- @success[element] = false unless @success[element]
43
- elsif((@stream[element] == match) && (! @success[element]))
44
- @success[element], found = true, true
45
- else
46
- @success[first] = false
42
+ def check_last_element_success(match, first, last)
43
+ found = false
44
+ last.downto(first) do |element|
45
+ if found
46
+ @success[element] = false unless @success[element]
47
+ elsif((@stream[element] == match) && (! @success[element]))
48
+ @success[element], found = true, true
49
+ else
50
+ @success[first] = false
51
+ end
47
52
  end
48
53
  end
49
- end
50
54
 
51
- def get_first
52
- first = @last_element - @active_region - 1
53
- first = 0 if(first < 0)
54
- first
55
- end
55
+ def get_first
56
+ first = @last_element - @active_region - 1
57
+ first = 0 if(first < 0)
58
+ first
59
+ end
56
60
 
57
- def get_last
58
- @last_element - 1
59
- end
61
+ def get_last
62
+ @last_element - 1
63
+ end
60
64
 
61
- def count
62
- @last_element - @first_element
63
- end
65
+ def count
66
+ @last_element - @first_element
67
+ end
64
68
 
65
- def inc_last_element
66
- @last_element += 1
67
- end
69
+ def inc_last_element
70
+ @last_element += 1
71
+ end
72
+
73
+ def inc_first_element
74
+ @first_element += 1
75
+ end
68
76
 
69
- def inc_first_element
70
- @first_element += 1
71
77
  end
72
78
 
73
79
  end
@@ -1,16 +1,31 @@
1
1
  # encoding: utf-8
2
2
 
3
- class FileDetails
4
- HERE = File.dirname(__FILE__) + '/'
5
- TEXT = HERE + '../../data/text/'
6
- AUDIO = HERE + '../../audio/'
3
+ module CWG
7
4
 
8
- def initialize
9
- @repeat_tone = AUDIO + "rpt.mp3"
10
- @r_tone = AUDIO + "r.mp3"
11
- @sentence_folder = TEXT + "sentences/"
12
- @text_folder = TEXT
13
- @progress_file = 'progress.txt'
14
- end
5
+ module FileDetails
6
+ HERE = File.dirname(__FILE__)
7
+ ROOT = File.expand_path File.join(HERE,'..','..')
8
+ TEXT = File.join(ROOT,'data','text')
9
+ AUDIO = File.join(ROOT,'audio')
10
+
11
+ ENGLISH_DICT = File.join TEXT, "english.txt"
12
+ ABBREVIATIONS = File.join TEXT, "abbreviations.txt"
13
+ Q_CODES = File.join TEXT, "q_codes.txt"
14
+ DOT_FILENAME = File.join AUDIO, "dot.wav"
15
+ DASH_FILENAME = File.join AUDIO, "dash.wav"
16
+ SPACE_FILENAME = File.join AUDIO, "space.wav"
17
+ E_SPACE_FILENAME = File.join AUDIO, "e_space.wav"
18
+ CONFIG_FILENAME = File.join ROOT, ".cw_config"
15
19
 
20
+ def init_filenames
21
+ @repeat_tone = File.join(AUDIO, "rpt.mp3")
22
+ @r_tone = File.join(AUDIO, "r.mp3")
23
+ @text_folder = TEXT
24
+ @progress_file = 'progress.txt'
25
+ end
26
+
27
+ def expand path
28
+ File.expand_path path
29
+ end
30
+ end
16
31
  end
@@ -1,53 +1,71 @@
1
1
  # encoding: utf-8
2
2
 
3
- class KeyInput
3
+ module CWG
4
4
 
5
- def initialize
6
- @quit_ary = Array.new(4)
7
- end
5
+ class KeyInput
8
6
 
9
- def char
10
- @chr
11
- end
7
+ def initialize
8
+ @quit_count = 0
9
+ end
12
10
 
13
- def read
14
- @chr = nil
15
- begin
16
- system("stty raw -echo")
17
- @chr = STDIN.getc
18
- ensure
19
- system("stty raw -echo")
11
+ def char
12
+ @chr
20
13
  end
21
- end
22
14
 
23
- def is_letter?
24
- @chr >= 'a' && @chr <= 'z'
25
- end
15
+ def read
16
+ @chr = nil
17
+ begin
18
+ system("stty raw -echo")
19
+ @chr = STDIN.getc
20
+ ensure
21
+ system("stty raw -echo")
22
+ end
23
+ end
26
24
 
27
- def is_number?
28
- @chr >= '0' && @chr <= '9'
29
- end
25
+ def is_letter?
26
+ @chr >= 'a' && @chr <= 'z'
27
+ end
30
28
 
31
- def is_punctuation?
32
- [' ', ',', '.', '=', '?'].detect{|letr| letr == @chr}
33
- end
29
+ def is_number?
30
+ @chr >= '0' && @chr <= '9'
31
+ end
34
32
 
35
- def is_relevant_char?
36
- is_letter? || is_number? || is_punctuation? ? true : false
37
- end
33
+ def is_punctuation?
34
+ [' ', ',', '.', '=', '?'].detect{|letr| letr == @chr}
35
+ end
38
36
 
39
- def reset_stdin
40
- system("stty -raw echo")
41
- end
37
+ def is_relevant_char?
38
+ is_letter? || is_number? || is_punctuation? ? true : false
39
+ end
40
+
41
+ def reset_stdin
42
+ system("stty -raw echo")
43
+ end
44
+
45
+
46
+ def push_to_quit_maybe
47
+ if @chr == 'q'
48
+ @quit_count += 1
49
+ else
50
+ @quit_count = 0
51
+ end
52
+ end
53
+
54
+ def is_quit?
55
+ @quit_count >= 4
56
+ end
42
57
 
43
- def quit_input?
44
- @quit_ary.rotate!
45
- @quit_ary[3] = @chr
46
- quit_str = @quit_ary.join.downcase
47
- if quit_str == 'qqqq'
58
+ def quit
59
+ Cfg.config.params["exit"] = true
48
60
  reset_stdin
49
61
  return true
50
62
  end
63
+
64
+ def quit_input?
65
+ push_to_quit_maybe
66
+ return quit if is_quit?
67
+ end
68
+
51
69
  end
52
70
 
53
71
  end
@@ -1,29 +1,36 @@
1
1
  # encoding: utf-8
2
2
 
3
- #class Numbers provides the Number Testing functionality
3
+ module CWG
4
4
 
5
- class Numbers
5
+ #class Numbers provides the Number Testing functionality
6
6
 
7
- def initialize(options = {})
8
- @options = options
9
- end
7
+ class Numbers
10
8
 
11
- def number_list
12
- '1234567890'
13
- end
9
+ def initialize(options = {})
10
+ @options = options
11
+ end
14
12
 
15
- def reverse_numbers_maybe
16
- @numbers.reverse! if @options[:reverse]
17
- end
13
+ def number_list
14
+ '1234567890'
15
+ end
18
16
 
19
- def shuffle_numbers_maybe
20
- @numbers = @numbers.split('').shuffle.join if @options[:shuffle]
21
- end
17
+ def reverse_numbers_maybe
18
+ @numbers.reverse! if @options[:reverse]
19
+ end
20
+
21
+ def shuffle_numbers_maybe
22
+ unless(ENV["CW_ENV"] == "test")
23
+ @numbers = @numbers.split('').shuffle.join if @options[:shuffle]
24
+ end
25
+ end
26
+
27
+ def generate
28
+ @numbers = number_list
29
+ shuffle_numbers_maybe
30
+ reverse_numbers_maybe
31
+ @numbers.split('').join(' ')
32
+ end
22
33
 
23
- def generate
24
- @numbers = number_list
25
- shuffle_numbers_maybe
26
- reverse_numbers_maybe
27
- @numbers.split('').join(' ')
28
34
  end
35
+
29
36
  end
@@ -0,0 +1,13 @@
1
+ require 'os'
2
+
3
+ module CWG
4
+ module OStest
5
+ def is_mac?
6
+ OS.mac?
7
+ end
8
+
9
+ def is_posix?
10
+ OS.posix?
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+
3
+ module CWG
4
+
5
+ class Play
6
+
7
+ def initialize words
8
+ @words = words
9
+ end
10
+
11
+ def quit?
12
+ if Cfg.config["quit"].nil?
13
+ Cfg.config.params["quit"] = false
14
+ Cfg.config["quit"]
15
+ end
16
+ end
17
+
18
+ def audio
19
+ @audio ||= AudioPlayer.new
20
+ end
21
+
22
+ def init_play_words_timeout
23
+ @start_play_time, @delay_play_time = Time.now, 2.0
24
+ end
25
+
26
+ def play_words_timeout?
27
+ (Time.now - @start_play_time) > @delay_play_time
28
+ end
29
+
30
+ def start_sync
31
+ @start_sync = true
32
+ end
33
+
34
+ def start_sync?
35
+ if @start_sync
36
+ @start_sync = nil
37
+ true
38
+ else
39
+ nil
40
+ end
41
+ end
42
+
43
+ def wait_player_startup_delay
44
+ sleep 0.2
45
+ end
46
+
47
+ def add_space words
48
+ str = ''
49
+ words.to_array.collect { |word| str << word + ' '}
50
+ str
51
+ end
52
+
53
+ def play
54
+ audio.play
55
+ end
56
+
57
+ def play_audio
58
+ audio.convert_words add_space @words
59
+ start_sync()
60
+ play
61
+ end
62
+
63
+ def play_words_exit
64
+ # puts "play_words_exit"
65
+ init_play_words_timeout
66
+ loop do
67
+ break if quit?
68
+ break if play_words_timeout?
69
+ if Cfg.config["exit"]
70
+ audio.stop
71
+ break
72
+ end
73
+ sleep 0.01
74
+ end
75
+ Cfg.config["exit"] = true
76
+ sleep 0.1
77
+ end
78
+
79
+ def play_words_until_quit
80
+ play_audio
81
+ play_words_exit unless Cfg.config["print_letters"]
82
+ end
83
+
84
+ def still_playing?
85
+ audio.still_playing?
86
+ end
87
+
88
+ def stop
89
+ audio.stop
90
+ end
91
+ end
92
+ end
@@ -3,136 +3,138 @@
3
3
  require 'paint'
4
4
  require 'io/console'
5
5
 
6
- class Print
6
+ module CWG
7
7
 
8
- class ProgressPrint
9
- def colour
10
- :yellow
11
- end
8
+ class Print
12
9
 
13
- def print x
14
- STDOUT.print Paint[x, colour]
15
- end
16
- def puts x
17
- STDOUT.puts Paint[x, colour]
18
- end
10
+ class ProgressPrint
11
+ def colour
12
+ :yellow
13
+ end
19
14
 
20
- def flush
21
- STDOUT.flush
22
- end
15
+ def print x
16
+ STDOUT.print Paint[x, colour]
17
+ end
18
+ def puts x
19
+ STDOUT.puts Paint[x, colour]
20
+ end
21
+
22
+ def flush
23
+ STDOUT.flush
24
+ end
23
25
 
24
- def tty?
25
- true
26
+ def tty?
27
+ true
28
+ end
26
29
  end
27
- end
28
30
 
29
- def initialize
30
- update_console_size
31
- reset
32
- end
31
+ def initialize
32
+ update_console_size
33
+ reset
34
+ end
33
35
 
34
- def console_size
35
- IO.console.winsize
36
- rescue LoadError
37
- [Integer(`tput li`), Integer(`tput co`)]
38
- end
36
+ def console_size
37
+ IO.console.winsize
38
+ rescue LoadError
39
+ [Integer(`tput li`), Integer(`tput co`)]
40
+ end
39
41
 
40
- def update_console_size
41
- @rows, @cols = console_size
42
- # printf "%d rows by %d columns\n", @rows, @cols
43
- end
42
+ def update_console_size
43
+ @rows, @cols = console_size
44
+ # printf "%d rows by %d columns\n", @rows, @cols
45
+ end
44
46
 
45
- def reset
46
- @print_count = 0
47
- puts "\r"
48
- end
47
+ def reset
48
+ @print_count = 0
49
+ puts "\r"
50
+ end
49
51
 
50
- def newline
51
- reset
52
- update_console_size
53
- end
52
+ def newline
53
+ reset
54
+ update_console_size
55
+ end
54
56
 
55
- def force_newline_maybe
56
- if @print_count >= (@cols - 1)
57
- newline
58
- true
57
+ def force_newline_maybe
58
+ if @print_count >= (@cols - 1)
59
+ newline
60
+ true
61
+ end
59
62
  end
60
- end
61
63
 
62
- def newline_maybe word
63
- @print_count += word.size unless force_newline_maybe
64
- return if((word.size == 1) && (word != ' '))
65
- if @print_count > (@cols - 10)
66
- newline
67
- true
64
+ def newline_maybe word
65
+ @print_count += word.size unless force_newline_maybe
66
+ return if((word.size == 1) && (word != ' '))
67
+ if @print_count > (@cols - 10)
68
+ newline
69
+ true
70
+ end
68
71
  end
69
- end
70
72
 
71
- def results popped, type = :pass_and_fail
72
- if popped
73
- value = popped[:value]
74
- success = popped[:success]
73
+ def results popped, type = :pass_and_fail
74
+ if popped
75
+ value = popped[:value]
76
+ success = popped[:success]
75
77
 
76
- newline_maybe value
78
+ newline_maybe value
77
79
 
78
- print Paint["#{value} ", success_colour] if success
79
- print Paint["#{value} ", fail_colour ] unless (success || type == :pass_only)
80
- return true
80
+ print Paint["#{value} ", success_colour] if success
81
+ print Paint["#{value} ", fail_colour ] unless (success || type == :pass_only)
82
+ return true
83
+ end
81
84
  end
82
- end
83
85
 
84
- def paint(value, colour)
85
- Paint[value, colour]
86
- end
86
+ def paint(value, colour)
87
+ Paint[value, colour]
88
+ end
87
89
 
88
- def paint_success_failure(popped)
89
- print paint(popped[:value], success_colour) if popped[:success]
90
- print paint(popped[:value], fail_colour ) unless popped[:success]
91
- end
90
+ def paint_success_failure(popped)
91
+ print paint(popped[:value], success_colour) if popped[:success]
92
+ print paint(popped[:value], fail_colour ) unless popped[:success]
93
+ end
92
94
 
93
- def char_result popped
94
- unless newline_maybe popped[:value]
95
- popped[:value] = '_' if((popped[:value] == ' ') && (popped[:success] != true))
96
- paint_success_failure(popped)
97
- return true
95
+ def char_result popped
96
+ unless newline_maybe popped[:value]
97
+ popped[:value] = '_' if((popped[:value] == ' ') && (popped[:success] != true))
98
+ paint_success_failure(popped)
99
+ return true
100
+ end
98
101
  end
99
- end
100
102
 
101
- def heading
102
- "Current Sentence is duration: secs".length.times do
103
- print paint('*', list_colour)
104
- puts
103
+ def heading
104
+ "Current Sentence is duration: secs".length.times do
105
+ print paint('*', list_colour)
106
+ puts
107
+ end
105
108
  end
106
- end
107
109
 
108
- def fail word
109
- print paint("#{word}", fail_colour)
110
- end
110
+ def fail word
111
+ print paint("#{word}", fail_colour)
112
+ end
111
113
 
112
- def list word
113
- print paint("#{word}", list_colour)
114
- end
114
+ def list word
115
+ print paint("#{word}", list_colour)
116
+ end
115
117
 
116
- def success word
117
- newline_maybe word
118
- return if(@print_count == 0 && word == ' ')
119
- print paint("#{word}", success_colour)
120
- end
118
+ def success word
119
+ newline_maybe word
120
+ return if(@print_count == 0 && word == ' ')
121
+ print paint("#{word}", success_colour)
122
+ end
121
123
 
122
- def success_colour
123
- Params.success_colour ||= :blue
124
- end
124
+ def success_colour
125
+ Cfg.config["success_colour"].to_sym || :blue
126
+ end
125
127
 
126
- def fail_colour
127
- Params.fail_colour ||= :red
128
- end
128
+ def fail_colour
129
+ Cfg.config["fail_colour"].to_sym || :red
130
+ end
129
131
 
130
- def list_colour
131
- Params.list_colour ||= :white
132
- end
132
+ def list_colour
133
+ Cfg.config["list_colour"].to_sym || :default
134
+ end
133
135
 
134
- def print_advice name
135
- puts "#{name}: Press Q 4 times to Exit"
136
+ def print_advice name
137
+ puts "#{name}: Press Q 4 times to Exit"
138
+ end
136
139
  end
137
-
138
140
  end