chordy 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'bundler'
5
+
5
6
  begin
6
7
  Bundler.setup(:default, :development)
7
8
  rescue Bundler::BundlerError => e
@@ -9,6 +10,14 @@ rescue Bundler::BundlerError => e
9
10
  $stderr.puts "Run `bundle install` to install missing gems"
10
11
  exit e.status_code
11
12
  end
13
+
14
+ if !File.exist?('VERSION')
15
+ $stderr.puts "Could not find VERSION file"
16
+ exit 1
17
+ end
18
+
19
+ VERSION = File.read('VERSION').gsub(/\n/, '')
20
+
12
21
  require 'rake/dsl_definition'
13
22
  require 'rake'
14
23
 
@@ -16,11 +25,11 @@ require 'jeweler'
16
25
  Jeweler::Tasks.new do |gem|
17
26
  gem.name = "chordy"
18
27
  gem.rubyforge_project = "chordy"
19
- gem.version = "0.7.1"
28
+ gem.version = VERSION
20
29
  gem.homepage = "http://github.com/darth10/chordy"
21
30
  gem.license = "MIT"
22
31
  gem.summary = %Q{DSL for guitar chords}
23
- gem.description = %Q{Chordy is a DSL written in Ruby to print guitar chords diagrams}
32
+ gem.description = %Q{A Ruby DSL for printing guitar chords diagrams}
24
33
  gem.email = "akhil.wali.10@gmail.com"
25
34
  gem.authors = ["Akhil Wali"]
26
35
  end
@@ -37,10 +46,8 @@ task :default => [:test, :build]
37
46
 
38
47
  require 'rdoc/task'
39
48
  Rake::RDocTask.new do |rdoc|
40
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
-
42
49
  rdoc.rdoc_dir = 'rdoc'
43
- rdoc.title = "chordy #{version}"
50
+ rdoc.title = "chordy #{VERSION}"
44
51
  rdoc.rdoc_files.include('README*')
45
52
  rdoc.rdoc_files.include('LICENSE.rdoc')
46
53
  rdoc.rdoc_files.include('lib/**/*.rb')
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.7.2
@@ -1,51 +1,56 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'chord'
4
-
5
- require 'c_chords'
6
- require 'c_sharp_chords'
7
- require 'd_chords'
8
- require 'd_sharp_chords'
9
- require 'e_chords'
10
- require 'f_chords'
11
- require 'f_sharp_chords'
12
- require 'g_chords'
13
- require 'g_sharp_chords'
14
- require 'a_chords'
15
- require 'a_sharp_chords'
16
- require 'b_chords'
17
-
18
- require 'text'
19
- require 'section'
20
-
21
- require 'tuning'
22
- include Tuning
3
+ includes = ['chords', 'util']
4
+
5
+ include_dirs = includes.map { |dir| "chordy/#{dir}/" }
6
+ include_dirs.each do |dir|
7
+ Dir[File.join(File.dirname(__FILE__), dir + '**.rb')].each do |file|
8
+ require file
9
+ end
10
+ end
23
11
 
24
12
  module Chordy
25
- $line_length = 8
26
- $separator_length = 40
27
- $chords = []
28
- $auto = true
29
- $tuning = tuning_6_standard.map { |e| e.capitalize }
30
- $reverse = false
13
+ extend self, Util, Util::Tuning
31
14
 
32
- # printing delimiters
33
- $chord_space = "-"
34
- $half_length_delimiter = "|"
35
- $start_delimiter = "["
36
- $end_delimiter = "]"
15
+ attr_accessor :chords, :line_length, :separator_length, :tuning, :auto, :low_to_high
16
+ attr_accessor :chord_space, :half_length_delimiter, :start_delimiter, :end_delimiter
17
+
18
+ @line_length = 8
19
+ @separator_length = 40
20
+ @chords = []
21
+ @auto = true
22
+ @tuning = tuning_6_standard
23
+ @low_to_high = false
37
24
 
