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.
- data/lib/chords/command_line_parser.rb +5 -2
- data/lib/chords/fingering.rb +6 -1
- data/lib/chords/fretboard.rb +61 -3
- metadata +5 -5
@@ -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
|
-
|
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"
|
data/lib/chords/fingering.rb
CHANGED
@@ -87,7 +87,12 @@ module Chords
|
|
87
87
|
@positions.hash
|
88
88
|
end
|
89
89
|
|
90
|
-
#
|
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
|
data/lib/chords/fretboard.rb
CHANGED
@@ -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),
|
30
|
-
:cross_c => [C.new(-1), G.new, C.new, G.new(1), C.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:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
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-
|
18
|
+
date: 2010-08-10 00:00:00 +03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|