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.
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