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