wtf_chord 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cec796fdac73df072faef8d89c98f6fc37aded7f
4
+ data.tar.gz: 17772eb9d7105e1445ff40e6873c37d12914cca7
5
+ SHA512:
6
+ metadata.gz: 945c5110c7e52340a4eca72385710d9cfa031cb647c2a2f8ae8207af7179467f3dc72059dc42bcf8b64083d0338644f018f85f5be551d53e4b722d3cd76f5e63
7
+ data.tar.gz: ba92873418bb4224f7dbf841501b02694c2fda562ea86030b4c918364b004c74b8f9d3bca6eb38168aeaf939934829ddc6186b44d09d79bc2daa86e01143a89e
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /.ruby-version
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wtf_chord.gemspec
4
+ gemspec
5
+
6
+ # To use a debugger
7
+ gem 'byebug', group: [:development, :test]
8
+
9
+ group :development, :test do
10
+ # You need these
11
+ gem "rspec"
12
+ gem "pry"
13
+ end
14
+
15
+ group :development do
16
+ # You don't need these, but I use them
17
+ gem "awesome_print"
18
+ end
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # WTFChord
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/wtf_chord`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'wtf_chord'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install wtf_chord
22
+
23
+ ## Usage
24
+
25
+ $ wtfchord F#dim
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec wtf_chord` to use the gem in this directory, ignoring other installed copies of this gem.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/wtf_chord.
36
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "wtf_chord"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/wtfchord ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path('../../lib', __FILE__)
4
+
5
+ require 'rubygems' unless Object.const_defined?(:Gem)
6
+ require "wtf_chord"
7
+
8
+ WTFChord.chord(ARGV[0]).draw_fingerings(ARGV[1]&.to_i || 3)
@@ -0,0 +1,56 @@
1
+ module WTFChord
2
+ class Chord
3
+ MAX_DIST = 5
4
+ MAX_FRET = 7
5
+
6
+ attr_reader :pitch, :steps, :notes, :name
7
+
8
+ def initialize(note, name)
9
+ @pitch = note.is_a?(Pitch) ? note : WTFChord.note(note)
10
+ @name = "#{@pitch.key}#{name}".freeze
11
+ @steps = Array(WTFChord.rules[name])
12
+ @notes = @steps.map { |dist| (@pitch + dist).note }.tap(&:uniq!)
13
+ end
14
+
15
+ def inspect
16
+ "#{name} (#{@notes.map(&:key) * ' - '})"
17
+ end
18
+
19
+ def fingerings(limit = 3)
20
+ list = []
21
+ (0..MAX_FRET).each do |from_fret|
22
+ fingering = get_fingering(from_fret)
23
+
24
+ next if list.include?(fingering)
25
+
26
+ if all_notes?(fingering.used_strings)
27
+ list << fingering
28
+ end
29
+ end
30
+
31
+ list.sort_by!(&:complexity)[0...limit].sort_by!(&:min_fret)
32
+ end
33
+
34
+ def draw_fingerings(limit = 3)
35
+ puts (fingerings(limit).map(&:draw) * "\n\n")
36
+ end
37
+
38
+ def get_fingering(from_fret = 0)
39
+ GUITAR.dup.tap do |guitar|
40
+ guitar.strings.each do |s|
41
+ fret = (from_fret..(from_fret+MAX_DIST)).detect { |dist| @notes.include?((s.original + dist).note) }
42
+ fret ? s.hold_on(fret) : s.dead
43
+ end
44
+
45
+ while guitar.used_strings[0] && guitar.used_strings[0].note != @notes[0]
46
+ guitar.used_strings.detect { |x| !x.dead? && x.note != @notes[0] }&.dead
47
+ end
48
+ end
49
+ end
50
+
51
+ def all_notes?(strings)
52
+ snotes = strings.map(&:note).tap(&:uniq!)
53
+ @notes.all? { |n| snotes.include?(n) }
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,79 @@
1
+ require 'forwardable'
2
+
3
+ module WTFChord
4
+ class Drawer
5
+ FRETS = 6
6
+ OPEN = "|".freeze
7
+ HORIZ = "–".freeze
8
+ SPACE = " ".freeze
9
+ BULL = "\u2022".freeze
10
+ LATIN = %w(0 I II III IV V VI VII VIII IX X XII XIII).freeze
11
+ NEWLINE = "\n".freeze
12
+
13
+ extend Forwardable
14
+ def_delegators :@fret, :strings
15
+
16
+ def initialize(fret, newline: nil)
17
+ @fret = fret
18
+ @newline = newline || NEWLINE
19
+ end
20
+
21
+ def draw
22
+ [
23
+ "[ #{head} ]#{capo}",
24
+ " #{border}",
25
+ *fret_rows,
26
+ " #{border}",
27
+ " #{string_keys}"
28
+ ] * @newline
29
+ end
30
+
31
+ protected
32
+
33
+ def min_fret
34
+ @min_fret = begin
35
+ frets = strings.map(&:fret).tap(&:compact!)
36
+ _min = frets.min.to_i || 1
37
+ _min > 2 ? _min : 1
38
+ end
39
+ end
40
+
41
+ def head
42
+ @fret.fingers * SPACE
43
+ end
44
+
45
+ def capo
46
+ " (capo #{to_latin @fret.capo})" if @fret.capo > 0
47
+ end
48
+
49
+ def border
50
+ @border ||= HORIZ * 3 * strings.length
51
+ end
52
+
53
+ def string_rows
54
+ strings.map { |string| draw_string(string.fret) }
55
+ end
56
+
57
+ def fret_rows
58
+ string_rows.transpose.map! { |row| " #{row * SPACE} " }.tap do |rows|
59
+ rows[0] << " #{to_latin min_fret}" if min_fret > 1
60
+ end
61
+ end
62
+
63
+ def string_keys
64
+ strings.map { |s| s.dead? ? SPACE : "%-2s" % s.key } * " "
65
+ end
66
+
67
+ private
68
+
69
+ def to_latin(num)
70
+ LATIN[num]
71
+ end
72
+
73
+ def draw_string(fret)
74
+ Array.new(FRETS, OPEN).tap do |rows|
75
+ rows[(fret - min_fret.pred).pred] = BULL if fret.to_i > 0
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,102 @@
1
+ require 'wtf_chord/guitar_string'
2
+ require 'wtf_chord/drawer'
3
+
4
+ module WTFChord
5
+ class Fingerboard
6
+ attr_reader :strings, :capo
7
+
8
+ def initialize(*strings)
9
+ @capo = 0
10
+ @strings = strings.map! do |string|
11
+ GuitarString.new(string, @capo)
12
+ end
13
+ end
14
+
15
+ def [] idx
16
+ case idx
17
+ when 1..@strings.length then @strings[-idx]
18
+ end
19
+ end
20
+
21
+ def set_capo(capo = 0)
22
+ @capo = capo
23
+ @strings.each do |string|
24
+ string.set_capo(@capo)
25
+ end
26
+ self
27
+ end
28
+
29
+ def fingers
30
+ strings.map { |string| string.dead? ? "×" : string.fret }
31
+ end
32
+
33
+ def to_s
34
+ "[ #{fingers * " "} ]"
35
+ end
36
+
37
+ def initialize_dup(other)
38
+ super
39
+ @strings = other.strings.map(&:dup)
40
+ @code = nil
41
+ @complexity = nil
42
+ end
43
+
44
+ def set_fingers(fingers)
45
+ fingers.each_with_index do |f, i|
46
+ f.nil? ? @strings[i].dead : @strings[i].hold_on(f)
47
+ end
48
+ end
49
+
50
+ def with_fingers(*fingers)
51
+ strings_was = @strings.dup
52
+ set_fingers(fingers)
53
+ yield(self)
54
+ self
55
+ ensure
56
+ @strings = strings_was
57
+ end
58
+
59
+ def draw
60
+ Drawer.new(self).draw
61
+ end
62
+
63
+ def count_holded_strings
64
+ strings.count(&:holded?)
65
+ end
66
+
67
+ def holded_strings
68
+ strings.select(&:holded?)
69
+ end
70
+
71
+ def used_strings
72
+ strings.reject(&:dead?)
73
+ end
74
+
75
+ def inspect
76
+ to_s
77
+ end
78
+
79
+ def code
80
+ @code ||= strings.map(&:code).pack("c*")
81
+ end
82
+
83
+ def complexity
84
+ @complexity ||= count_holded_strings * finger_dist
85
+ end
86
+
87
+ def finger_dist
88
+ frets = holded_strings.map(&:fret)
89
+ ((frets.max - frets.min).nonzero? || 1)
90
+ end
91
+
92
+ def min_fret
93
+ holded_strings.map(&:fret).min
94
+ end
95
+
96
+ def == other
97
+ case other
98
+ when Fingerboard then other.code == code
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,57 @@
1
+ require 'wtf_chord/pitch'
2
+
3
+ module WTFChord
4
+ class GuitarString < DelegateClass(WTFChord::Pitch)
5
+ attr_reader :capo, :fret, :original
6
+
7
+ def initialize(note, capo = 0)
8
+ @original = WTFChord.note(note)
9
+ @fret = nil
10
+ @capo = capo
11
+ super(@original + capo)
12
+ end
13
+
14
+ def initialize_dup(other)
15
+ super
16
+ __setobj__(@original.dup)
17
+ end
18
+
19
+ def set_capo(capo)
20
+ @capo = capo
21
+ calculate_note!
22
+ end
23
+
24
+ def hold_on(fret)
25
+ @fret = fret
26
+ calculate_note!
27
+ end
28
+
29
+ def open
30
+ @fret = 0
31
+ calculate_note!
32
+ end
33
+
34
+ def dead
35
+ @fret = nil
36
+ calculate_note!
37
+ end
38
+
39
+ def dead?
40
+ @fret.nil?
41
+ end
42
+
43
+ def holded?
44
+ !dead? && @fret > 0
45
+ end
46
+
47
+ def code
48
+ dead? ? -1 : to_i
49
+ end
50
+
51
+ private
52
+
53
+ def calculate_note!
54
+ __setobj__(@original + @capo + (@fret || 0))
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,58 @@
1
+ module WTFChord
2
+ class Note
3
+ include Comparable
4
+
5
+ attr_reader :key, :name, :position
6
+
7
+ def initialize(key, position = nil)
8
+ if /^(?<note>[a-h])(?<sign>#|b)?$/i =~ key
9
+ note.upcase!
10
+ @key = "#{note}#{sign}".freeze
11
+ @name = "#{DIATONIC[note]}#{SIGNS[sign]}".freeze
12
+ @position = position
13
+ else
14
+ raise ArgumentError
15
+ end
16
+ end
17
+
18
+ def to_s
19
+ @key.sub(/[b#]$/, SIGNS)
20
+ end
21
+
22
+ def inspect
23
+ "#@name (#{to_s}: #@position)"
24
+ end
25
+
26
+ def == other
27
+ case other
28
+ when String then other.casecmp(@key).zero?
29
+ when Integer, Note then other == @position
30
+ end
31
+ end
32
+
33
+ def <=> other
34
+ case other
35
+ when Note then @position <=> other.position
36
+ when Integer then @position <=> other
37
+ end
38
+ end
39
+
40
+ def aliases
41
+ @aliases ||= SCALE.select { |t| t.position == @position && t.key != @key }
42
+ end
43
+
44
+ def semitone?
45
+ @key.end_with?(FLAT, SHARP)
46
+ end
47
+
48
+ def with_octave(octave)
49
+ Pitch.new(self, octave)
50
+ end
51
+
52
+ def chord(name)
53
+ with_octave.chord(name)
54
+ end
55
+
56
+ alias :[] :with_octave
57
+ end
58
+ end
@@ -0,0 +1,83 @@
1
+ require 'scanf'
2
+ require 'wtf_chord/note'
3
+ require 'forwardable'
4
+
5
+ module WTFChord
6
+ class Pitch
7
+ extend Forwardable
8
+ include Comparable
9
+
10
+ def_delegators :@note, :key
11
+ attr_reader :note, :octave
12
+
13
+ def initialize(note, octave = nil)
14
+ raise ArgumentError unless note.is_a?(Note)
15
+
16
+ @note = note
17
+ @octave = octave || 4
18
+ end
19
+
20
+ def to_str
21
+ "#{@note.key}#{octave}"
22
+ end
23
+
24
+ def to_s
25
+ "#{@note.to_s}#{octave}"
26
+ end
27
+
28
+ alias :inspect :to_s
29
+
30
+ def move(amount)
31
+ return self if amount.zero?
32
+
33
+ to_octave, to_pos = (to_i + amount).divmod(12)
34
+
35
+ if to_pos.zero?
36
+ to_octave -= 1
37
+ to_pos = 12
38
+ end
39
+
40
+ SCALE[to_pos][to_octave]
41
+ end
42
+
43
+ alias :+ :move
44
+
45
+ def - amount
46
+ move -amount
47
+ end
48
+
49
+ def to_i
50
+ (@octave * 12) + @note.position
51
+ end
52
+
53
+ def == other
54
+ case other
55
+ when Integer, Pitch then other == to_i
56
+ when String then other.casecmp(to_str).zero?
57
+ when Note then other == @note
58
+ end
59
+ end
60
+
61
+ def <=> other
62
+ case other
63
+ when Note then @note <=> other
64
+ when Integer then to_i <=> other
65
+ when Pitch then to_i <=> other.to_i
66
+ end
67
+ end
68
+
69
+ def chord(name)
70
+ Chord.new(self, name)
71
+ end
72
+ end
73
+
74
+ NOTE_FSTR ||= "%2[A-Ha-h#b]%d".freeze
75
+
76
+ def self.note(val)
77
+ case val
78
+ when String
79
+ key, octave = val.scanf(NOTE_FSTR)
80
+ SCALE[key][octave || 4] if key
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,40 @@
1
+ require 'yaml'
2
+ require 'wtf_chord/chord'
3
+
4
+ module WTFChord
5
+ class Rules
6
+ attr_reader :path, :chords, :extra, :pattern
7
+
8
+ def initialize(path)
9
+ @path = path
10
+ rules = YAML.load_file(@path)
11
+ @chords = rules[:chords]
12
+ @extra = rules[:extra]
13
+ @pattern = /
14
+ (?<name>#{Regexp.union(@chords.keys.sort_by(&:length).reverse!)})?
15
+ (?<ext>#{Regexp.union(@extra.keys.sort_by(&:length).reverse!)})?
16
+ /x
17
+ end
18
+
19
+ def find(name = nil)
20
+ steps = []
21
+ name ||= ""
22
+
23
+ name.match(pattern) do |m|
24
+ base = chords[m[:name]] || chords["M"]
25
+ steps.concat(base)
26
+ steps.concat(extra[m[:ext]]) if m[:ext] && m[:ext].length <= (6 - steps.length)
27
+ end
28
+
29
+ steps.tap(&:uniq!)
30
+ end
31
+
32
+ alias :[] :find
33
+ end
34
+
35
+ def self.chord(name)
36
+ name.match /^(?<note>[A-H][b#]?)(?<name>.+)?$/ do |m|
37
+ Chord.new(m[:note], m[:name])
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,67 @@
1
+ require 'wtf_chord/note'
2
+ require 'wtf_chord/pitch'
3
+ require 'wtf_chord/fingerboard'
4
+
5
+ module WTFChord
6
+ class ScaleArray < Array
7
+ attr_reader :last_position
8
+
9
+ def self.build(*list)
10
+ tones = list.flat_map.with_index do |keys, position|
11
+ keys.split("|").map! { |key| Note.new(key, position.next) }
12
+ end
13
+ new(tones)
14
+ end
15
+
16
+ def initialize(list)
17
+ @last_position = list.map(&:position).sort![-1]
18
+ super(list)
19
+ end
20
+
21
+ def [] idx
22
+ case idx
23
+ when 0 then nil
24
+ when Integer then super(index(idx < 0 ? last_position + idx.next : idx))
25
+ when String then super(index(idx))
26
+ else super
27
+ end
28
+ end
29
+ end
30
+
31
+ private_constant :ScaleArray
32
+
33
+ FLAT ||= "b".freeze
34
+ SHARP ||= "#".freeze
35
+ SIGNS ||= { FLAT => "\u266D".freeze, SHARP => "\u266F".freeze }.freeze
36
+
37
+ DIATONIC = {
38
+ "C" => "Do",
39
+ "D" => "Re",
40
+ "E" => "Mi",
41
+ "F" => "Fa",
42
+ "G" => "Sol",
43
+ "A" => "La",
44
+ "B" => "Si",
45
+ "H" => "Si"
46
+ }.freeze
47
+
48
+ SCALE ||= begin
49
+ chromatic_scale = %W(
50
+ C
51
+ C#|Db
52
+ D
53
+ D#|Eb
54
+ E
55
+ F
56
+ F#|Gb
57
+ G
58
+ G#|Ab
59
+ A
60
+ Bb|A#
61
+ B|H
62
+ )
63
+ ScaleArray.build(*chromatic_scale).freeze
64
+ end
65
+
66
+ GUITAR ||= Fingerboard.new(*%w(E2 A2 D3 G3 B3 E4))
67
+ end
@@ -0,0 +1,3 @@
1
+ module WTFChord
2
+ VERSION = "0.1.0"
3
+ end
data/lib/wtf_chord.rb ADDED
@@ -0,0 +1,25 @@
1
+ require "wtf_chord/scale"
2
+ require "wtf_chord/rules"
3
+ require "wtf_chord/version"
4
+
5
+ module WTFChord
6
+ DEFAULTS = {
7
+ :rules_file => File.expand_path("../wtf_chord.yml", __FILE__)
8
+ }.freeze
9
+
10
+ class << self
11
+ attr_accessor :rules
12
+
13
+ def config # :yields:
14
+ yield(self)
15
+ end
16
+
17
+ def rules_file= value
18
+ self.rules = Rules.new(File.expand_path(value))
19
+ end
20
+
21
+ def rules
22
+ @rules ||= Rules.new(DEFAULTS[:rules_file])
23
+ end
24
+ end
25
+ end
data/lib/wtf_chord.yml ADDED
@@ -0,0 +1,27 @@
1
+ :chords:
2
+ "M": [0, 4, 7]
3
+ "m": [0, 3, 7]
4
+ "aug": [0, 4, 6]
5
+ "dim": [0, 3, 6]
6
+ "sus2": [0, 2, 7]
7
+ "sus4": [0, 5, 7]
8
+ "6": [0, 4, 7, 9]
9
+ "m6": [0, 3, 7, 9]
10
+ "7": [0, 4, 7, 10]
11
+ "7M": [0, 4, 7, 11]
12
+ "m7": [0, 3, 7, 10]
13
+ "m7M": [0, 3, 7, 11]
14
+ "dim7": [0, 3, 6, 9]
15
+ "7sus2": [0, 2, 7, 10]
16
+ "7sus4": [0, 5, 7, 10]
17
+ "7Msus2": [0, 2, 7, 11]
18
+ "7Msus4": [0, 5, 7, 11]
19
+ "5": [0, 7]
20
+
21
+ :extra:
22
+ "9": [14]
23
+ "11": [17]
24
+ "13": [21]
25
+ "add9": [10, 14]
26
+ "add11": [10, 14, 17]
27
+ "add13": [10, 14, 17, 21]
data/wtf_chord.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'wtf_chord/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "wtf_chord"
8
+ spec.version = WTFChord::VERSION
9
+ spec.authors = ["Anton"]
10
+ spec.email = ["anton.estum@gmail.com"]
11
+
12
+ spec.summary = %q{WTF Chord? is a Ruby Gem for generating guitar chords.}
13
+ spec.description = %q{WTF Chord? provides the library and CLI-tool for generating guitar chords.}
14
+ spec.homepage = "https://github.com/estum/wtf_chord"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", ">= 1.11", "< 2"
22
+ spec.add_development_dependency "rake", ">= 10.0", "< 12"
23
+ spec.add_development_dependency "rspec", ">= 3.0", "< 4"
24
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wtf_chord
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Anton
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-03-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.11'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '10.0'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '12'
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '10.0'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '12'
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '3.0'
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '4'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '3.0'
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '4'
73
+ description: WTF Chord? provides the library and CLI-tool for generating guitar chords.
74
+ email:
75
+ - anton.estum@gmail.com
76
+ executables:
77
+ - wtfchord
78
+ extensions: []
79
+ extra_rdoc_files: []
80
+ files:
81
+ - ".gitignore"
82
+ - ".rspec"
83
+ - ".travis.yml"
84
+ - Gemfile
85
+ - README.md
86
+ - Rakefile
87
+ - bin/console
88
+ - bin/setup
89
+ - exe/wtfchord
90
+ - lib/wtf_chord.rb
91
+ - lib/wtf_chord.yml
92
+ - lib/wtf_chord/chord.rb
93
+ - lib/wtf_chord/drawer.rb
94
+ - lib/wtf_chord/fingerboard.rb
95
+ - lib/wtf_chord/guitar_string.rb
96
+ - lib/wtf_chord/note.rb
97
+ - lib/wtf_chord/pitch.rb
98
+ - lib/wtf_chord/rules.rb
99
+ - lib/wtf_chord/scale.rb
100
+ - lib/wtf_chord/version.rb
101
+ - wtf_chord.gemspec
102
+ homepage: https://github.com/estum/wtf_chord
103
+ licenses: []
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.5.1
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: WTF Chord? is a Ruby Gem for generating guitar chords.
125
+ test_files: []
126
+ has_rdoc: