chordy 0.7.1 → 0.7.2

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.
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