coltrane 0.0.2 → 1.0.0

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.
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