chords 0.3.2 → 0.4.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.
@@ -43,10 +43,11 @@ module Chords
43
43
 
44
44
  @opts.on("-t", "--tuning TUNING",
45
45
  "Tuning to use. See -l for list of available tunings and chords.") do |t|
46
- if !Chords::Fretboard::TUNINGS.has_key?(t.to_sym)
46
+ begin
47
+ @tuning = Fretboard.send(t.downcase).open_notes
48
+ rescue Exception => e
47
49
  raise OptionParser::ParseError.new("Invalid tuning")
48
50
  end
49
- @tuning = Chords::Fretboard::TUNINGS[t.to_sym]
50
51
  end
51
52
 
52
53
  @opts.on("--pdf", "Output to pdf. Requires Prawn.") do
@@ -109,6 +110,8 @@ module Chords
109
110
  Chords::Fretboard::TUNINGS.each do |key, value|
110
111
  out += "#{key.to_s.ljust(12, ' ')}: #{value.map{|n| n.class.to_s.gsub(/.*::/,'')}.join(',')}\n"
111
112
  end
113
+ out += "\nYou can also give a tuning as a string of notes, e.g. 'eadgbe'. Note that "+
114
+ "all 'b':s are considered notes, not flats, so use 's':s for sharps instead.\n"
112
115
  out += "\nChords:\n======\n"
113
116
  Chords::ChordFactory::CHORDS.each do |key, value|
114
117
  out += "#{key}\n"
@@ -87,7 +87,12 @@ module Chords
87
87
  @positions.hash
88
88
  end
89
89
 
90
- # fingering id, a unique identifier for fretboard/fingering combo
90
+ # Fingering id, a unique identifier for fretboard/fingering combo.
91
+ # Actually, fid is not unique if max_fret_distance >= 9,
92
+ # as positions [0,10,0,0,1,0] and [0,1,0,0,0,10] produce the
93
+ # same fid (if the tuning is the same).
94
+ # However, max_fret_distance of 9 or greater is not
95
+ # realistic.
91
96
  def fid
92
97
  @fretboard.open_notes.map{|n| n.class.title}.to_s +
93
98
  @positions.map{|pos| pos.nil? ? 'x' : pos}.to_s
@@ -26,8 +26,8 @@ module Chords
26
26
  :cross_e => [E.new, B.new, E.new(1), G.new(1), B.new(1), E.new(2)],
27
27
  :cross_d => [D.new(-1), A.new, D.new, F.new(1), A.new(1), D.new(1)],
28
28
  :cross_a => [E.new, A.new, E.new(1), A.new(1), C.new(1), E.new(2)],
29
- :cross_g => [D.new(-1), G.new, D.new, G.new(1), Bb.new(1), D.new(1)],
30
- :cross_c => [C.new(-1), G.new, C.new, G.new(1), C.new(1), Eb.new(1)],
29
+ :cross_g => [D.new(-1), G.new, D.new, G.new(1), As.new(1), D.new(1)],
30
+ :cross_c => [C.new(-1), G.new, C.new, G.new(1), C.new(1), Ds.new(1)],
31
31
 
32
32
  # Modal tunings
33
33
  :cacgce => [C.new(-1), A.new, C.new, G.new(1), C.new(1), E.new(2)],
@@ -47,15 +47,44 @@ module Chords
47
47
 
48
48
  attr_reader :frets, :open_notes, :formatter
49
49
 
50
- def initialize(open_notes, frets, formatter_class=TextFormatter)
50
+ def initialize(open_notes, frets=DEFAULT_FRETS, formatter_class=TextFormatter)
51
51
  @open_notes, @frets = open_notes, frets
52
52
  @formatter = formatter_class.new(self)
53
53
  end
54
54
 
55
+ # Creates a new fretboard, parsing the open notes from the open_notes_str.
56
+ # All 'b':s are interpreted as B-notes, not flats, so use 's' for sharps instead.
57
+ def self.new_by_string(open_notes_str, frets=DEFAULT_FRETS,
58
+ formatter_class=TextFormatter)
59
+ open_notes_str.upcase!
60
+ raise "Provide at least 3 strings" if open_notes_str.scan(/[^S]/m).size < 3
61
+ open_notes = []
62
+
63
+ open_notes_str.scan(/./m).each do |chr|
64
+ if chr == 'S'
65
+ raise "Invalid tuning!" if open_notes.empty?
66
+ open_notes[open_notes.size-1] += 1
67
+ else
68
+ open_notes << Chords.const_get(chr).new
69
+ end
70
+ end
71
+
72
+ (1..(open_notes.size-1)).each do |i|
73
+ open_notes[i] += 12 while open_notes[i-1] > open_notes[i]
74
+ end
75
+
76
+ Fretboard.new(open_notes, frets, formatter_class)
77
+ end
78
+
55
79
  def self.method_missing(meth, *args)
56
80
  if TUNINGS.has_key?(meth)
57
81
  Fretboard.new(TUNINGS[meth], (args[0] || DEFAULT_FRETS),
58
82
  args[1] || TextFormatter)
83
+
84
+ elsif meth.to_s =~ /^[efgabhcds]+$/
85
+ Fretboard.new_by_string(meth.to_s, (args[0] || DEFAULT_FRETS),
86
+ args[1] || TextFormatter)
87
+
59
88
  else
60
89
  super
61
90
  end
@@ -70,5 +99,34 @@ module Chords
70
99
  @formatter.print(chord.title, fingerings, opts)
71
100
  end
72
101
 
102
+ # Method for printing a single fingering using Fingering#fid,
103
+ # which contains also the tuning/fretboard used.
104
+ # Doesn't handle big max_fret_distances right.
105
+ def self.print_fingering_by_fid(fid, opts={}, formatter_class=TextFormatter)
106
+ fingering_part = fid.split(/[efgabhcds]/).last
107
+ raise "Invalid fingering" if fingering_part.nil?
108
+ tuning_part = fid.sub(fingering_part, '')
109
+
110
+ fretboard = Fretboard.new_by_string(tuning_part, 50, formatter_class)
111
+ over_tens = fingering_part.size - fretboard.open_notes.size
112
+
113
+ i=0
114
+ positions = []
115
+
116
+ while i < fingering_part.size
117
+ fp = fingering_part[i,1]
118
+ fp == 'x' ? pos = nil : pos = fp.to_i
119
+ if over_tens > 0 and pos and pos < 4
120
+ over_tens -= 1
121
+ i += 2
122
+ pos = "#{pos}#{fingering_part[i+1,1]}".to_i
123
+ else
124
+ i += 1
125
+ end
126
+ positions << pos
127
+ end
128
+ fretboard.formatter.print('', [Fingering.new(fretboard, positions)], opts)
129
+ end
130
+
73
131
  end
74
132
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chords
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
9
- - 2
10
- version: 0.3.2
8
+ - 4
9
+ - 1
10
+ version: 0.4.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Antti Hakala
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-23 00:00:00 +03:00
18
+ date: 2010-08-10 00:00:00 +03:00
19
19
  default_executable:
20
20
  dependencies: []
21
21