lydown 0.12.4 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/lydown/lilypond.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'lydown/errors'
|
2
2
|
require 'lydown/cli/output'
|
3
|
+
require 'lydown/cli/signals'
|
3
4
|
|
4
5
|
require 'tempfile'
|
5
6
|
require 'fileutils'
|
@@ -8,6 +9,49 @@ require 'open3'
|
|
8
9
|
module Lydown
|
9
10
|
module Lilypond
|
10
11
|
class << self
|
12
|
+
MINIMAL_LILYPOND_VERSION = Gem::Version.new('2.18')
|
13
|
+
|
14
|
+
def lilypond_path
|
15
|
+
# detect lyp-installed lilypond
|
16
|
+
# path = `lyp which lilypond`.lines.last rescue nil
|
17
|
+
# return path.chomp if path
|
18
|
+
#
|
19
|
+
# path = `which lilypond` rescue nil
|
20
|
+
# return path.chomp if path && !path.empty?
|
21
|
+
|
22
|
+
return 'lilypond'
|
23
|
+
end
|
24
|
+
|
25
|
+
# detect the lilypond version. If lilypond is not found, or the version is
|
26
|
+
# less than the minimal supported version, display an error message.
|
27
|
+
def detect_lilypond_version(exit_on_error)
|
28
|
+
version = nil
|
29
|
+
if path = lilypond_path
|
30
|
+
msg = `#{lilypond_path} --version`
|
31
|
+
if msg.lines.first =~ /LilyPond ([\d\.]+)/
|
32
|
+
version = $1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
unless version && Gem::Version.new(version) >= MINIMAL_LILYPOND_VERSION
|
37
|
+
display_lilypond_version_error_msg(version)
|
38
|
+
exit!(1) if exit_on_error
|
39
|
+
version = nil
|
40
|
+
end
|
41
|
+
version
|
42
|
+
rescue => e
|
43
|
+
display_lilypond_version_error_msg(nil)
|
44
|
+
exit!(1) if exit_on_error
|
45
|
+
end
|
46
|
+
|
47
|
+
def display_lilypond_version_error_msg(version)
|
48
|
+
if version
|
49
|
+
STDERR.puts "ERROR: The installed lilypond (version #{version}) is too old."
|
50
|
+
else
|
51
|
+
STDERR.puts "ERROR: No copy of lilypond found."
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
11
55
|
def tmpdir
|
12
56
|
@tmpdir ||= Dir.mktmpdir
|
13
57
|
end
|
@@ -67,14 +111,30 @@ module Lydown
|
|
67
111
|
end
|
68
112
|
end
|
69
113
|
|
114
|
+
# In order to be able to run the lyp lilypond wrapper (if present),
|
115
|
+
# we need to reset the environment variables set by bundler when running
|
116
|
+
# lydown.
|
117
|
+
RESET_ENV = {
|
118
|
+
"_ORIGINAL_GEM_PATH" => "",
|
119
|
+
"BUNDLE_GEMFILE" => "",
|
120
|
+
"BUNDLE_BIN_PATH" => "",
|
121
|
+
"RUBYOPT" => "",
|
122
|
+
"RUBYLIB" => ""
|
123
|
+
}
|
124
|
+
|
70
125
|
# Run lilypond, pipe source into its STDIN, and capture its STDERR
|
71
126
|
def invoke(source, opts = {})
|
72
|
-
|
127
|
+
tmp_source_path = Tempfile.new('lydown').path
|
128
|
+
File.open(tmp_source_path, 'w') {|f| f << source}
|
129
|
+
|
130
|
+
cmd = format_cmd(opts, tmp_source_path)
|
131
|
+
puts cmd if opts[:verbose]
|
73
132
|
|
74
133
|
err_info = ''
|
75
134
|
exit_value = nil
|
76
|
-
|
77
|
-
|
135
|
+
|
136
|
+
Open3.popen2e(RESET_ENV, cmd) do |input, output, wait_thr|
|
137
|
+
err_info = exec(wait_thr, input, output, opts)
|
78
138
|
exit_value = wait_thr.value
|
79
139
|
end
|
80
140
|
if exit_value != 0
|
@@ -87,23 +147,23 @@ module Lydown
|
|
87
147
|
end
|
88
148
|
end
|
89
149
|
|
90
|
-
def format_cmd(opts)
|
150
|
+
def format_cmd(opts, source_path)
|
91
151
|
format = opts[:format]
|
92
152
|
format = nil if (format == :midi) || (format == :mp3)
|
93
153
|
|
94
|
-
cmd =
|
95
|
-
cmd << "-dbackend=eps " if opts[:mode] == :proof
|
154
|
+
cmd = "#{lilypond_path} "
|
155
|
+
# cmd << "-dbackend=eps " if opts[:mode] == :proof
|
96
156
|
cmd << "-o #{opts[:output_filename]} "
|
97
157
|
cmd << "-dno-point-and-click "
|
98
158
|
cmd << "--#{opts[:format]} " if format
|
99
|
-
cmd <<
|
159
|
+
cmd << "-V " if opts[:verbose]
|
160
|
+
cmd << source_path
|
100
161
|
|
101
162
|
cmd
|
102
163
|
end
|
103
164
|
|
104
|
-
def exec(wait_thr, input, output,
|
165
|
+
def exec(wait_thr, input, output, opts)
|
105
166
|
Lydown::CLI.register_abortable_process(wait_thr.pid)
|
106
|
-
input.puts source
|
107
167
|
input.close_write
|
108
168
|
err_info = read_lilypond_progress(output, opts)
|
109
169
|
output.close
|
@@ -128,7 +188,7 @@ module Lydown
|
|
128
188
|
|
129
189
|
def read_lilypond_progress(f, opts)
|
130
190
|
info = ''
|
131
|
-
|
191
|
+
if !opts[:verbose] && !opts[:no_progress_bar]
|
132
192
|
Lydown::CLI::show_progress('Compile', STATUS_TOTAL) do |bar|
|
133
193
|
while !f.eof?
|
134
194
|
line = f.gets
|
@@ -140,6 +200,12 @@ module Lydown
|
|
140
200
|
end
|
141
201
|
bar.progress = STATUS_TOTAL
|
142
202
|
end
|
203
|
+
elsif opts[:verbose]
|
204
|
+
while !f.eof?
|
205
|
+
line = f.gets
|
206
|
+
STDERR.puts line
|
207
|
+
info += line
|
208
|
+
end
|
143
209
|
else
|
144
210
|
info = f.read
|
145
211
|
end
|
data/lib/lydown/ly_lib/lib.ly
CHANGED
@@ -1,53 +1,53 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
#(define-markup-command (mm-feed layout props amount) (number?)
|
2
|
+
(let ((o-s (ly:output-def-lookup layout 'output-scale)))
|
3
|
+
(ly:make-stencil "" '(0 . 0) (cons 0 (abs (/ amount o-s))))))
|
4
4
|
|
5
5
|
segno = {
|
6
|
-
\once \override Score.RehearsalMark
|
6
|
+
\once \override Score.RehearsalMark.font-size = #-2
|
7
7
|
\mark \markup { \musicglyph #"scripts.segno" }
|
8
8
|
}
|
9
9
|
|
10
10
|
segnobottom = {
|
11
|
-
\once \override Score.RehearsalMark
|
12
|
-
\once \override Score.RehearsalMark
|
11
|
+
\once \override Score.RehearsalMark.direction = #DOWN
|
12
|
+
\once \override Score.RehearsalMark.font-size = #-2
|
13
13
|
\mark \markup { \musicglyph #"scripts.segno" }
|
14
14
|
}
|
15
15
|
|
16
16
|
dalsegno = {
|
17
|
-
\once \override Score.RehearsalMark
|
18
|
-
\once \override Score.RehearsalMark
|
19
|
-
\once \override Score.RehearsalMark
|
20
|
-
\once \override Score.RehearsalMark
|
17
|
+
\once \override Score.RehearsalMark.break-visibility = #begin-of-line-invisible
|
18
|
+
\once \override Score.RehearsalMark.direction = #DOWN
|
19
|
+
\once \override Score.RehearsalMark.self-alignment-X = #RIGHT
|
20
|
+
\once \override Score.RehearsalMark.font-size = #-2
|
21
21
|
\mark \markup { \fontsize #2 {"dal segno "} \musicglyph #"scripts.segno" }
|
22
22
|
}
|
23
23
|
|
24
24
|
dacapo = {
|
25
|
-
\once \override Score.RehearsalMark
|
26
|
-
\once \override Score.RehearsalMark
|
27
|
-
\once \override Score.RehearsalMark
|
25
|
+
\once \override Score.RehearsalMark.break-visibility = #begin-of-line-invisible
|
26
|
+
\once \override Score.RehearsalMark.direction = #DOWN
|
27
|
+
\once \override Score.RehearsalMark.self-alignment-X = #RIGHT
|
28
28
|
\mark \markup {\bold {\italic {"Da capo"}}}
|
29
29
|
}
|
30
30
|
|
31
31
|
dalsegnoadlib = {
|
32
|
-
\once \override Score.RehearsalMark
|
33
|
-
\once \override Score.RehearsalMark
|
34
|
-
\once \override Score.RehearsalMark
|
32
|
+
\once \override Score.RehearsalMark.direction = #DOWN
|
33
|
+
\once \override Score.RehearsalMark.self-alignment-X = #LEFT
|
34
|
+
\once \override Score.RehearsalMark.font-size = #-2
|
35
35
|
\mark \markup { \musicglyph #"scripts.segno" ad lib }
|
36
36
|
}
|
37
37
|
|
38
38
|
finedellaparteprima = {
|
39
|
-
\once \override Score.RehearsalMark
|
40
|
-
\once \override Score.RehearsalMark
|
41
|
-
\once \override Score.RehearsalMark
|
39
|
+
\once \override Score.RehearsalMark.break-visibility = #begin-of-line-invisible
|
40
|
+
\once \override Score.RehearsalMark.direction = #DOWN
|
41
|
+
\once \override Score.RehearsalMark.self-alignment-X = #RIGHT
|
42
42
|
\mark \markup {\bold {\italic {"Fine della parte prima"}}}
|
43
43
|
}
|
44
44
|
|
45
45
|
padbarlinebefore = {
|
46
|
-
\once \override Staff.BarLine
|
46
|
+
\once \override Staff.BarLine.extra-spacing-width = #'(-2 . 0)
|
47
47
|
}
|
48
48
|
|
49
49
|
padbarlineafter = {
|
50
|
-
\once \override Staff.BarLine
|
50
|
+
\once \override Staff.BarLine.extra-spacing-width = #'(0 . 2)
|
51
51
|
}
|
52
52
|
|
53
53
|
editF = \markup { \center-align \concat { \bold { \italic ( }
|
@@ -63,7 +63,8 @@ fort = \markup { \center-align \bold { \italic fort }}
|
|
63
63
|
ten = \markup { \italic ten. }
|
64
64
|
|
65
65
|
ficta = {
|
66
|
-
\once \override AccidentalSuggestion
|
66
|
+
\once \override AccidentalSuggestion.avoid-slur = #'outside
|
67
|
+
\once \override AccidentalSuggestion.parenthesized = ##t
|
67
68
|
\once \set suggestAccidentals = ##t
|
68
69
|
}
|
69
70
|
|
@@ -84,99 +85,6 @@ ficta = {
|
|
84
85
|
#f))))
|
85
86
|
|
86
87
|
|
87
|
-
\layout {
|
88
|
-
#(layout-set-staff-size 17)
|
89
|
-
indent = 0\cm
|
90
|
-
|
91
|
-
\context {
|
92
|
-
\Score
|
93
|
-
\override InstrumentName #'self-alignment-X = #right
|
94
|
-
\override InstrumentName #'padding = 0.6
|
95
|
-
|
96
|
-
\override BarNumber #'padding = 1.5
|
97
|
-
|
98
|
-
%make note stems a bit thicker
|
99
|
-
\override Stem.thickness = #2
|
100
|
-
|
101
|
-
% slurs and ties are a bit curvier and thicker
|
102
|
-
% ties are also a bit more distant from note heads
|
103
|
-
% all that with a bit of randomness
|
104
|
-
\override Slur.eccentricity = #(lambda (grob) (* 0.05 (random:normal)))
|
105
|
-
\override Slur.height-limit = #(lambda (grob) (+ 2.8 (* 0.2 (random:normal))))
|
106
|
-
\override Slur.thickness = #(lambda (grob) (+ 2.9 (* 0.1 (random:normal))))
|
107
|
-
\override Slur.ratio = #(lambda (grob) (+ 0.3 (* 0.05 (random:normal))))
|
108
|
-
|
109
|
-
\override Tie.thickness = #(lambda (grob) (+ 2.9 (* 0.1 (random:normal))))
|
110
|
-
\override Tie.ratio = #(lambda (grob) (+ 0.3 (* 0.05 (random:normal))))
|
111
|
-
\override Tie #'details #'note-head-gap = #(lambda (grob) (+ 0.5 (* 0.1 (random:normal))))
|
112
|
-
|
113
|
-
\override Beam.beam-thickness = #(lambda (grob) (+ 0.55 (* 0.02 (random:normal))))
|
114
|
-
\override Beam.length-fraction = #1.15
|
115
|
-
|
116
|
-
% \remove "Bar_number_engraver"
|
117
|
-
}
|
118
|
-
|
119
|
-
\context {
|
120
|
-
\Staff
|
121
|
-
\override StaffSymbol.color = #(rgb-color 0.25 0.2 0.2)
|
122
|
-
|
123
|
-
}
|
124
|
-
|
125
|
-
\context {
|
126
|
-
\Lyrics
|
127
|
-
% candidates: Georgia, Hoefler Text, Hoefler Text Italic,
|
128
|
-
%
|
129
|
-
\override LyricText #'font-name = #"Hoefler Text"
|
130
|
-
% \override LyricText #'font-size = #3
|
131
|
-
}
|
132
|
-
|
133
|
-
\context {
|
134
|
-
\override MarkupText #'font-name = #"Hoefler Text"
|
135
|
-
}
|
136
|
-
}
|
137
|
-
|
138
|
-
\paper {
|
139
|
-
% #(set-default-paper-size "A5")
|
140
|
-
|
141
|
-
% system-system-spacing #'basic-distance = #17
|
142
|
-
|
143
|
-
top-margin = 1.4\cm
|
144
|
-
bottom-margin = 1.4\cm
|
145
|
-
two-sided = ##t
|
146
|
-
inner-margin = 1.4\cm
|
147
|
-
outer-margin = 2\cm
|
148
|
-
|
149
|
-
markup-system-spacing #'padding = #3
|
150
|
-
markup-system-spacing #'stretchability = #10
|
151
|
-
score-markup-spacing #'padding = #7
|
152
|
-
top-system-spacing #'padding = #3
|
153
|
-
top-markup-spacing #'padding = #3
|
154
|
-
system-system-spacing #'minimum-distance = #9
|
155
|
-
system-system-spacing #'stretchability = #15
|
156
|
-
|
157
|
-
|
158
|
-
% ragged-last-bottom = ##t
|
159
|
-
ragged-bottom = ##t
|
160
|
-
|
161
|
-
print-first-page-number = ##f
|
162
|
-
|
163
|
-
oddHeaderMarkup = \markup
|
164
|
-
\fill-line {
|
165
|
-
%% force the header to take some space, otherwise the
|
166
|
-
%% page layout becomes a complete mess.
|
167
|
-
" "
|
168
|
-
% \on-the-fly #not-first-page {
|
169
|
-
\on-the-fly #print-page-number-check-first \fromproperty #'page:page-number-string
|
170
|
-
% }
|
171
|
-
}
|
172
|
-
|
173
|
-
evenHeaderMarkup = \markup
|
174
|
-
\fill-line {
|
175
|
-
\on-the-fly #print-page-number-check-first \fromproperty #'page:page-number-string
|
176
|
-
" "
|
177
|
-
}
|
178
|
-
|
179
|
-
}
|
180
88
|
|
181
89
|
% trill = #(make-articulation "stopped")
|
182
90
|
trillSharp = #(make-articulation "trillSharp")
|
@@ -277,21 +185,126 @@ prallupbefore = {
|
|
277
185
|
(markup #:fontsize 0 fig-markup)
|
278
186
|
empty-markup)))
|
279
187
|
|
280
|
-
\layout {
|
188
|
+
\layout {
|
281
189
|
\context {
|
282
190
|
\FiguredBass
|
283
191
|
figuredBassFormatter = #better-format-bass-figure
|
284
|
-
% \override BassFigure
|
285
|
-
% \override BassFigure
|
192
|
+
% \override BassFigure.font-size = #-1
|
193
|
+
% \override BassFigure.font-name = #"Georgia"
|
286
194
|
}
|
287
195
|
|
288
|
-
% \context {
|
289
|
-
% \StaffGroup
|
290
|
-
% \override StaffGrouper.staff-staff-spacing =
|
291
|
-
% #'((basic-distance . 10)
|
292
|
-
% (minimum-distance . 7)
|
293
|
-
% (padding . 0)
|
294
|
-
% (stretchability . 7))
|
295
|
-
%
|
296
|
-
% }
|
297
196
|
}
|
197
|
+
|
198
|
+
#(define-markup-command (when-property layout props symbol markp) (symbol?
|
199
|
+
markup?)
|
200
|
+
(if (chain-assoc-get symbol props)
|
201
|
+
(interpret-markup layout props markp)
|
202
|
+
(ly:make-stencil empty-stencil)))
|
203
|
+
|
204
|
+
#(define-markup-command (apply-fromproperty layout props fn symbol)
|
205
|
+
(procedure? symbol?)
|
206
|
+
(let ((m (chain-assoc-get symbol props)))
|
207
|
+
(if (markup? m)
|
208
|
+
(interpret-markup layout props (fn m))
|
209
|
+
empty-stencil)))
|
210
|
+
|
211
|
+
\header { tagline = ##f } % no tagline
|
212
|
+
|
213
|
+
setVerticalMargins = #(define-scheme-function
|
214
|
+
(parser location top-staff top-markup bottom) (number? number? number?)
|
215
|
+
#{
|
216
|
+
\paper {
|
217
|
+
top-system-spacing.basic-distance = #top-staff
|
218
|
+
top-system-spacing.minimum-distance = #top-staff
|
219
|
+
top-system-spacing.padding = -100 % negative padding to ignore skyline
|
220
|
+
top-system-spacing.stretchability = 0 % fixed position
|
221
|
+
|
222
|
+
top-markup-spacing.basic-distance = #top-markup
|
223
|
+
top-markup-spacing.minimum-distance = #top-markup
|
224
|
+
top-markup-spacing.padding = -100 % negative padding to ignore skyline
|
225
|
+
top-markup-spacing.stretchability = 0 % fixed position
|
226
|
+
|
227
|
+
last-bottom-spacing.basic-distance = #bottom
|
228
|
+
last-bottom-spacing.minimum-distance = #bottom
|
229
|
+
last-bottom-spacing.padding = -100 % negative padding to ignore skyline
|
230
|
+
last-bottom-spacing.stretchability = 0 % fixed position
|
231
|
+
}
|
232
|
+
#}
|
233
|
+
)
|
234
|
+
|
235
|
+
halfBarline = {
|
236
|
+
\once \hide Score.SpanBar
|
237
|
+
\once \override Score.BarLine.bar-extent = #'(-1 . 1)
|
238
|
+
\noBreak
|
239
|
+
\bar "|"
|
240
|
+
}
|
241
|
+
|
242
|
+
scoreMode = #(define-void-function (parser location music) (scheme?)
|
243
|
+
(if (eq? lydown:render-mode 'score)
|
244
|
+
#{ #music #}
|
245
|
+
))
|
246
|
+
|
247
|
+
partMode = #(define-music-function (parser location music) (ly:music?)
|
248
|
+
(if (eq? lydown:render-mode 'part)
|
249
|
+
#{ #music #}
|
250
|
+
#{ #}
|
251
|
+
))
|
252
|
+
|
253
|
+
#(define lydown:score-mode (eq? lydown:render-mode 'score))
|
254
|
+
#(define lydown:part-mode (eq? lydown:render-mode 'part))
|
255
|
+
|
256
|
+
\layout {
|
257
|
+
% The OrchestraGroup is used in score mode as a wrapping context for staff
|
258
|
+
% groups. It is based on the ChoirStaff in order to allow individual span
|
259
|
+
% bars.
|
260
|
+
\context {
|
261
|
+
\ChoirStaff
|
262
|
+
\name "OrchestraGroup"
|
263
|
+
\accepts StaffGroup
|
264
|
+
systemStartDelimiter = #'SystemStartBar
|
265
|
+
}
|
266
|
+
|
267
|
+
\context {
|
268
|
+
\Score
|
269
|
+
\accepts OrchestraGroup
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
273
|
+
tacetScore = {
|
274
|
+
\new Staff \with {
|
275
|
+
\override StaffSymbol.staff-space = 0.001
|
276
|
+
\override StaffSymbol.line-count = 1
|
277
|
+
\override StaffSymbol.thickness = 0
|
278
|
+
\override StaffSymbol.color = #(rgb-color 1 1 1)
|
279
|
+
\remove "Time_signature_engraver"
|
280
|
+
\remove "Clef_engraver"
|
281
|
+
}
|
282
|
+
{ s4 }
|
283
|
+
}
|
284
|
+
|
285
|
+
% Shaping commands
|
286
|
+
|
287
|
+
sR = #(define-music-function (parser location r) (number?)
|
288
|
+
#{ \once \override Slur.ratio = #r #}
|
289
|
+
)
|
290
|
+
sE = #(define-music-function (parser location e) (number?)
|
291
|
+
#{ \once \override Slur.eccentricity = #e #}
|
292
|
+
)
|
293
|
+
|
294
|
+
sHL = #(define-music-function (parser location l) (number?)
|
295
|
+
#{ \once \override Slur.height-limit = #l #}
|
296
|
+
)
|
297
|
+
|
298
|
+
sP = #(define-music-function (parser location p1 p2) (number? number?)
|
299
|
+
#{ \once \override Slur.positions = #(cons p1 p2) #}
|
300
|
+
)
|
301
|
+
|
302
|
+
#(define (convert-shape-coords s)
|
303
|
+
(map (lambda (v) (if (eq? v #f) '(0 . 0) v)) s)
|
304
|
+
)
|
305
|
+
|
306
|
+
sS = #(define-music-function (parser location s) (scheme?)
|
307
|
+
#{ \once \shape #(convert-shape-coords s) Slur #}
|
308
|
+
)
|
309
|
+
|
310
|
+
knee = \once \override Beam.auto-knee-gap = #0
|