38
- def auto a=true
39
- $auto = if a then true else false end
25
+ # printing delimiters
26
+ @chord_space = "-"
27
+ @half_length_delimiter = "|"
28
+ @start_delimiter = "["
29
+ @end_delimiter = "]"
30
+
31
+ def do_auto a=true
32
+ Chordy.auto = a
33
+ Chordy.auto
40
34
  end
41
35
 
42
36
  def no_auto
43
- auto false
37
+ Chordy.auto = false
38
+ Chordy.auto
44
39
  end
45
40
 
46
- def line_length a
41
+ def do_low_to_high
42
+ Chordy.low_to_high = true
43
+ do_print
44
+ end
45
+
46
+ def do_high_to_low
47
+ Chordy.low_to_high = false
48
+ do_print
49
+ end
50
+
51
+ def set_line_length a
47
52
  if a.instance_of? Fixnum
48
- $line_length = a
53
+ Chordy.line_length = a
49
54
  do_print
50
55
  else
51
56
  puts "Invalid length"
@@ -53,26 +58,30 @@ module Chordy
53
58
  end
54
59
 
55
60
  def clear
56
- $chords = []
61
+ Chordy.chords = []
57
62
  do_print
58
63
  end
59
64
 
60
65
  # TODO document + examples
61
66
 
62
- def set_tuning_with_padding tuning
67
+ def set_chords_to_tuning tuning
63
68
  longest_tuning_str_length = tuning.max.length
64
- $tuning = tuning.map { |e| e.capitalize.rjust(longest_tuning_str_length) }
65
-
66
- $chords = $chords.each { |e| e.pad_or_trim $tuning.length, true }
69
+ Chordy.tuning = tuning.map { |e| e.rjust(longest_tuning_str_length) }
70
+
71
+ Chordy.chords.select { |c| c.is_a? Chord } .each { |e| e.pad_or_trim Chordy.tuning.length, true }
67
72
  end
68
73
 
69
- def tune new_tuning
74
+ def tune new_tuning, direction=:low_to_high
70
75
  to_do_print = false
71
76
  strings = [6, 7, 8]
72
77
 
73
78
  if new_tuning.is_a? Array
74
79
  if strings.include? new_tuning.length
75
- set_tuning_with_padding new_tuning
80
+ if direction == :high_to_low
81
+ new_tuning = new_tuning.reverse
82
+ end
83
+
84
+ set_chords_to_tuning new_tuning
76
85
  to_do_print = true
77
86
  else
78
87
  puts "Invalid tuning; only " + strings.join(",") + " strings are allowed"
@@ -80,7 +89,7 @@ module Chordy
80
89
  else
81
90
  if is_tuning? new_tuning.to_s
82
91
  new_tuning = eval("#{new_tuning}")
83
- set_tuning_with_padding new_tuning
92
+ set_chords_to_tuning new_tuning
84
93
  to_do_print = true
85
94
  else
86
95
  puts "Unknown or invalid tuning"
@@ -110,41 +119,48 @@ module Chordy
110
119
  eval("defined?(#{chord_name}) == 'constant' and #{chord_name}.class == Class")
111
120
  end
112
121
 
113
- def play chords, chord_type=:major
122
+ def play chords, chord_type_or_direction=:major
114
123
  chord = nil
115
124
  begin
116
125
  if chords.instance_of? Array
117
- chord = Chord.new(chords, $tuning.length)
126
+ chord = Chord.new(chords, Chordy.tuning.length)
127
+
128
+ # play high-to-low, unless :low_to_high is specified
129
+ if chord_type_or_direction != :low_to_high
130
+ chord.reverse_strings!
131
+ end
118
132
  else
119
133
  chord_name = chords.to_s
120
134
  if !check_chord_class chord_name
121
135
  chord_name = check_sharp_or_flat_chord chord_name
