]> git.donarmstrong.com Git - lilypond.git/blob - ly/music-functions-init.ly
Let \autochange accept optional arguments for the turning-point and clefs
[lilypond.git] / ly / music-functions-init.ly
1 %%%% -*- Mode: Scheme -*-
2
3 %%%% This file is part of LilyPond, the GNU music typesetter.
4 %%%%
5 %%%% Copyright (C) 2003--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 %%%%                          Jan Nieuwenhuizen <janneke@gnu.org>
7 %%%%
8 %%%% LilyPond is free software: you can redistribute it and/or modify
9 %%%% it under the terms of the GNU General Public License as published by
10 %%%% the Free Software Foundation, either version 3 of the License, or
11 %%%% (at your option) any later version.
12 %%%%
13 %%%% LilyPond is distributed in the hope that it will be useful,
14 %%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
15 %%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 %%%% GNU General Public License for more details.
17 %%%%
18 %%%% You should have received a copy of the GNU General Public License
19 %%%% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
20
21 \version "2.19.25"
22
23
24 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25 %% this file is alphabetically sorted.
26 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
27
28 %% need SRFI-1 for filter; optargs for lambda*
29 #(use-modules (srfi srfi-1)
30               (ice-9 optargs))
31
32 %% TODO: using define-music-function in a .scm causes crash.
33
34 absolute =
35 #(define-music-function (music)
36    (ly:music?)
37    (_i "Make @var{music} absolute.  This does not actually change the
38 music itself but rather hides it from surrounding @code{\\relative}
39 and @code{\\fixed} commands.")
40    (make-music 'RelativeOctaveMusic 'element music))
41
42 acciaccatura =
43 #(def-grace-function startAcciaccaturaMusic stopAcciaccaturaMusic
44    (_i "Create an acciaccatura from the following music expression"))
45
46 %% keep these two together
47 instrument-definitions = #'()
48 addInstrumentDefinition =
49 #(define-void-function
50    (name lst) (string? list?)
51    (_i "Create instrument @var{name} with properties @var{list}.")
52    (set! instrument-definitions (acons name lst instrument-definitions)))
53
54 addQuote =
55 #(define-void-function (name music) (string? ly:music?)
56    (_i "Define @var{music} as a quotable music expression named
57 @var{name}")
58    (add-quotable name music))
59
60 %% keep these two together
61 afterGraceFraction = #(cons 6 8)
62 afterGrace =
63 #(define-music-function (main grace) (ly:music? ly:music?)
64    (_i "Create @var{grace} note(s) after a @var{main} music expression.")
65    (let ((main-length (ly:music-length main))
66          (fraction  (ly:parser-lookup 'afterGraceFraction)))
67      (make-simultaneous-music
68       (list
69        main
70        (make-sequential-music
71         (list
72
73          (make-music 'SkipMusic
74                      'duration (ly:make-duration
75                                 0 0
76                                 (* (ly:moment-main-numerator main-length)
77                                    (car fraction))
78                                 (* (ly:moment-main-denominator main-length)
79                                    (cdr fraction))))
80          (make-music 'GraceMusic
81                      'element grace)))))))
82
83
84 %% music identifiers not allowed at top-level,
85 %% so this is a music-function instead.
86 allowPageTurn =
87 #(define-music-function () ()
88    (_i "Allow a page turn. May be used at toplevel (ie between scores or
89 markups), or inside a score.")
90    (make-music 'EventChord
91                'page-marker #t
92                'page-turn-permission 'allow
93                'elements (list (make-music 'PageTurnEvent
94                                            'break-permission 'allow))))
95
96 alterBroken =
97 #(define-music-function (property arg item)
98   (symbol-list-or-symbol? list? symbol-list-or-music?)
99   (_i "Override @var{property} for pieces of broken spanner @var{item}
100 with values @var{arg}.  @var{item} may either be music in the form of
101 a starting spanner event, or a symbol list in the form
102 @samp{Context.Grob} or just @samp{Grob}.  Iff @var{item} is in the
103 form of a spanner event, @var{property} may also have the form
104 @samp{Grob.property} for specifying a directed tweak.")
105   (if (ly:music? item)
106       (if (eq? (ly:music-property item 'span-direction) START)
107           (tweak property (value-for-spanner-piece arg) item)
108           (begin
109             (ly:music-warning item (_ "not a spanner"))
110             item))
111       (let* ((p (check-grob-path item (*location*)
112                                  #:default 'Bottom
113                                  #:min 2
114                                  #:max 2))
115              (name (and p (second p)))
116              (description
117               (and name (assoc-get name all-grob-descriptions))))
118         (if (and description
119                  (member 'spanner-interface
120                          (assoc-get 'interfaces
121                                     (assoc-get 'meta description))))
122             (propertyOverride (append item (if (symbol? property)
123                                        (list property)
124                                        property))
125                       (value-for-spanner-piece arg))
126             (begin
127               (ly:input-warning (*location*) (_ "not a spanner name, `~a'") name)
128               (make-music 'Music))))))
129
130 appendToTag =
131 #(define-music-function (tag more music)
132    (symbol? ly:music? ly:music?)
133    (_i "Append @var{more} to the @code{elements} of all music
134 expressions in @var{music} that are tagged with @var{tag}.")
135    (music-map (lambda (m)
136                 (if (memq tag (ly:music-property m 'tags))
137                     (set! (ly:music-property m 'elements)
138                           (append (ly:music-property m 'elements)
139                                   (list more))))
140                 m)
141               music))
142
143 applyContext =
144 #(define-music-function (proc) (procedure?)
145    (_i "Modify context properties with Scheme procedure @var{proc}.")
146    (make-music 'ApplyContext
147                'procedure proc))
148
149 applyMusic =
150 #(define-music-function (func music) (procedure? ly:music?)
151    (_i"Apply procedure @var{func} to @var{music}.")
152    (func music))
153
154 applyOutput =
155 #(define-music-function (target proc) (symbol-list-or-symbol? procedure?)
156    (_i "Apply function @code{proc} to every layout object matched by
157 @var{target} which takes the form @code{Context} or @code{Context.Grob}.")
158    (let ((p (check-grob-path target (*location*) #:max 2)))
159      (if p
160          (make-music 'ApplyOutputEvent
161                      'procedure proc
162                      'context-type (car p)
163                      (if (pair? (cdr p))
164                          (list (cons 'symbol (cadr p)))
165                          '()))
166          (make-music 'Music))))
167
168 appoggiatura =
169 #(def-grace-function startAppoggiaturaMusic stopAppoggiaturaMusic
170    (_i "Create an appoggiatura from @var{music}"))
171
172 % for regression testing purposes.
173 assertBeamQuant =
174 #(define-music-function (l r) (pair? pair?)
175    (_i "Testing function: check whether the beam quants @var{l} and @var{r} are correct")
176    (make-grob-property-override 'Beam 'positions (check-quant-callbacks l r)))
177
178 % for regression testing purposes.
179 assertBeamSlope =
180 #(define-music-function (comp) (procedure?)
181    (_i "Testing function: check whether the slope of the beam is the same as @code{comp}")
182    (make-grob-property-override 'Beam 'positions (check-slope-callbacks comp)))
183
184 autochange =
185 #(define-music-function (pitch clef-1 clef-2 music)
186   ((ly:pitch? (ly:make-pitch 0 0)) (ly:context-mod?)(ly:context-mod?) ly:music?)
187   (_i "Make voices that switch between staves automatically.  As an option the
188 pitch where to switch staves may be specified.  The clefs for the staves are
189 optional as well.  Setting clefs  works only for implicitly instantiated
190 staves.")
191   (let ;; keep the contexts alive for the full duration
192        ((skip (make-skip-music (make-duration-of-length
193                                      (ly:music-length music)))))
194     #{
195       <<
196         \context Staff = "up" $(or clef-1 #{ \with { \clef "treble" } #})
197           <<
198           #(make-autochange-music pitch music)
199           \new Voice { #skip }
200           >>
201         \context Staff = "down" $(or clef-2 #{ \with { \clef "bass" } #})
202           \new Voice { #skip }
203       >>
204     #}))
205
206 balloonGrobText =
207 #(define-music-function (grob-name offset text)
208    (symbol? number-pair? markup?)
209    (_i "Attach @var{text} to @var{grob-name} at offset @var{offset}
210  (use like @code{\\once})")
211    (make-event-chord
212     (list
213      (make-music 'AnnotateOutputEvent
214                  'symbol grob-name
215                  'X-offset (car offset)
216                  'Y-offset (cdr offset)
217                  'text text))))
218
219 balloonText =
220 #(define-event-function (offset text) (number-pair? markup?)
221    (_i "Attach @var{text} at @var{offset} (use like @code{\\tweak})")
222    (make-music 'AnnotateOutputEvent
223                'X-offset (car offset)
224                'Y-offset (cdr offset)
225                'text text))
226
227 bar =
228 #(define-music-function (type) (string?)
229    (_i "Insert a bar line of type @var{type}")
230    (context-spec-music
231     (make-property-set 'whichBar type)
232     'Timing))
233
234 barNumberCheck =
235 #(define-music-function (n) (integer?)
236    (_i "Print a warning if the current bar number is not @var{n}.")
237    (make-music 'ApplyContext
238                'procedure
239                (lambda (c)
240                  (let ((cbn (ly:context-property c 'currentBarNumber)))
241                    (if (and  (number? cbn) (not (= cbn n)))
242                        (ly:input-warning (*location*)
243                                          "Barcheck failed got ~a expect ~a"
244                                          cbn n))))))
245
246 beamExceptions =
247 #(define-scheme-function (music) (ly:music?)
248    (_i "Extract a value suitable for setting
249 @code{Timing.beamExceptions} from the given pattern with explicit
250 beams in @var{music}.  A bar check @code{|} has to be used between
251 bars of patterns in order to reset the timing.")
252    (extract-beam-exceptions music))
253
254 bendAfter =
255 #(define-event-function (delta) (real?)
256    (_i "Create a fall or doit of pitch interval @var{delta}.")
257    (make-music 'BendAfterEvent
258                'delta-step delta))
259
260 bookOutputName =
261 #(define-void-function (newfilename) (string?)
262    (_i "Direct output for the current book block to @var{newfilename}.")
263    (set! (paper-variable #f 'output-filename) newfilename))
264
265 bookOutputSuffix =
266 #(define-void-function (newsuffix) (string?)
267    (_i "Set the output filename suffix for the current book block to
268 @var{newsuffix}.")
269    (set! (paper-variable #f 'output-suffix) newsuffix))
270
271 %% \breathe is defined as a music function rather than an event identifier to
272 %% ensure it gets useful input location information: as an event identifier,
273 %% it would have to be wrapped in an EventChord to prevent it from being
274 %% treated as a post_event by the parser
275 breathe =
276 #(define-music-function () ()
277    (_i "Insert a breath mark.")
278    (make-music 'BreathingEvent))
279
280 clef =
281 #(define-music-function (type) (string?)
282    (_i "Set the current clef to @var{type}.")
283    (make-clef-set type))
284
285
286 compoundMeter =
287 #(define-music-function (args) (pair?)
288   (_i "Create compound time signatures. The argument is a Scheme list of
289 lists. Each list describes one fraction, with the last entry being the
290 denominator, while the first entries describe the summands in the
291 enumerator. If the time signature consists of just one fraction,
292 the list can be given directly, i.e. not as a list containing a single list.
293 For example, a time signature of (3+1)/8 + 2/4 would be created as
294 @code{\\compoundMeter #'((3 1 8) (2 4))}, and a time signature of (3+2)/8
295 as @code{\\compoundMeter #'((3 2 8))} or shorter
296 @code{\\compoundMeter #'(3 2 8)}.")
297   (let* ((mlen (calculate-compound-measure-length args))
298          (beat (calculate-compound-base-beat args))
299          (beatGrouping (calculate-compound-beat-grouping args))
300          (timesig (cons (ly:moment-main-numerator mlen)
301                         (ly:moment-main-denominator mlen))))
302   #{
303     \once \override Timing.TimeSignature.stencil = #(lambda (grob)
304       (grob-interpret-markup grob (make-compound-meter-markup args)))
305     \set Timing.timeSignatureFraction = #timesig
306     \set Timing.baseMoment = #beat
307     \set Timing.beatStructure = #beatGrouping
308     \set Timing.beamExceptions = #'()
309     \set Timing.measureLength = #mlen
310   #} ))
311
312 compressMMRests =
313 #(define-music-function (music) (ly:music?)
314   (_i "Remove the empty bars created by multi-measure rests,
315 leaving just the first bar containing the MM rest itself.")
316    (music-map
317     (lambda (m)
318       (if (eq? 'MultiMeasureRestMusic (ly:music-property m 'name))
319           #{ \once \set Score.skipBars = ##t #m #}
320           #{ #m #} ))
321     music))
322
323 crossStaff =
324 #(define-music-function (notes) (ly:music?)
325   (_i "Create cross-staff stems")
326   #{
327   \temporary \override Stem.cross-staff = #cross-staff-connect
328   \temporary \override Flag.style = #'no-flag
329   #notes
330   \revert Stem.cross-staff
331   \revert Flag.style
332 #})
333
334 cueClef =
335 #(define-music-function (type) (string?)
336   (_i "Set the current cue clef to @var{type}.")
337   (make-cue-clef-set type))
338
339 cueClefUnset =
340 #(define-music-function () ()
341   (_i "Unset the current cue clef.")
342   (make-cue-clef-unset))
343
344 cueDuring =
345 #(define-music-function
346    (what dir main-music) (string? ly:dir? ly:music?)
347    (_i "Insert contents of quote @var{what} corresponding to @var{main-music},
348 in a CueVoice oriented by @var{dir}.")
349    (make-music 'QuoteMusic
350                'element main-music
351                'quoted-context-type 'CueVoice
352                'quoted-context-id "cue"
353                'quoted-music-name what
354                'quoted-voice-direction dir))
355
356 cueDuringWithClef =
357 #(define-music-function
358    (what dir clef main-music) (string? ly:dir? string? ly:music?)
359    (_i "Insert contents of quote @var{what} corresponding to @var{main-music},
360 in a CueVoice oriented by @var{dir}.")
361    (make-music 'QuoteMusic
362                'element main-music
363                'quoted-context-type 'CueVoice
364                'quoted-context-id "cue"
365                'quoted-music-name what
366                'quoted-music-clef clef
367                'quoted-voice-direction dir))
368
369
370
371 displayLilyMusic =
372 #(define-music-function (port music) ((output-port?) ly:music?)
373    (_i "Display the LilyPond input representation of @var{music}
374 to @var{port}, defaulting to the console.")
375    (let ((port (or port (current-output-port))))
376      (newline port)
377      (display-lily-music music port))
378    music)
379
380 displayMusic =
381 #(define-music-function (port music) ((output-port?) ly:music?)
382    (_i "Display the internal representation of @var{music} to
383 @var{port}, default to the console.")
384    (let ((port (or port (current-output-port))))
385      (newline port)
386      (display-scheme-music music port))
387    music)
388
389 displayScheme =
390 #(define-scheme-function (port expr) ((output-port?) scheme?)
391    (_i "Display the internal representation of @var{expr} to
392 @var{port}, default to the console.")
393    (let ((port (or port (current-output-port))))
394      (newline port)
395      (display-scheme-music expr port))
396    expr)
397
398
399
400 endSpanners =
401 #(define-music-function (music) (ly:music?)
402    (_i "Terminate the next spanner prematurely after exactly one note
403 without the need of a specific end spanner.")
404    (let* ((start-span-evs (filter (lambda (ev)
405                                     (equal? (ly:music-property ev 'span-direction)
406                                             START))
407                                   (extract-typed-music music 'span-event)))
408           (stop-span-evs
409            (map (lambda (m)
410                   (music-clone m 'span-direction STOP))
411                 start-span-evs))
412           (end-ev-chord (make-music 'EventChord
413                                     'elements stop-span-evs))
414           (total (make-music 'SequentialMusic
415                              'elements (list music
416                                              end-ev-chord))))
417      total))
418
419 eventChords =
420 #(define-music-function (music) (ly:music?)
421    (_i "Compatibility function wrapping @code{EventChord} around
422 isolated rhythmic events occuring since version 2.15.28, after
423 expanding repeat chords @samp{q}.")
424    (event-chord-wrap! music))
425
426 featherDurations=
427 #(define-music-function (factor argument) (ly:moment? ly:music?)
428    (_i "Adjust durations of music in @var{argument} by rational @var{factor}.")
429    (let ((orig-duration (ly:music-length argument))
430          (multiplier (ly:make-moment 1 1)))
431
432      (for-each
433       (lambda (mus)
434         (if (< 0 (ly:moment-main-denominator (ly:music-length mus)))
435             (begin
436               (ly:music-compress mus multiplier)
437               (set! multiplier (ly:moment-mul factor multiplier)))))
438       (extract-named-music argument '(EventChord NoteEvent RestEvent SkipEvent)))
439      (ly:music-compress
440       argument
441       (ly:moment-div orig-duration (ly:music-length argument)))
442
443      argument))
444
445 finger =
446 #(define-event-function (finger) (number-or-markup?)
447    (_i "Apply @var{finger} as a fingering indication.")
448
449    (make-music
450             'FingeringEvent
451             (if (number? finger) 'digit 'text)
452             finger))
453
454 fixed =
455 #(define-music-function (pitch music)
456    (ly:pitch? ly:music?)
457    (_i "Use the octave of @var{pitch} as the default octave for @var{music}.")
458    (let ((octave-marks (1+ (ly:pitch-octave pitch))))
459      (cond ((not (= 0 octave-marks))
460             (ly:music-transpose music (ly:make-pitch octave-marks 0 0))
461             ;;In order to leave unchanged the notes in any enclosed
462             ;; \absolute or \fixed or \relative, make a cancelling shift
463             (map (lambda (m)
464                    (ly:music-transpose m (ly:make-pitch (- octave-marks) 0 0)))
465                  (extract-named-music music 'RelativeOctaveMusic)))))
466    (make-music 'RelativeOctaveMusic 'element music))
467
468 footnote =
469 #(define-music-function (mark offset footnote item)
470    ((markup?) number-pair? markup? symbol-list-or-music?)
471    (_i "Make the markup @var{footnote} a footnote on @var{item}.  The
472 footnote is marked with a markup @var{mark} moved by @var{offset} with
473 respect to the marked music.
474
475 If @var{mark} is not given or specified as @var{\\default}, it is
476 replaced by an automatically generated sequence number.  If @var{item}
477 is a symbol list of form @samp{Grob} or @samp{Context.Grob}, then
478 grobs of that type will be marked at the current time step in the
479 given context (default @code{Bottom}).
480
481 If @var{item} is music, the music will get a footnote attached to a
482 grob immediately attached to the event, like @var{\\tweak} does.  For
483 attaching a footnote to an @emph{indirectly} caused grob, write
484 @code{\\single\\footnote}, use @var{item} to specify the grob, and
485 follow it with the music to annotate.
486
487 Like with @code{\\tweak}, if you use a footnote on a following
488 post-event, the @code{\\footnote} command itself needs to be attached
489 to the preceding note or rest as a post-event with @code{-}.")
490    (let ((mus (make-music
491                'FootnoteEvent
492                'X-offset (car offset)
493                'Y-offset (cdr offset)
494                'automatically-numbered (not mark)
495                'text (or mark (make-null-markup))
496                'footnote-text footnote)))
497      (once (tweak 'footnote-music mus item))))
498
499 grace =
500 #(def-grace-function startGraceMusic stopGraceMusic
501    (_i "Insert @var{music} as grace notes."))
502
503 grobdescriptions =
504 #(define-scheme-function (descriptions) (list?)
505    (_i "Create a context modification from @var{descriptions}, a list
506 in the format of @code{all-grob-descriptions}.")
507    (ly:make-context-mod
508     (map (lambda (p)
509            (list 'assign (car p) (ly:make-grob-properties (cdr p))))
510          descriptions)))
511
512 harmonicByFret = #(define-music-function (fret music) (number? ly:music?)
513   (_i "Convert @var{music} into mixed harmonics; the resulting notes resemble
514 harmonics played on a fretted instrument by touching the strings at @var{fret}.")
515   #{
516     \set harmonicDots = ##t
517     \temporary \override TabNoteHead.stencil = #(tab-note-head::print-custom-fret-label (number->string fret))
518     \temporary \override NoteHead.Y-extent = #grob::always-Y-extent-from-stencil
519     \temporary \override NoteHead.stencil = #(lambda (grob) (ly:grob-set-property! grob 'style 'harmonic-mixed)
520                                             (ly:note-head::print grob))
521     #(make-harmonic
522        (calc-harmonic-pitch (fret->pitch (number->string fret)) music))
523     \unset harmonicDots
524     \revert TabNoteHead.stencil
525     \revert NoteHead.Y-extent
526     \revert NoteHead.stencil
527   #})
528
529 harmonicByRatio = #(define-music-function (ratio music) (number? ly:music?)
530     (_i "Convert @var{music} into mixed harmonics; the resulting notes resemble
531 harmonics played on a fretted instrument by touching the strings at the point
532 given through @var{ratio}.")
533   #{
534     \set harmonicDots = ##t
535     \temporary \override TabNoteHead.stencil = #(tab-note-head::print-custom-fret-label (ratio->fret ratio))
536     \temporary \override NoteHead.Y-extent = #(ly:make-unpure-pure-container ly:grob::stencil-height)
537     \temporary \override NoteHead.stencil = #(lambda (grob) (ly:grob-set-property! grob 'style 'harmonic-mixed)
538                                             (ly:note-head::print grob))
539     #(make-harmonic
540       (calc-harmonic-pitch (ratio->pitch ratio) music))
541     \unset harmonicDots
542     \revert TabNoteHead.stencil
543     \revert NoteHead.Y-extent
544     \revert NoteHead.stencil
545   #})
546
547 hide =
548 #(define-music-function (item) (symbol-list-or-music?)
549    (_i "Set @var{item}'s @samp{transparent} property to @code{#t},
550 making it invisible while still retaining its dimensions.
551
552 If @var{item} is a symbol list of form @code{GrobName} or
553 @code{Context.GrobName}, the result is an override for the grob name
554 specified by it.  If @var{item} is a music expression, the result is
555 the same music expression with an appropriate tweak applied to it.")
556    (tweak 'transparent #t item))
557
558 inStaffSegno =
559 #(define-music-function () ()
560    (_i "Put the segno variant 'varsegno' at this position into the staff,
561 compatible with the repeat command.")
562    (make-music 'ApplyContext
563                'procedure
564                (lambda (ctx)
565                  (let ((score-ctx (ly:context-find ctx 'Score)))
566                    (if (ly:context? score-ctx)
567                      (let ((old-rc (ly:context-property score-ctx 'repeatCommands '())))
568                        (if (eq? (memq 'segno-display old-rc) #f)
569                          (ly:context-set-property! score-ctx 'repeatCommands (cons 'segno-display old-rc)))))))))
570
571 instrumentSwitch =
572 #(define-music-function
573    (name) (string?)
574    (_i "Switch instrument to @var{name}, which must be predefined with
575 @code{\\addInstrumentDefinition}.")
576    (let* ((handle (assoc name instrument-definitions))
577           (instrument-def (if handle (cdr handle) '())))
578
579      (if (not handle)
580          (ly:input-warning (*location*) "No such instrument: ~a" name))
581      (context-spec-music
582       (make-music 'SimultaneousMusic
583                   'elements
584                   (map (lambda (kv)
585                          (make-property-set
586                           (car kv)
587                           (cdr kv)))
588                        instrument-def))
589       'Staff)))
590
591
592
593 keepWithTag =
594 #(define-music-function (tags music)
595    (symbol-list-or-symbol? ly:music?)
596    (_i "Include only elements of @var{music} that are tagged with one
597 of the tags in @var{tags}.  @var{tags} may be either a single symbol
598 or a list of symbols.
599
600 Each tag may be declared as a member of at most one tag group (defined
601 with @code{\\tagGroup}).  If none of a @var{music} element's tags
602 share a tag group with one of the specified @var{tags}, the element is
603 retained.")
604    (music-filter
605     (tags-keep-predicate tags)
606     music))
607
608 key =
609 #(define-music-function (tonic pitch-alist)
610    ((ly:pitch? '()) (list? '()))
611    (_i "Set key to @var{tonic} and scale @var{pitch-alist}.
612 If both are null, just generate @code{KeyChangeEvent}.")
613    (cond ((null? tonic) (make-music 'KeyChangeEvent))
614          ((null? pitch-alist)
615           (ly:parser-error (_ "second argument must be pitch list")
616                            (*location*))
617           (make-music 'SequentialMusic 'void #t))
618          (else
619           (ly:music-transpose
620            (make-music 'KeyChangeEvent
621                 'tonic (ly:make-pitch 0 0 0)
622                 'pitch-alist pitch-alist)
623            tonic))))
624
625 killCues =
626 #(define-music-function (music) (ly:music?)
627    (_i "Remove cue notes from @var{music}.")
628    (music-map
629     (lambda (mus)
630       (if (and (string? (ly:music-property mus 'quoted-music-name))
631                (string=? (ly:music-property mus 'quoted-context-id "") "cue"))
632           (ly:music-property mus 'element)
633           mus))
634     music))
635
636
637
638 label =
639 #(define-music-function (label) (symbol?)
640    (_i "Create @var{label} as a bookmarking label.")
641    (make-music 'EventChord
642                'page-marker #t
643                'page-label label
644                'elements (list (make-music 'LabelEvent
645                                            'page-label label))))
646
647
648 language =
649 #(define-void-function (language) (string?)
650    (_i "Set note names for language @var{language}.")
651    (note-names-language language))
652
653 languageSaveAndChange =
654 #(define-void-function (language) (string?)
655   (_i "Store the previous pitchnames alist, and set a new one.")
656   (set! previous-pitchnames pitchnames)
657   (note-names-language language))
658
659 languageRestore =
660 #(define-void-function () ()
661    (_i "Restore a previously-saved pitchnames alist.")
662    (if previous-pitchnames
663        (begin
664         (set! pitchnames previous-pitchnames)
665         (ly:parser-set-note-names pitchnames))
666       (ly:input-warning (*location*) (_ "No other language was defined previously. Ignoring."))))
667
668
669 magnifyMusic =
670 #(define-music-function (mag music) (positive? ly:music?)
671    (_i "Magnify the notation of @var{music} without changing the
672 staff-size, using @var{mag} as a size factor.  Stems, beams,
673 slurs, ties, and horizontal spacing are adjusted automatically.")
674
675    ;; these props are NOT allowed to shrink below default size
676    (define unshrinkable-props
677      '(
678        ;; stems
679        (Stem thickness)
680
681        ;; slurs
682        (Slur line-thickness)
683        (Slur thickness)
684        (PhrasingSlur line-thickness)
685        (PhrasingSlur thickness)
686
687        ;; ties
688        (Tie line-thickness)
689        (Tie thickness)
690        (LaissezVibrerTie line-thickness)
691        (LaissezVibrerTie thickness)
692        (RepeatTie line-thickness)
693        (RepeatTie thickness)
694        ))
695
696    ;; these props ARE allowed to shrink below default size
697    (define shrinkable-props
698      (let ((baseline-skip-props
699              (find-named-props 'baseline-skip all-grob-descriptions))
700            (word-space-props
701              (find-named-props 'word-space all-grob-descriptions)))
702        (append
703          baseline-skip-props
704          word-space-props
705          '(
706            ;; TODO: uncomment spacing-increment here once Issue 3987 is fixed
707            ;; override at the 'Score level
708            ;(SpacingSpanner spacing-increment)
709
710            ;; lengths and heights
711            (Beam length-fraction)
712            (Stem length-fraction)
713            (Stem beamlet-default-length)
714            (Stem double-stem-separation)
715            (Slur height-limit)
716            (Slur minimum-length)
717            (PhrasingSlur height-limit)
718            (PhrasingSlur minimum-length)
719
720            ;; Beam.beam-thickness is dealt with separately below
721            ))))
722    #{
723      \context Bottom {
724        %% TODO: uncomment \newSpacingSection once Issue 3990 is fixed
725        %\newSpacingSection
726        #(scale-fontSize 'magnifyMusic mag)
727        #(scale-props    'magnifyMusic mag #f unshrinkable-props)
728        #(scale-props    'magnifyMusic mag #t shrinkable-props)
729        #(scale-beam-thickness mag)
730
731        #music
732
733        %% TODO: uncomment \newSpacingSection once Issue 3990 is fixed
734        %\newSpacingSection
735        %% reverse engineer the former fontSize value instead of using \unset
736        #(revert-fontSize 'magnifyMusic mag)
737        #(revert-props    'magnifyMusic mag (append unshrinkable-props
738                                                    shrinkable-props
739                                                    '((Beam beam-thickness))))
740      }
741    #})
742
743 magnifyStaff =
744 #(define-music-function (mag) (positive?)
745    (_i "Change the size of the staff, adjusting notation size and
746 horizontal spacing automatically, using @var{mag} as a size factor.")
747
748    ;; these props are NOT allowed to shrink below default size
749    (define unshrinkable-props
750      '((StaffSymbol thickness)))
751
752    ;; these props ARE allowed to shrink below default size
753    (define shrinkable-props
754      (let* ((baseline-skip-props
755               (find-named-props 'baseline-skip all-grob-descriptions))
756             (word-space-props
757               (find-named-props 'word-space all-grob-descriptions))
758             (space-alist-props
759               (find-named-props 'space-alist all-grob-descriptions)))
760        (append
761          baseline-skip-props
762          word-space-props
763          space-alist-props
764          '(
765            ;; override at the 'Score level
766            (SpacingSpanner spacing-increment)
767
768            (StaffSymbol staff-space)
769            (BarLine kern)
770            (BarLine segno-kern)
771            (BarLine hair-thickness)
772            (BarLine thick-thickness)
773            (Stem beamlet-default-length)
774            (Stem double-stem-separation)
775            ))))
776
777    #{
778      \stopStaff
779
780      %% revert settings from last time
781      %% (but only if \magnifyStaff has already been used
782      %% and the staff magnification is changing)
783      #(revert-fontSize 'magnifyStaff mag)
784      #(revert-props    'magnifyStaff mag (append unshrinkable-props
785                                                  shrinkable-props))
786
787      %% scale settings
788      %% (but only if staff magnification is changing
789      %% and does not equal 1)
790      #(scale-fontSize 'magnifyStaff mag)
791      #(scale-props    'magnifyStaff mag #f unshrinkable-props)
792      #(scale-props    'magnifyStaff mag #t shrinkable-props)
793
794      %% this might cause problems until Issue 3990 is fixed
795      \newSpacingSection
796
797      \startStaff
798      \set Staff.magnifyStaffValue = #mag
799    #})
800
801 makeClusters =
802 #(define-music-function (arg) (ly:music?)
803    (_i "Display chords in @var{arg} as clusters.")
804    (music-map note-to-cluster arg))
805
806 modalInversion =
807 #(define-music-function (around to scale music)
808     (ly:pitch? ly:pitch? ly:music? ly:music?)
809     (_i "Invert @var{music} about @var{around} using @var{scale} and
810 transpose from @var{around} to @var{to}.")
811     (let ((inverter (make-modal-inverter around to scale)))
812       (change-pitches music inverter)
813       music))
814
815 modalTranspose =
816 #(define-music-function (from to scale music)
817     (ly:pitch? ly:pitch? ly:music? ly:music?)
818     (_i "Transpose @var{music} from pitch @var{from} to pitch @var{to}
819 using @var{scale}.")
820     (let ((transposer (make-modal-transposer from to scale)))
821       (change-pitches music transposer)
822       music))
823
824 inversion =
825 #(define-music-function
826    (around to music) (ly:pitch? ly:pitch? ly:music?)
827    (_i "Invert @var{music} about @var{around} and
828 transpose from @var{around} to @var{to}.")
829    (music-invert around to music))
830
831 mark =
832 #(define-music-function
833    (label) ((number-or-markup?))
834   "Make the music for the \\mark command."
835   (let* ((set (and (integer? label)
836                    (context-spec-music (make-property-set 'rehearsalMark label)
837                                       'Score)))
838          (ev (make-music 'MarkEvent
839                          'origin (*location*))))
840
841     (if set
842         (make-sequential-music (list set ev))
843         (begin
844           (if label (set! (ly:music-property ev 'label) label))
845           ev))))
846
847 musicMap =
848 #(define-music-function (proc mus) (procedure? ly:music?)
849    (_i "Apply @var{proc} to @var{mus} and all of the music it contains.")
850    (music-map proc mus))
851
852 %% noPageBreak and noPageTurn are music functions (not music indentifiers),
853 %% because music identifiers are not allowed at top-level.
854 noPageBreak =
855 #(define-music-function () ()
856    (_i "Forbid a page break.  May be used at toplevel (i.e., between scores or
857 markups), or inside a score.")
858    (make-music 'EventChord
859                'page-marker #t
860                'page-break-permission 'forbid
861                'elements (list (make-music 'PageBreakEvent
862                                            'break-permission '()))))
863
864 noPageTurn =
865 #(define-music-function () ()
866    (_i "Forbid a page turn.  May be used at toplevel (i.e., between scores or
867 markups), or inside a score.")
868    (make-music 'EventChord
869                'page-marker #t
870                'page-turn-permission 'forbid
871                'elements (list (make-music 'PageTurnEvent
872                                            'break-permission '()))))
873
874
875
876 octaveCheck =
877 #(define-music-function (pitch) (ly:pitch?)
878    (_i "Octave check.")
879    (make-music 'RelativeOctaveCheck
880                'pitch pitch))
881
882 offset =
883 #(define-music-function (property offsets item)
884   (symbol-list-or-symbol? scheme? symbol-list-or-music?)
885    (_i "Offset the default value of @var{property} of @var{item} by
886 @var{offsets}.  If @var{item} is a string, the result is
887 @code{\\override} for the specified grob type.  If @var{item} is
888 a music expression, the result is the same music expression with an
889 appropriate tweak applied.")
890   (if (ly:music? item)
891       ; In case of a tweak, grob property path is Grob.property
892       (let ((prop-path (check-grob-path
893                          (if (symbol? property)
894                              (list property)
895                              property) (*location*)
896                          #:start 1 #:default #t #:min 2 #:max 2)))
897         (if prop-path
898             ; If the head of the grob property path is a symbol--i.e.,
899             ; a grob name, produce a directed tweak.  Otherwise, create
900             ; an ordinary tweak.
901             (if (symbol? (car prop-path))
902                 (tweak prop-path (offsetter (second prop-path) offsets) item)
903                 (tweak (second prop-path)
904                        (offsetter (second prop-path) offsets)
905                        item))
906             item))
907       ; In case of an override, grob property path is Context.Grob.property.
908       (let ((prop-path (check-grob-path
909                          (append item
910                                  (if (symbol? property)
911                                      (list property)
912                                      property)) (*location*)
913                          #:default 'Bottom #:min 3 #:max 3)))
914         (if prop-path
915             (propertyOverride prop-path (offsetter (third prop-path) offsets))
916             (make-music 'Music)))))
917
918 omit =
919 #(define-music-function (item) (symbol-list-or-music?)
920    (_i "Set @var{item}'s @samp{stencil} property to @code{#f},
921 effectively omitting it without taking up space.
922
923 If @var{item} is a symbol list of form @code{GrobName} or
924 @code{Context.GrobName}, the result is an override for the grob name
925 specified by it.  If @var{item} is a music expression, the result is
926 the same music expression with an appropriate tweak applied to it.")
927    (tweak 'stencil #f item))
928
929 once =
930 #(define-music-function (music) (ly:music?)
931    (_i "Set @code{once} to @code{#t} on all layout instruction events
932 in @var{music}.  This will complain about music with an actual
933 duration.  As a special exception, if @var{music} contains
934 @samp{tweaks} it will be silently ignored in order to allow for
935 @code{\\once \\tweak} to work as both one-time override and proper
936 tweak.")
937    (if (not (pair? (ly:music-property music 'tweaks)))
938        (for-some-music
939         (lambda (m)
940           (cond ((music-is-of-type? m 'layout-instruction-event)
941                  (set! (ly:music-property m 'once) #t)
942                  #t)
943                 ((ly:duration? (ly:music-property m 'duration))
944                  (ly:music-warning m (_ "Cannot apply \\once to timed music"))
945                  #t)
946                 (else #f)))
947         music))
948    music)
949
950 ottava =
951 #(define-music-function (octave) (integer?)
952    (_i "Set the octavation.")
953    (make-music 'OttavaMusic
954                'ottava-number octave))
955
956 overrideTimeSignatureSettings =
957 #(define-music-function
958    (time-signature base-moment beat-structure beam-exceptions)
959    (fraction? fraction? list? list?)
960
961    (_i "Override @code{timeSignatureSettings}
962 for time signatures of @var{time-signature} to have settings
963 of @var{base-moment}, @var{beat-structure}, and @var{beam-exceptions}.")
964
965    ;; TODO -- add warning if largest value of grouping is
966    ;;       greater than time-signature.
967   (let ((setting (make-setting base-moment beat-structure beam-exceptions)))
968     (override-time-signature-setting time-signature setting)))
969
970 overrideProperty =
971 #(define-music-function (grob-property-path value)
972    (symbol-list? scheme?)
973
974    (_i "Set the grob property specified by @var{grob-property-path} to
975 @var{value}.  @var{grob-property-path} is a symbol list of the form
976 @code{Context.GrobName.property} or @code{GrobName.property}, possibly
977 with subproperties given as well.
978
979 As opposed to @code{\\override} which overrides the context-dependent
980 defaults with which a grob is created, this command uses
981 @code{Output_property_engraver} at the grob acknowledge stage.  This
982 may be necessary for overriding values set after the initial grob
983 creation.")
984    (let ((p (check-grob-path grob-property-path (*location*)
985                              #:default 'Bottom
986                              #:min 3)))
987      (if p
988          (make-music 'ApplyOutputEvent
989                      'context-type (first p)
990                      'procedure
991                      (lambda (grob orig-context context)
992                        (if (equal?
993                             (cdr (assoc 'name (ly:grob-property grob 'meta)))
994                             (second p))
995                            (ly:grob-set-nested-property!
996                             grob (cddr p) value))))
997          (make-music 'Music))))
998
999
1000
1001
1002
1003
1004 %% pageBreak and pageTurn are music functions (iso music indentifiers),
1005 %% because music identifiers are not allowed at top-level.
1006 pageBreak =
1007 #(define-music-function () ()
1008    (_i "Force a page break.  May be used at toplevel (i.e., between scores or
1009 markups), or inside a score.")
1010    (make-music 'EventChord
1011                'page-marker #t
1012                'line-break-permission 'force
1013                'page-break-permission 'force
1014                'elements (list (make-music 'LineBreakEvent
1015                                            'break-permission 'force)
1016                                (make-music 'PageBreakEvent
1017                                            'break-permission 'force))))
1018
1019 pageTurn =
1020 #(define-music-function () ()
1021    (_i "Force a page turn between two scores or top-level markups.")
1022    (make-music 'EventChord
1023                'page-marker #t
1024                'line-break-permission 'force
1025                'page-break-permission 'force
1026                'page-turn-permission 'force
1027                'elements (list (make-music 'LineBreakEvent
1028                                            'break-permission 'force)
1029                                (make-music 'PageBreakEvent
1030                                            'break-permission 'force)
1031                                (make-music 'PageTurnEvent
1032                                            'break-permission 'force))))
1033
1034 parallelMusic =
1035 #(define-void-function (voice-ids music) (list? ly:music?)
1036    (_i "Define parallel music sequences, separated by '|' (bar check signs),
1037 and assign them to the identifiers provided in @var{voice-ids}.
1038
1039 @var{voice-ids}: a list of music identifiers (symbols containing only letters)
1040
1041 @var{music}: a music sequence, containing BarChecks as limiting expressions.
1042
1043 Example:
1044
1045 @verbatim
1046   \\parallelMusic #'(A B C) {
1047     c c | d d | e e |
1048     d d | e e | f f |
1049   }
1050 <==>
1051   A = { c c | d d | }
1052   B = { d d | e e | }
1053   C = { e e | f f | }
1054 @end verbatim
1055
1056 The last bar checks in a sequence are not copied to the result in
1057 order to facilitate ending the last entry at non-bar boundaries.
1058 ")
1059    (define voice-count (length voice-ids))
1060    (define (bar-check? m)
1061      "Checks whether m is a bar check."
1062      (eq? (ly:music-property m 'name) 'BarCheck))
1063    (define (recurse-and-split-list lst)
1064      "Return either a list of music lists split along barchecks, or @code{#f}."
1065      (if (any bar-check? lst)
1066          (let* ((voices (apply circular-list (make-list voice-count '())))
1067                 (current-voices voices)
1068                 (current-sequence '()))
1069            ;;
1070            ;; utilities
1071            (define (push-music m)
1072              "Push the music expression into the current sequence"
1073              (set! current-sequence (cons m current-sequence)))
1074            (define (change-voice)
1075              "Store the previously built sequence into the current voice and
1076 change to the following voice."
1077              (set-car! current-voices
1078                        (cons current-sequence
1079                              (car current-voices)))
1080              (set! current-sequence '())
1081              (set! current-voices (cdr current-voices)))
1082            (for-each (lambda (m)
1083                        (let ((split? (recurse-and-split m)))
1084                          (if split?
1085                              (for-each
1086                               (lambda (m)
1087                                 (push-music m)
1088                                 (change-voice))
1089                               split?)
1090                              (begin
1091                                (push-music m)
1092                                (if (bar-check? m) (change-voice))))))
1093                      lst)
1094            (if (pair? current-sequence) (change-voice))
1095            ;; Un-circularize voices
1096            (set! voices (list-head voices voice-count))
1097
1098            ;; Remove trailing bar checks to facilitate ending a
1099            ;; sequence on a non-bar, reverse partial sequences and sequences
1100            (set! voices (map!
1101                          (lambda (l)
1102                            (map! reverse!
1103                                  (reverse!
1104                                   (if (and (pair? l) (pair? (car l))
1105                                            (bar-check? (caar l)))
1106                                       (cons (cdar l) (cdr l))
1107                                       l))))
1108                          voices))
1109
1110            ;; check sequence length
1111            (apply for-each (lambda seqs
1112                              (define (seq-len seq)
1113                                (reduce ly:moment-add
1114                                        (ly:make-moment 0)
1115                                        (map ly:music-length seq)))
1116                              (let ((moment-reference (seq-len (car seqs))))
1117                                (for-each (lambda (seq)
1118                                            (if (not (equal? (seq-len seq)
1119                                                             moment-reference))
1120                                                (ly:music-warning
1121                                                 (if (pair? seq)
1122                                                     (last seq)
1123                                                     (caar seqs))
1124                                                 (_ "Bars in parallel music don't have the same length"))))
1125                                          seqs)))
1126                   voices)
1127            (map concatenate! voices))
1128          (let ((deeper (map recurse-and-split lst)))
1129            (and (any pair? deeper)
1130                 (apply zip (map
1131                             (lambda (m split)
1132                               (or split
1133                                   (ly:music-deep-copy (make-list voice-count m))))
1134                             lst deeper))))))
1135    (define (recurse-and-split music)
1136      "This returns either a list of music split along barchecks, or
1137 @code{#f}."
1138      (let* ((elt (ly:music-property music 'element))
1139             (elts (ly:music-property music 'elements))
1140             (split-elt (and (ly:music? elt) (recurse-and-split elt)))
1141             (split-elts (and (pair? elts) (recurse-and-split-list elts))))
1142        (and (or split-elt split-elts)
1143             (map
1144              (lambda (e es)
1145                (let ((m (ly:music-deep-copy music
1146                        ;;; reassigning the origin of the parent only
1147                        ;;; makes sense if the first expression in the
1148                        ;;; result is from a distributed origin
1149                                             (or (and (ly:music? e) e)
1150                                                 (and (pair? es) (car es))))))
1151                  (if (ly:music? e)
1152                      (set! (ly:music-property m 'element) e))
1153                  (if (pair? es)
1154                      (set! (ly:music-property m 'elements) es))
1155                  m))
1156              (or split-elt (circular-list #f))
1157              (or split-elts (circular-list #f))))))
1158    (let ((voices (recurse-and-split music)))
1159      (if voices
1160          ;;
1161          ;; bind voice identifiers to the voices
1162          (for-each (lambda (voice-id voice)
1163                      (ly:parser-define! voice-id voice))
1164                    voice-ids voices)
1165          (ly:music-warning music
1166                            (_ "ignoring parallel music without barchecks")))))
1167
1168 parenthesize =
1169 #(define-music-function (arg) (ly:music?)
1170    (_i "Tag @var{arg} to be parenthesized.")
1171
1172    (if (memq 'event-chord (ly:music-property arg 'types))
1173        ;; arg is an EventChord -> set the parenthesize property
1174        ;; on all child notes and rests
1175        (for-each
1176         (lambda (ev)
1177           (if (or (memq 'note-event (ly:music-property ev 'types))
1178                   (memq 'rest-event (ly:music-property ev 'types)))
1179               (set! (ly:music-property ev 'parenthesize) #t)))
1180         (ly:music-property arg 'elements))
1181        ;; No chord, simply set property for this expression:
1182        (set! (ly:music-property arg 'parenthesize) #t))
1183    arg)
1184
1185 #(define (make-directed-part-combine-music direction chord-range part1 part2
1186           one-context-settings
1187           two-context-settings
1188           shared-context-settings)
1189
1190    (let* ((pc-music (make-music 'PartCombineMusic))
1191           (m1 (context-spec-music (make-non-relative-music part1) 'Voice "one"))
1192           (m2 (context-spec-music (make-non-relative-music part2) 'Voice "two"))
1193           (listener (ly:parser-lookup 'partCombineListener))
1194           (evs2 (recording-group-emulate m2 listener))
1195           (evs1 (recording-group-emulate m1 listener))
1196           (split-list
1197            (if (and (assoc "one" evs1) (assoc "two" evs2))
1198                (determine-split-list (reverse! (assoc-get "one" evs1) '())
1199                                      (reverse! (assoc-get "two" evs2) '())
1200                                      chord-range)
1201                '()))
1202           (L1 (ly:music-length part1))
1203           (L2 (ly:music-length part2))
1204           ;; keep the contexts alive for the full duration
1205           (skip (make-skip-music (make-duration-of-length
1206                                   (if (ly:moment<? L1 L2) L2 L1)))))
1207
1208      (set! (ly:music-property pc-music 'elements)
1209            (list (make-music
1210                   'PartCombinePartMusic
1211                   'element m1
1212                   'context-change-list
1213                   (make-part-combine-context-changes
1214                    default-part-combine-context-change-state-machine-one
1215                    split-list))
1216                  (make-music
1217                   'PartCombinePartMusic
1218                   'element m2
1219                   'context-change-list
1220                   (make-part-combine-context-changes
1221                    default-part-combine-context-change-state-machine-two
1222                    split-list))))
1223
1224      (set! (ly:music-property pc-music 'direction) direction)
1225
1226      #{ \context Staff <<
1227           \context Voice = "one" \with #one-context-settings { #skip }
1228           \context Voice = "two" \with #two-context-settings { #skip }
1229           \context Voice = "shared" \with #shared-context-settings { #skip }
1230           \context Voice = "solo" { #skip }
1231           \context NullVoice = "null" { #skip }
1232           #pc-music
1233           #(make-part-combine-marks
1234             default-part-combine-mark-state-machine split-list)
1235         >> #} ))
1236
1237 partcombine =
1238 #(define-music-function (chord-range part1 part2)
1239    ((number-pair? '(0 . 8)) ly:music? ly:music?)
1240    (_i "Take the music in @var{part1} and @var{part2} and return
1241 a music expression containing simultaneous voices, where @var{part1}
1242 and @var{part2} are combined into one voice where appropriate.
1243 Optional @var{chord-range} sets the distance in steps between notes
1244 that may be combined into a chord or unison.")
1245    (make-directed-part-combine-music #f chord-range part1 part2
1246     #{ \with { \voiceOne \override DynamicLineSpanner.direction = #UP } #}
1247     #{ \with { \voiceTwo \override DynamicLineSpanner.direction = #DOWN } #}
1248     #{ #} ))
1249
1250 partcombineUp =
1251 #(define-music-function (chord-range part1 part2)
1252    ((number-pair? '(0 . 8)) ly:music? ly:music?)
1253    (_i "Take the music in @var{part1} and @var{part2} and typeset so
1254 that they share a staff with stems directed upward.")
1255    (make-directed-part-combine-music UP chord-range part1 part2
1256     #{ \with { \voiceOne \override DynamicLineSpanner.direction = #UP } #}
1257     #{ \with { \voiceThree \override DynamicLineSpanner.direction = #UP } #}
1258     #{ \with { \voiceOne \override DynamicLineSpanner.direction = #UP } #} ))
1259
1260 partcombineDown =
1261 #(define-music-function (chord-range part1 part2)
1262    ((number-pair? '(0 . 8)) ly:music? ly:music?)
1263    (_i "Take the music in @var{part1} and @var{part2} and typeset so
1264 that they share a staff with stems directed downward.")
1265    (make-directed-part-combine-music DOWN chord-range part1 part2
1266     #{ \with { \voiceFour \override DynamicLineSpanner.direction = #DOWN } #}
1267     #{ \with { \voiceTwo \override DynamicLineSpanner.direction = #DOWN } #}
1268     #{ \with { \voiceTwo \override DynamicLineSpanner.direction = #DOWN } #} ))
1269
1270 partcombineForce =
1271 #(define-music-function (type once) (boolean-or-symbol? boolean?)
1272    (_i "Override the part-combiner.")
1273    (make-music 'EventChord
1274                'elements (list (make-music 'PartCombineForceEvent
1275                                            'forced-type type
1276                                            'once once))))
1277 partcombineApart = \partcombineForce #'apart ##f
1278 partcombineApartOnce = \partcombineForce #'apart ##t
1279 partcombineChords = \partcombineForce #'chords ##f
1280 partcombineChordsOnce = \partcombineForce #'chords ##t
1281 partcombineUnisono = \partcombineForce #'unisono ##f
1282 partcombineUnisonoOnce = \partcombineForce #'unisono ##t
1283 partcombineSoloI = \partcombineForce #'solo1 ##f
1284 partcombineSoloIOnce = \partcombineForce #'solo1 ##t
1285 partcombineSoloII = \partcombineForce #'solo2 ##f
1286 partcombineSoloIIOnce = \partcombineForce #'solo2 ##t
1287 partcombineAutomatic = \partcombineForce ##f ##f
1288 partcombineAutomaticOnce = \partcombineForce ##f ##t
1289
1290 partial =
1291 #(define-music-function (dur) (ly:duration?)
1292   (_i "Make a partial measure.")
1293
1294   ;; We use `descend-to-context' here instead of `context-spec-music' to
1295   ;; ensure \partial still works if the Timing_translator is moved
1296     (descend-to-context
1297      (context-spec-music (make-music 'PartialSet
1298                                      'origin (*location*)
1299                                      'duration dur)
1300                          'Timing)
1301      'Score))
1302
1303 pitchedTrill =
1304 #(define-music-function
1305    (main-note secondary-note)
1306    (ly:music? ly:music?)
1307    (_i "Print a trill with @var{main-note} as the main note of the trill and
1308 print @var{secondary-note} as a stemless note head in parentheses.")
1309    (let* ((get-notes (lambda (ev-chord)
1310                        (extract-named-music ev-chord 'NoteEvent)))
1311           (sec-note-events (get-notes secondary-note))
1312           (trill-events (extract-named-music main-note 'TrillSpanEvent)))
1313      (if (pair? sec-note-events)
1314          (begin
1315            (let* ((trill-pitch (ly:music-property (car sec-note-events) 'pitch))
1316                   (forced (ly:music-property (car sec-note-events) 'force-accidental)))
1317
1318              (if (ly:pitch? trill-pitch)
1319                  (for-each (lambda (m)
1320                              (ly:music-set-property! m 'pitch trill-pitch)) trill-events)
1321                  (begin
1322                    (ly:input-warning (*location*) (_ "Second argument of \\pitchedTrill should be single note: "))
1323                    (display sec-note-events)))
1324
1325              (if (eq? forced #t)
1326                  (for-each (lambda (m)
1327                              (ly:music-set-property! m 'force-accidental forced))
1328                            trill-events)))))
1329      main-note))
1330
1331 propertyOverride =
1332 #(define-music-function (grob-property-path value)
1333    (symbol-list? scheme?)
1334    (_i "Set the grob property specified by @var{grob-property-path} to
1335 @var{value}.  @var{grob-property-path} is a symbol list of the form
1336 @code{Context.GrobName.property} or @code{GrobName.property}, possibly
1337 with subproperties given as well.  This music function is mostly intended
1338 for use from Scheme as a substitute for the built-in @code{\\override}
1339 command.")
1340    (let ((p (check-grob-path grob-property-path (*location*)
1341                              #:default 'Bottom
1342                              #:min 3)))
1343      (if p
1344          (context-spec-music
1345           (make-music 'OverrideProperty
1346                       'symbol (cadr p)
1347                       'origin (*location*)
1348                       'grob-value value
1349                       'grob-property-path (cddr p)
1350                       'pop-first #t)
1351           (car p))
1352          (make-music 'Music))))
1353
1354 propertyRevert =
1355 #(define-music-function (grob-property-path)
1356    (symbol-list?)
1357    (_i "Revert the grob property specified by @var{grob-property-path} to
1358 its previous value.  @var{grob-property-path} is a symbol list of the form
1359 @code{Context.GrobName.property} or @code{GrobName.property}, possibly
1360 with subproperties given as well.  This music function is mostly intended
1361 for use from Scheme as a substitute for the built-in @code{\\revert}
1362 command.")
1363    (let ((p (check-grob-path grob-property-path (*location*)
1364                              #:default 'Bottom
1365                              #:min 3)))
1366      (if p
1367          (context-spec-music
1368           (make-music 'RevertProperty
1369                       'symbol (cadr p)
1370                       'origin (*location*)
1371                       'grob-property-path (cddr p))
1372           (car p))
1373          (make-music 'Music))))
1374
1375 propertySet =
1376 #(define-music-function (property-path value)
1377    (symbol-list-or-symbol? scheme?)
1378    (_i "Set the context property specified by @var{property-path} to
1379 @var{value}.  This music function is mostly intended for use from
1380 Scheme as a substitute for the built-in @code{\\set} command.")
1381    (let ((p (check-context-path property-path (*location*))))
1382      (if p
1383          (context-spec-music
1384           (make-music 'PropertySet
1385                       'symbol (cadr p)
1386                       'value value
1387                       'origin (*location*))
1388           (car p))
1389          (make-music 'Music))))
1390
1391 propertyUnset =
1392 #(define-music-function (property-path)
1393    (symbol-list-or-symbol?)
1394    (_i "Unset the context property specified by @var{property-path}.
1395 This music function is mostly intended for use from Scheme as a
1396 substitute for the built-in @code{\\unset} command.")
1397    (let ((p (check-context-path property-path (*location*))))
1398      (if p
1399          (context-spec-music
1400           (make-music 'PropertyUnset
1401                       'symbol (cadr p)
1402                       'origin (*location*))
1403           (car p))
1404          (make-music 'Music))))
1405
1406 pushToTag =
1407 #(define-music-function (tag more music)
1408    (symbol? ly:music? ly:music?)
1409    (_i "Add @var{more} to the front of @code{elements} of all music
1410 expressions in @var{music} that are tagged with @var{tag}.")
1411    (music-map (lambda (m)
1412                 (if (memq tag (ly:music-property m 'tags))
1413                     (set! (ly:music-property m 'elements)
1414                           (cons more (ly:music-property m 'elements))))
1415                 m)
1416               music))
1417
1418 quoteDuring =
1419 #(define-music-function (what main-music) (string? ly:music?)
1420    (_i "Indicate a section of music to be quoted.  @var{what} indicates the name
1421 of the quoted voice, as specified in an @code{\\addQuote} command.
1422 @var{main-music} is used to indicate the length of music to be quoted;
1423 usually contains spacers or multi-measure rests.")
1424    (make-music 'QuoteMusic
1425                'element main-music
1426                'quoted-music-name what))
1427
1428
1429 relative =
1430 #(define-music-function (pitch music)
1431    ((ly:pitch?) ly:music?)
1432    (_i "Make @var{music} relative to @var{pitch}.  If @var{pitch} is
1433 omitted, the first note in @var{music} is given in absolute pitch.")
1434    ;; When \relative has no clear decision (can only happen with
1435    ;; scales with an even number of steps), it goes down (see
1436    ;; pitch.cc).  The following formula puts out f for both the normal
1437    ;; 7-step scale as well as for a "shortened" scale missing the
1438    ;; final b.  In either case, a first note of c will end up as c,
1439    ;; namely pitch (-1, 0, 0).
1440    (ly:make-music-relative! music
1441                             (or pitch
1442                                 (ly:make-pitch
1443                                  -1
1444                                  (quotient
1445                                   ;; size of current scale:
1446                                   (ly:pitch-steps (ly:make-pitch 1 0))
1447                                   2))))
1448    (make-music 'RelativeOctaveMusic
1449                'element music))
1450
1451 removeWithTag =
1452 #(define-music-function (tags music)
1453    (symbol-list-or-symbol? ly:music?)
1454    (_i "Remove elements of @var{music} that are tagged with one of the
1455 tags in @var{tags}.  @var{tags} may be either a single symbol or a list
1456 of symbols.")
1457    (music-filter
1458     (tags-remove-predicate tags)
1459     music))
1460
1461 resetRelativeOctave =
1462 #(define-music-function (pitch) (ly:pitch?)
1463    (_i "Set the octave inside a \\relative section.")
1464
1465    (make-music 'SequentialMusic
1466                'to-relative-callback
1467                (lambda (music last-pitch) pitch)))
1468
1469 retrograde =
1470 #(define-music-function (music)
1471     (ly:music?)
1472     (_i "Return @var{music} in reverse order.")
1473     (retrograde-music music))
1474
1475 revertTimeSignatureSettings =
1476 #(define-music-function
1477    (time-signature)
1478    (pair?)
1479
1480    (_i "Revert @code{timeSignatureSettings}
1481 for time signatures of @var{time-signature}.")
1482    (revert-time-signature-setting time-signature))
1483
1484 rightHandFinger =
1485 #(define-event-function (finger) (number-or-markup?)
1486    (_i "Apply @var{finger} as a fingering indication.")
1487
1488    (make-music
1489             'StrokeFingerEvent
1490             (if (number? finger) 'digit 'text)
1491             finger))
1492
1493 scaleDurations =
1494 #(define-music-function (fraction music)
1495    (fraction? ly:music?)
1496    (_i "Multiply the duration of events in @var{music} by @var{fraction}.")
1497    (ly:music-compress music
1498                       (ly:make-moment (car fraction) (cdr fraction))))
1499
1500 settingsFrom =
1501 #(define-scheme-function (ctx music)
1502    ((symbol?) ly:music?)
1503    (_i "Take the layout instruction events from @var{music}, optionally
1504 restricted to those applying to context type @var{ctx}, and return
1505 a context modification duplicating their effect.")
1506    (let ((mods (ly:make-context-mod)))
1507      (define (musicop m)
1508        (if (music-is-of-type? m 'layout-instruction-event)
1509            (ly:add-context-mod
1510             mods
1511             (case (ly:music-property m 'name)
1512               ((PropertySet)
1513                (list 'assign
1514                      (ly:music-property m 'symbol)
1515                      (ly:music-property m 'value)))
1516               ((PropertyUnset)
1517                (list 'unset
1518                      (ly:music-property m 'symbol)))
1519               ((OverrideProperty)
1520                (cons* 'push
1521                       (ly:music-property m 'symbol)
1522                       (ly:music-property m 'grob-value)
1523                       (cond
1524                        ((ly:music-property m 'grob-property #f) => list)
1525                        (else
1526                         (ly:music-property m 'grob-property-path)))))
1527               ((RevertProperty)
1528                (cons* 'pop
1529                       (ly:music-property m 'symbol)
1530                       (cond
1531                        ((ly:music-property m 'grob-property #f) => list)
1532                        (else
1533                         (ly:music-property m 'grob-property-path)))))))
1534            (case (ly:music-property m 'name)
1535              ((ApplyContext)
1536               (ly:add-context-mod mods
1537                                   (list 'apply
1538                                         (ly:music-property m 'procedure))))
1539              ((ContextSpeccedMusic)
1540               (if (or (not ctx)
1541                       (eq? ctx (ly:music-property m 'context-type)))
1542                   (musicop (ly:music-property m 'element))))
1543              (else
1544               (let ((callback (ly:music-property m 'elements-callback)))
1545                 (if (procedure? callback)
1546                     (for-each musicop (callback m))))))))
1547      (musicop music)
1548      mods))
1549
1550 shape =
1551 #(define-music-function (offsets item)
1552    (list? symbol-list-or-music?)
1553    (_i "Offset control-points of @var{item} by @var{offsets}.  The
1554 argument is a list of number pairs or list of such lists.  Each
1555 element of a pair represents an offset to one of the coordinates of a
1556 control-point.  If @var{item} is a string, the result is
1557 @code{\\once\\override} for the specified grob type.  If @var{item} is
1558 a music expression, the result is the same music expression with an
1559 appropriate tweak applied.")
1560    (define (shape-curve grob)
1561      (let* ((orig (ly:grob-original grob))
1562             (siblings (if (ly:spanner? grob)
1563                           (ly:spanner-broken-into orig) '()))
1564             (total-found (length siblings))
1565             (function (assoc-get 'control-points
1566                                  (reverse (ly:grob-basic-properties grob))))
1567             (coords (function grob)))
1568
1569        (define (offset-control-points offsets)
1570          (if (null? offsets)
1571              coords
1572              (map
1573                (lambda (x y) (coord-translate x y))
1574                coords offsets)))
1575
1576        (define (helper sibs offs)
1577          (if (pair? offs)
1578              (if (eq? (car sibs) grob)
1579                  (offset-control-points (car offs))
1580                  (helper (cdr sibs) (cdr offs)))
1581              coords))
1582
1583        ;; we work with lists of lists
1584        (if (or (null? offsets)
1585                (not (list? (car offsets))))
1586            (set! offsets (list offsets)))
1587
1588        (if (>= total-found 2)
1589            (helper siblings offsets)
1590            (offset-control-points (car offsets)))))
1591    (once (tweak 'control-points shape-curve item)))
1592
1593 shiftDurations =
1594 #(define-music-function (dur dots arg)
1595    (integer? integer? ly:music?)
1596    (_i "Change the duration of @var{arg} by adding @var{dur} to the
1597 @code{durlog} of @var{arg} and @var{dots} to the @code{dots} of @var{arg}.")
1598
1599    (shift-duration-log arg dur dots))
1600
1601 single =
1602 #(define-music-function (overrides music)
1603    (ly:music? ly:music?)
1604    (_i "Convert @var{overrides} to tweaks and apply them to @var{music}.
1605 This does not convert @code{\\revert}, @code{\\set} or @code{\\unset}.")
1606    (set! (ly:music-property music 'tweaks)
1607          (fold-some-music
1608           (lambda (m) (eq? (ly:music-property m 'name)
1609                            'OverrideProperty))
1610           (lambda (m tweaks)
1611             (let ((p (cond
1612                       ((ly:music-property m 'grob-property #f) => list)
1613                       (else
1614                        (ly:music-property m 'grob-property-path)))))
1615               (acons (cons (ly:music-property m 'symbol) ;grob name
1616                            (if (pair? (cdr p))
1617                                p ;grob property path
1618                                (car p))) ;grob property
1619                      (ly:music-property m 'grob-value)
1620                      tweaks)))
1621           (ly:music-property music 'tweaks)
1622           overrides))
1623    music)
1624
1625 skip =
1626 #(define-music-function (dur) (ly:duration?)
1627   (_i "Skip forward by @var{dur}.")
1628   (make-music 'SkipMusic
1629               'duration dur))
1630
1631
1632 slashedGrace =
1633 #(def-grace-function startSlashedGraceMusic stopSlashedGraceMusic
1634    (_i "Create slashed graces (slashes through stems, but no slur) from
1635 the following music expression"))
1636
1637 spacingTweaks =
1638 #(define-music-function (parameters) (list?)
1639    (_i "Set the system stretch, by reading the 'system-stretch property of
1640 the `parameters' assoc list.")
1641    (overrideProperty
1642     '(Score NonMusicalPaperColumn line-break-system-details)
1643     (list (cons 'alignment-extra-space (cdr (assoc 'system-stretch parameters)))
1644           (cons 'system-Y-extent (cdr (assoc 'system-Y-extent parameters))))))
1645
1646 styledNoteHeads =
1647 #(define-music-function (style heads music)
1648    (symbol? symbol-list-or-symbol? ly:music?)
1649    (_i "Set @var{heads} in @var{music} to @var{style}.")
1650    (style-note-heads heads style music))
1651
1652 tag =
1653 #(define-music-function (tags music) (symbol-list-or-symbol? ly:music?)
1654    (_i "Tag the following @var{music} with @var{tags} and return the
1655 result, by adding the single symbol or symbol list @var{tags} to the
1656 @code{tags} property of @var{music}.")
1657
1658    (set!
1659     (ly:music-property music 'tags)
1660     ((if (symbol? tags) cons append)
1661      tags
1662      (ly:music-property music 'tags)))
1663    music)
1664
1665 tagGroup =
1666 #(define-void-function (tags) (symbol-list?)
1667    (_i "Define a tag group comprising the symbols in the symbol list
1668 @var{tags}.  Tag groups must not overlap.")
1669    (let ((err (define-tag-group tags)))
1670      (if err (ly:parser-error err (*location*)))))
1671
1672 temporary =
1673 #(define-music-function (music)
1674    (ly:music?)
1675    (_i "Make any @code{\\override} in @var{music} replace an existing
1676 grob property value only temporarily, restoring the old value when a
1677 corresponding @code{\\revert} is executed.  This is achieved by
1678 clearing the @samp{pop-first} property normally set on
1679 @code{\\override}s.
1680
1681 An @code{\\override}/@/@code{\\revert} sequence created by using
1682 @code{\\temporary} and @code{\\undo} on the same music containing
1683 overrides will cancel out perfectly or cause a@tie{}warning.
1684
1685 Non-property-related music is ignored, warnings are generated for any
1686 property-changing music that isn't an @code{\\override}.")
1687    (define warned #f)
1688    (for-some-music
1689     (lambda (m)
1690       (and (or (music-is-of-type? m 'layout-instruction-event)
1691                (music-is-of-type? m 'context-specification)
1692                (music-is-of-type? m 'apply-context)
1693                (music-is-of-type? m 'time-signature-music))
1694            (case (ly:music-property m 'name)
1695              ((OverrideProperty)
1696               (if (ly:music-property m 'pop-first #f)
1697                   (set! (ly:music-property m 'pop-first) '()))
1698               (if (ly:music-property m 'once #f)
1699                   (set! (ly:music-property m 'once) '()))
1700               #t)
1701              ((ContextSpeccedMusic)
1702               #f)
1703              (else
1704               (if (not warned)
1705                   (begin
1706                     (ly:input-warning (*location*) (_ "Cannot make ~a revertible")
1707                                       (ly:music-property m 'name))
1708                     (set! warned #t)))
1709               #t))))
1710     music)
1711    music)
1712
1713 time =
1714 #(define-music-function (beat-structure fraction)
1715    ((number-list? '()) fraction?)
1716    (_i "Set @var{fraction} as time signature, with optional
1717 number list @var{beat-structure} before it.")
1718   (make-music 'TimeSignatureMusic
1719               'numerator (car fraction)
1720               'denominator (cdr fraction)
1721               'beat-structure beat-structure))
1722
1723 times =
1724 #(define-music-function (fraction music)
1725    (fraction? ly:music?)
1726    (_i "Scale @var{music} in time by @var{fraction}.")
1727   (make-music 'TimeScaledMusic
1728               'element (ly:music-compress music (ly:make-moment (car fraction) (cdr fraction)))
1729               'numerator (car fraction)
1730               'denominator (cdr fraction)))
1731
1732 transpose =
1733 #(define-music-function
1734    (from to music)
1735    (ly:pitch? ly:pitch? ly:music?)
1736
1737    (_i "Transpose @var{music} from pitch @var{from} to pitch @var{to}.")
1738    (make-music 'TransposedMusic
1739                'element (ly:music-transpose music (ly:pitch-diff to from))))
1740
1741 transposedCueDuring =
1742 #(define-music-function
1743    (what dir pitch main-music)
1744    (string? ly:dir? ly:pitch? ly:music?)
1745
1746    (_i "Insert notes from the part @var{what} into a voice called @code{cue},
1747 using the transposition defined by @var{pitch}.  This happens
1748 simultaneously with @var{main-music}, which is usually a rest.  The
1749 argument @var{dir} determines whether the cue notes should be notated
1750 as a first or second voice.")
1751
1752    (make-music 'QuoteMusic
1753                'element main-music
1754                'quoted-context-type 'CueVoice
1755                'quoted-context-id "cue"
1756                'quoted-music-name what
1757                'quoted-voice-direction dir
1758                ;; following is inverse of instrumentTransposition for
1759                ;; historical reasons
1760                'quoted-transposition pitch))
1761
1762 transposition =
1763 #(define-music-function (pitch) (ly:pitch?)
1764    (_i "Set instrument transposition")
1765
1766    (context-spec-music
1767     (make-property-set 'instrumentTransposition pitch)
1768     'Staff))
1769
1770 tuplet =
1771 #(define-music-function (ratio tuplet-span music)
1772    (fraction? (ly:duration? '()) ly:music?)
1773    (_i "Scale the given @var{music} to tuplets.  @var{ratio} is a
1774 fraction that specifies how many notes are played in place of the
1775 nominal value: it will be @samp{3/2} for triplets, namely three notes
1776 being played in place of two.  If the optional duration
1777 @var{tuplet-span} is specified, it is used instead of
1778 @code{tupletSpannerDuration} for grouping the tuplets.
1779 For example,
1780 @example
1781 \\tuplet 3/2 4 @{ c8 c c c c c @}
1782 @end example
1783 will result in two groups of three tuplets, each group lasting for a
1784 quarter note.")
1785    (make-music 'TimeScaledMusic
1786                'element (ly:music-compress
1787                          music
1788                          (ly:make-moment (cdr ratio) (car ratio)))
1789                'numerator (cdr ratio)
1790                'denominator (car ratio)
1791                'duration tuplet-span))
1792
1793 tupletSpan =
1794 #(define-music-function (tuplet-span)
1795    ((ly:duration?))
1796    (_i "Set @code{tupletSpannerDuration}, the length into which
1797 @code{\\tuplet} without an explicit @samp{tuplet-span} argument of its
1798 own will group its tuplets, to the duration @var{tuplet-span}.  To
1799 revert to the default of not subdividing the contents of a @code{\\tuplet}
1800 command without explicit @samp{tuplet-span}, use
1801 @example
1802 \\tupletSpan \\default
1803 @end example
1804 ")
1805    (if tuplet-span
1806        #{ \set tupletSpannerDuration = #(ly:duration-length tuplet-span) #}
1807        #{ \unset tupletSpannerDuration #}))
1808
1809 tweak =
1810 #(define-music-function (prop value item)
1811    (symbol-list-or-symbol? scheme? symbol-list-or-music?)
1812    (_i "Add a tweak to the following @var{item}, usually music.
1813 Layout objects created by @var{item} get their property @var{prop}
1814 set to @var{value}.  If @var{prop} has the form @samp{Grob.property}, like with
1815 @example
1816 \\tweak Accidental.color #red cis'
1817 @end example
1818 an indirectly created grob (@samp{Accidental} is caused by
1819 @samp{NoteHead}) can be tweaked; otherwise only directly created grobs
1820 are affected.
1821
1822 As a special case, @var{item} may be a symbol list specifying a grob
1823 path, in which case @code{\\override} is called on it instead of
1824 creating tweaked music.  This is mainly useful when using
1825 @code{\\tweak} as as a component for building other functions.
1826
1827 If this use case would call for @code{\\once \\override} rather than a
1828 plain @code{\\override}, writing @code{\\once \\tweak @dots{}} can be
1829 convenient.
1830
1831 @var{prop} can contain additional elements in which case a nested
1832 property (inside of an alist) is tweaked.")
1833    (if (ly:music? item)
1834        (let ((p (check-grob-path prop (*location*)
1835                                  #:start 1
1836                                  #:default #t
1837                                  #:min 2)))
1838          (cond ((not p))
1839                ;; p now contains at least two elements.  The first
1840                ;; element is #t when no grob has been explicitly
1841                ;; specified, otherwise it is a grob name.
1842                ((music-is-of-type? item 'context-specification)
1843                 ;; This is essentially dealing with the case
1844                 ;; \tweak color #red \tweak font-size #3 NoteHead
1845                 ;; namely when stacked tweaks end in a symbol list
1846                 ;; rather than a music expression.
1847                 ;;
1848                 ;; We have a tweak here to convert into an override,
1849                 ;; so we need to know the grob to apply it to.  That's
1850                 ;; easy if we have a directed tweak, and otherwise we
1851                 ;; need to find the symbol in the expression itself.
1852                 (let* ((elt (ly:music-property item 'element))
1853                        (seq (if (music-is-of-type? elt 'sequential-music)
1854                                 elt
1855                                 (make-sequential-music (list elt))))
1856                        (elts (ly:music-property seq 'elements))
1857                        (symbol (if (symbol? (car p))
1858                                    (car p)
1859                                    (and (pair? elts)
1860                                         (ly:music-property (car elts)
1861                                                            'symbol)))))
1862                   (if (symbol? symbol)
1863                       (begin
1864                         (set! (ly:music-property seq 'elements)
1865                               (cons (make-music 'OverrideProperty
1866                                                 'symbol symbol
1867                                                 'grob-property-path (cdr p)
1868                                                 'pop-first #t
1869                                                 'grob-value value
1870                                                 'origin (*location*))
1871                                     elts))
1872                         (set! (ly:music-property item 'element) seq))
1873                       (begin
1874                         (ly:parser-error (_ "Cannot \\tweak")
1875                                          (*location*))
1876                         (ly:music-message item (_ "untweakable"))))))
1877                (else
1878                 (set! (ly:music-property item 'tweaks)
1879                       (acons (cond ((pair? (cddr p)) p)
1880                                    ((symbol? (car p))
1881                                     (cons (car p) (cadr p)))
1882                                    (else (cadr p)))
1883                              value
1884                              (ly:music-property item 'tweaks)))))
1885          item)
1886        (propertyOverride (append item (if (symbol? prop) (list prop) prop)) value)))
1887
1888 undo =
1889 #(define-music-function (music)
1890    (ly:music?)
1891    (_i "Convert @code{\\override} and @code{\\set} in @var{music} to
1892 @code{\\revert} and @code{\\unset}, respectively.  Any reverts and
1893 unsets already in @var{music} cause a warning.  Non-property-related music is ignored.")
1894    (define warned #f)
1895    (let loop
1896        ((music music))
1897      (let
1898          ((lst
1899            (fold-some-music
1900             (music-type-predicate '(layout-instruction-event
1901                                     context-specification
1902                                     apply-context
1903                                     time-signature-music))
1904             (lambda (m overrides)
1905               (case (ly:music-property m 'name)
1906                 ((OverrideProperty)
1907                  (cons
1908                   (make-music 'RevertProperty
1909                               'symbol (ly:music-property m 'symbol)
1910                               'grob-property-path
1911                               (cond
1912                                ((ly:music-property m 'grob-property #f) => list)
1913                                (else
1914                                 (ly:music-property m 'grob-property-path))))
1915                   overrides))
1916                 ((PropertySet)
1917                  (cons
1918                   (make-music 'PropertyUnset
1919                               'symbol (ly:music-property m 'symbol))
1920                   overrides))
1921                 ((ContextSpeccedMusic)
1922                  (cons
1923                   (make-music 'ContextSpeccedMusic
1924                               'element (loop (ly:music-property m 'element))
1925                               'context-type (ly:music-property m 'context-type))
1926                   overrides))
1927                 (else
1928                  (if (not warned)
1929                      (begin
1930                        (ly:input-warning (*location*) (_ "Cannot revert ~a")
1931                                          (ly:music-property m 'name))
1932                        (set! warned #t)))
1933                  overrides)))
1934             '()
1935             music)))
1936        (cond
1937         ((null? lst) (make-music 'Music))
1938         ((null? (cdr lst)) (car lst))
1939         (else (make-sequential-music lst))))))
1940
1941 unfoldRepeats =
1942 #(define-music-function (music) (ly:music?)
1943    (_i "Force any @code{\\repeat volta}, @code{\\repeat tremolo} or
1944 @code{\\repeat percent} commands in @var{music} to be interpreted
1945 as @code{\\repeat unfold}.")
1946    (unfold-repeats music))
1947
1948 void =
1949 #(define-void-function (arg) (scheme?)
1950    (_i "Accept a scheme argument, return a void expression.
1951 Use this if you want to have a scheme expression evaluated
1952 because of its side-effects, but its value ignored."))
1953
1954 withMusicProperty =
1955 #(define-music-function (sym val music)
1956    (symbol? scheme? ly:music?)
1957    (_i "Set @var{sym} to @var{val} in @var{music}.")
1958
1959    (set! (ly:music-property music sym) val)
1960    music)