gitara 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +2 -0
  2. data/.yardopts +5 -0
  3. data/CHANGELOG.markdown +5 -0
  4. data/README.markdown +135 -99
  5. data/examples/tab-with-repeats.ly +117 -0
  6. data/examples/tab-with-repeats.rb +19 -0
  7. data/gitara.gemspec +3 -0
  8. data/lib/gitara.rb +5 -3
  9. data/lib/gitara/dsl.rb +13 -0
  10. data/lib/gitara/node/alternative.rb +14 -0
  11. data/lib/gitara/node/bar.rb +3 -1
  12. data/lib/gitara/node/base.rb +22 -24
  13. data/lib/gitara/node/base/chorded_version.rb +1 -4
  14. data/lib/gitara/node/base/node_version.rb +35 -0
  15. data/lib/gitara/node/base/stanza_version.rb +1 -4
  16. data/lib/gitara/node/base/voiced_version.rb +5 -6
  17. data/lib/gitara/node/repeat.rb +10 -0
  18. data/lib/gitara/node/tab.rb +3 -5
  19. data/lib/gitara/utilities.rb +8 -0
  20. data/lib/gitara/version.rb +1 -1
  21. data/lib/gitara/voice.rb +2 -0
  22. data/spec/factories.rb +6 -0
  23. data/spec/lib/gitara/app_spec.rb +12 -28
  24. data/spec/lib/gitara/dsl_spec.rb +218 -173
  25. data/spec/lib/gitara/node/alternative_spec.rb +15 -0
  26. data/spec/lib/gitara/node/bar/chorded_version_spec.rb +2 -2
  27. data/spec/lib/gitara/node/bar/stanza_version_spec.rb +2 -2
  28. data/spec/lib/gitara/node/bar/voiced_version_spec.rb +2 -2
  29. data/spec/lib/gitara/node/bar_spec.rb +7 -7
  30. data/spec/lib/gitara/node/base/chorded_version_spec.rb +1 -1
  31. data/spec/lib/gitara/node/base/node_version_spec.rb +66 -0
  32. data/spec/lib/gitara/node/base/voiced_version_spec.rb +5 -5
  33. data/spec/lib/gitara/node/base_spec.rb +36 -42
  34. data/spec/lib/gitara/node/chord_set/chorded_version_spec.rb +2 -2
  35. data/spec/lib/gitara/node/chord_set_spec.rb +1 -1
  36. data/spec/lib/gitara/node/note_set_spec.rb +1 -1
  37. data/spec/lib/gitara/node/repeat_spec.rb +15 -0
  38. data/spec/lib/gitara/node/stanza_spec.rb +2 -2
  39. data/spec/lib/gitara/node/tab_spec.rb +6 -6
  40. data/spec/lib/gitara/voice_spec.rb +9 -9
  41. data/spec/lib/gitara_spec.rb +3 -1
  42. data/spec/spec_helper.rb +1 -0
  43. data/spec/support/app_tester.rb +22 -0
  44. metadata +70 -29
  45. data/lib/gitara/is_node_version.rb +0 -23
  46. data/lib/gitara/pow/base.rb +0 -11
  47. data/spec/lib/gitara/is_node_version_spec.rb +0 -58
data/.gitignore CHANGED
@@ -3,7 +3,9 @@
3
3
  git.bundle
4
4
  .geanyprj
5
5
  .rvmrc
6
+ .yardoc
6
7
  Gemfile.lock