122
136
  end
123
137
 
124
- chord_init = "#{chord_name}.new :#{chord_type}, #{$tuning.length}"
138
+ chord_init = "#{chord_name}.new :#{chord_type_or_direction}, #{Chordy.tuning.length}"
125
139
  chord = eval(chord_init)
126
140
  end
127
141
 
128
- $chords.push chord
142
+ Chordy.chords.push chord
129
143
  do_print
130
144
  rescue NameError => ne
131
145
  puts "Unknown chord or chord type"
132
146
  puts ne.message
147
+ puts ne.backtrace
133
148
  rescue Exception => e
134
149
  puts e.class.to_s
135
150
  puts e.message
151
+ puts e.backtrace
136
152
  end
137
153
 
138
154
  chord
139
155
  end
140
156
 
141
157
  def text text
142
- $chords.push Text.new(text)
158
+ Chordy.chords.push Util::Text.new(text)
143
159
  do_print
144
160
  end
145
161
 
146
162
  def section title=""
147
- $chords.push Section.new(title, $separator_length)
163
+ Chordy.chords.push Util::Section.new(title, Chordy.separator_length)
148
164
  do_print
149
165
  end
150
166
 
@@ -153,7 +169,7 @@ module Chordy
153
169
  end
154
170
 
155
171
  def do_print
156
- if $auto
172
+ if Chordy.auto
157
173
  print_chords
158
174
  end
159
175
  end
@@ -162,18 +178,22 @@ module Chordy
162
178
  lines_to_print = []
163
179
  chord_index = 0
164
180
  chords_in_section = 0
165
- tuning_length = $tuning.length
181
+ tuning_length = Chordy.tuning.length
166
182
  is_done = false
167
183
  is_new_line = true
168
- is_even_line_length = ($line_length % 2) == 0
184
+ is_even_line_length = (Chordy.line_length % 2) == 0
169
185
  is_next_chord_section_or_text = false
170
186
  to_print_start_chords = false
171
187
  to_skip_end_strings = false
172
188
 
189
+ chords = Chordy.chords.to_a
190
+ chords.select { |c| c.is_a? Util::Section } .map { |s| s.separator_length = Chordy.separator_length }
191
+
173
192
  while !is_done
174
193
  if is_new_line or to_print_start_chords
175
- if $chords[chord_index].is_a? Chord
176
- start_strings = Chord.start_of_strings $tuning, $start_delimiter
194
+ if chords[chord_index].is_a? Chord
195
+ start_strings = Chord.start_of_strings Chordy.tuning, Chordy.start_delimiter, Chordy.low_to_high
196
+
177
197
  start_strings.each { |s| lines_to_print.push s }
178
198
  end
179
199
  to_print_start_chords = false
@@ -181,40 +201,40 @@ module Chordy
181
201
  end
182
202
 
183
203
  last_chord_lines = lines_to_print.last(tuning_length + 1)
184
- curr_chord = $chords[chord_index]
204
+ curr_chord = chords[chord_index]
185
205
  if curr_chord.is_a? Chord
186
- last_chord_lines.each_with_index do |line,i|
206
+ last_chord_lines.each_with_index do |line, i|
187
207
  if i == tuning_length
188
208
  line << curr_chord.print_flag
189
209
  else
190
- line << curr_chord.print_string_at(i, $chord_space)
210
+ line << curr_chord.print_string_at(i, Chordy.chord_space, Chordy.low_to_high)
191
211
  end
192
212
  end
193
213
 
194
214
  chords_in_section = chords_in_section + 1
195
215
  to_skip_end_strings = false
196
- elsif ($chords[chord_index].is_a? Text) or ($chords[chord_index].is_a? Section)
197
- lines_to_print.push $chords[chord_index].to_s
216
+ elsif (chords[chord_index].is_a? Util::Text) or (chords[chord_index].is_a? Util::Section)
217
+ lines_to_print.push chords[chord_index].to_s
198
218
  to_skip_end_strings = true
