lydown 0.12.4 → 0.14.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -1
  3. data/bin/lydown +2 -0
  4. data/lib/lydown.rb +6 -2
  5. data/lib/lydown/cache.rb +5 -1
  6. data/lib/lydown/cli.rb +1 -1
  7. data/lib/lydown/cli/commands.rb +7 -11
  8. data/lib/lydown/cli/compiler.rb +5 -0
  9. data/lib/lydown/cli/proofing.rb +2 -2
  10. data/lib/lydown/cli/repl.rb +1 -1
  11. data/lib/lydown/cli/support.rb +0 -33
  12. data/lib/lydown/defaults.yml +50 -8
  13. data/lib/lydown/inverso.rb +84 -0
  14. data/lib/lydown/lilypond.rb +76 -10
  15. data/lib/lydown/ly_lib/lib.ly +140 -127
  16. data/lib/lydown/parsing/lydown.treetop +25 -12
  17. data/lib/lydown/parsing/nodes.rb +55 -19
  18. data/lib/lydown/rendering.rb +72 -1
  19. data/lib/lydown/rendering/base.rb +21 -0
  20. data/lib/lydown/rendering/command.rb +53 -0
  21. data/lib/lydown/rendering/layout.rb +83 -0
  22. data/lib/lydown/rendering/lyrics.rb +1 -1
  23. data/lib/lydown/rendering/markup.rb +23 -0
  24. data/lib/lydown/rendering/movement.rb +7 -4
  25. data/lib/lydown/rendering/music.rb +35 -29
  26. data/lib/lydown/rendering/notes.rb +75 -41
  27. data/lib/lydown/rendering/repeats.rb +27 -0
  28. data/lib/lydown/rendering/settings.rb +36 -9
  29. data/lib/lydown/rendering/skipping.rb +10 -2
  30. data/lib/lydown/rendering/staff.rb +38 -31
  31. data/lib/lydown/rendering/voices.rb +1 -1
  32. data/lib/lydown/templates.rb +8 -8
  33. data/lib/lydown/templates/layout.rb +40 -0
  34. data/lib/lydown/templates/lilypond_doc.rb +95 -0
  35. data/lib/lydown/templates/movement.rb +188 -0
  36. data/lib/lydown/templates/multi_voice.rb +25 -0
  37. data/lib/lydown/templates/part.rb +146 -0
  38. data/lib/lydown/templates/variables.rb +43 -0
  39. data/lib/lydown/translation/ripple.rb +1 -1
  40. data/lib/lydown/translation/ripple/nodes.rb +51 -2
  41. data/lib/lydown/translation/ripple/ripple.treetop +87 -10
  42. data/lib/lydown/version.rb +1 -1
  43. data/lib/lydown/work.rb +19 -2
  44. data/lib/lydown/work_context.rb +10 -2
  45. metadata +12 -8
  46. data/lib/lydown/cli/installer.rb +0 -175
  47. data/lib/lydown/templates/lilypond_doc.erb +0 -34
  48. data/lib/lydown/templates/movement.erb +0 -118
  49. data/lib/lydown/templates/multi_voice.erb +0 -16
  50. data/lib/lydown/templates/part.erb +0 -118
  51. data/lib/lydown/templates/variables.erb +0 -43
