gitara 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.gitignore +4 -0
  2. data/Guardfile +8 -0
  3. data/README.markdown +214 -0
  4. data/bin/gitara +4 -0
  5. data/examples/aimee-man-wise-up/aimee-man-wise-up.ly +186 -0
  6. data/examples/aimee-man-wise-up/aimee-man-wise-up.midi +0 -0
  7. data/examples/aimee-man-wise-up/aimee-man-wise-up.pdf +0 -0
  8. data/examples/aimee-man-wise-up/aimee-man-wise-up.rb +170 -0
  9. data/examples/tab-with-bar.rb +7 -0
  10. data/examples/tab-with-reused-bar.rb +9 -0
  11. data/examples/tab.ly +117 -0
  12. data/examples/tab.rb +43 -0
  13. data/gitara.gemspec +15 -5
  14. data/lib/gitara.rb +38 -1
  15. data/lib/gitara/app.rb +29 -0
  16. data/lib/gitara/dsl.rb +35 -0
  17. data/lib/gitara/id_as_word.rb +8 -0
  18. data/lib/gitara/node/bar.rb +9 -0
  19. data/lib/gitara/node/bar/voiced_node.rb +13 -0
  20. data/lib/gitara/node/base.rb +82 -0
  21. data/lib/gitara/node/base/voiced_node.rb +22 -0
  22. data/lib/gitara/node/line.rb +6 -0
  23. data/lib/gitara/node/note_set.rb +6 -0
  24. data/lib/gitara/node/score.rb +6 -0
  25. data/lib/gitara/node/tab.rb +21 -0
  26. data/lib/gitara/pow/base.rb +11 -0
  27. data/lib/gitara/template/bar.erb +3 -0
  28. data/lib/gitara/template/line.erb +3 -0
  29. data/lib/gitara/template/score.erb +3 -0
  30. data/lib/gitara/template/tab.erb +91 -0
  31. data/lib/gitara/template/voice.erb +1 -0
  32. data/lib/gitara/version.rb +1 -1
  33. data/lib/gitara/voice.rb +20 -0
  34. data/spec/lib/gitara/app_spec.rb +12 -0
  35. data/spec/lib/gitara/dsl_spec.rb +173 -0
  36. data/spec/lib/gitara/node/bar/voiced_node_spec.rb +17 -0
  37. data/spec/lib/gitara/node/bar_spec.rb +22 -0
  38. data/spec/lib/gitara/node/base/voiced_node_spec.rb +35 -0
  39. data/spec/lib/gitara/node/base_spec.rb +201 -0
  40. data/spec/lib/gitara/node/note_set_spec.rb +4 -0
  41. data/spec/lib/gitara/node/tab_spec.rb +57 -0
  42. data/spec/lib/gitara/voice_spec.rb +31 -0
  43. data/spec/lib/gitara_spec.rb +23 -0
  44. data/spec/spec_helper.rb +27 -0
  45. 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,6 @@
1
+ module Gitara
2
+ module Node
3
+ class Line < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Gitara
2
+ module Node
3
+ class NoteSet < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Gitara
2
+ module Node
3
+ class Score < Base
4
+ end
5
+ end
6
+ 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,11 @@
1
+ module Pow
2
+ class Base
3
+ def read!
4
+ if exists?
5
+ read
6
+ else
7
+ raise PowError, "#{self} does not exist"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ <% self.voiced_as(self.root.voices).each do |voiced_bar| %>
2
+ <%= voiced_bar.definition_name %> = { <%= voiced_bar.matching_note_set.value %> }
3
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% self.voiced_as(self.root.voices).each do |voiced_line| %>
2
+ <%= voiced_line.definition_name %> = { <%= voiced_line.children.map(&:call_name).join(' ') %> \break }
3
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% self.voiced_as(self.root.voices).each do |voiced_score| %>
2
+ <%= voiced_score.definition_name %> = { <%= voiced_score.children.map(&:call_name).join(' ') %> }
3
+ <% 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 %> }
@@ -1,3 +1,3 @@
1
1
  module Gitara
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -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