199
219
  chords_in_section = 0
200
220
 
201
- if $chords[chord_index + 1].is_a? Chord
221
+ if chords[chord_index + 1].is_a? Chord
202
222
  to_print_start_chords = true
203
223
  end
204
224
  end
205
225
 
206
226
  chord_index = chord_index + 1
207
- if ($chords[chord_index].is_a? Text) or ($chords[chord_index].is_a? Section)
227
+ if (chords[chord_index].is_a? Util::Text) or (chords[chord_index].is_a? Util::Section)
208
228
  is_next_chord_section_or_text = true
209
229
  else
210
230
  is_next_chord_section_or_text = false
211
231
  end
212
232
 
213
- if ((chords_in_section % $line_length) == 0) or (chord_index == $chords.length) or is_next_chord_section_or_text
233
+ if ((chords_in_section % Chordy.line_length) == 0) or (chord_index == chords.length) or is_next_chord_section_or_text
214
234
  if to_skip_end_strings
215
235
  to_skip_end_strings = false
216
236
  else
217
- end_strings = Chord.end_of_strings $tuning, $end_delimiter
237
+ end_strings = Chord.end_of_strings Chordy.tuning, Chordy.end_delimiter
218
238
  last_chord_lines.each_with_index do |line, i|
219
239
  line << end_strings[i]
220
240
  end
@@ -223,9 +243,9 @@ module Chordy
223
243
  # start the next actual line
224
244
  lines_to_print.push ""
225
245
  is_new_line = true
226
- elsif (chords_in_section % $line_length) == ($line_length / 2) and is_even_line_length
246
+ elsif (chords_in_section % Chordy.line_length) == (Chordy.line_length / 2) and is_even_line_length
227
247
  last_chord_lines.each_with_index do |line, i|
228
- line << Chord.print_half_length_string_at(i, $tuning, $half_length_delimiter, $chord_space)
248
+ line << Chord.print_half_length_string_at(i, Chordy.tuning, Chordy.half_length_delimiter, Chordy.chord_space)
229
249
  end
230
250
  end
231
251
 
@@ -233,7 +253,7 @@ module Chordy
233
253
  is_new_line = false
234
254
  end
235
255
 
236
- if chord_index >= $chords.length
256
+ if chord_index >= chords.length
237
257
  is_done = true
238
258
  end
239
259
  end
@@ -246,20 +266,21 @@ module Chordy
246
266
  Chord::CHORD_FLAGS.each_with_index do |name,i|
247
267
  eval <<-ENDOFEVAL
248
268
  def #{name}
249
- saved_auto = $auto
250
- saved_chord_index = $chords.length
251
- $auto = false
269
+ saved_auto = Chordy.auto
270
+ saved_chord_index = Chordy.chords.length
271
+ Chordy.auto = false
252
272
  begin
253
273
  chord = yield if block_given?
254
274
 