@@ -0,0 +1,25 @@
1
+ beaming_mode = Lydown::Rendering::Staff.beaming_mode(context,
2
+ context.current_setting_opts)
3
+ voice_prefix = part.nil? || (part == "") ? nil : "#{part}_"
4
+
5
+ `
6
+ <<
7
+ `
8
+
9
+ context['process/voices'].each do |voice, stream|
10
+ `
11
+ {{? voice != 'voice1' }}
12
+ \new Voice = "{{voice_prefix}}{{voice}}"
13
+ {{/}}
14
+
15
+ {
16
+ {{beaming_mode}}
17
+ {{Lydown::Rendering::VoiceSelect.voice_command(voice)}}
18
+ {{stream['music']}}
19
+ }
20
+ `
21
+ end
22
+ `
23
+ >>
24
+ \oneVoice
25
+ `
@@ -0,0 +1,146 @@
1
+ render_mode = context.render_mode
2
+
3
+ setting_opts = {movement: movement_name, part: name}
4
+
5
+ inline_part_title = nil
6
+ if name && (name != '')
7
+ part_title = Lydown::Rendering::Staff.part_title(context, setting_opts)
8
+ voice_prefix = "#{name}_"
9
+ else
10
+ part_title = "#\"\""
11
+ voice_prefix = nil
12
+ end
13
+ staff_id = Lydown::Rendering::Staff.staff_id(name)
14
+
15
+ score_mode = render_mode == :score
16
+
17
+ clef = Lydown::Rendering::Staff.clef(context, setting_opts)
18
+ prevent_remove_empty = Lydown::Rendering::Staff.prevent_remove_empty(context, setting_opts)
19
+
20
+ midi_mode = (context['render_opts/format'] == 'midi') ||
21
+ (context['render_opts/format'] == 'mp3')
22
+ midi_instrument = midi_mode && Lydown::Rendering::Staff.midi_instrument(name)
23
+
24
+ beaming_mode = Lydown::Rendering::Staff.beaming_mode(context, setting_opts)
25
+ partial = context.get_setting(:pickup, setting_opts)
26
+ partial = partial ? "\\partial #{partial}" : ""
27
+
28
+ end_barline = Lydown::Rendering::Staff.end_barline(context, setting_opts)
29
+
30
+ time = context.get_setting(:time, setting_opts)
31
+ cadenza = time == 'unmetered'
32
+
33
+ skip_bars = (render_mode == :proof) || (render_mode == :part)
34
+
35
+ instrument_names = context.get_setting(:instrument_names, setting_opts)
36
+ hide_instrument_names =
37
+ (instrument_names == 'hide') ||
38
+ (instrument_names =~ /^inline\-?(.+)?$/)
39
+
40
+ if instrument_names =~ /^inline\-?(.+)?$/
41
+ alignment = $1 && "\\#{$1}"
42
+ inline_part_title = Lydown::Rendering::Staff.inline_part_title(
43
+ context, setting_opts.merge(alignment: alignment)
44
+ )
45
+ end
46
+
47
+ layout = Lydown::Rendering.layout_info(context, setting_opts)
48
+ show_original_clef = score_mode && (layout[:original_clefs] == 'show')
49
+ original_clef = context.get_setting(:original_clef, setting_opts)
50
+
51
+ `
52
+ <<
53
+
54
+ \new Staff = {{staff_id}} \with {
55
+ {{? prevent_remove_empty }}
56
+ \override VerticalAxisGroup.remove-empty = ##f
57
+ {{/}}
58
+
59
+ {{? size = context.get_setting(:staff_size, setting_opts)}}
60
+ fontSize = #{{ size }}
61
+ \override StaffSymbol.staff-space = #(magstep {{ size }})
62
+ {{/}}
63
+
64
+ }
65
+
66
+ \context Staff = {{staff_id}} {
67
+ {{? skip_bars }}
68
+ \set Score.skipBars = ##t
69
+ {{/}}
70
+
71
+ {{? tempo = context.get_setting(:tempo, setting_opts)}}
72
+ \tempo "{{tempo}}"
73
+ {{/}}
74
+
75
+ {{? score_mode && !hide_instrument_names}}
76
+ \set Staff.instrumentName = {{part_title}}
77
+ {{/}}
78
+
79
+ {{? show_original_clef && original_clef }}
80
+ \incipit { \omit MensuralStaff.TimeSignature \clef "{{original_clef}}" s4 }
81
+ {{/}}
82
+ {{? show_original_clef && !original_clef }}
83
+ \incipit { \override MensuralStaff.StaffSymbol.color = #(rgb-color 1 1 1)
84
+ \omit MensuralStaff.TimeSignature \omit MensuralStaff.Clef s4 }
85
+ {{/}}
86
+
87
+ {{? midi_instrument}}
88
+ \set Staff.midiInstrument = #"{{midi_instrument}}"
89
+ {{/}}
90
+
91
+ {{? clef}}
92
+ \clef "{{clef}}"
93
+ {{/}}
94
+
95
+ {{partial}}
96
+
97
+ {{? score_mode && inline_part_title}}
98
+ {{inline_part_title}}
99
+ {{/}}
100
+
101
+ {{beaming_mode}}
102
+
103
+ {{? t = context.get_setting(:transpose, setting_opts)}}
104
+ \transpose {{t}}
105
+ {{/}}
106
+
107
+ \{{Lydown::Rendering.variable_name(setting_opts.merge(stream: :music))}}
108
+
109
+ {{? end_barline}}
110
+ \bar "{{end_barline}}"
111
+ {{/}}
112
+ }
113
+ `
114
+
115
+ if part['lyrics']
116
+ multi_voice = part['lyrics'].size > 1
117
+ part['lyrics'].each_key do |voice|
118
+ above_staff = multi_voice && ['voice1', 'voice3'].include?(voice)
119
+ part['lyrics'][voice].keys.sort.each do |idx|
120
+ var_name = Lydown::Rendering.variable_name(setting_opts.merge(
121
+ stream: :lyrics, voice: voice, idx: idx))
122
+ `
123
+ \new Lyrics \with {
124
+ {{? above_staff}}
125
+ alignAboveContext = "{{staff_id}}"
126
+ {{/}}
127
+ {{? size = context.get_setting(:staff_size, setting_opts)}}
128
+ fontSize = #{{ size }}
129
+ {{/}}
130
+ }
131
+ { \lyricsto "{{voice_prefix}}{{voice}}" { \{{var_name}} } }
132
+ `
133
+ end
134
+ end
135
+ end
136
+
137
+ if part['figures']
138
+ var_name = Lydown::Rendering.variable_name(setting_opts.merge(stream: :figures))
139
+ `
140
+ \new FiguredBass { \{{var_name}} }
141
+ `
142
+ end
143
+
144
+ `
145
+ >>
146
+ `
@@ -0,0 +1,43 @@
1
+ var_name = lambda {|opts| Lydown::Rendering.variable_name(opts)}
2
+ context['movements'].each do |mvt_name, mvt|
3
+ mvt['parts'].each do |part_name, part|
4
+ var_opts = {movement: mvt_name, part: part_name}
5
+ notation_size = context.get_setting(:notation_size, var_opts)
6
+ notation_size = "\\#{notation_size}" if notation_size
7
+
8
+ if part_name && !part_name.empty?
9
+ voice_prefix = "#{part_name}_"
10
+ else
11
+ voice_prefix = nil
12
+ end
13
+
14
+ `
15
+ {{var_name[var_opts.merge(stream: :music)]}} = \relative c {
16
+ <<
17
+ \new Voice = "{{voice_prefix}}voice1" {
18
+ {{notation_size}}
19
+ {{part['music']}}
20
+ }
21
+ >>
22
+ }
23
+ `
24
+
25
+ if part['lyrics']
26
+ part['lyrics'].each do |voice, voice_lyrics|
27
+ voice_lyrics.each do |idx, lyrics|
28
+ opts = var_opts.merge(stream: :lyrics, voice: voice, idx: idx)
29
+ `
30
+ {{var_name[opts]}} = \lyricmode { {{lyrics}} }
31
+ `
32
+ end
33
+ end
34
+ end
35
+
36
+ if part['figures']
37
+ `
38
+ {{var_name[var_opts.merge(stream: :figures)]}} =
39
+ \figuremode { {{part['figures']}} }
40
+ `
41
+ end
42
+ end
43
+ end
@@ -24,7 +24,7 @@ class RippleParser
24
24
 