8
+ doc/*
7
9
  files/*
8
10
  pkg/*
9
11
  tmp/*
@@ -0,0 +1,5 @@
1
+ lib
2
+ spec
3
+ --files CHANGELOG.markdown
4
+ --no-private
5
+ --plugin yard-rspec
@@ -1,3 +1,8 @@
1
+ 0.6.0 - 2012-04-01
2
+ ------------------
3
+
4
+ * [#22] I should be able to add repeats and alternatives.
5
+
1
6
  0.5.0 - 2012-03-18
2
7
  ------------------
3
8
 
@@ -1,26 +1,27 @@
1
1
  Gitara is a Ruby DSL for generating Lilypond guitar tablatures
2
2
 
3
3
 
4
- Installation
5
- ------------
4
+ Usage
5
+ -----
6
+
7
+ To install,
6
8
 
7
9
  gem install gitara
8
10
 
9
- You need to have [lilypond](http://lilypond.org) 2.12 or higher to generate pdfs and midis.
11
+ You need [lilypond](http://lilypond.org) 2.12 or higher in order to generate pdfs and midis.
10
12
 
11
- Gitara is tested on 1.9.3 only. Patches are welcome.
13
+ Gitara is tested on Ruby 1.9.3 only. Patches are welcome.
12
14
 
13
15
 
14
- Usage
15
- ------
16
+ To run,
16
17
 
17
18
  gitara export PATH [OPTIONS]...
18
19
 
19
20
  This will generate a lilypond .ly file and then call lilypond to export the .ly file to pdf and midi. Please see `gitara help export` for the available options.
20
21
 
21
22
 
22
- Syntax
23
- ------
23
+ Basic syntax
24
+ ------------
24
25
 
25
26
  Gitara is a Ruby DSL. A typical Gitara file will have the following structure:
26
27
 
@@ -36,13 +37,13 @@ Gitara is a Ruby DSL. A typical Gitara file will have the following structure:
36
37
  end
37
38
  end
38
39
 
39
- You can find examples in the examples directory.
40
+ You can find examples at https://github.com/gsmendoza/gitara/tree/master/examples.
40
41
 
41
42
 
42
43
  Bars
43
44
  ----
44
45
 
45
- Bars are the smallest expressions in Gitara, that is, a gitara file must have at least one bar. The notes inside a bar follow [Lilypond syntax](http://lilypond.org/doc/v2.12/Documentation/user/lilypond-learning/Simple-notation).
46
+ Bars are the smallest expressions in Gitara. That is, a gitara file must have at least one bar. The notes inside a bar follow [Lilypond syntax](http://lilypond.org/doc/v2.12/Documentation/user/lilypond-learning/Simple-notation).
46
47
 
47
48
  Gitara.define do
48
49
  bar do
@@ -50,26 +51,31 @@ Bars are the smallest expressions in Gitara, that is, a gitara file must have at
50
51
  end
51
52
  end
52
53
 
53
- With Gitara, it's easier to write notes using [absolute note names](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Writing-pitches#Absolute-octave-entry) instead of relative note names. This is because we'll be reusing bars and other Gitara expressions (see Reusing bars below).
54
+ With Gitara, it's easier to write notes using [absolute note names](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Writing-pitches#Absolute-octave-entry) instead of relative note names. This is because we'll be reusing bars and other Gitara expressions (see Reusing expressions below).
54
55
 
55
- Partial measures
56
- ----------------
57
56
 
58
- To indicate that a bar is a [partial measure](http://lilypond.org/doc/v2.12/Documentation/user/lilypond-learning/Advanced-rhythmic-commands#Partial-measure), call `partial <duration>`:
57
+ ### Notes with single quotes and backslashes
59
58
 
60
- chords :G8, 'r8-"G"'
59
+ In Lilypond syntax, single quotes refer to octaves while backslashes refer to string numbers. So, the c note in the second string is written as
61
60
 
62
- bar do
63
- partial 8
64
- notes "<g/3>8"
65
- notes "r8"
66
- chords :G8
67
- end
61
+ c'\2
62
+
63
+ Since a Gitara file is a Ruby program, you have to be careful with backslashes when writing notes like the one above. Ruby provides AFAIK two ways to preserve the backslash in the note above:
68
64
 
69
- As shown by the example, the durations of the chords and notes within the bar must also have one-eighth durations in order for the tab to render properly.
65
+ notes %q|c'\2|
70
66
 
71
- Multiple voices
72
- ---------------
67
+ or
68
+
69
+ notes "c'\\2"
70
+
71
+ Gitara provides a third option: it will automatically convert slashes to backslashes. This way, you can write the note above as
72
+
73
+ notes "c'/2"
74
+
75
+ Prettier and easier to search and replace.
76
+
77
+
78
+ ### Multiple voices
73
79
 
74
80
  Each line of notes in a bar is a [voice](http://lilypond.org/doc/v2.12/Documentation/user/lilypond-learning/Voices-contain-music):
75
81
 
@@ -83,29 +89,47 @@ Each line of notes in a bar is a [voice](http://lilypond.org/doc/v2.12/Documenta
83
89
  The tab above will play "c d e f g a b c" and "c' d' e' f' g' a' b' c'" simultaneously, not sequentially.
84
90
 
85
91
 
86
- Reusing bars
87
- ------------
92
+ ### Partial bars
88
93
 
89
- If you want to repeat a bar, you can name the bar and call it later:
94
+ To indicate that a bar is a [partial measure](http://lilypond.org/doc/v2.12/Documentation/user/lilypond-learning/Advanced-rhythmic-commands#Partial-measure), call `partial <duration>`:
90
95
 
91
- Gitara.define do
92
- score do
93
- bar :Intro do
94
- notes "c d e f g a b c"
95
- notes "c' d' e' f' g' a' b' c'"
96
- end
96
+ bar do
97
+ partial 8
98
+ notes "<g/3>8"
99
+ notes "r8"
100
+ end
97
101
 
98
- bar :Intro
99
- end
102
+ As shown by the example, the durations of the notes within the bar must also have one-eighth durations in order for the tab to render properly.
103
+
104
+ Grouping bars together
105
+ ----------------------
106
+
107
+ ### Lines
108
+
109
+ You can group bars in a line:
110
+
111
+ line :LineOne do
112
+ bar :BayangMagiliw
113
+ bar :PerlasNgSilanganan
114
+ bar :AlabNgPuso
115
+ bar :SaDibdibMoyBuhay
100
116
  end
101
117
 
102
- This will generate a tab with two Intro bars. It's important to group the two bars inside a score, because...
118
+ Lines are [manually breaked](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Line-breaking) in Gitara.
119
+
120
+ ### Stanzas
103
121
 
122
+ Lines can be grouped in stanzas. The names of a stanza will be displayed at the top of the stanza's first bar.
104
123
 
105
- Only the last expression under Gitara.define will be generated
106
- --------------------------------------------------------------
107
124
 
108
- When writing a tab, oftentimes you want to generate only a part of the tab for testing purposes. Gitara makes this easy by processing only for the last expression under Gitara.define. For example:
125
+ ### Score
126
+
127
+ Finally, stanzas can be grouped in a score. Scores are important in grouping the tab in a single unit because...
128
+
129
+
130
+ ### Only the last expression under Gitara.define will be generated
131
+
132
+ When writing a tab, oftentimes you want to generate only a part of the tab for testing purposes. Gitara makes this easy by processing only for the last expression under Gitara.define. For example, in the following tab, only the second bar (notes "g a b c") will be generated.
109
133
 
110
134
  Gitara.define do
111
135
  bar do
@@ -117,7 +141,7 @@ When writing a tab, oftentimes you want to generate only a part of the tab for t
117
141
  end
118
142
  end
119
143
 
120
- This tab will generate only the second bar (notes "g a b c"). If you want Gitara to generate both bars, group them inside a score.
144
+ If you want Gitara to generate both bars, you must group them inside a score.
121
145
 
122
146
  Gitara.define do
123
147
  score do
@@ -131,7 +155,7 @@ This tab will generate only the second bar (notes "g a b c"). If you want Gitara
131
155
  end
132
156
  end
133
157
 
134
- If you want to generate a particular bar inside the score, you can copy it after the score:
158
+ If you want to test a particular bar inside the score, you can copy it after the score:
135
159
 
136
160
  Gitara.define do
137
161
  score do
@@ -149,78 +173,78 @@ If you want to generate a particular bar inside the score, you can copy it after
149
173
  end
150
174
  end
151
175
 
152
- Or you can define the bar to call later:
176
+ Or, as you'll see below, you can give the bar a name so that you can call it later.
177
+
178
+
179
+ Reusing expressions
180
+ -------------------
181
+
182
+ Bars, lines, and other Gitara expressions can be reused. For example, if you want a repeat a bar, you can name the bar and call the name afterwards:
153
183
 
154
184
  Gitara.define do
155
- bar :FirstBar do
156
- notes "c d e f"
185
+ score do
186
+ bar :Intro do
187
+ notes "c d e f g a b c"
188
+ notes "c' d' e' f' g' a' b' c'"
189
+ end
190
+
191
+ bar :Intro
157
192
  end
193
+ end
158
194
 
195
+ This will generate a tab with two Intro bars. It's important to group the two bars above inside a score, because otherwise Gitara will only generate the second bar.
196
+
197
+ You can reuse a Gitara expression as long as it is defined before the call. The definition can even be deeper than the level of the call:
198
+
199
+ Gitara.define do
159
200
  score do
160
- bar :FirstBar
201
+ bar :testing do
202
+ notes "c d e f"
203
+ end
161
204
 
162
205
  bar do
163
206
  notes "g a b c"
164
207
  end
165
208
  end
166
209
 
167
- bar :FirstBar
210
+ bar :testing
168
211
  end
169
212
 
213
+ In the example above, Gitara will only generate the last :testing bar.
170
214
 
171
- Calling multiple bars
172
- ---------------------
173
-
174
- You can call multiple bars in a single line:
215
+ Finally, you can call multiple expressions in a single line:
175
216
 
176
217
  bar :BayangMagiliw, :PerlasNgSilanganan, :AlabNgPuso, :SaDibdibMoyBuhay
177
218
 
178
219
 
179
- Lines
180
- -----
181
-
182
- You can group bars in a line:
183
-
184
- line :LineOne do
185
- bar :BayangMagiliw, :PerlasNgSilanganan, :AlabNgPuso, :SaDibdibMoyBuhay
186
- end
187
-
188
- Lines are manually breaked with [\\break](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Line-breaking).
189
-
190
- Like bars, lines can be named, reused, etc.
191
-
192
-
193
- Stanzas
194
- -------
195
-
196
- The names of a stanza will be displayed at the top of the stanza's first bar.
220
+ ### Repeats and alternative endings
197
221
 
198
- Chord labels (optional)
199
- -----------------------
200
-
201
- You can add chord labels to bars:
222
+ You can also group expressions under [repeats](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Long-repeats) and provide alternative endings:
202
223
 
203
224
  Gitara.define do
204
- chords :FC, 'r4-"F" r r-"C" r'
225
+ line do
226
+ repeat 4 do
227
+ bar do
228
+ notes "c4 d e f"
229
+ end
230
+ end
205
231
 
206
- bar :BeganIt do
207
- notes "/skip 4 <a/3 c'/2 >8 <g/3>8 /skip 4 <g/3 c'/2 >8 <g/3>8"
208
- notes "<f/4>4 <f/4>4 <c/5>4 <e/4>4"
209
- chords :FC
232
+ alternative do
233
+ bar do
234
+ notes "d2 e"
235
+ end
236
+
237
+ bar do
238
+ notes "f2 g"
239
+ end
240
+ end
210
241
  end
211
242
  end
212
243
 
213
- `r4-"F" r r-"C" r` is a [lilypond music expression](http://lilypond.org/doc/v2.12/Documentation/user/lilypond-learning/Music-expressions-explained).
214
-
215
- * `r` is a rest. `r4` is a rest that is a quarter note long. Succeeding rests have the same duration as the first one.
216
- * `-"F"` means 'place the text "F" below the rest note'. See http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Writing-text.
217
-
218
- When these chord labels are added to the Gitara lilypond output, Gitara hides the rest notes so only the chord labels are visible.
219
-
220
244
  Properties
221
245
  ----------
222
246
 
223
- A gitara file can have the following optional properties:
247
+ A gitara file can have the following properties:
224
248
 
225
249
  Gitara.define do
226
250
  title "Wise Up"
@@ -237,34 +261,46 @@ A gitara file can have the following optional properties:
237
261
  * arranger - tab's arranger
238
262
  * composer - song's composer
239
263
  * instrument - description of the instrument used on the tab
240
- * key - [key signature](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Displaying-pitches#Key-signature)
264
+ * [key](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Displaying-pitches#Key-signature)
241
265
  * midi_instrument - the type of instrument played in the midi export of the tab. By default, "acoustic guitar (nylon)".
242
- * string_tunings - see [lilypond](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Common-notation-for-fretted-strings#Custom-tablatures)
243
- * tempo - see [lilypond](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Writing-parts#Metronome-marks) for the format
266
+ * [string_tunings](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Common-notation-for-fretted-strings#Custom-tablatures)
267
+ * [tempo](http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Writing-parts#Metronome-marks)
244
268
  * title - title of the song
245
269
  * transposition - adjusts the pitch of the instrument. The default transposition is "c". If you set it to "d", then you have to play the tab two frets higher on the guitar (capo on second fret).
246
270
 
247
- Notes with single quotes and backslashes
248
- ----------------------------------------
249
271
 
250
- In Lilypond syntax, single quotes refer to octaves while backslashes refer to string numbers. So, the c note in the second string is written as
272
+ Chord labels
273
+ ------------
251
274
 
252
- c'\2
275
+ You can add chord labels to bars:
253
276
 
254
- Since a Gitara file is a Ruby program, you have to be careful with backslashes when writing notes like the one above. As far as I know, Ruby provides two ways to preserve the backslash in the note above:
277
+ Gitara.define do
278
+ chords :FC, 'r4-"F" r r-"C" r'
255
279
 
256
- notes %q|c'\2|
280
+ bar :BeganIt do
281
+ notes "/skip 4 <a/3 c'/2 >8 <g/3>8 /skip 4 <g/3 c'/2 >8 <g/3>8"
282
+ notes "<f/4>4 <f/4>4 <c/5>4 <e/4>4"
283
+ chords :FC
284
+ end
285
+ end
257
286
 
258
- or
287
+ `r4-"F" r r-"C" r` is a [lilypond music expression](http://lilypond.org/doc/v2.12/Documentation/user/lilypond-learning/Music-expressions-explained).
259
288
 
260
- notes "c'\\2"
289
+ * `r` is a rest. `r4` is a rest that is a quarter note long. Succeeding rests have the same duration as the first one.
290
+ * `-"F"` means 'place the text "F" below the rest note'. See http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Writing-text.
261
291
 
262
- Gitara provides a third option: it will automatically convert slashes to backslashes. This way, you can write the note above as
292
+ When these chord labels are added to the Gitara lilypond output, Gitara hides the rest notes so only the chord labels are visible.
263
293
 
264
- notes "c'/2"
294
+ If the bar is a partial measure, the duration of the chords within the bar must match the bar's duration:
265
295
 
266
- Prettier and easier to search and replace.
296
+ chords :G8, 'r8-"G"'
267
297
 
298
+ bar do
299
+ partial 8
300
+ notes "<g/3>8"
301
+ notes "r8"
302
+ chords :G8
303
+ end
268
304
 
269
305
  Workflow
270
306
  --------
@@ -0,0 +1,117 @@
1
+ \version "2.12.3"
2
+ \include "english.ly"
3
+
4
+ \paper {
5
+ indent = #0
6
+ }
7
+
8
+ \header {
9
+ title = ""
10
+ composer = ""
11
+ arranger = ""
12
+ instrument = ""
13
+ }
14
+
15
+ %-----------------------------------------------------------------------
16
+ % Chord Sets
17
+ %-----------------------------------------------------------------------
18
+ % Bars
19
+
20
+ vOneBarTabOneLineOneRepeatOneBarOne = { c4 d e f }
21
+ cBarTabOneLineOneRepeatOneBarOne = { }
22
+ sBarTabOneLineOneRepeatOneBarOne = { r1 }
23
+
24
+ vOneBarTabOneLineOneAlternativeOneBarOne = { d2 e }
25
+ cBarTabOneLineOneAlternativeOneBarOne = { }
26
+ sBarTabOneLineOneAlternativeOneBarOne = { r1 }
27
+
28
+ vOneBarTabOneLineOneAlternativeOneBarTwo = { f2 g }
29
+ cBarTabOneLineOneAlternativeOneBarTwo = { }
30
+ sBarTabOneLineOneAlternativeOneBarTwo = { r1 }
31
+ %-----------------------------------------------------------------------
32
+ % Lines
33
+
34
+ vOneLineTabOneLineOne = { \repeat volta 4 { \vOneBarTabOneLineOneRepeatOneBarOne } \alternative { { \vOneBarTabOneLineOneAlternativeOneBarOne } { \vOneBarTabOneLineOneAlternativeOneBarTwo } } \break }
35
+ cLineTabOneLineOne = { \repeat volta 4 { \cBarTabOneLineOneRepeatOneBarOne } \alternative { { \cBarTabOneLineOneAlternativeOneBarOne } { \cBarTabOneLineOneAlternativeOneBarTwo } } }
36
+ sLineTabOneLineOne = { \repeat volta 4 { \sBarTabOneLineOneRepeatOneBarOne } \alternative { { \sBarTabOneLineOneAlternativeOneBarOne } { \sBarTabOneLineOneAlternativeOneBarTwo } } }
37
+ %-----------------------------------------------------------------------
38
+ % Stanzas
39
+ %-----------------------------------------------------------------------
40
+ % Scores
41
+ %-----------------------------------------------------------------------
42
+ % Voices
43
+
44
+ vOne = {
45
+ \vOneLineTabOneLineOne
46
+ }
47
+ %-----------------------------------------------------------------------
48
+ % Stanza Headings
49
+
50
+ stanzaHeadings = { \sLineTabOneLineOne }
51
+
52
+ %-----------------------------------------------------------------------
53
+ % Chord Headings
54
+
55
+ chordHeadings = { \cLineTabOneLineOne }
56
+
57
+ %-----------------------------------------------------------------------
58
+
59
+ \score {
60
+ \new StaffGroup <<
61
+ \new Staff <<
62
+ \clef "treble_8"
63
+
64
+ \new Voice \with { \remove Rest_engraver } {
65
+ \stanzaHeadings
66
+ }
67
+
68
+ \new Voice {
69
+ \voiceOne
70
+ \vOne
71
+ }
72
+ >>
73
+
74
+ \new TabStaff <<
75
+ \new TabVoice {
76
+ \slurUp
77
+ \vOne
78
+ }
79
+ \new TabVoice {
80
+ \chordHeadings
81
+ }
82
+ >>
83
+ >>
84
+
85
+ \layout {
86
+ \context { \Staff
87
+ \override TimeSignature #'style = #'numbered
88
+ \override StringNumber #'transparent = ##t
89
+ }
90
+ \context { \TabStaff
91
+ \override TimeSignature #'style = #'numbered
92
+ }
93
+ \context { \Voice
94
+ \remove Slur_engraver
95
+ }
96
+ \context { \TabVoice
97
+ \remove Dots_engraver
98
+ \remove Stem_engraver
99
+ \remove Rest_engraver
100
+ }
101
+ }
102
+ }
103
+
104
+ % showLastLength = R1*4
105
+ \score {
106
+ \new Staff \with {midiInstrument = #"acoustic guitar (nylon)"} <<
107
+ \clef "treble_8"
108
+
109
+ \new Voice {
110
+ \unfoldRepeats {
111
+ \vOne
112
+ }
113
+ }
114
+ >>
115
+
116
+ \midi {}
117
+ }