gitara 0.0.1 → 0.1.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 +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
|