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.
- checksums.yaml +4 -4
- data/README.md +41 -1
- data/bin/lydown +2 -0
- data/lib/lydown.rb +6 -2
- data/lib/lydown/cache.rb +5 -1
- data/lib/lydown/cli.rb +1 -1
- data/lib/lydown/cli/commands.rb +7 -11
- data/lib/lydown/cli/compiler.rb +5 -0
- data/lib/lydown/cli/proofing.rb +2 -2
- data/lib/lydown/cli/repl.rb +1 -1
- data/lib/lydown/cli/support.rb +0 -33
- data/lib/lydown/defaults.yml +50 -8
- data/lib/lydown/inverso.rb +84 -0
- data/lib/lydown/lilypond.rb +76 -10
- data/lib/lydown/ly_lib/lib.ly +140 -127
- data/lib/lydown/parsing/lydown.treetop +25 -12
- data/lib/lydown/parsing/nodes.rb +55 -19
- data/lib/lydown/rendering.rb +72 -1
- data/lib/lydown/rendering/base.rb +21 -0
- data/lib/lydown/rendering/command.rb +53 -0
- data/lib/lydown/rendering/layout.rb +83 -0
- data/lib/lydown/rendering/lyrics.rb +1 -1
- data/lib/lydown/rendering/markup.rb +23 -0
- data/lib/lydown/rendering/movement.rb +7 -4
- data/lib/lydown/rendering/music.rb +35 -29
- data/lib/lydown/rendering/notes.rb +75 -41
- data/lib/lydown/rendering/repeats.rb +27 -0
- data/lib/lydown/rendering/settings.rb +36 -9
- data/lib/lydown/rendering/skipping.rb +10 -2
- data/lib/lydown/rendering/staff.rb +38 -31
- data/lib/lydown/rendering/voices.rb +1 -1
- data/lib/lydown/templates.rb +8 -8
- data/lib/lydown/templates/layout.rb +40 -0
- data/lib/lydown/templates/lilypond_doc.rb +95 -0
- data/lib/lydown/templates/movement.rb +188 -0
- data/lib/lydown/templates/multi_voice.rb +25 -0
- data/lib/lydown/templates/part.rb +146 -0
- data/lib/lydown/templates/variables.rb +43 -0
- data/lib/lydown/translation/ripple.rb +1 -1
- data/lib/lydown/translation/ripple/nodes.rb +51 -2
- data/lib/lydown/translation/ripple/ripple.treetop +87 -10
- data/lib/lydown/version.rb +1 -1
- data/lib/lydown/work.rb +19 -2
- data/lib/lydown/work_context.rb +10 -2
- metadata +12 -8
- data/lib/lydown/cli/installer.rb +0 -175
- data/lib/lydown/templates/lilypond_doc.erb +0 -34
- data/lib/lydown/templates/movement.erb +0 -118
- data/lib/lydown/templates/multi_voice.erb +0 -16
- data/lib/lydown/templates/part.erb +0 -118
- 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
|
-
(
|
14
|
-
|
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
|
18
|
-
|
19
|
+
rule no_brace_events
|
20
|
+
white_space? no_brace_event* <Root>
|
19
21
|
end
|
20
22
|
|
21
|
-
rule
|
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'
|
43
|
+
'\key' white_space+ key_note_head white_space+ key_mode <KeySignature>
|
31
44
|
end
|
32
45
|
|
33
46
|
rule key_mode
|
34
|
-
'
|
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
|