coltrane 3.4.2 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.ruby-version +1 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +88 -75
- data/bin/bundle +23 -14
- data/bin/console +24 -12
- data/bin/gambiarra +29 -0
- data/bin/old-coltrane +29 -0
- data/bin/setup +27 -6
- data/bin/thor +1 -1
- data/coltrane.gemspec +4 -4
- data/exe/coltrane +14 -55
- data/lib/.DS_Store +0 -0
- data/lib/coltrane/.DS_Store +0 -0
- data/lib/coltrane/commands.rb +4 -9
- data/lib/coltrane/commands/available_chord_representations.rb +9 -0
- data/lib/coltrane/commands/available_classic_scales.rb +9 -0
- data/lib/coltrane/commands/available_notable_progressions.rb +9 -0
- data/lib/coltrane/commands/available_representations.rb +9 -0
- data/lib/coltrane/commands/command.rb +3 -54
- data/lib/coltrane/commands/find_chord_by_notes.rb +9 -0
- data/lib/coltrane/commands/find_common_chords.rb +9 -0
- data/lib/coltrane/commands/find_progressions_from_chords.rb +9 -0
- data/lib/coltrane/commands/find_scale_by_chords.rb +9 -0
- data/lib/coltrane/commands/find_scale_by_notes.rb +9 -0
- data/lib/coltrane/commands/get_chords_from_notable_progression.rb +9 -0
- data/lib/coltrane/commands/get_chords_from_progression.rb +9 -0
- data/lib/coltrane/commands/get_chords_from_scale.rb +9 -0
- data/lib/coltrane/commands/get_chords_from_string.rb +11 -0
- data/lib/coltrane/commands/get_classic_scale.rb +9 -0
- data/lib/coltrane/commands/get_notes.rb +9 -0
- data/lib/coltrane/commands/get_notes_from_string.rb +9 -0
- data/lib/coltrane/commands/get_representation_chords.rb +18 -0
- data/lib/coltrane/commands/get_representation_notes.rb +12 -0
- data/lib/coltrane/commands/render.rb +9 -0
- data/lib/coltrane/renderers/text_renderer/hash_drawer.rb +1 -0
- data/lib/coltrane/renderers/text_renderer/representation_guitar_chord_drawer.rb +2 -2
- data/lib/coltrane/renderers/text_renderer/representation_piano_note_set_drawer.rb +1 -1
- data/lib/coltrane/renderers/text_renderer/theory_chord_drawer.rb +1 -2
- data/lib/coltrane/theory/classic_scales.rb +1 -1
- data/lib/coltrane/theory/interval.rb +1 -1
- data/lib/coltrane/ui.rb +8 -0
- data/lib/coltrane/ui/.DS_Store +0 -0
- data/lib/coltrane/ui/base_view.rb +9 -0
- data/lib/coltrane/ui/views/.DS_Store +0 -0
- data/lib/coltrane/ui/views/chords.rb +19 -0
- data/lib/coltrane/ui/views/custom_progression.rb +27 -0
- data/lib/coltrane/ui/views/find_chord_by_notes.rb +16 -0
- data/lib/coltrane/ui/views/find_chords_in_scale.rb +36 -0
- data/lib/coltrane/ui/views/find_common_chords_in_scales.rb +40 -0
- data/lib/coltrane/ui/views/find_progressions_from_chords.rb +14 -0
- data/lib/coltrane/ui/views/find_scale.rb +14 -0
- data/lib/coltrane/ui/views/find_scale_by_chords.rb +16 -0
- data/lib/coltrane/ui/views/find_scale_by_notes.rb +16 -0
- data/lib/coltrane/ui/views/index.rb +14 -0
- data/lib/coltrane/ui/views/notes.rb +20 -0
- data/lib/coltrane/ui/views/progressions.rb +18 -0
- data/lib/coltrane/ui/views/scales.rb +17 -0
- data/lib/coltrane/ui/views/show_chord.rb +21 -0
- data/lib/coltrane/ui/views/show_progression.rb +26 -0
- data/lib/coltrane/ui/views/show_scale.rb +26 -0
- data/lib/coltrane/version.rb +1 -1
- metadata +61 -26
- data/lib/coltrane/commands/chords.rb +0 -93
- data/lib/coltrane/commands/common_chords.rb +0 -33
- data/lib/coltrane/commands/errors.rb +0 -44
- data/lib/coltrane/commands/find_guitar_chord.rb +0 -25
- data/lib/coltrane/commands/find_progression.rb +0 -28
- data/lib/coltrane/commands/find_scale.rb +0 -39
- data/lib/coltrane/commands/notes.rb +0 -50
- data/lib/coltrane/commands/progression.rb +0 -28
- data/lib/coltrane/commands/scale.rb +0 -46
@@ -1,93 +0,0 @@
|
|
1
|
-
module Coltrane
|
2
|
-
module Commands
|
3
|
-
class Chords < Command
|
4
|
-
attr_reader :chord, :flavor, :on, :preface, :voicings
|
5
|
-
|
6
|
-
def initialize(chord = nil,
|
7
|
-
flavor: :notes,
|
8
|
-
on: :text,
|
9
|
-
notes: nil,
|
10
|
-
preface: nil,
|
11
|
-
voicings: 4,
|
12
|
-
**options)
|
13
|
-
if chord
|
14
|
-
@chord = chord.is_a?(Theory::Chord) ? chord : Theory::Chord.new(name: chord)
|
15
|
-
elsif notes
|
16
|
-
@chord = Theory::Chord.new(notes: notes&.split('-'))
|
17
|
-
else
|
18
|
-
raise 'Provide chord names or notes. Ex: coltrane chords Cm7-Db7, ' \
|
19
|
-
'or coltrane chords --notes C-E-G'
|
20
|
-
end
|
21
|
-
|
22
|
-
@flavor = flavor.to_sym
|
23
|
-
@preface = preface || @chord.name
|
24
|
-
@on = on.to_sym
|
25
|
-
@voicings = voicings.to_i
|
26
|
-
end
|
27
|
-
|
28
|
-
def representation
|
29
|
-
return on_model if on == :text
|
30
|
-
{ preface => on_model }
|
31
|
-
end
|
32
|
-
|
33
|
-
def on_model
|
34
|
-
case on
|
35
|
-
when :text then chord
|
36
|
-
when :guitar then Representation::Guitar.find_chords(chord).first(voicings)
|
37
|
-
when :ukulele, :ukelele then Representation::Ukulele.find_chords(chord).first(voicings)
|
38
|
-
when :bass then Representation::Bass.find_notes(chord.notes)
|
39
|
-
when :piano then Representation::Piano.find_notes(chord.notes)
|
40
|
-
when :'guitar-frets' then Representation::Guitar.find_notes(chord.notes)
|
41
|
-
when :'ukulele-frets', :'ukelele-frets' then Representation::Ukulele.find_notes(chord.notes)
|
42
|
-
when /custom_guitar_frets/ then custom_guitar_notes
|
43
|
-
when /custom_guitar/ then custom_guitar_chords.first(voicings)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def custom_guitar_notes
|
48
|
-
Representation::Guitar::NoteSet.new(chord.notes, guitar: custom_guitar)
|
49
|
-
end
|
50
|
-
|
51
|
-
def custom_guitar_chords
|
52
|
-
Representation::Guitar::Chord.find(chord, guitar: custom_guitar)
|
53
|
-
end
|
54
|
-
|
55
|
-
def layout_horizontal?
|
56
|
-
on.to_s =~ /guitar|ukulele|ukelele|bass|piano/
|
57
|
-
end
|
58
|
-
|
59
|
-
def renderer_options
|
60
|
-
[
|
61
|
-
{ flavor: flavor },
|
62
|
-
(
|
63
|
-
{
|
64
|
-
layout: :horizontal,
|
65
|
-
per_row: 4,
|
66
|
-
} if layout_horizontal?
|
67
|
-
)
|
68
|
-
]
|
69
|
-
.compact
|
70
|
-
.reduce({}, :merge)
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.mercenary_init(program)
|
74
|
-
program.command(:chords) do |c|
|
75
|
-
c.alias(:chord)
|
76
|
-
c.syntax 'chords [<chord-name>] [--on <instrument>]'
|
77
|
-
c.description 'Shows the given chord. Ex: coltrane chord Cmaj7 --on piano'
|
78
|
-
c.option :notes, '--notes C-D-E', 'finds chords with those notes, ' \
|
79
|
-
'provided they are separated by dashes'
|
80
|
-
|
81
|
-
add_shared_option(:flavor, c)
|
82
|
-
add_shared_option(:on, c)
|
83
|
-
add_shared_option(:voicings, c)
|
84
|
-
c.action { |(chords), **options|
|
85
|
-
(chords&.split('-') || [nil]).each { |chord|
|
86
|
-
new(chord, **options).render
|
87
|
-
}
|
88
|
-
}
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module Coltrane
|
2
|
-
module Commands
|
3
|
-
class CommonChords < Command
|
4
|
-
def self.parse(scale_notation)
|
5
|
-
scale_notation
|
6
|
-
.split(' ', 2)
|
7
|
-
.yield_self { |(tone, scale_name)|
|
8
|
-
Theory::Scale.fetch(scale_name.gsub(' ', '_'), tone)
|
9
|
-
}
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.mercenary_init(program)
|
13
|
-
program.command(:'common-chords') do |c|
|
14
|
-
c.alias(:'common-chord')
|
15
|
-
add_shared_option(:flavor, c)
|
16
|
-
add_shared_option(:on, c)
|
17
|
-
c.syntax 'common-chords [TONE_1 SCALE_NAME_1], [TONE_2 SCALE_NAME_2], [...]'
|
18
|
-
c.description 'Finds chords that are shared between the given scales'
|
19
|
-
c.action do |(*scale_strings), **options|
|
20
|
-
scale_strings
|
21
|
-
.join(' ')
|
22
|
-
.split(',')
|
23
|
-
.map { |scale_notation|
|
24
|
-
Commands::Scale.parse(scale_notation).all_chords
|
25
|
-
}
|
26
|
-
.reduce(:&)
|
27
|
-
.each { |chord| Commands::Chords.new(chord, **options).render }
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# rubocop:disable Style/Documentation
|
4
|
-
|
5
|
-
module Coltrane
|
6
|
-
class CommandError < StandardError
|
7
|
-
def initialize(msg)
|
8
|
-
super msg
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class WrongFlavorError < CommandError
|
13
|
-
def initialize(msg = nil)
|
14
|
-
super msg || 'Wrong flavor. Check possible flavors with `coltrane list flavors`.'
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class BadFindScales < CommandError
|
19
|
-
def initialize(msg = nil)
|
20
|
-
super msg || 'Provide --notes or --chords. Ex: `coltrane find-scale --notes C-E-G`.'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class WrongRepresentationTypeError < CommandError
|
25
|
-
def initialize(type)
|
26
|
-
super "The provided representation type (#{type}) "\
|
27
|
-
'is not available at the moment.'
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class BadScaleError < CommandError
|
32
|
-
def initialize(msg = nil)
|
33
|
-
super msg || 'Incorrect scale, please specify scale and root separated by `-`. Ex: `coltrane scale major-C'
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
class BadChordError < CommandError
|
38
|
-
def initialize(msg = nil)
|
39
|
-
super msg || 'Incorrect chord, please specify a set of chords separated by `-`. Ex: coltrane chord CM7'
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# rubocop:enable Style/Documentation
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Coltrane
|
2
|
-
module Commands
|
3
|
-
class FindGuitarChord < Command
|
4
|
-
attr_reader :notation
|
5
|
-
|
6
|
-
def initialize(notation)
|
7
|
-
@notation = notation
|
8
|
-
end
|
9
|
-
|
10
|
-
def representation
|
11
|
-
Representation::Guitar.find_chord_by_notation(notation)
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.mercenary_init(program)
|
15
|
-
program.command(:'find-guitar-chord') do |c|
|
16
|
-
c.syntax 'find-guitar-chord x-2-2-4-5-x'
|
17
|
-
c.description 'find the chord name assuming the standard tuning (EADGBE)'
|
18
|
-
c.action do |(notation)|
|
19
|
-
new(notation).render
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Coltrane
|
2
|
-
module Commands
|
3
|
-
class FindProgression < Command
|
4
|
-
attr_reader :progression_set
|
5
|
-
|
6
|
-
def initialize(progression_set, **options)
|
7
|
-
@progression_set = progression_set
|
8
|
-
end
|
9
|
-
|
10
|
-
def representation
|
11
|
-
progression_set
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.mercenary_init(program)
|
15
|
-
program.command(:'find-progression') do |c|
|
16
|
-
c.syntax 'find-progression <list of chords>'
|
17
|
-
c.description 'Find progressions in scales. Ex: coltrane find-progression AM-DM-F#m-EM'
|
18
|
-
c.action do |(chord_notation)|
|
19
|
-
chord_notation
|
20
|
-
.split('-')
|
21
|
-
.yield_self { |chords| Theory::Progression.find(*chords) }
|
22
|
-
.yield_self { |progression_set| new(progression_set).render }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module Coltrane
|
2
|
-
module Commands
|
3
|
-
class FindScale < Command
|
4
|
-
attr_reader :scale_set
|
5
|
-
|
6
|
-
def initialize(scale_set)
|
7
|
-
@scale_set = scale_set
|
8
|
-
end
|
9
|
-
|
10
|
-
def representation
|
11
|
-
scale_set
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.mercenary_init(program)
|
15
|
-
program.command(:'find-scale') do |c|
|
16
|
-
c.syntax 'find-scale --notes C-D-E-...] OR --chord Cmaj7-Db7'
|
17
|
-
c.description 'finds scales with the provided --notes or --chord'
|
18
|
-
c.option :notes, '--notes C-D-E', 'Find scales with those notes'
|
19
|
-
c.option :chords, '--chords Cmaj7-D11', 'find scales with those chords'
|
20
|
-
c.action do |(_), notes: nil, chords: nil|
|
21
|
-
begin
|
22
|
-
if notes
|
23
|
-
Theory::Scale.having_notes(
|
24
|
-
Theory::NoteSet[*notes.to_s.split('-')]
|
25
|
-
)
|
26
|
-
elsif chords
|
27
|
-
Theory::Scale.having_chords(*chords.to_s.split('-'))
|
28
|
-
else
|
29
|
-
raise 'Provide --notes or --chords separated by dashes.' \
|
30
|
-
'For example coltrane find-scale --notes C-E-F#'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
.yield_self { |scale_set| new(scale_set).render }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
module Coltrane
|
2
|
-
module Commands
|
3
|
-
class Notes < Command
|
4
|
-
attr_reader :notes, :flavor, :on, :preface
|
5
|
-
|
6
|
-
def initialize(notes, flavor: :notes, on: :text, preface: nil)
|
7
|
-
raise 'Provide some notes. Ex: coltrane notes C-D-Gb' if notes.nil?
|
8
|
-
@notes = notes.is_a?(Theory::NoteSet) ? notes : Theory::NoteSet[*notes.split('-')]
|
9
|
-
@flavor = flavor.to_sym
|
10
|
-
@preface = preface || 'Here are the notes you asked for'
|
11
|
-
@on = on
|
12
|
-
end
|
13
|
-
|
14
|
-
def representation
|
15
|
-
{ preface => on_model }
|
16
|
-
end
|
17
|
-
|
18
|
-
def renderer_options
|
19
|
-
{ flavor: flavor }
|
20
|
-
end
|
21
|
-
|
22
|
-
def on_model
|
23
|
-
case on.to_sym
|
24
|
-
when /custom_guitar/ then custom_guitar_notes
|
25
|
-
when :text then notes
|
26
|
-
when :guitar then Representation::Guitar.find_notes(notes)
|
27
|
-
when :ukulele, :ukelele then Representation::Ukulele.find_notes(notes)
|
28
|
-
when :bass then Representation::Bass.find_notes(notes)
|
29
|
-
when :piano then Representation::Piano.find_notes(notes)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def custom_guitar_notes
|
34
|
-
Representation::Guitar::NoteSet.new(notes, guitar: custom_guitar)
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.mercenary_init(program)
|
38
|
-
program.command(:notes) do |c|
|
39
|
-
c.alias(:note)
|
40
|
-
c.syntax 'notes <notes separated by space> [--on <instrument>]'
|
41
|
-
c.description 'Shows the given notes.'
|
42
|
-
add_shared_option(:voicings, c)
|
43
|
-
add_shared_option(:flavor, c)
|
44
|
-
add_shared_option(:on, c)
|
45
|
-
c.action { |(notes), **options| new(notes, **options).render }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Coltrane
|
2
|
-
module Commands
|
3
|
-
class Progression < Command
|
4
|
-
def self.mercenary_init(program)
|
5
|
-
program.command(:progression) do |c|
|
6
|
-
c.syntax 'progression <roman numeral notation> in <key> [--on <instrument>]'
|
7
|
-
c.description 'Gives you chords of a progression in a key. Ex: coltrane progression I-IV-iv-V in Am --on guitar'
|
8
|
-
add_shared_option(:flavor, c)
|
9
|
-
add_shared_option(:on, c)
|
10
|
-
add_shared_option(:voicings, c)
|
11
|
-
c.action do |(prog, _, key), **options|
|
12
|
-
prog
|
13
|
-
.tr('-', '_')
|
14
|
-
.yield_self { |possible_method|
|
15
|
-
if Theory::Progression.respond_to?(possible_method)
|
16
|
-
Theory::Progression.send(possible_method, key)
|
17
|
-
else
|
18
|
-
Theory::Progression.new(prog, key: key)
|
19
|
-
end
|
20
|
-
}
|
21
|
-
.chords
|
22
|
-
.each { |chord| Commands::Chords.new(chord, **options).render }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
module Coltrane
|
2
|
-
module Commands
|
3
|
-
class Scale < Command
|
4
|
-
def representation
|
5
|
-
return on_model if on == :text
|
6
|
-
{ preface => on_model }
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.parse(scale_notation)
|
10
|
-
scale_notation
|
11
|
-
.split(' ', 2)
|
12
|
-
.yield_self { |(tone, scale_name)|
|
13
|
-
Theory::Scale.fetch(scale_name.gsub(' ', '_'), tone)
|
14
|
-
}
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.mercenary_init(program)
|
18
|
-
program.command(:scale) do |c|
|
19
|
-
c.syntax 'scale <root_note> <scale name> [--on <instrument>]'
|
20
|
-
c.description 'Gives you information about a scale. Ex: coltrane scale D Natural Minor --on guitar'
|
21
|
-
c.option :tertians, '--tertians <SIZE>', 'Outputs all tertian chords from the given size from the scale'
|
22
|
-
c.option :chords, '--chords [SIZE]', 'Outputs all chords from given size from the scale. Leave size empty to retrieve all'
|
23
|
-
add_shared_option(:flavor, c)
|
24
|
-
add_shared_option(:on, c)
|
25
|
-
add_shared_option(:voicings, c)
|
26
|
-
|
27
|
-
c.action { |scale_notation, **options|
|
28
|
-
parse(scale_notation.join(' '))
|
29
|
-
.yield_self { |scale|
|
30
|
-
if options[:tertians]
|
31
|
-
scale
|
32
|
-
.tertians(options[:tertians].to_i)
|
33
|
-
.each { |chord| Commands::Chords.new(chord, **options).render }
|
34
|
-
elsif options[:chords]
|
35
|
-
scale.chords(options[:chords].to_i)
|
36
|
-
.each { |chord| Commands::Chords.new(chord, **options).render }
|
37
|
-
else
|
38
|
-
Commands::Notes.new(scale.notes, **options.merge(preface: scale.full_name)).render
|
39
|
-
end
|
40
|
-
}
|
41
|
-
}
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|