coltrane 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +15 -10
  5. data/Gemfile.lock +47 -128
  6. data/README.md +30 -8
  7. data/Rakefile +0 -4
  8. data/bin/bundle +105 -0
  9. data/bin/byebug +29 -0
  10. data/bin/coderay +12 -0
  11. data/bin/coltrane +25 -7
  12. data/bin/htmldiff +12 -0
  13. data/bin/kill-pry-rescue +12 -0
  14. data/bin/ldiff +12 -0
  15. data/bin/pry +12 -0
  16. data/bin/rake +12 -0
  17. data/bin/rescue +12 -0
  18. data/bin/rspec +12 -0
  19. data/bin/rubocop +12 -0
  20. data/bin/ruby-parse +12 -0
  21. data/bin/ruby-rewrite +12 -0
  22. data/exe/coltrane +173 -0
  23. data/lib/cli/bass_guitar.rb +9 -0
  24. data/lib/cli/chord.rb +24 -0
  25. data/lib/cli/errors.rb +28 -0
  26. data/lib/cli/guitar.rb +55 -0
  27. data/lib/cli/notes.rb +18 -0
  28. data/lib/cli/piano.rb +54 -0
  29. data/lib/cli/representation.rb +47 -0
  30. data/lib/cli/scale.rb +48 -0
  31. data/lib/cli/text.rb +13 -0
  32. data/lib/cli/ukulele.rb +11 -0
  33. data/lib/coltrane-cli.rb +12 -0
  34. data/lib/coltrane.rb +16 -31
  35. data/lib/coltrane/cache.rb +34 -0
  36. data/lib/coltrane/chord.rb +28 -41
  37. data/lib/coltrane/chord_quality.rb +14 -39
  38. data/lib/coltrane/classic_progressions.rb +37 -0
  39. data/lib/coltrane/classic_scales.rb +92 -118
  40. data/lib/coltrane/errors.rb +54 -0
  41. data/lib/coltrane/interval.rb +25 -17
  42. data/lib/coltrane/interval_sequence.rb +57 -27
  43. data/lib/coltrane/note.rb +44 -30
  44. data/lib/coltrane/note_set.rb +37 -22
  45. data/lib/coltrane/piano_representation.rb +0 -58
  46. data/lib/coltrane/pitch.rb +12 -3
  47. data/lib/coltrane/progression.rb +31 -0
  48. data/lib/coltrane/qualities.rb +115 -114
  49. data/lib/coltrane/roman_chord.rb +36 -0
  50. data/lib/coltrane/scale.rb +85 -77
  51. data/lib/coltrane/version.rb +1 -1
  52. data/lib/core_ext.rb +12 -0
  53. data/pkg/coltrane-0.0.2.gem +0 -0
  54. metadata +27 -14
  55. data/lib/coltrane/essential_guitar_chords.rb +0 -82
  56. data/lib/coltrane/fret_set.rb +0 -0
  57. data/lib/coltrane/guitar.rb +0 -15
  58. data/lib/coltrane/guitar_chord.rb +0 -50
  59. data/lib/coltrane/guitar_chord_finder.rb +0 -98
  60. data/lib/coltrane/guitar_note.rb +0 -50
  61. data/lib/coltrane/guitar_note_set.rb +0 -61
  62. data/lib/coltrane/guitar_representation.rb +0 -96
  63. data/lib/coltrane/guitar_string.rb +0 -52
  64. data/lib/coltrane/scale_cache.rb +0 -4
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
@@ -1,11 +1,29 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- $LOAD_PATH << "#{__dir__}/../lib"
4
- ENV['RAILS_ENV'] = 'production'
5
- require 'bundler'
6
- Bundler.require
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'coltrane' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
7
10
 
8
- require 'coltrane'
9
- include Coltrane
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
10
14
 
11
- pry
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("coltrane", "coltrane")
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
data/bin/ldiff CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
data/bin/pry CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
data/bin/rake CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
data/bin/rescue CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
data/bin/rspec CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -11,6 +12,17 @@ require "pathname"
11
12
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
13
  Pathname.new(__FILE__).realpath)
