wtf_chord 0.1.1 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +36 -1
- data/exe/wtfchord +3 -5
- data/lib/wtf_chord/chord.rb +5 -3
- data/lib/wtf_chord/cli.rb +42 -0
- data/lib/wtf_chord/fingering.rb +2 -2
- data/lib/wtf_chord/formatter.rb +32 -0
- data/lib/wtf_chord/formatters/base.rb +37 -0
- data/lib/wtf_chord/formatters/default.rb +64 -0
- data/lib/wtf_chord/formatters/simple.rb +9 -0
- data/lib/wtf_chord/version.rb +1 -1
- data/wtf_chord.gemspec +2 -0
- metadata +21 -3
- data/lib/wtf_chord/drawer.rb +0 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63e6deb4fcd84c93ca4b45c777e8510bc721cfb8
|
4
|
+
data.tar.gz: c8a5cd9fa823393c02b09670cb59094e48685fad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82eb003ec0978911c7806e8b1d338ec495fcd63f72d26262baa075209f29b4854a0237c885887177e26e4d3b438909023e07ad5201152b873ea456266fb7d14e
|
7
|
+
data.tar.gz: d2f439cd8f2dc14886520b8a5f72f16cce4c7934e250742cc1e5c5a2e9a107a967d25e470992411cf3e2d730d2d7d5698baf64467eab0b61441b69e3e6805295
|
data/README.md
CHANGED
@@ -27,9 +27,31 @@ Or install it yourself as:
|
|
27
27
|
|
28
28
|
## CLI-tool usage
|
29
29
|
|
30
|
+
Usage: wtfchord [options] name
|
31
|
+
|
32
|
+
Finds fingerings of the requested chord.
|
33
|
+
|
34
|
+
v0.2.0
|
35
|
+
|
36
|
+
Options:
|
37
|
+
-h, --help Show command line help
|
38
|
+
--version Show help/version info
|
39
|
+
-n, --amount N Amount of fingering variants to output.
|
40
|
+
(default: 3)
|
41
|
+
-o, --output FORMAT Output format.
|
42
|
+
(default: default)
|
43
|
+
--log-level LEVEL Set the logging level
|
44
|
+
(debug|info|warn|error|fatal)
|
45
|
+
(Default: info)
|
46
|
+
|
47
|
+
Arguments:
|
48
|
+
|
49
|
+
name
|
50
|
+
Chord name to find.
|
51
|
+
|
30
52
|
For example, to print two fingering variants of the `Dm` chord, just run:
|
31
53
|
|
32
|
-
$ wtfchord Dm 2
|
54
|
+
$ wtfchord Dm -n 2
|
33
55
|
|
34
56
|
And you'll get the visual presentation of chords' fingerings:
|
35
57
|
|
@@ -55,6 +77,19 @@ And you'll get the visual presentation of chords' fingerings:
|
|
55
77
|
––––––––––––––––––
|
56
78
|
D A D F A
|
57
79
|
|
80
|
+
You can get simpler output, using the `--output` option:
|
81
|
+
|
82
|
+
$ wtfchord Dm -n 10 --output=simple
|
83
|
+
Dm (D - F - A)
|
84
|
+
|
85
|
+
[ × × 0 2 3 1 ]
|
86
|
+
[ × 5 3 2 3 1 ]
|
87
|
+
[ × 5 3 2 3 5 ]
|
88
|
+
[ × 5 3 7 3 5 ]
|
89
|
+
[ × 5 7 7 6 5 ]
|
90
|
+
[ 10 8 7 7 6 10 ]
|
91
|
+
[ 10 8 7 7 10 10 ]
|
92
|
+
|
58
93
|
## Development
|
59
94
|
|
60
95
|
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.
|
data/exe/wtfchord
CHANGED
@@ -3,9 +3,7 @@
|
|
3
3
|
$:.unshift File.expand_path('../../lib', __FILE__)
|
4
4
|
|
5
5
|
require 'rubygems' unless Object.const_defined?(:Gem)
|
6
|
-
require
|
6
|
+
require 'wtf_chord'
|
7
|
+
require 'wtf_chord/cli'
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
puts chord.inspect, nil
|
11
|
-
chord.draw_fingerings(ARGV[1]&.to_i || 3)
|
9
|
+
WTFChord::CLI.go!
|
data/lib/wtf_chord/chord.rb
CHANGED
@@ -20,13 +20,14 @@ module WTFChord
|
|
20
20
|
|
21
21
|
def fingerings(limit = 3)
|
22
22
|
list = []
|
23
|
+
|
23
24
|
(0..MAX_FRET).each do |from_fret|
|
24
25
|
f = get_fingering(from_fret)
|
25
26
|
next if list.include?(f)
|
26
27
|
list << f if all_notes?(f.used_strings)
|
27
28
|
end
|
28
29
|
|
29
|
-
list
|
30
|
+
sort_fingerings(list, limit)
|
30
31
|
end
|
31
32
|
|
32
33
|
def get_fingering(from_fret = 0)
|
@@ -59,8 +60,9 @@ module WTFChord
|
|
59
60
|
string && string.note != @notes[i]
|
60
61
|
end
|
61
62
|
|
62
|
-
def
|
63
|
-
|
63
|
+
def sort_fingerings(list, limit)
|
64
|
+
list.sort_by!(&:complexity)
|
65
|
+
list[0...limit].sort_by!(&:min_fret)
|
64
66
|
end
|
65
67
|
end
|
66
68
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'methadone'
|
3
|
+
|
4
|
+
module WTFChord
|
5
|
+
class CLI
|
6
|
+
include Methadone::Main
|
7
|
+
include Methadone::CLILogging
|
8
|
+
|
9
|
+
main do |name|
|
10
|
+
chord = WTFChord.chord(name)
|
11
|
+
fingerings = chord.fingerings(options['amount'])
|
12
|
+
formatter = WTFChord::Formatter.new(options['output'])
|
13
|
+
|
14
|
+
debug { "Output using formatter: #{formatter.formatter.to_s}\n" }
|
15
|
+
|
16
|
+
puts chord.inspect, nil
|
17
|
+
formatter.(*fingerings)
|
18
|
+
end
|
19
|
+
|
20
|
+
version VERSION
|
21
|
+
|
22
|
+
description "Finds fingerings of the requested chord."
|
23
|
+
|
24
|
+
|
25
|
+
##
|
26
|
+
# Arguments
|
27
|
+
#
|
28
|
+
arg :name, "Chord name to find."
|
29
|
+
|
30
|
+
|
31
|
+
##
|
32
|
+
# Options
|
33
|
+
#
|
34
|
+
options['amount'] = 3
|
35
|
+
options['output'] = 'default'
|
36
|
+
|
37
|
+
on "-n N", "--amount N", Integer, "Amount of fingering variants to output."
|
38
|
+
on "-o FORMAT", "--output FORMAT", "Output format."
|
39
|
+
|
40
|
+
use_log_level_option
|
41
|
+
end
|
42
|
+
end
|
data/lib/wtf_chord/fingering.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'wtf_chord/fretboard'
|
2
2
|
require 'wtf_chord/complexity_counter'
|
3
|
-
require 'wtf_chord/
|
3
|
+
require 'wtf_chord/formatter'
|
4
4
|
|
5
5
|
module WTFChord
|
6
6
|
class Fingering < Fretboard
|
@@ -23,7 +23,7 @@ module WTFChord
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def draw
|
26
|
-
|
26
|
+
Formatter.new(:default).call(self)
|
27
27
|
end
|
28
28
|
|
29
29
|
def set_fingers(fingers)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'wtf_chord/formatters/base'
|
2
|
+
|
3
|
+
module WTFChord
|
4
|
+
class Formatter
|
5
|
+
def initialize(name)
|
6
|
+
@name = name
|
7
|
+
require_formatter! unless formatter?
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(*fingerings)
|
11
|
+
puts (fingerings.map(&formatter) * formatter.separator)
|
12
|
+
end
|
13
|
+
|
14
|
+
alias :[] :call
|
15
|
+
|
16
|
+
def formatter
|
17
|
+
WTFChord::Formatters.const_get(formatter_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def formatter?
|
21
|
+
WTFChord::Formatters.const_defined?(formatter_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def formatter_name
|
25
|
+
@formatter_name ||= @name.gsub(/(?:^|_)([a-z\d]*)/i) { "#{$1.capitalize}" }.to_s.freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
def require_formatter!
|
29
|
+
require "wtf_chord/formatters/#{@name}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module WTFChord
|
4
|
+
module Formatters
|
5
|
+
class Base
|
6
|
+
FRETS = 6
|
7
|
+
|
8
|
+
extend Forwardable
|
9
|
+
def_delegators :@fret, :strings
|
10
|
+
|
11
|
+
def self.separator
|
12
|
+
"\n".freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.to_proc
|
16
|
+
proc { |fret| new(fret).draw }
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(fret)
|
20
|
+
@fret = fret
|
21
|
+
end
|
22
|
+
|
23
|
+
def draw
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def min_fret
|
29
|
+
@min_fret = begin
|
30
|
+
frets = strings.map(&:fret).tap(&:compact!)
|
31
|
+
_min = frets.min.to_i || 1
|
32
|
+
_min > 2 ? _min : 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module WTFChord
|
2
|
+
module Formatters
|
3
|
+
class Default < Base
|
4
|
+
OPEN = "|".freeze
|
5
|
+
HORIZ = "–".freeze
|
6
|
+
SPACE = " ".freeze
|
7
|
+
BULL = "\u2022".freeze
|
8
|
+
LATIN = %w(0 I II III IV V VI VII VIII IX X XII XIII).freeze
|
9
|
+
NEWLINE = "\n".freeze
|
10
|
+
|
11
|
+
def self.separator
|
12
|
+
"\n\n".freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
def draw
|
16
|
+
[
|
17
|
+
"[ #{head} ]#{capo}",
|
18
|
+
" #{border}",
|
19
|
+
*fret_rows,
|
20
|
+
" #{border}",
|
21
|
+
" #{string_keys}"
|
22
|
+
] * NEWLINE
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def head
|
28
|
+
@fret.fingers * SPACE
|
29
|
+
end
|
30
|
+
|
31
|
+
def capo
|
32
|
+
" (capo #{to_latin @fret.capo})" if @fret.capo > 0
|
33
|
+
end
|
34
|
+
|
35
|
+
def border
|
36
|
+
@border ||= HORIZ * 3 * strings.length
|
37
|
+
end
|
38
|
+
|
39
|
+
def string_rows
|
40
|
+
strings.map { |string| draw_string(string.fret) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def fret_rows
|
44
|
+
string_rows.transpose.map! { |row| " #{row * SPACE} " }.tap do |rows|
|
45
|
+
rows[0] << " #{to_latin min_fret}" if min_fret > 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def string_keys
|
50
|
+
strings.map { |s| s.dead? ? SPACE : "%-2s" % s.key } * " "
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_latin(num)
|
54
|
+
LATIN[num]
|
55
|
+
end
|
56
|
+
|
57
|
+
def draw_string(fret)
|
58
|
+
Array.new(FRETS, OPEN).tap do |rows|
|
59
|
+
rows[(fret - min_fret.pred).pred] = BULL if fret.to_i > 0
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/wtf_chord/version.rb
CHANGED
data/wtf_chord.gemspec
CHANGED
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
+
spec.add_runtime_dependency "methadone"
|
24
|
+
|
23
25
|
spec.add_development_dependency "bundler", ">= 1.11", "< 2"
|
24
26
|
spec.add_development_dependency "rake", ">= 10.0", "< 12"
|
25
27
|
spec.add_development_dependency "rspec", ">= 3.0", "< 4"
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wtf_chord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: methadone
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,9 +104,13 @@ files:
|
|
90
104
|
- lib/wtf_chord.rb
|
91
105
|
- lib/wtf_chord.yml
|
92
106
|
- lib/wtf_chord/chord.rb
|
107
|
+
- lib/wtf_chord/cli.rb
|
93
108
|
- lib/wtf_chord/complexity_counter.rb
|
94
|
-
- lib/wtf_chord/drawer.rb
|
95
109
|
- lib/wtf_chord/fingering.rb
|
110
|
+
- lib/wtf_chord/formatter.rb
|
111
|
+
- lib/wtf_chord/formatters/base.rb
|
112
|
+
- lib/wtf_chord/formatters/default.rb
|
113
|
+
- lib/wtf_chord/formatters/simple.rb
|
96
114
|
- lib/wtf_chord/fretboard.rb
|
97
115
|
- lib/wtf_chord/guitar_string.rb
|
98
116
|
- lib/wtf_chord/note.rb
|
data/lib/wtf_chord/drawer.rb
DELETED
@@ -1,79 +0,0 @@
|
|
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
|