255
- num_new_chords = $chords.length - saved_chord_index
256
- $chords.last(num_new_chords).each { |c| c.send :#{name} }
275
+ num_new_chords = Chordy.chords.length - saved_chord_index
276
+ Chordy.chords.last(num_new_chords).each { |c| c.send :#{name} }
257
277
  rescue Exception => e
258
278
  puts e.class.to_s
259
279
  puts e.message
280
+ puts e.backtrace
260
281
  end
261
282
 
262
- $auto = saved_auto
283
+ Chordy.auto = saved_auto
263
284
  do_print
264
285
  chord
265
286
  end
@@ -267,8 +288,8 @@ module Chordy
267
288
 
268
289
  if name != "dont_play"
269
290
  eval <<-ENDOFEVAL
270
- def play_#{name} chords, chord_type=:major
271
- #{name} { play chords, chord_type }
291
+ def play_#{name} chords, chord_type_or_direction=:major
292
+ #{name} { play chords, chord_type_or_direction }
272
293
  end
273
294
  ENDOFEVAL
274
295
  end
@@ -0,0 +1,228 @@
1
+ # encoding: utf-8
2
+
3
+ module Chordy
4
+
5
+ class Chord
6
+ CHORD_FLAGS = %w(mute harmonic bend pull hammer_down slide_down slide_up dont_play vibrato)
7
+
8
+ def self.all_flags
9
+ CHORD_FLAGS.to_a
10
+ end
11
+
12
+ # gets number of high strings in a tuning by approximation
13
+ def self.get_num_high_strings length
14
+ (length / 3.0).ceil
15
+ end
16
+
17
+ def self.start_of_strings tuning, start_delimiter, low_to_high
18
+ num_strings = tuning.length
19
+ num_high_strings = get_num_high_strings num_strings
20
+
21
+ strings_in_downcase = tuning.map { |s| s.downcase }
22
+ high_strings = strings_in_downcase.last(num_high_strings)
23
+ low_strings = strings_in_downcase.first(num_strings - num_high_strings).map { |s| s.capitalize }
24
+
25
+ strings_range = low_strings + high_strings
26
+ if !low_to_high
27
+ strings_range = strings_range.reverse
28
+ end
29
+
30
+ strings_to_print = strings_range.map { |s| s.rjust(2) + start_delimiter.rjust(2) }
31
+ strings_to_print + [ " " * 4 ]
32
+ end
33
+
34
+ def self.end_of_strings tuning, end_delimiter
35
+ num_strings = tuning.length
36
+ ([ end_delimiter ] * num_strings) + [ "" ]
37
+ end
38
+
39
+ def self.print_half_length_string_at string_pos, tuning, half_length_delimiter, chord_space
40
+ if string_pos == tuning.length
41
+ "".rjust(2)
42
+ else
43
+ half_length_delimiter.rjust(2, chord_space)
44
+ end
45
+ end
46
+
47
+ def self.short_chords
48
+ {
49
+ :M => :major,
50
+ :m => :minor,
51
+ :_7 => :dominant_7,
52
+ :_7_5 => :dominant_7_5,
53
+ :_9 => :diminished_9,
54
+ :M6 => :major_6,
55
+ :M7 => :major_7,
56
+ :M9 => :major_9,
57
+ :m5 => :diminished_5,
58
+ :m6 => :minor_6,
59
+ :m7 => :minor_7,
60
+ :m7_5 => :half_diminished_7,
61
+ :mM7 => :minor_major_7,
62
+ :aug5 => :augmented_5,
63
+ :aug7 => :augmented_7,
64
+ :aug7_5 => :augmented_major_7,
65
+ :dim => :diminished_7,
66
+ :dim7 => :diminished_7,
67
+ :dim5 => :diminished_5,
68
+ :dim9 => :diminished_9,
69
+ :sus => :suspended_4,
70
+ :sus4 => :suspended_4,
71
+ :sus7 => :suspended_7,
72
+ }
73
+ end
74
+
75
+ def initialize chord, strings
76
+ @strings = [-1] * strings
77
+ pad_low = false
78
+ if chord.instance_of? String or chord.instance_of? Symbol
79
+ short_chords = Chord.short_chords
80
+ if short_chords.key? chord
81
+ chord_strings = play short_chords[chord]
82
+ @type = short_chords[chord]
83
+ else
84
+ chord_strings = play chord.to_sym
85
+ @type = chord.to_sym
86
+ end
87
+ pad_low = true
88
+ elsif chord.instance_of? Array
89
+ chord_strings = chord.to_a
90
+ end
91
+
92
+ @strings = chord_strings
93
+ pad_or_trim strings, pad_low
94
+ @flags = 0
95
+ end
96
+
97
+ def pad_or_trim length, pad_low
98
+ if @strings.length > length
99
+ @strings = @strings.last length
100
+ elsif @strings.length < length
101
+ diff = length - @strings.length
102
+ if pad_low
103
+ first = @strings.first
104
+ min = @strings.min
105
+
106
+ # play as bar chord
107
+ bar_chord_string = ((first == min) and (min > 0) and (first > 0)) ? first : -1
108
+ @strings = ([bar_chord_string] * diff) + @strings
109
+ else
110
+ @strings = @strings + [-1] * diff
111
+ end
112
+
113
+ self
114
+ end
115
+ end
116
+
117
+ def play chord_type
118
+ method_for_chord_type = "play_" + chord_type.to_s
119
+ chord = eval(method_for_chord_type)
120
+ chord
121
+ end
122
+
123
+ def reverse_strings!
124
+ @strings = @strings.reverse
125
+ self
126
+ end
127
+
128
+ def strings
129
+ @strings
130
+ end
131
+
132
+ def flags
133
+ @flags
134
+ end
135
+
136
+ def has_flag flag
137
+ (@flags & flag) == flag
138
+ end
139
+
140
+ def add_flag flag
141
+ @flags = @flags | flag
142
+ self
143
+ end
144
+
145
+ def get_index_to_print i, low_to_high
146
+ if low_to_high
147
+ i
148
+ else
149
+ @strings.length - i - 1
150
+ end
151
+ end
152
+
153
+ def print_string_at i, chord_space, low_to_high=false
154
+ to_print = chord_space
155
+ index_to_print = get_index_to_print i, low_to_high
156
+ string = @strings[index_to_print]
157
+ if string != -1
158
+ to_print = string.to_s
159
+ end
160
+
161
+ to_print = to_print.rjust(3, chord_space)
162
+
163
+ if @flags != 0
164
+ to_print = print_string_with_flag_at index_to_print, to_print, chord_space
165
+ end
166
+
167
+ to_print.ljust(4, chord_space)
168
+ end
169
+
170
+ def print_string_with_flag_at i, printed_string, chord_space
171
+ to_print = printed_string
172
+ string = @strings[i]
173
+
174
+ if string != -1
175
+ if has_flag DONT_PLAY
176
+ to_print = "x".rjust(3, chord_space)
177
+ elsif has_flag BEND
178
+ to_print = to_print + "b"
179
+ elsif has_flag HAMMER_DOWN
180
+ to_print = to_print + "h"
181
+ elsif has_flag PULL
182
+ to_print = to_print + "p"
183
+ elsif has_flag SLIDE_UP
184
+ to_print = to_print + "/"
185
+ elsif has_flag SLIDE_DOWN
186
+ to_print = to_print + "\\"
187
+ elsif has_flag VIBRATO
188
+ to_print = to_print + "~"
189
+ end
190
+ end
191
+
192
+ to_print
193
+ end
194
+
195
+ # for printing flags on diff line
196
+ def print_flag
197
+ to_print = ""
198
+
199
+ if has_flag MUTE
200
+ to_print = "M"
201
+ elsif has_flag HARMONIC
202
+ to_print = "H"
203
+ end
204
+
205
+ to_print.rjust(3).ljust(4)
206
+ end
207
+ end
208
+
209
+ Chord::CHORD_FLAGS.each_with_index do |name,i|
210
+ Chord.class_eval <<-ENDOFEVAL
211
+ #{name.upcase} = #{2**i}
212
+
213
+ def #{name}
214
+ add_flag #{name.upcase}
215
+ self
216
+ end
217
+ ENDOFEVAL
218
+ end
219
+
220
+ Chord.short_chords.values.each do |chord_type|
221
+ chord_type_str = chord_type.to_s
222
+ Chord.class_eval <<-ENDOFEVAL
223
+ def play_#{chord_type_str}
224
+ [-1] * 6
225
+ end
226
+ ENDOFEVAL
227
+ end
228
+ end