13
14
 
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
14
26
  require "rubygems"
15
27
  require "bundler/setup"
16
28
 
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler'
4
+ require 'pry'
5
+
6
+ Bundler.require(:cli)
7
+
8
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
9
+
10
+ require 'core_ext'
11
+ require 'coltrane'
12
+ require 'coltrane-cli'
13
+
14
+ full_color_terminals = %w[iTerm.app]
15
+ safe_mode_terminals = %w[Unsupported]
16
+
17
+ if full_color_terminals.include?(ENV['TERM_PROGRAM'])
18
+ Paint.mode = 0xFFFFFF
19
+ elsif safe_mode_terminals.include?(ENV['TERM_PROGRAM'])
20
+ Paint.mode = 0
21
+ end
22
+
23
+ Mercenary.program(:Coltrane) do |p|
24
+ p.version Coltrane::VERSION
25
+ p.description <<~DESC
26
+ A music querying interface
27
+ by Pedro Maciel (pedro@pedromaciel.com)
28
+
29
+ [ check the repo for more details (github.com/pedrozath/coltrane) ]
30
+ DESC
31
+ p.syntax 'coltrane <subcommand> [options]'
32
+
33
+ @instrument_option = [
34
+ :on,
35
+ '--on guitar INSTRUMENT',
36
+ 'Shows the notes on the given instrument/representation type. Can be piano, guitar, ukulele, bass or text'
37
+ ]
38
+
39
+ @flavor_option = [
40
+ :flavor,
41
+ '--flavor FLAVOR',
42
+ 'Chooses which <additional></additional> information to display: marks, notes, intervals or degrees'
43
+ ]
44
+
45
+ p.command(:notes) do |c|
46
+ c.syntax 'notes <notes separated by space> [--on <instrument>]'
47
+ c.description 'Shows the given notes.'
48
+ c.option(*@instrument_option)
49
+ c.option(*@flavor_option)
50
+ c.action do |(notes), on: 'text', flavor: 'notes'|
51
+ raise 'Provide some notes. Ex: coltrane notes C-D-Gb' if notes.empty?
52
+ notes = Coltrane::NoteSet[*notes.split('-')]
53
+ Coltrane::Cli::Notes.new(notes, on: on, flavor: flavor)
54
+ end
55
+ end
56
+
57
+ p.command(:chord) do |c|
58
+ c.syntax 'chord <chord-name> [--on <instrument>]'
59
+ c.description 'Shows the given chord. Ex: coltrane chord Cmaj7 --on piano'
60
+ c.option(*@instrument_option)
61
+ c.option(*@flavor_option)
62
+ c.option :notes, '--notes C-D-E', 'finds chords with those notes, provided they are separated by dashes'
63
+ c.action do |(chords), notes: nil, on: 'text', flavor: 'notes'|
64
+ chords = chords&.split('-')
65
+ Coltrane::Cli::Chord.new(*chords, notes: notes&.split('-'), on: on, flavor: flavor)
66
+ end
67
+ end
68
+
69
+ p.command(:scale) do |c|
70
+ c.syntax 'scale <name of scale>-<root note> [--on <instrument>]'
71
+ c.description 'Gives you information about a scale. Ex: coltrane scale natural-minor-Db --on guitar'
72
+ c.option(*@instrument_option)
73
+ c.option(*@flavor_option)
74
+ c.option :triads, '--triads', 'Outputs triads from the scale'
75
+ c.option :sevenths, '--sevenths', 'Outputs seventh chords from the scale'
76
+ c.option :pentads, '--pentads', 'Outputs pentad chords from the scale'
77
+ c.option :tertians, '--tertians SIZE', 'Outputs all tertian chords from the given size from the scale'
78
+ c.option :chords, '--chords [SIZE]', 'Outputs all chords from given size from the scale. Leave size empty to retrieve all'
79
+ c.action do |(scale_str), flavor:'degrees', on:'text', **options|
80
+ scale = Coltrane::Cli::Scale.parse(scale_str)
81
+ keyword_args = {flavor: flavor, on: on }
82
+ if options.include?(:triads)
83
+ chords = scale.triads
84
+ Coltrane::Cli::Chord.new(*chords, **keyword_args)
85
+ elsif options.include?(:sevenths)
86
+ chords = scale.sevenths
87
+ Coltrane::Cli::Chord.new(*chords, **keyword_args)
88
+ elsif options.include?(:pentads)
89
+ chords = scale.pentads
90
+ Coltrane::Cli::Chord.new(*chords, **keyword_args)
91
+ elsif options.include?(:tertians)
92
+ chords = scale.tertians(options[:tertians].to_i)
93
+ Coltrane::Cli::Chord.new(*chords, **keyword_args)
94
+ elsif options.include?(:chords)
95
+ if options[:chords].nil?
96
+ chords = scale.all_chords
97
+ else
98
+ chords = scale.chords(options[:chords])
99
+ end
100
+ Coltrane::Cli::Chord.new(*chords, **keyword_args)
101
+ else
102
+ Coltrane::Cli::Scale.new(scale, **keyword_args)
103
+ end
104
+ end
105
+ end
106
+
107
+ p.command(:list) do |list|
108
+ list.syntax 'list [scales, flavors, instruments (used in --on options), chord-qualities]'
109
+ list.description 'List information.'
110
+ list.action do |(arg)|
111
+ puts case arg
112
+ when 'scales' then Coltrane::Scale.known_scales
113
+ when 'flavors' then %w[marks notes intervals degrees]
114
+ when 'instruments' then %w[guitar bass ukulele piano text]
115
+ when 'chords', 'chord-qualities' then Coltrane::Qualities::CHORD_QUALITIES.keys.sort.join(' ')
116
+ end
117
+ end
118
+ end
119
+
120
+ p.command(:'find-scale') do |c|
121
+ c.syntax 'find-scale --notes C-D-E-...] OR --chord Cmaj7-Db7'
122
+ c.description 'finds scales with the provided --notes or --chord'
123
+ c.option :notes, '--notes C-D-E', 'Find scales with those notes'
124
+ c.option :chords, '--chords Cmaj7-D11', 'find scales with those chords'
125
+ c.action do |(arg), options|
126
+ options[:notes] = "#{options[:notes]}".split('-')
127
+ options[:chords] = "#{options[:chords]}".split('-')
128
+ Coltrane::Cli::Scale.find(**options)
129
+ end
130
+ end
131
+
132
+ p.command(:'common-chords') do |c|
133
+ c.syntax 'common-chords <SCALE1 SCALE2 [SCALE3]>'
134
+ c.description 'Finds chords that are shared between the given scales'
135
+ c.option(*@instrument_option)
136
+ c.option(*@flavor_option)
137
+ c.action do |(*scale_strings), on: 'text', flavor: 'notes'|
138
+ raise 'Provide at least 2 scales' if scale_strings.size < 2
139
+ first_scale_str, *other_scales_strs = scale_strings
140
+ first_scale = Coltrane::Cli::Scale.parse(first_scale_str)
141
+ chords = other_scales_strs.reduce(first_scale.all_chords.map(&:name)) do |memo, scale_str|
142
+ scale = Coltrane::Cli::Scale.parse(scale_str)
143
+ memo & scale.all_chords.map(&:name)
144
+ end
145
+ raise 'No common chords were found' if chords.empty?
146
+ Coltrane::Cli::Chord.new(*chords, on: on, flavor: flavor)
147
+ end
148
+ end
149
+
150
+ p.command(:help) do |c|
151
+ c.description 'May give you some help.'
152
+ c.syntax 'help <command> [subcommand, sub-subcommand, ...]'
153
+ c.action do |(*command_path), options|
154
+ if command_path.empty?
155
+ puts p
156
+ return
157
+ else
158
+ puts (command_path.reduce(p) do |memo, key|
159
+ memo.commands.delete(key.to_sym)
160
+ end || "\n Sorry, command found.")
161
+ end
162
+ end
163
+ end
164
+
165
+ p.command(:about) do |c|
166
+ c.description 'Shows this screen'
167
+ c.action do
168
+ puts p
169
+ end
170
+ end
171
+
172
+ p.default_command(:about)
173
+ end