gitara 0.5.0 → 0.6.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.
- data/.gitignore +2 -0
- data/.yardopts +5 -0
- data/CHANGELOG.markdown +5 -0
- data/README.markdown +135 -99
- data/examples/tab-with-repeats.ly +117 -0
- data/examples/tab-with-repeats.rb +19 -0
- data/gitara.gemspec +3 -0
- data/lib/gitara.rb +5 -3
- data/lib/gitara/dsl.rb +13 -0
- data/lib/gitara/node/alternative.rb +14 -0
- data/lib/gitara/node/bar.rb +3 -1
- data/lib/gitara/node/base.rb +22 -24
- data/lib/gitara/node/base/chorded_version.rb +1 -4
- data/lib/gitara/node/base/node_version.rb +35 -0
- data/lib/gitara/node/base/stanza_version.rb +1 -4
- data/lib/gitara/node/base/voiced_version.rb +5 -6
- data/lib/gitara/node/repeat.rb +10 -0
- data/lib/gitara/node/tab.rb +3 -5
- data/lib/gitara/utilities.rb +8 -0
- data/lib/gitara/version.rb +1 -1
- data/lib/gitara/voice.rb +2 -0
- data/spec/factories.rb +6 -0
- data/spec/lib/gitara/app_spec.rb +12 -28
- data/spec/lib/gitara/dsl_spec.rb +218 -173
- data/spec/lib/gitara/node/alternative_spec.rb +15 -0
- data/spec/lib/gitara/node/bar/chorded_version_spec.rb +2 -2
- data/spec/lib/gitara/node/bar/stanza_version_spec.rb +2 -2
- data/spec/lib/gitara/node/bar/voiced_version_spec.rb +2 -2
- data/spec/lib/gitara/node/bar_spec.rb +7 -7
- data/spec/lib/gitara/node/base/chorded_version_spec.rb +1 -1
- data/spec/lib/gitara/node/base/node_version_spec.rb +66 -0
- data/spec/lib/gitara/node/base/voiced_version_spec.rb +5 -5
- data/spec/lib/gitara/node/base_spec.rb +36 -42
- data/spec/lib/gitara/node/chord_set/chorded_version_spec.rb +2 -2
- data/spec/lib/gitara/node/chord_set_spec.rb +1 -1
- data/spec/lib/gitara/node/note_set_spec.rb +1 -1
- data/spec/lib/gitara/node/repeat_spec.rb +15 -0
- data/spec/lib/gitara/node/stanza_spec.rb +2 -2
- data/spec/lib/gitara/node/tab_spec.rb +6 -6
- data/spec/lib/gitara/voice_spec.rb +9 -9
- data/spec/lib/gitara_spec.rb +3 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/support/app_tester.rb +22 -0
- metadata +70 -29
- data/lib/gitara/is_node_version.rb +0 -23
- data/lib/gitara/pow/base.rb +0 -11
- data/spec/lib/gitara/is_node_version_spec.rb +0 -58
data/gitara.gemspec
CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_runtime_dependency "erubis"
|
23
23
|
s.add_runtime_dependency "linguistics"
|
24
24
|
s.add_runtime_dependency "pow"
|
25
|
+
s.add_runtime_dependency "redwood"
|
25
26
|
s.add_runtime_dependency "thor"
|
26
27
|
s.add_runtime_dependency "valuable"
|
27
28
|
|
@@ -31,4 +32,6 @@ Gem::Specification.new do |s|
|
|
31
32
|
s.add_development_dependency "pry"
|
32
33
|
s.add_development_dependency "rb-inotify"
|
33
34
|
s.add_development_dependency "rspec"
|
35
|
+
s.add_development_dependency "yard"
|
36
|
+
s.add_development_dependency "yard-rspec"
|
34
37
|
end
|
data/lib/gitara.rb
CHANGED
@@ -2,16 +2,18 @@ require "active_support/inflector"
|
|
2
2
|
require "erubis"
|
3
3
|
require "linguistics"
|
4
4
|
require "pow"
|
5
|
+
require "redwood"
|
5
6
|
require "thor"
|
6
7
|
require "valuable"
|
7
8
|
|
8
9
|
require "gitara/app"
|
9
10
|
require "gitara/dsl"
|
10
|
-
require "gitara/is_node_version"
|
11
11
|
require "gitara/node/base"
|
12
|
+
require "gitara/node/base/node_version"
|
12
13
|
require "gitara/node/base/chorded_version"
|
13
14
|
require "gitara/node/base/stanza_version"
|
14
15
|
require "gitara/node/base/voiced_version"
|
16
|
+
require "gitara/node/alternative"
|
15
17
|
require "gitara/node/bar"
|
16
18
|
require "gitara/node/bar/chorded_version"
|
17
19
|
require "gitara/node/bar/stanza_version"
|
@@ -20,10 +22,10 @@ require "gitara/node/chord_set"
|
|
20
22
|
require "gitara/node/chord_set/chorded_version"
|
21
23
|
require "gitara/node/line"
|
22
24
|
require "gitara/node/note_set"
|
25
|
+
require "gitara/node/repeat"
|
23
26
|
require "gitara/node/score"
|
24
27
|
require "gitara/node/stanza"
|
25
28
|
require "gitara/node/tab"
|
26
|
-
require "gitara/pow/base"
|
27
29
|
require "gitara/utilities"
|
28
30
|
require "gitara/version"
|
29
31
|
require "gitara/voice"
|
@@ -39,7 +41,7 @@ module Gitara
|
|
39
41
|
|
40
42
|
def self.render(path, object)
|
41
43
|
template = (Pow!('gitara/template') / "#{path}.erb")
|
42
|
-
erb = Erubis::Eruby.new(
|
44
|
+
erb = Erubis::Eruby.new(Utilities.read!(template))
|
43
45
|
erb.evaluate(object)
|
44
46
|
end
|
45
47
|
|
data/lib/gitara/dsl.rb
CHANGED
@@ -4,8 +4,13 @@ module Gitara
|
|
4
4
|
class Dsl < Valuable
|
5
5
|
extend DslMacros
|
6
6
|
|
7
|
+
# @macro [attach] has_value
|
8
|
+
# @attribute $1
|
7
9
|
has_value :node
|
8
10
|
|
11
|
+
# @macro [attach] can_add_property
|
12
|
+
# @method $1(value)
|
13
|
+
# Set value as the $1
|
9
14
|
can_add_property :arranger
|
10
15
|
can_add_property :composer
|
11
16
|
can_add_property :instrument
|
@@ -30,6 +35,10 @@ module Gitara
|
|
30
35
|
end
|
31
36
|
end
|
32
37
|
|
38
|
+
def alternative(&block)
|
39
|
+
add Node::Alternative.new, &block
|
40
|
+
end
|
41
|
+
|
33
42
|
def bar(*names, &block)
|
34
43
|
add_names :names => names, :node_class => Node::Bar, &block
|
35
44
|
end
|
@@ -50,6 +59,10 @@ module Gitara
|
|
50
59
|
node.specified_duration = duration
|
51
60
|
end
|
52
61
|
|
62
|
+
def repeat(value, &block)
|
63
|
+
add Node::Repeat.new(:value => value), &block
|
64
|
+
end
|
65
|
+
|
53
66
|
def score(*names, &block)
|
54
67
|
add_names :names => names, :node_class => Node::Score, &block
|
55
68
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Gitara
|
2
|
+
module Node
|
3
|
+
class Alternative < Base
|
4
|
+
def call_value(node_version)
|
5
|
+
alternatives = node_version.definition_children.map do |child|
|
6
|
+
"{ #{child.call_value} }"
|
7
|
+
end
|
8
|
+
|
9
|
+
"\\alternative { #{alternatives.join(' ')} }"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
data/lib/gitara/node/bar.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Gitara
|
2
2
|
module Node
|
3
3
|
class Bar < Base
|
4
|
+
# @macro [attach] has_value
|
5
|
+
# @attribute $1
|
4
6
|
has_value :specified_duration
|
5
7
|
|
6
8
|
def duration
|
@@ -12,7 +14,7 @@ module Gitara
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def note_sets
|
15
|
-
|
17
|
+
definition_children.select{|child| child.is_a?(Node::NoteSet)}
|
16
18
|
end
|
17
19
|
|
18
20
|
def specified_duration_as_lilypond
|
data/lib/gitara/node/base.rb
CHANGED
@@ -1,31 +1,37 @@
|
|
1
1
|
module Gitara
|
2
2
|
module Node
|
3
3
|
class Base < Valuable
|
4
|
+
include Redwood
|
5
|
+
|
6
|
+
# @macro [attach] has_value
|
7
|
+
# @attribute $1
|
4
8
|
has_value :name
|
5
9
|
has_value :id, :default => 1
|
6
|
-
has_value :parent
|
7
10
|
has_value :value
|
8
11
|
|
9
12
|
def add(child)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
+
child.id = children.select{|c| c.is_a?(child.class)}.size + 1
|
14
|
+
graft child
|
15
|
+
end
|
16
|
+
|
17
|
+
def ancestor(klass)
|
18
|
+
ancestors.detect{|ancestor| ancestor.is_a?(klass)}
|
13
19
|
end
|
14
20
|
|
15
|
-
def
|
16
|
-
|
21
|
+
def call_value(node_version)
|
22
|
+
node_version.call_name
|
17
23
|
end
|
18
24
|
|
19
|
-
def
|
20
|
-
if
|
21
|
-
definition ? definition.
|
25
|
+
def definition_children
|
26
|
+
if leaf?
|
27
|
+
definition ? definition.children : []
|
22
28
|
else
|
23
|
-
|
29
|
+
children
|
24
30
|
end
|
25
31
|
end
|
26
32
|
|
27
33
|
def children=(values)
|
28
|
-
|
34
|
+
children.clear
|
29
35
|
values.each do |child|
|
30
36
|
add child
|
31
37
|
end
|
@@ -39,13 +45,13 @@ module Gitara
|
|
39
45
|
if self.definition_of?(target)
|
40
46
|
self
|
41
47
|
else
|
42
|
-
result = parent.
|
48
|
+
result = parent.children.detect{|node| node.definition_of?(target) }
|
43
49
|
result ? result : parent.definition(target)
|
44
50
|
end
|
45
51
|
end
|
46
52
|
|
47
53
|
def definition?
|
48
|
-
|
54
|
+
has_children? || ! value.nil?
|
49
55
|
end
|
50
56
|
|
51
57
|
def definition_name
|
@@ -60,11 +66,11 @@ module Gitara
|
|
60
66
|
end
|
61
67
|
|
62
68
|
def definitions(klass)
|
63
|
-
self.is_a?(klass) && self.definition? ? [self] : self.
|
69
|
+
self.is_a?(klass) && self.definition? ? [self] : self.children.map{|child| child.definitions(klass) }.flatten
|
64
70
|
end
|
65
71
|
|
66
72
|
def descendants(klass)
|
67
|
-
self.is_a?(klass) ? [self.definition] : self.
|
73
|
+
self.is_a?(klass) ? [self.definition] : self.definition_children.map{|child| child.descendants(klass) }.flatten
|
68
74
|
end
|
69
75
|
|
70
76
|
def id_as_word
|
@@ -79,20 +85,12 @@ module Gitara
|
|
79
85
|
attributes[:name] || "#{parent && parent.name}#{self.class.to_s.split('::').last}#{self.id_as_word}"
|
80
86
|
end
|
81
87
|
|
82
|
-
def own_children
|
83
|
-
@children ||= []
|
84
|
-
end
|
85
|
-
|
86
|
-
def root
|
87
|
-
parent.nil? ? self : parent.root
|
88
|
-
end
|
89
|
-
|
90
88
|
def stanza_version
|
91
89
|
self.class::StanzaVersion.new(:node => self)
|
92
90
|
end
|
93
91
|
|
94
92
|
def value
|
95
|
-
attributes[:value] ? attributes[:value].gsub('/', "\\") :
|
93
|
+
attributes[:value].respond_to?(:gsub) ? attributes[:value].gsub('/', "\\") : attributes[:value]
|
96
94
|
end
|
97
95
|
|
98
96
|
def voiced_as(arg)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Gitara
|
2
|
+
module Node
|
3
|
+
class Base
|
4
|
+
class NodeVersion < Valuable
|
5
|
+
# @macro [attach] has_value
|
6
|
+
# @attribute $1
|
7
|
+
has_value :node
|
8
|
+
|
9
|
+
def call_name
|
10
|
+
"\\#{definition_name}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def call_value
|
14
|
+
node.call_value(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
def definition_children
|
18
|
+
node.definition_children.map{|child| self.class.new(:node => child)}
|
19
|
+
end
|
20
|
+
|
21
|
+
def definition_name
|
22
|
+
"#{prefix}#{node.class.to_s.split('::').last}#{node.definition_name}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def prefix
|
26
|
+
self.class.to_s.split('::').last[0].downcase
|
27
|
+
end
|
28
|
+
|
29
|
+
def value
|
30
|
+
definition_children.map(&:call_value).join(' ')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,14 +1,13 @@
|
|
1
1
|
module Gitara
|
2
2
|
module Node
|
3
3
|
class Base
|
4
|
-
class VoicedVersion <
|
5
|
-
|
6
|
-
|
7
|
-
has_value :node
|
4
|
+
class VoicedVersion < NodeVersion
|
5
|
+
# @macro [attach] has_value
|
6
|
+
# @attribute $1
|
8
7
|
has_value :voice
|
9
8
|
|
10
|
-
def
|
11
|
-
node.
|
9
|
+
def definition_children
|
10
|
+
node.definition_children.map{|child| child.voiced_as(voice) }
|
12
11
|
end
|
13
12
|
|
14
13
|
def prefix
|
data/lib/gitara/node/tab.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Gitara
|
2
2
|
module Node
|
3
3
|
class Tab < Base
|
4
|
+
# @macro [attach] has_value
|
5
|
+
# @attribute $1
|
4
6
|
has_value :arranger
|
5
7
|
has_value :composer
|
6
8
|
has_value :instrument
|
@@ -11,16 +13,12 @@ module Gitara
|
|
11
13
|
has_value :title
|
12
14
|
has_value :transposition
|
13
15
|
|
14
|
-
def self.parse(text)
|
15
|
-
Transform.new.apply(Parser.new.parse(text))
|
16
|
-
end
|
17
|
-
|
18
16
|
def max_number_of_voices
|
19
17
|
definitions(Node::Bar).map{|bar| bar.note_sets.size}.max
|
20
18
|
end
|
21
19
|
|
22
20
|
def playable_child
|
23
|
-
|
21
|
+
definition_children.last
|
24
22
|
end
|
25
23
|
|
26
24
|
def voices
|
data/lib/gitara/utilities.rb
CHANGED
@@ -7,6 +7,14 @@ module Gitara
|
|
7
7
|
def self.inspect_attributes(object, *attributes)
|
8
8
|
"#{object.class}(" + attributes.collect{|a| "#{a}=#{object.send(a).inspect}"}.join(', ') + ")"
|
9
9
|
end
|
10
|
+
|
11
|
+
def self.read!(pow)
|
12
|
+
if pow.exists?
|
13
|
+
pow.read
|
14
|
+
else
|
15
|
+
raise PowError, "#{pow} does not exist"
|
16
|
+
end
|
17
|
+
end
|
10
18
|
end
|
11
19
|
end
|
12
20
|
|
data/lib/gitara/version.rb
CHANGED
data/lib/gitara/voice.rb
CHANGED
data/spec/factories.rb
CHANGED
@@ -2,6 +2,9 @@ FactoryGirl.define do
|
|
2
2
|
factory :note_set, :class => Node::NoteSet do
|
3
3
|
end
|
4
4
|
|
5
|
+
factory :alternative, :class => Node::Alternative do
|
6
|
+
end
|
7
|
+
|
5
8
|
factory :app, :class => App do
|
6
9
|
end
|
7
10
|
|
@@ -28,6 +31,9 @@ FactoryGirl.define do
|
|
28
31
|
children [FactoryGirl.build(:bar)]
|
29
32
|
end
|
30
33
|
|
34
|
+
factory :repeat, :class => Node::Repeat do
|
35
|
+
end
|
36
|
+
|
31
37
|
factory :stanza, :class => Node::Stanza do
|
32
38
|
children [FactoryGirl.build(:line)]
|
33
39
|
end
|
data/spec/lib/gitara/app_spec.rb
CHANGED
@@ -1,49 +1,33 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe App do
|
4
|
-
|
5
|
-
has_value :name
|
6
|
-
|
7
|
-
def run
|
8
|
-
app = FactoryGirl.build(:app)
|
9
|
-
app.invoke :export, ["examples/#{name}.rb"], "target-directory" => test_tmp_dir.path, "run-lilypond" => false
|
10
|
-
(Pow("tmp") / "#{name}.ly").write actual if self.expected != self.actual
|
11
|
-
end
|
12
|
-
|
13
|
-
def expected
|
14
|
-
@expected ||= Pow("examples/#{name}.ly").read!.gsub(/\n\s+\n/, "\n")
|
15
|
-
rescue PowError => e
|
16
|
-
puts "#{e.message}. Copying actual result..."
|
17
|
-
Pow("examples/#{name}.ly").write actual
|
18
|
-
retry
|
19
|
-
end
|
20
|
-
|
21
|
-
def actual
|
22
|
-
@actual ||= (test_tmp_dir / "#{name}.ly").read!.gsub(/\n\s+\n/, "\n")
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "export" do
|
3
|
+
describe Gitara::App do
|
4
|
+
describe "#export" do
|
27
5
|
it "can convert a tab to lilypond" do
|
28
|
-
app_test =
|
6
|
+
app_test = AppTester.new(:name => 'tab')
|
29
7
|
app_test.run
|
30
8
|
app_test.actual.should == app_test.expected
|
31
9
|
end
|
32
10
|
|
33
11
|
it "can convert a tab with a partial to lilypond" do
|
34
|
-
app_test =
|
12
|
+
app_test = AppTester.new(:name => 'tab-with-partial')
|
35
13
|
app_test.run
|
36
14
|
app_test.actual.should == app_test.expected
|
37
15
|
end
|
38
16
|
|
39
17
|
it "can convert a tab with alternate tuning to lilypond" do
|
40
|
-
app_test =
|
18
|
+
app_test = AppTester.new(:name => 'tab-with-alternate-tuning')
|
41
19
|
app_test.run
|
42
20
|
app_test.actual.should == app_test.expected
|
43
21
|
end
|
44
22
|
|
45
23
|
it "can convert a tab with a specified key signature to lilypond" do
|
46
|
-
app_test =
|
24
|
+
app_test = AppTester.new(:name => 'tab-with-key-signature')
|
25
|
+
app_test.run
|
26
|
+
app_test.actual.should == app_test.expected
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can convert a tab with repeats to lilypond" do
|
30
|
+
app_test = AppTester.new(:name => 'tab-with-repeats')
|
47
31
|
app_test.run
|
48
32
|
app_test.actual.should == app_test.expected
|
49
33
|
end
|