25
25
  def self.format_parser_error(source, parser, opts)
26
26
  msg = "#{parser.failure_reason} at #{parser.failure_line}:#{parser.failure_column}\n"
27
- msg << " #{source.lines[parser.failure_line - 1].chomp}\n #{' ' * parser.failure_column}^"
27
+ # msg << " #{source.lines[parser.failure_line - 1].chomp}\n #{' ' * parser.failure_column}^"
28
28
  msg
29
29
  end
30
30
  end
@@ -68,6 +68,10 @@ module Lydown::Translation::Ripple
68
68
  note[:duration] ||= opts[:post_macro_value]
69
69
  opts[:post_macro_value] = nil
70
70
  end
71
+
72
+ if note[:duration] && note[:grace]
73
+ note[:duration] += note[:grace]
74
+ end
71
75
 
72
76
  stream << "%s%s%s" % [
73
77
  note[:duration],
@@ -76,6 +80,12 @@ module Lydown::Translation::Ripple
76
80
  ]
77
81
  end
78
82
 
83
+ class Grace < Root
84
+ def translate(note, opts)
85
+ note[:grace] = text_value
86
+ end
87
+ end
88
+
79
89
  class Head < Root
80
90
  def translate(note, opts)
81
91
  head = text_value.dup
@@ -96,7 +106,13 @@ module Lydown::Translation::Ripple
96
106
  note[:duration] = text_value
