coltrane 1.0.1 → 1.0.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +19 -0
- data/Gemfile +5 -2
- data/Gemfile.lock +3 -3
- data/coltrane.gemspec +1 -1
- data/exe/coltrane +27 -21
- data/lib/{coltrane-cli.rb → cli.rb} +7 -1
- data/lib/cli/bass_guitar.rb +4 -1
- data/lib/cli/chord.rb +10 -3
- data/lib/cli/errors.rb +10 -4
- data/lib/cli/guitar.rb +12 -10
- data/lib/cli/notes.rb +7 -4
- data/lib/cli/piano.rb +11 -8
- data/lib/cli/representation.rb +14 -14
- data/lib/cli/scale.rb +15 -11
- data/lib/cli/text.rb +6 -3
- data/lib/cli/ukulele.rb +5 -2
- data/lib/coltrane.rb +4 -7
- data/lib/coltrane/cache.rb +10 -9
- data/lib/coltrane/cadence.rb +3 -1
- data/lib/coltrane/chord.rb +16 -8
- data/lib/coltrane/chord_quality.rb +7 -8
- data/lib/coltrane/classic_progressions.rb +10 -7
- data/lib/coltrane/classic_scales.rb +30 -43
- data/lib/coltrane/errors.rb +17 -10
- data/lib/coltrane/interval.rb +24 -23
- data/lib/coltrane/interval_sequence.rb +8 -7
- data/lib/coltrane/interval_set.rb +1 -0
- data/lib/coltrane/note.rb +23 -46
- data/lib/coltrane/note_set.rb +12 -14
- data/lib/coltrane/pitch.rb +5 -4
- data/lib/coltrane/progression.rb +9 -20
- data/lib/coltrane/qualities.rb +114 -112
- data/lib/coltrane/roman_chord.rb +8 -5
- data/lib/coltrane/scale.rb +25 -33
- data/lib/coltrane/version.rb +3 -1
- data/lib/core_ext.rb +7 -4
- metadata +7 -10
- data/db/schema.rb +0 -30
- data/lib/coltrane/chord_cache.rb +0 -4
- data/lib/coltrane/scale_chord.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea60cb4885291b3da70a6b6be31aa82a7e98f409615b74c5a7898df377c741b5
|
4
|
+
data.tar.gz: 938b8a0d42dfee3fe443d90065e8e437b6b4f57ec6ad5358a65c1fc325c7d4dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81c54ad075e562d37ed4929e8b07d951a738240dadd95a76d5f453fd37f2fd5f894fbe5052ddcc8e25ba36109e877ed366a237980373b3213c1b740ad988574a
|
7
|
+
data.tar.gz: da5f20ad56a53244e88a7408cdcf53bb50655d9af2ddb8e57725ed88dcdc8573eb85d8634289d7fce0fa8315ec5f4fa73da8428c9d78fd9933006f9f5b15112e
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
AllCops:
|
2
|
+
Include:
|
3
|
+
- 'lib/**/*'
|
4
|
+
Exclude:
|
5
|
+
- 'bin/**/*'
|
6
|
+
- '*'
|
7
|
+
|
8
|
+
Metrics/AbcSize:
|
9
|
+
Enabled: false
|
10
|
+
Metrics/ClassLength:
|
11
|
+
Enabled: false
|
12
|
+
Metrics/MethodLength:
|
13
|
+
Enabled: false
|
14
|
+
Metrics/ModuleLength:
|
15
|
+
Enabled: false
|
16
|
+
Lint/UnneededSplatExpansion:
|
17
|
+
Enabled: false
|
18
|
+
Security/MarshalLoad:
|
19
|
+
Enabled: false
|
data/Gemfile
CHANGED
@@ -2,11 +2,14 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
group :test do
|
6
|
-
gem 'rspec'
|
5
|
+
group :test, :development do
|
7
6
|
gem 'pry'
|
8
7
|
gem 'pry-byebug'
|
9
8
|
gem 'pry-rescue'
|
9
|
+
end
|
10
|
+
|
11
|
+
group :test do
|
12
|
+
gem 'rspec'
|
10
13
|
gem 'simplecov', require: false
|
11
14
|
gem 'rubocop', require: false
|
12
15
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
coltrane (1.0.
|
5
|
-
|
4
|
+
coltrane (1.0.11)
|
5
|
+
color (~> 1.8)
|
6
6
|
facets (~> 3.1)
|
7
7
|
mercenary (~> 0.3)
|
8
8
|
paint (~> 2.0)
|
@@ -12,8 +12,8 @@ GEM
|
|
12
12
|
specs:
|
13
13
|
ast (2.3.0)
|
14
14
|
byebug (9.1.0)
|
15
|
-
chroma (0.2.0)
|
16
15
|
coderay (1.1.2)
|
16
|
+
color (1.8)
|
17
17
|
diff-lcs (1.3)
|
18
18
|
docile (1.1.5)
|
19
19
|
facets (3.1.0)
|
data/coltrane.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
|
33
33
|
spec.add_runtime_dependency 'facets', '~> 3.1'
|
34
34
|
spec.add_runtime_dependency 'paint', '~> 2.0'
|
35
|
-
spec.add_runtime_dependency '
|
35
|
+
spec.add_runtime_dependency 'color', '~> 1.8'
|
36
36
|
spec.add_runtime_dependency 'mercenary', '~> 0.3'
|
37
37
|
spec.add_development_dependency "bundler", '~> 1.14'
|
38
38
|
spec.add_development_dependency "rake", '~> 10.0'
|
data/exe/coltrane
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# rubocop:disable Metrics/BlockLength
|
2
5
|
|
3
6
|
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
|
4
7
|
|
5
8
|
require 'core_ext'
|
6
9
|
require 'coltrane'
|
7
|
-
require '
|
10
|
+
require 'cli'
|
8
11
|
|
9
12
|
full_color_terminals = %w[iTerm.app]
|
10
13
|
safe_mode_terminals = %w[Unsupported]
|
@@ -71,9 +74,9 @@ Mercenary.program(:Coltrane) do |p|
|
|
71
74
|
c.option :pentads, '--pentads', 'Outputs pentad chords from the scale'
|
72
75
|
c.option :tertians, '--tertians SIZE', 'Outputs all tertian chords from the given size from the scale'
|
73
76
|
c.option :chords, '--chords [SIZE]', 'Outputs all chords from given size from the scale. Leave size empty to retrieve all'
|
74
|
-
c.action do |(scale_str), flavor:'degrees', on:'text', **options|
|
77
|
+
c.action do |(scale_str), flavor: 'degrees', on: 'text', **options|
|
75
78
|
scale = Coltrane::Cli::Scale.parse(scale_str)
|
76
|
-
keyword_args = {flavor: flavor, on: on }
|
79
|
+
keyword_args = { flavor: flavor, on: on }
|
77
80
|
if options.include?(:triads)
|
78
81
|
chords = scale.triads
|
79
82
|
Coltrane::Cli::Chord.new(*chords, **keyword_args)
|
@@ -87,11 +90,11 @@ Mercenary.program(:Coltrane) do |p|
|
|
87
90
|
chords = scale.tertians(options[:tertians].to_i)
|
88
91
|
Coltrane::Cli::Chord.new(*chords, **keyword_args)
|
89
92
|
elsif options.include?(:chords)
|
90
|
-
if options[:chords].nil?
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
93
|
+
chords = if options[:chords].nil?
|
94
|
+
scale.all_chords
|
95
|
+
else
|
96
|
+
scale.chords(options[:chords])
|
97
|
+
end
|
95
98
|
Coltrane::Cli::Chord.new(*chords, **keyword_args)
|
96
99
|
else
|
97
100
|
Coltrane::Cli::Scale.new(scale, **keyword_args)
|
@@ -104,11 +107,11 @@ Mercenary.program(:Coltrane) do |p|
|
|
104
107
|
list.description 'List information.'
|
105
108
|
list.action do |(arg)|
|
106
109
|
puts case arg
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
110
|
+
when 'scales' then Coltrane::Scale.known_scales
|
111
|
+
when 'flavors' then %w[marks notes intervals degrees]
|
112
|
+
when 'instruments' then %w[guitar bass ukulele piano text]
|
113
|
+
when 'chords', 'chord-qualities' then Coltrane::Qualities::CHORD_QUALITIES.keys.sort.join(' ')
|
114
|
+
end
|
112
115
|
end
|
113
116
|
end
|
114
117
|
|
@@ -117,9 +120,9 @@ Mercenary.program(:Coltrane) do |p|
|
|
117
120
|
c.description 'finds scales with the provided --notes or --chord'
|
118
121
|
c.option :notes, '--notes C-D-E', 'Find scales with those notes'
|
119
122
|
c.option :chords, '--chords Cmaj7-D11', 'find scales with those chords'
|
120
|
-
c.action do |(
|
121
|
-
options[:notes] =
|
122
|
-
options[:chords] =
|
123
|
+
c.action do |(_arg), options|
|
124
|
+
options[:notes] = (options[:notes]).to_s.split('-')
|
125
|
+
options[:chords] = (options[:chords]).to_s.split('-')
|
123
126
|
Coltrane::Cli::Scale.find(**options)
|
124
127
|
end
|
125
128
|
end
|
@@ -145,14 +148,15 @@ Mercenary.program(:Coltrane) do |p|
|
|
145
148
|
p.command(:help) do |c|
|
146
149
|
c.description 'May give you some help.'
|
147
150
|
c.syntax 'help <command> [subcommand, sub-subcommand, ...]'
|
148
|
-
c.action do |(*command_path),
|
151
|
+
c.action do |(*command_path), _options|
|
149
152
|
if command_path.empty?
|
150
153
|
puts p
|
151
|
-
return
|
152
154
|
else
|
153
|
-
puts
|
154
|
-
|
155
|
-
|
155
|
+
puts begin
|
156
|
+
command_path.reduce(p) do |memo, key|
|
157
|
+
memo.commands.delete(key.to_sym)
|
158
|
+
end || "\n Sorry, command found."
|
159
|
+
end
|
156
160
|
end
|
157
161
|
end
|
158
162
|
end
|
@@ -166,3 +170,5 @@ Mercenary.program(:Coltrane) do |p|
|
|
166
170
|
|
167
171
|
p.default_command(:about)
|
168
172
|
end
|
173
|
+
|
174
|
+
# rubocop:enable Metrics/BlockLength
|
@@ -1,3 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mercenary'
|
4
|
+
require 'paint'
|
5
|
+
require 'color'
|
6
|
+
|
1
7
|
require 'cli/errors'
|
2
8
|
|
3
9
|
require 'cli/representation'
|
@@ -9,4 +15,4 @@ require 'cli/ukulele'
|
|
9
15
|
|
10
16
|
require 'cli/notes'
|
11
17
|
require 'cli/chord'
|
12
|
-
require 'cli/scale'
|
18
|
+
require 'cli/scale'
|
data/lib/cli/bass_guitar.rb
CHANGED
data/lib/cli/chord.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Coltrane
|
2
4
|
module Cli
|
5
|
+
# Interfaces chord functionality with the lib
|
3
6
|
class Chord
|
4
7
|
def initialize(*chords, on: :text, flavor: 'intervals', notes: nil)
|
5
8
|
@chords =
|
@@ -10,15 +13,19 @@ module Coltrane
|
|
10
13
|
chords
|
11
14
|
end
|
12
15
|
elsif !notes.nil?
|
13
|
-
|
16
|
+
[Coltrane::Chord.new(notes: notes)]
|
14
17
|
end
|
15
18
|
|
16
19
|
@chords.each do |chord|
|
17
20
|
raise ChordNotFoundError unless chord.named?
|
18
21
|
desc = "#{chord.name} chord:"
|
19
|
-
Coltrane::Cli::Notes.new
|
22
|
+
Coltrane::Cli::Notes.new chord.notes, on: on,
|
23
|
+
desc: desc,
|
24
|
+
flavor: flavor
|
20
25
|
end
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
24
|
-
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# rubocop:enable Metrics/MethodLength
|
data/lib/cli/errors.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Style/Documentation
|
4
|
+
|
1
5
|
module Coltrane
|
2
6
|
module Cli
|
3
7
|
class ColtraneCliError < StandardError
|
@@ -7,13 +11,13 @@ module Coltrane
|
|
7
11
|
end
|
8
12
|
|
9
13
|
class WrongFlavorError < ColtraneCliError
|
10
|
-
def initialize(msg=nil)
|
14
|
+
def initialize(msg = nil)
|
11
15
|
super msg || 'Wrong flavor. Check possible flavors with `coltrane list flavors`.'
|
12
16
|
end
|
13
17
|
end
|
14
18
|
|
15
19
|
class BadFindScales < ColtraneCliError
|
16
|
-
def initialize(msg=nil)
|
20
|
+
def initialize(msg = nil)
|
17
21
|
super msg || 'Provide --notes or --chords. Ex: `coltrane find-scale --notes C E G`.'
|
18
22
|
end
|
19
23
|
end
|
@@ -21,8 +25,10 @@ module Coltrane
|
|
21
25
|
class WrongRepresentationTypeError < ColtraneCliError
|
22
26
|
def initialize(type)
|
23
27
|
super "The provided representation type (#{type}) "\
|
24
|
-
|
28
|
+
'is not available at the moment.'
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
28
|
-
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# rubocop:enable Style/Documentation
|
data/lib/cli/guitar.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Coltrane
|
2
4
|
module Cli
|
3
|
-
SPECIAL_FRETS = [3, 5, 7, 9, 12, 15, 17, 19]
|
5
|
+
SPECIAL_FRETS = [3, 5, 7, 9, 12, 15, 17, 19].freeze
|
4
6
|
|
7
|
+
# Renders notes in a common most popular ukulele scheme
|
5
8
|
class Guitar < Representation
|
6
9
|
def initialize(notes, flavor, tuning: %w[E A D G B E], frets: 22)
|
7
10
|
@notes = notes
|
@@ -12,34 +15,33 @@ module Coltrane
|
|
12
15
|
end
|
13
16
|
|
14
17
|
def render
|
15
|
-
[render_notes, render_special_frets, hint].join("\n"*2)
|
18
|
+
[render_notes, render_special_frets, hint].join("\n" * 2)
|
16
19
|
end
|
17
20
|
|
18
21
|
def render_notes
|
19
22
|
@tuning.map do |string|
|
20
23
|
string_note = Note[string]
|
21
|
-
(@frets+2)
|
24
|
+
Array.new(@frets + 2) do |i|
|
22
25
|
if i.zero?
|
23
26
|
string
|
24
27
|
else
|
25
28
|
fret = i - 1
|
26
29
|
note = string_note + fret
|
27
|
-
m = (@notes.include?(note) ? place_mark(note) :
|
28
|
-
fret.zero? ? (m +
|
30
|
+
m = (@notes.include?(note) ? place_mark(note) : '--')
|
31
|
+
fret.zero? ? (m + ' |') : m
|
29
32
|
end
|
30
33
|
end.join(' ')
|
31
34
|
end.join("\n")
|
32
35
|
end
|
33
36
|
|
34
37
|
def render_special_frets
|
35
|
-
(@frets+1)
|
38
|
+
Array.new(@frets + 1) do |fret|
|
36
39
|
m = SPECIAL_FRETS.include?(fret) ? fret.to_s.rjust(2, 0.to_s) : ' '
|
37
40
|
"#{m}#{' ' if fret.zero?}"
|
38
41
|
end.join(' ')
|
39
42
|
end
|
40
43
|
|
41
|
-
def render_dotted_frets
|
42
|
-
end
|
44
|
+
def render_dotted_frets; end
|
43
45
|
|
44
46
|
def place_mark(note)
|
45
47
|
case @flavor
|
@@ -47,9 +49,9 @@ module Coltrane
|
|
47
49
|
when :intervals then (@ref_note - note).name.ljust(2, '-')
|
48
50
|
when :degrees then @notes.degree(note).to_s.rjust(2, '0')
|
49
51
|
when :marks then '◼◼'
|
50
|
-
else raise WrongFlavorError
|
52
|
+
else raise WrongFlavorError
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
55
|
-
end
|
57
|
+
end
|
data/lib/cli/notes.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Coltrane
|
2
4
|
module Cli
|
5
|
+
# Interfaces notes outputting functionality with the lib
|
3
6
|
class Notes
|
4
|
-
def initialize(notes, on: 'text', desc:
|
5
|
-
@desc = desc
|
7
|
+
def initialize(notes, on: 'text', desc: nil, flavor: 'notes')
|
8
|
+
@desc = desc || 'The notes you supplied:'
|
6
9
|
flavor = flavor.underscore.to_sym
|
7
10
|
on = on.to_sym
|
8
11
|
notes = Coltrane::NoteSet.new(notes)
|
@@ -11,8 +14,8 @@ module Coltrane
|
|
11
14
|
end
|
12
15
|
|
13
16
|
def render
|
14
|
-
puts "\n"+[@desc, @representation.render].join("\n"*2)
|
17
|
+
puts "\n" + [@desc, @representation.render].join("\n" * 2)
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
18
|
-
end
|
21
|
+
end
|
data/lib/cli/piano.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Coltrane
|
2
4
|
module Cli
|
5
|
+
# It allows rendering notes in an ASCII piano
|
3
6
|
class Piano < Representation
|
4
7
|
PIANO_TEMPLATE = <<~ASCII
|
5
8
|
┌─┬─┬┬─┬─╥─┬─┬┬─┬┬─┬─╥─┬─┬┬─┬─╥─┬─┬┬─┬┬─┬─┐
|
@@ -24,11 +27,11 @@ module Coltrane
|
|
24
27
|
|
25
28
|
private
|
26
29
|
|
27
|
-
def replace_x(line, notes, size, index=0)
|
28
|
-
line.gsub('X'*size).with_index do |
|
29
|
-
note = notes[i%notes.size]
|
30
|
-
next ' '*size unless @notes.include?(note)
|
31
|
-
Paint[replacer(note)[size == 2 ? 0..2 : index
|
30
|
+
def replace_x(line, notes, size, index = 0)
|
31
|
+
line.gsub('X' * size).with_index do |_match, i|
|
32
|
+
note = notes[i % notes.size]
|
33
|
+
next ' ' * size unless @notes.include?(note)
|
34
|
+
Paint[replacer(note)[size == 2 ? 0..2 : index], 'red']
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
@@ -37,7 +40,7 @@ module Coltrane
|
|
37
40
|
case @flavor
|
38
41
|
when :intervals then (@ref_note - note).name
|
39
42
|
when :marks then '◼ '
|
40
|
-
when :degrees then @notes.degree(note).to_s.rjust(2,'0')
|
43
|
+
when :degrees then @notes.degree(note).to_s.rjust(2, '0')
|
41
44
|
when :notes then note.pretty_name.to_s.ljust(2, "\u266E")
|
42
45
|
end
|
43
46
|
end
|
@@ -47,8 +50,8 @@ module Coltrane
|
|
47
50
|
end
|
48
51
|
|
49
52
|
def black_notes
|
50
|
-
Coltrane::Scale.pentatonic_major('C#',4).notes
|
53
|
+
Coltrane::Scale.pentatonic_major('C#', 4).notes
|
51
54
|
end
|
52
55
|
end
|
53
56
|
end
|
54
|
-
end
|
57
|
+
end
|
data/lib/cli/representation.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Coltrane
|
2
4
|
module Cli
|
5
|
+
# It manages notes representations, most of times instruments
|
3
6
|
class Representation
|
4
|
-
ACCEPTED_FLAVORS = %i[marks notes intervals degrees]
|
7
|
+
ACCEPTED_FLAVORS = %i[marks notes intervals degrees].freeze
|
5
8
|
|
6
9
|
def self.inherited(subclass)
|
7
10
|
@@types ||= {}
|
@@ -9,18 +12,15 @@ module Coltrane
|
|
9
12
|
end
|
10
13
|
|
11
14
|
def self.build(type, notes, flavor)
|
12
|
-
raise WrongFlavorError
|
15
|
+
raise WrongFlavorError unless ACCEPTED_FLAVORS.include?(flavor)
|
13
16
|
type = case type
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
when :ukelele then :ukulele
|
18
|
+
when :bass then :bass_guitar
|
19
|
+
else type
|
20
|
+
end
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
raise WrongRepresentationTypeError.new(type)
|
23
|
-
end
|
22
|
+
raise(WrongRepresentationTypeError, type) unless @@types.include?(type)
|
23
|
+
@@types[type].new(notes, flavor)
|
24
24
|
end
|
25
25
|
|
26
26
|
def initialize(notes, flavor)
|
@@ -31,7 +31,7 @@ module Coltrane
|
|
31
31
|
|
32
32
|
def hint
|
33
33
|
case @flavor
|
34
|
-
when :marks then
|
34
|
+
when :marks then ''
|
35
35
|
when :notes then "(\u266E means the note is natural, not flat nor sharp)"
|
36
36
|
when :intervals
|
37
37
|
<<~DESC
|
@@ -39,9 +39,9 @@ module Coltrane
|
|
39
39
|
Ex: 1P = Perfect First / 3m = Minor Third / 4A = Augmented Fourth
|
40
40
|
DESC
|
41
41
|
|
42
|
-
when :degrees then
|
42
|
+
when :degrees then '(The numbers represent the degree of the note in the scale)'
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
47
|
-
end
|
47
|
+
end
|