gitara 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Guardfile +8 -0
- data/README.markdown +214 -0
- data/bin/gitara +4 -0
- data/examples/aimee-man-wise-up/aimee-man-wise-up.ly +186 -0
- data/examples/aimee-man-wise-up/aimee-man-wise-up.midi +0 -0
- data/examples/aimee-man-wise-up/aimee-man-wise-up.pdf +0 -0
- data/examples/aimee-man-wise-up/aimee-man-wise-up.rb +170 -0
- data/examples/tab-with-bar.rb +7 -0
- data/examples/tab-with-reused-bar.rb +9 -0
- data/examples/tab.ly +117 -0
- data/examples/tab.rb +43 -0
- data/gitara.gemspec +15 -5
- data/lib/gitara.rb +38 -1
- data/lib/gitara/app.rb +29 -0
- data/lib/gitara/dsl.rb +35 -0
- data/lib/gitara/id_as_word.rb +8 -0
- data/lib/gitara/node/bar.rb +9 -0
- data/lib/gitara/node/bar/voiced_node.rb +13 -0
- data/lib/gitara/node/base.rb +82 -0
- data/lib/gitara/node/base/voiced_node.rb +22 -0
- data/lib/gitara/node/line.rb +6 -0
- data/lib/gitara/node/note_set.rb +6 -0
- data/lib/gitara/node/score.rb +6 -0
- data/lib/gitara/node/tab.rb +21 -0
- data/lib/gitara/pow/base.rb +11 -0
- data/lib/gitara/template/bar.erb +3 -0
- data/lib/gitara/template/line.erb +3 -0
- data/lib/gitara/template/score.erb +3 -0
- data/lib/gitara/template/tab.erb +91 -0
- data/lib/gitara/template/voice.erb +1 -0
- data/lib/gitara/version.rb +1 -1
- data/lib/gitara/voice.rb +20 -0
- data/spec/lib/gitara/app_spec.rb +12 -0
- data/spec/lib/gitara/dsl_spec.rb +173 -0
- data/spec/lib/gitara/node/bar/voiced_node_spec.rb +17 -0
- data/spec/lib/gitara/node/bar_spec.rb +22 -0
- data/spec/lib/gitara/node/base/voiced_node_spec.rb +35 -0
- data/spec/lib/gitara/node/base_spec.rb +201 -0
- data/spec/lib/gitara/node/note_set_spec.rb +4 -0
- data/spec/lib/gitara/node/tab_spec.rb +57 -0
- data/spec/lib/gitara/voice_spec.rb +31 -0
- data/spec/lib/gitara_spec.rb +23 -0
- data/spec/spec_helper.rb +27 -0
- metadata +217 -10
@@ -0,0 +1,22 @@
|
|
1
|
+
module Gitara
|
2
|
+
module Node
|
3
|
+
class Base
|
4
|
+
class VoicedNode < Valuable
|
5
|
+
has_value :node
|
6
|
+
has_value :voice
|
7
|
+
|
8
|
+
def call_name
|
9
|
+
"\\#{definition_name}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def children
|
13
|
+
node.children.map{|child| child.voiced_as(voice) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def definition_name
|
17
|
+
"#{voice.definition_name}#{node.class.to_s.split('::').last}#{node.name}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Gitara
|
2
|
+
module Node
|
3
|
+
class Tab < Base
|
4
|
+
def self.parse(text)
|
5
|
+
Transform.new.apply(Parser.new.parse(text))
|
6
|
+
end
|
7
|
+
|
8
|
+
def max_number_of_voices
|
9
|
+
definitions(Node::Bar).map{|bar| bar.note_sets.size}.max
|
10
|
+
end
|
11
|
+
|
12
|
+
def playable_child
|
13
|
+
children.last
|
14
|
+
end
|
15
|
+
|
16
|
+
def voices
|
17
|
+
@voices ||= Array.new(max_number_of_voices){|i| Voice.new(:id => i + 1, :parent => self)}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
\version "2.12.3"
|
2
|
+
\include "english.ly"
|
3
|
+
|
4
|
+
%-----------------------------------------------------------------------
|
5
|
+
% Bars
|
6
|
+
|
7
|
+
<% definitions(Gitara::Node::Bar).each do |bar| %>
|
8
|
+
<%= Gitara.render('bar', bar) %>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
%-----------------------------------------------------------------------
|
12
|
+
% Lines
|
13
|
+
|
14
|
+
<% definitions(Gitara::Node::Line).each do |line| %>
|
15
|
+
<%= Gitara.render('line', line) %>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
%-----------------------------------------------------------------------
|
19
|
+
% Scores
|
20
|
+
|
21
|
+
<% definitions(Gitara::Node::Score).each do |score| %>
|
22
|
+
<%= Gitara.render('score', score) %>
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
%-----------------------------------------------------------------------
|
26
|
+
% Voices
|
27
|
+
|
28
|
+
<% voices.each do |voice| %>
|
29
|
+
<%= Gitara.render('voice', voice) %>
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
\score {
|
33
|
+
\new StaffGroup <<
|
34
|
+
\new Staff <<
|
35
|
+
\tempo 4 = 75
|
36
|
+
\clef "treble_8"
|
37
|
+
|
38
|
+
<% voices.each do |voice| %>
|
39
|
+
\new Voice {
|
40
|
+
<%= voice.stem_type %>
|
41
|
+
<%= voice.call_name %>
|
42
|
+
}
|
43
|
+
<% end %>
|
44
|
+
>>
|
45
|
+
|
46
|
+
\new TabStaff <<
|
47
|
+
<% voices.each do |voice| %>
|
48
|
+
\new TabVoice {
|
49
|
+
\slurUp
|
50
|
+
<%= voice.call_name %>
|
51
|
+
}
|
52
|
+
<% end %>
|
53
|
+
>>
|
54
|
+
>>
|
55
|
+
|
56
|
+
\layout {
|
57
|
+
\context { \Staff
|
58
|
+
\override TimeSignature #'style = #'numbered
|
59
|
+
\override StringNumber #'transparent = ##t
|
60
|
+
}
|
61
|
+
\context { \TabStaff
|
62
|
+
\override TimeSignature #'style = #'numbered
|
63
|
+
}
|
64
|
+
\context { \Voice
|
65
|
+
\remove Slur_engraver
|
66
|
+
}
|
67
|
+
\context { \TabVoice
|
68
|
+
\remove Dots_engraver
|
69
|
+
\remove Stem_engraver
|
70
|
+
\remove Rest_engraver
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
% showLastLength = R1*4
|
76
|
+
\score {
|
77
|
+
\new Staff \with {midiInstrument = #"acoustic guitar (nylon)"} <<
|
78
|
+
\tempo 4 = 75
|
79
|
+
\clef "treble_8"
|
80
|
+
|
81
|
+
<% voices.each do |voice| %>
|
82
|
+
\new Voice {
|
83
|
+
\unfoldRepeats {
|
84
|
+
<%= voice.call_name %>
|
85
|
+
}
|
86
|
+
}
|
87
|
+
<% end %>
|
88
|
+
>>
|
89
|
+
|
90
|
+
\midi {}
|
91
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= definition_name %> = { <%= parent.playable_child.voiced_as(self).call_name %> }
|
data/lib/gitara/version.rb
CHANGED
data/lib/gitara/voice.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Gitara
|
2
|
+
class Voice < Valuable
|
3
|
+
include IdAsWord
|
4
|
+
|
5
|
+
has_value :id
|
6
|
+
has_value :parent
|
7
|
+
|
8
|
+
def call_name
|
9
|
+
"\\#{definition_name}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def definition_name
|
13
|
+
"v#{id_as_word}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def stem_type
|
17
|
+
"\\voice#{id_as_word}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe App do
|
4
|
+
describe "export" do
|
5
|
+
it "can convert a tab without a reused bar to lilypond" do
|
6
|
+
app = Gitara::App.new
|
7
|
+
app.invoke :export, ['examples/tab.rb'], "target-directory" => test_tmp_dir.path, "run-lilypond" => false
|
8
|
+
|
9
|
+
(test_tmp_dir / 'tab.ly').read.should == Pow('examples/tab.ly').read
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gitara do
|
4
|
+
describe Dsl do
|
5
|
+
describe "bar(name, &block)" do
|
6
|
+
it "should add a bar with the name" do
|
7
|
+
dsl = Dsl.new(:node => Node::Tab.new)
|
8
|
+
dsl.node.own_children.should be_empty
|
9
|
+
|
10
|
+
dsl.bar 'Intro'
|
11
|
+
|
12
|
+
dsl.node.own_children.should have(1).bar
|
13
|
+
|
14
|
+
bar = dsl.node.own_children[0]
|
15
|
+
bar.name.should == 'Intro'
|
16
|
+
bar.own_children.should be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should add the children declared in the block to the bar" do
|
20
|
+
dsl = Dsl.new(:node => Node::Tab.new)
|
21
|
+
dsl.node.own_children.should be_empty
|
22
|
+
|
23
|
+
note_set = Node::NoteSet.new
|
24
|
+
|
25
|
+
dsl.bar 'Intro' do
|
26
|
+
add note_set
|
27
|
+
end
|
28
|
+
|
29
|
+
dsl.node.own_children.should have(1).bar
|
30
|
+
dsl.node.own_children[0].name.should == 'Intro'
|
31
|
+
|
32
|
+
bar = dsl.node.own_children[0]
|
33
|
+
bar.own_children.should have(1).note_set
|
34
|
+
bar.own_children[0].should == note_set
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "add(child, &block)" do
|
39
|
+
it "should add the child to the dsl's node" do
|
40
|
+
dsl = Dsl.new(:node => Node::Tab.new)
|
41
|
+
dsl.node.own_children.should be_empty
|
42
|
+
|
43
|
+
bar = Node::Bar.new(:name => 'Intro')
|
44
|
+
|
45
|
+
dsl.add bar
|
46
|
+
|
47
|
+
dsl.node.own_children.should have(1).bar
|
48
|
+
dsl.node.own_children[0].should == bar
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should add the children in the block to the child" do
|
52
|
+
dsl = Dsl.new(:node => Node::Tab.new)
|
53
|
+
dsl.node.own_children.should be_empty
|
54
|
+
|
55
|
+
bar = Node::Bar.new
|
56
|
+
note_set = Node::NoteSet.new
|
57
|
+
|
58
|
+
dsl.add bar do
|
59
|
+
add note_set
|
60
|
+
end
|
61
|
+
|
62
|
+
dsl.node.own_children.should have(1).bar
|
63
|
+
dsl.node.own_children[0].should == bar
|
64
|
+
|
65
|
+
bar.own_children.should have(1).note_set
|
66
|
+
bar.own_children[0].should == note_set
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "notes(value)" do
|
71
|
+
it "should add a note set with the value" do
|
72
|
+
dsl = Dsl.new(:node => Node::Bar.new)
|
73
|
+
dsl.node.own_children.should be_empty
|
74
|
+
|
75
|
+
dsl.notes 'test'
|
76
|
+
|
77
|
+
dsl.node.own_children.should have(1).note_set
|
78
|
+
dsl.node.own_children[0].value.should == 'test'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "line(name, &block)" do
|
83
|
+
it "should add a line with the name" do
|
84
|
+
dsl = Dsl.new(:node => Node::Tab.new)
|
85
|
+
dsl.node.own_children.should be_empty
|
86
|
+
|
87
|
+
dsl.line 'Intro'
|
88
|
+
|
89
|
+
dsl.node.own_children.should have(1).line
|
90
|
+
|
91
|
+
line = dsl.node.own_children[0]
|
92
|
+
line.name.should == 'Intro'
|
93
|
+
line.own_children.should be_empty
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should add the children declared in the block to the line" do
|
97
|
+
dsl = Dsl.new(:node => Node::Tab.new)
|
98
|
+
dsl.node.own_children.should be_empty
|
99
|
+
|
100
|
+
bar = Node::Bar.new
|
101
|
+
|
102
|
+
dsl.line 'Intro' do
|
103
|
+
add bar
|
104
|
+
end
|
105
|
+
|
106
|
+
dsl.node.own_children.should have(1).line
|
107
|
+
dsl.node.own_children[0].name.should == 'Intro'
|
108
|
+
|
109
|
+
line = dsl.node.own_children[0]
|
110
|
+
line.own_children.should have(1).bar
|
111
|
+
line.own_children[0].should == bar
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "add_names(o)" do
|
116
|
+
it "should add a node with o[:name] of o[:node_class] to the node" do
|
117
|
+
dsl = Dsl.new(:node => Node::Tab.new)
|
118
|
+
dsl.node.own_children.should be_empty
|
119
|
+
|
120
|
+
dsl.add_names :names => [:Intro, :Intro], :node_class => Node::Bar
|
121
|
+
|
122
|
+
dsl.node.own_children.should have(2).bars
|
123
|
+
dsl.node.own_children.each do |child|
|
124
|
+
child.should be_a(Node::Bar)
|
125
|
+
child.name.should == :Intro
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should add a node with nil name if the o[:names] is blank" do
|
130
|
+
dsl = Dsl.new(:node => Node::Tab.new)
|
131
|
+
dsl.node.own_children.should be_empty
|
132
|
+
|
133
|
+
dsl.add_names :names => [], :node_class => Node::Bar
|
134
|
+
|
135
|
+
dsl.node.own_children.should have(1).bar
|
136
|
+
dsl.node.own_children[0].attributes[:name].should be_nil
|
137
|
+
dsl.node.own_children[0].should be_a(Node::Bar)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "score(name, &block)" do
|
142
|
+
it "should add a score with the name" do
|
143
|
+
dsl = Dsl.new(:node => Node::Tab.new)
|
144
|
+
dsl.node.own_children.should be_empty
|
145
|
+
|
146
|
+
dsl.score
|
147
|
+
|
148
|
+
dsl.node.own_children.should have(1).score
|
149
|
+
|
150
|
+
score = dsl.node.own_children[0]
|
151
|
+
score.should be_a(Node::Score)
|
152
|
+
score.own_children.should be_empty
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should add the children declared in the block to the score" do
|
156
|
+
dsl = Dsl.new(:node => Node::Tab.new)
|
157
|
+
dsl.node.own_children.should be_empty
|
158
|
+
|
159
|
+
note_set = Node::NoteSet.new
|
160
|
+
|
161
|
+
dsl.score do
|
162
|
+
add note_set
|
163
|
+
end
|
164
|
+
|
165
|
+
dsl.node.own_children.should have(1).score
|
166
|
+
|
167
|
+
score = dsl.node.own_children[0]
|
168
|
+
score.own_children.should have(1).note_set
|
169
|
+
score.own_children[0].should == note_set
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Bar::VoicedNode' do
|
4
|
+
describe "matching_note_set" do
|
5
|
+
it "should be the note_set matching this voiced bar" do
|
6
|
+
note_set = Node::NoteSet.new
|
7
|
+
|
8
|
+
bar = Node::Bar.new
|
9
|
+
bar.add note_set
|
10
|
+
|
11
|
+
voice = Voice.new(:id => 1)
|
12
|
+
|
13
|
+
voiced_bar = Node::Bar::VoicedNode.new(:node => bar, :voice => voice)
|
14
|
+
voiced_bar.matching_note_set.should == note_set
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Bar' do
|
4
|
+
describe "note_sets" do
|
5
|
+
it "should be the note sets of its definition" do
|
6
|
+
definition_bar = Node::Bar.new(:name => 'Intro').tap {|bar|
|
7
|
+
bar.children = [
|
8
|
+
Node::NoteSet.new,
|
9
|
+
Node::NoteSet.new
|
10
|
+
]
|
11
|
+
}
|
12
|
+
|
13
|
+
call_bar = Node::Bar.new(:name => 'Intro')
|
14
|
+
|
15
|
+
tab = Node::Tab.new.tap {|tab|
|
16
|
+
tab.children = [definition_bar, call_bar]
|
17
|
+
}
|
18
|
+
|
19
|
+
call_bar.note_sets.should have(2).note_sets
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|