97
107
  end
98
108
  end
99
-
109
+
110
+ class Articulation < Root
111
+ def translate(note, opts)
112
+ note[:expressions] << text_value
113
+ end
114
+ end
115
+
100
116
  class Expression < Root
101
117
  def translate(note, opts)
102
118
  note[:expressions] << text_value
@@ -108,7 +124,7 @@ module Lydown::Translation::Ripple
108
124
  def translate(stream, opts)
109
125
  signature = {}
110
126
  _translate(self, signature, opts)
111
- opts[:key] = "#{signature[:head]} #{signature[:mode]}"
127
+ opts[:key] = "#{signature[:head]} #{signature[:mode]}".strip
112
128
  stream << "- key: #{opts[:key]}\n"
113
129
  end
114
130
 
@@ -188,4 +204,37 @@ module Lydown::Translation::Ripple
188
204
  stream << " #{cmd} "
189
205
  end
190
206
  end
207
+
208
+ class Noop < Root
209
+ def translate(stream, opts)
210
+ # noop
211
+ end
212
+ end
213
+
214
+ class Repeat < Root
215
+ def translate(stream, opts)
216
+ _translate(self, stream, opts)
217
+ stream << "*| "
218
+ end
219
+
220
+ class Start < Root
221
+ def translate(stream, opts)
222
+ stream << "|:*2 "
223
+ _translate(self, stream, opts)
224
+ end
225
+ end
226
+
227
+ class Alternative < Root
228
+ def translate(stream, opts)
229
+ stream << "|* "
230
+ _translate(self, stream, opts)
231
+ end
232
+ end
233
+ end
234
+
235
+ class Barline < Root
236
+ def translate(stream, opts)
237
+ stream << " #{text_value} "
238
+ end
239
+ end
191
240
  end
@@ -10,15 +10,28 @@ grammar Ripple
10
10
  end
11
11
 
12
12
  rule event
13
- (relative_cmd / curly_brace / key_signature / time_signature /
14
- full_rest / note / phrasing / named_macro / stop_macro / command) white_space?
13
+ (relative_command / repeat / curly_brace / key_signature / time_signature /
14
+ tempo_command / partial_command / full_rest / note / phrasing / named_macro / stop_macro /
15
+ noop / barline / command / comment
16
+ ) white_space?
15
17
  end
16
18
 
17
- rule relative_cmd
18
- '\relative' [\s]+ relative_cmd_note
19
+ rule no_brace_events
20
+ white_space? no_brace_event* <Root>
19
21
  end
20
22
 
21
- rule relative_cmd_note
23
+ rule no_brace_event
24
+ (key_signature / time_signature / partial_command /
25
+ tempo_command / full_rest / note / phrasing / named_macro / stop_macro /
26
+ noop / barline / command / comment
27
+ ) white_space?
28
+ end
29
+
30
+ rule relative_command
31
+ '\relative' [\s]+ relative_command_note
32
+ end
33
+
34
+ rule relative_command_note
22
35
  [a-g] accidental? octave* <RelativeCommand>
23
36
  end
24
37
 
@@ -27,21 +40,29 @@ grammar Ripple
27
40
  end
28
41
 
29
42
  rule key_signature
30
- '\key' [\s]+ note_head [\s+] key_mode <KeySignature>
43
+ '\key' white_space+ key_note_head white_space+ key_mode <KeySignature>
31
44
  end
32
45
 
33
46
  rule key_mode
34
- '\major' / '\minor' <KeySignature::Mode>
47
+ '\\' ('major' / 'minor') <KeySignature::Mode>
35
48
  end
36
49
 
37
50
  rule note
38
- note_head duration? expression* <Note>
51
+ grace? note_head duration? articulation* expression* <Note>
52
+ end
53
+
54
+ rule grace
55
+ [\^] <Note::Grace>
39
56
  end
40
57
 
41
58
  rule note_head
42
59
  [a-gr] accidental octave* accidental_flag? <Note::Head>
43
60
  end
44
61
 
62
+ rule key_note_head
63
+ [a-g] accidental <Note::Head>
64
+ end
65
+
45
66
  rule octave
46
67
  [,']+
47
68
  end
@@ -58,8 +79,12 @@ grammar Ripple
58
79
  [0-9]+ '.'* <Note::Duration>
59
80
  end
60
81
 
82
+ rule articulation
83
+ '-' [\+] <Note::Articulation>
84
+ end
85
+
61
86
  rule expression
62
- '\\' [a-zA-Z]+ <Note::Expression>
87
+ '_'? '\\' [a-zA-Z]+ <Note::Expression>
63
88
  end
64
89
 
65
90
  rule time_signature
@@ -70,8 +95,12 @@ grammar Ripple
70
95
  [0-9\/]+ <TimeSignature>
71
96
  end
72
97
 
98
+ rule partial_command
99
+ '\partial' white_space [0-9]+
100
+ end
101
+
73
102
  rule full_rest
74
- 'R' [0-9]+ ('*' [0-9]+)? <FullRest>
103
+ 'R' [0-9\.]+ ('*' [0-9]+)? <FullRest>
75
104
  end
76
105
 
77
106
  rule phrasing
@@ -97,4 +126,52 @@ grammar Ripple
97
126
  rule clef_command
98
127
  '\clef ' [a-z0-9_]+ <Command>
99
128
  end
129
+
130
+ rule tempo_command
131
+ '\tempo "' [^"]+ '"' <Noop>
132
+ end
133
+
134
+ rule noop
135
+ midi_block
136
+ end
137
+
138
+ rule midi_block
139
+ 'm{{' [^\}]+ '}}' <Noop>
140
+ end
141
+
142
+ rule repeat
143
+ repeat_start white_space? repeat_alternatives <Repeat>
144
+ end
145
+
146
+ rule repeat_start
147
+ repeat_start_prefix no_brace_events repeat_start_postfix <Repeat::Start>
148
+ end
149
+
150
+ rule repeat_start_prefix
151
+ '\repeat volta 2' white_space? '{'
152
+ end
153
+
154
+ rule repeat_start_postfix
155
+ '}' white_space?
156
+ end
157
+
158
+ rule repeat_alternatives
159
+ '\alternative' white_space? '{' repeat_alternative+ '}' <Root>
160
+ end
161
+
162
+ rule repeat_alternative
163
+ white_space? '{' no_brace_events '}' white_space? <Repeat::Alternative>
164
+ end
165
+
166
+ rule comment
167
+ '%' [^\n]*
168
+ end
169
+
170
+ rule barline
171
+ '\bar "'? barline_sign '"'?
172
+ end
173
+
174
+ rule barline_sign
175
+ '?|' / ':|][|:' / '[|:' / ':|]' / [\|\.\:]+ <Barline>
176
+ end
100
177
  end