]> git.donarmstrong.com Git - lilypond.git/blob - ly/music-functions-init.ly
music-functions-init.ly: Use Scheme functions instead of void music functions.
[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--2011 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.14.0"
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 acciaccatura =
35 #(def-grace-function startAcciaccaturaMusic stopAcciaccaturaMusic
36    (_i "Create an acciaccatura from the following music expression"))
37
38 %% keep these two together
39 "instrument-definitions" = #'()
40 addInstrumentDefinition =
41 #(define-scheme-function
42    (parser location name lst) (string? list?)
43    (_i "Create instrument @var{name} with properties @var{list}.")
44    (set! instrument-definitions (acons name lst instrument-definitions)))
45
46 addQuote =
47 #(define-scheme-function (parser location name music) (string? ly:music?)
48    (_i "Define @var{music} as a quotable music expression named
49 @var{name}")
50    (add-quotable parser name music))
51
52 %% keep these two together
53 afterGraceFraction = #(cons 6 8)
54 afterGrace =
55 #(define-music-function (parser location main grace) (ly:music? ly:music?)
56    (_i "Create @var{grace} note(s) after a @var{main} music expression.")
57    (let ((main-length (ly:music-length main))
58          (fraction  (ly:parser-lookup parser 'afterGraceFraction)))
59      (make-simultaneous-music
60       (list
61        main
62        (make-sequential-music
63         (list
64
65          (make-music 'SkipMusic
66                      'duration (ly:make-duration
67                                 0 0
68                                 (* (ly:moment-main-numerator main-length)
69                                    (car fraction))
70                                 (* (ly:moment-main-denominator main-length)
71                                    (cdr fraction))))
72          (make-music 'GraceMusic
73                      'element grace)))))))
74
75
76 %% music identifiers not allowed at top-level,
77 %% so this is a music-function instead.
78 allowPageTurn =
79 #(define-music-function (location parser) ()
80    (_i "Allow a page turn. May be used at toplevel (ie between scores or
81 markups), or inside a score.")
82    (make-music 'EventChord
83                'page-marker #t
84                'page-turn-permission 'allow
85                'elements (list (make-music 'PageTurnEvent
86                                            'break-permission 'allow))))
87
88 applyContext =
89 #(define-music-function (parser location proc) (procedure?)
90    (_i "Modify context properties with Scheme procedure @var{proc}.")
91    (make-music 'ApplyContext
92                'procedure proc))
93
94 applyMusic =
95 #(define-music-function (parser location func music) (procedure? ly:music?)
96    (_i"Apply procedure @var{func} to @var{music}.")
97    (func music))
98
99 applyOutput =
100 #(define-music-function (parser location ctx proc) (symbol? procedure?)
101    (_i "Apply function @code{proc} to every layout object in context @code{ctx}")
102    (make-music 'ApplyOutputEvent
103                'procedure proc
104                'context-type ctx))
105
106 appoggiatura =
107 #(def-grace-function startAppoggiaturaMusic stopAppoggiaturaMusic
108    (_i "Create an appoggiatura from @var{music}"))
109
110 % for regression testing purposes.
111 assertBeamQuant =
112 #(define-music-function (parser location l r) (pair? pair?)
113    (_i "Testing function: check whether the beam quants @var{l} and @var{r} are correct")
114    (make-grob-property-override 'Beam 'positions
115                                 (ly:make-simple-closure
116                                  (ly:make-simple-closure
117                                   (append
118                                    (list chain-grob-member-functions `(,cons 0 0))
119                                    (check-quant-callbacks l r))))))
120
121 % for regression testing purposes.
122 assertBeamSlope =
123 #(define-music-function (parser location comp) (procedure?)
124    (_i "Testing function: check whether the slope of the beam is the same as @code{comp}")
125    (make-grob-property-override 'Beam 'positions
126                                 (ly:make-simple-closure
127                                  (ly:make-simple-closure
128                                   (append
129                                    (list chain-grob-member-functions `(,cons 0 0))
130                                    (check-slope-callbacks comp))))))
131
132 autochange =
133 #(define-music-function (parser location music) (ly:music?)
134    (_i "Make voices that switch between staves automatically")
135    (make-autochange-music parser music))
136
137
138
139 balloonGrobText =
140 #(define-music-function (parser location grob-name offset text)
141    (symbol? number-pair? markup?)
142    (_i "Attach @var{text} to @var{grob-name} at offset @var{offset}
143  (use like @code{\\once})")
144    (make-music 'AnnotateOutputEvent
145                'symbol grob-name
146                'X-offset (car offset)
147                'Y-offset (cdr offset)
148                'text text))
149
150 balloonText =
151 #(define-music-function (parser location offset text) (number-pair? markup?)
152    (_i "Attach @var{text} at @var{offset} (use like @code{\\tweak})")
153    (make-music 'AnnotateOutputEvent
154                'X-offset (car offset)
155                'Y-offset (cdr offset)
156                'text text))
157
158 bar =
159 #(define-music-function (parser location type) (string?)
160    (_i "Insert a bar line of type @var{type}")
161    (context-spec-music
162     (make-property-set 'whichBar type)
163     'Timing))
164
165 barNumberCheck =
166 #(define-music-function (parser location n) (integer?)
167    (_i "Print a warning if the current bar number is not @var{n}.")
168    (make-music 'ApplyContext
169                'procedure
170                (lambda (c)
171                  (let ((cbn (ly:context-property c 'currentBarNumber)))
172                    (if (and  (number? cbn) (not (= cbn n)))
173                        (ly:input-warning location
174                                          "Barcheck failed got ~a expect ~a"
175                                          cbn n))))))
176
177 bendAfter =
178 #(define-music-function (parser location delta) (real?)
179    (_i "Create a fall or doit of pitch interval @var{delta}.")
180    (make-music 'BendAfterEvent
181                'delta-step delta))
182
183 bookOutputName =
184 #(define-scheme-function (parser location newfilename) (string?)
185    (_i "Direct output for the current book block to @var{newfilename}.")
186    (set! book-filename newfilename))
187
188 bookOutputSuffix =
189 #(define-scheme-function (parser location newsuffix) (string?)
190    (_i "Set the output filename suffix for the current book block to
191 @var{newsuffix}.")
192    (set! book-output-suffix newsuffix))
193
194 %% \breathe is defined as a music function rather than an event identifier to
195 %% ensure it gets useful input location information: as an event identifier,
196 %% it would have to be wrapped in an EventChord to prevent it from being
197 %% treated as a post_event by the parser
198 breathe =
199 #(define-music-function (parser location) ()
200    (_i "Insert a breath mark.")
201    (make-music 'BreathingEvent))
202
203 clef =
204 #(define-music-function (parser location type) (string?)
205    (_i "Set the current clef to @var{type}.")
206    (make-clef-set type))
207
208
209 compoundMeter =
210 #(define-music-function (parser location args) (pair?)
211   (_i "Create compound time signatures. The argument is a Scheme list of
212 lists. Each list describes one fraction, with the last entry being the
213 denominator, while the first entries describe the summands in the
214 enumerator. If the time signature consists of just one fraction,
215 the list can be given directly, i.e. not as a list containing a single list.
216 For example, a time signature of (3+1)/8 + 2/4 would be created as
217 @code{\\compoundMeter #'((3 1 8) (2 4))}, and a time signature of (3+2)/8
218 as @code{\\compoundMeter #'((3 2 8))} or shorter
219 @code{\\compoundMeter #'(3 2 8)}.")
220   (let* ((mlen (calculate-compound-measure-length args))
221          (beat (calculate-compound-base-beat args))
222          (beatGrouping (calculate-compound-beat-grouping args))
223          (timesig (cons (ly:moment-main-numerator mlen)
224                         (ly:moment-main-denominator mlen))))
225   #{
226     \once \override Staff.TimeSignature #'stencil = #(lambda (grob)
227                 (grob-interpret-markup grob (format-compound-time $args)))
228     \set Timing.timeSignatureFraction = $timesig
229     \set Timing.baseMoment = $beat
230     \set Timing.beatStructure = $beatGrouping
231     \set Timing.beamExceptions = #'()
232     \set Timing.measureLength = $mlen
233   #} ))
234
235
236 cueClef =
237 #(define-music-function (parser location type) (string?)
238   (_i "Set the current cue clef to @var{type}.")
239   (make-cue-clef-set type))
240 cueClefUnset =
241 #(define-music-function (parser location) ()
242   (_i "Unset the current cue clef.")
243   (make-cue-clef-unset))
244
245 cueDuring =
246 #(define-music-function
247    (parser location what dir main-music) (string? ly:dir? ly:music?)
248    (_i "Insert contents of quote @var{what} corresponding to @var{main-music},
249 in a CueVoice oriented by @var{dir}.")
250    (make-music 'QuoteMusic
251                'element main-music
252                'quoted-context-type 'Voice
253                'quoted-context-id "cue"
254                'quoted-music-name what
255                'quoted-voice-direction dir))
256
257 cueDuringWithClef =
258 #(define-music-function
259    (parser location what dir clef main-music) (string? ly:dir? string? ly:music?)
260    (_i "Insert contents of quote @var{what} corresponding to @var{main-music},
261 in a CueVoice oriented by @var{dir}.")
262    (make-music 'QuoteMusic
263                'element main-music
264                'quoted-context-type 'Voice
265                'quoted-context-id "cue"
266                'quoted-music-name what
267                'quoted-music-clef clef
268                'quoted-voice-direction dir))
269
270
271
272 displayLilyMusic =
273 #(define-music-function (parser location music) (ly:music?)
274    (_i "Display the LilyPond input representation of @var{music}
275 to the console.")
276    (newline)
277    (display-lily-music music parser)
278    music)
279
280 displayMusic =
281 #(define-music-function (parser location music) (ly:music?)
282    (_i "Display the internal representation of @var{music} to the console.")
283    (newline)
284    (display-scheme-music music)
285    music)
286
287
288
289 endSpanners =
290 #(define-music-function (parser location music) (ly:music?)
291    (_i "Terminate the next spanner prematurely after exactly one note
292 without the need of a specific end spanner.")
293    (if (eq? (ly:music-property music 'name) 'EventChord)
294        (let* ((elts (ly:music-property music 'elements))
295               (start-span-evs (filter (lambda (ev)
296                                         (and (music-has-type ev 'span-event)
297                                              (equal? (ly:music-property ev 'span-direction)
298                                                      START)))
299                                       elts))
300               (stop-span-evs
301                (map (lambda (m)
302                       (let ((c (music-clone m)))
303                         (set! (ly:music-property c 'span-direction) STOP)
304                         c))
305                     start-span-evs))
306               (end-ev-chord (make-music 'EventChord
307                                         'elements stop-span-evs))
308               (total (make-music 'SequentialMusic
309                                  'elements (list music
310                                                  end-ev-chord))))
311          total)
312
313        (ly:input-message location (_ "argument endSpanners is not an EventChord: ~a" music))))
314
315
316
317 featherDurations=
318 #(define-music-function (parser location factor argument) (ly:moment? ly:music?)
319    (_i "Adjust durations of music in @var{argument} by rational @var{factor}.")
320    (let ((orig-duration (ly:music-length argument))
321          (multiplier (ly:make-moment 1 1)))
322
323      (music-map
324       (lambda (mus)
325         (if (and (eq? (ly:music-property mus 'name) 'EventChord)
326                  (< 0 (ly:moment-main-denominator (ly:music-length mus))))
327             (begin
328               (ly:music-compress mus multiplier)
329               (set! multiplier (ly:moment-mul factor multiplier))))
330         mus)
331       argument)
332
333      (ly:music-compress
334       argument
335       (ly:moment-div orig-duration (ly:music-length argument)))
336
337      argument))
338
339 footnoteGrob =
340 #(define-music-function (parser location grob-name offset text footnote)
341    (symbol? number-pair? markup? markup?)
342    (_i "Attach @var{text} to @var{grob-name} at offset @var{offset},
343 with @var{text} referring to @var{footnote} (use like @code{\\once})")
344    (make-music 'FootnoteEvent
345                'automatically-numbered #f
346                'symbol grob-name
347                'X-offset (car offset)
348                'Y-offset (cdr offset)
349                'text text
350                'footnote-text footnote))
351
352 autoFootnoteGrob =
353 #(define-music-function (parser location grob-name offset footnote)
354    (symbol? number-pair? markup?)
355    (_i "Footnote @var{grob-name} with the text in @var{footnote}
356 allowing for the footnote to be automatically numbered such that
357 the number appears at @var{offset}.  Note that, for this to take effect,
358 auto-numbering must be turned on in the paper block.  Otherwise, no
359 number will appear.  Use like @code{\\once})")
360    (make-music 'FootnoteEvent
361                'automatically-numbered #t
362                'symbol grob-name
363                'X-offset (car offset)
364                'Y-offset (cdr offset)
365                'text (make-null-markup)
366                'footnote-text footnote))
367
368
369 footnote =
370 #(define-music-function (parser location offset text footnote)
371    (number-pair? markup? markup?)
372    (_i "Attach @var{text} at @var{offset} with @var{text} referring
373 to @var{footnote} (use like @code{\\tweak})")
374    (make-music 'FootnoteEvent
375                'automatically-numbered #f
376                'X-offset (car offset)
377                'Y-offset (cdr offset)
378                'text text
379                'footnote-text footnote))
380
381 autoFootnote =
382 #(define-music-function (parser location offset footnote)
383    (number-pair? markup?)
384    (_i "Footnote the item after which this comes with the text in
385 @var{footnote} allowing for the footnote to be automatically numbered
386 such that the number appears at @var{offset}.  Note that, for this to
387 take effect, auto-numbering must be turned on in the paper block.
388 Otherwise, no number will appear.  Use like @code{\\tweak})")
389    (make-music 'FootnoteEvent
390                'automatically-numbered #t
391                'X-offset (car offset)
392                'Y-offset (cdr offset)
393                'text (make-null-markup)
394                'footnote-text footnote))
395
396 grace =
397 #(def-grace-function startGraceMusic stopGraceMusic
398    (_i "Insert @var{music} as grace notes."))
399
400 harmonicByFret = #(define-music-function (parser location fret music) (number? ly:music?)
401   (let* ((fret (number->string fret))
402          (pitch (fret->pitch fret)))
403         (make-sequential-music
404          (list
405           #{
406             \override TabNoteHead #'stencil = #(tab-note-head::print-custom-fret-label $fret)
407           #}
408           (make-harmonic
409             (calc-harmonic-pitch pitch music))
410           #{
411             \revert TabNoteHead #'stencil
412           #}))))
413
414 harmonicByRatio = #(define-music-function (parser location ratio music) (number? ly:music?)
415   (let ((pitch (ratio->pitch ratio))
416         (fret (ratio->fret ratio)))
417        (make-sequential-music
418         (list
419          #{
420            \override TabNoteHead #'stencil = #(tab-note-head::print-custom-fret-label $fret)
421          #}
422          (make-harmonic
423            (calc-harmonic-pitch pitch music))
424          #{
425             \revert TabNoteHead #'stencil
426          #}))))
427
428 instrumentSwitch =
429 #(define-music-function
430    (parser location name) (string?)
431    (_i "Switch instrument to @var{name}, which must be predefined with
432 @code{\\addInstrumentDefinition}.")
433    (let* ((handle (assoc name instrument-definitions))
434           (instrument-def (if handle (cdr handle) '())))
435
436      (if (not handle)
437          (ly:input-warning location "No such instrument: ~a" name))
438      (context-spec-music
439       (make-music 'SimultaneousMusic
440                   'elements
441                   (map (lambda (kv)
442                          (make-property-set
443                           (car kv)
444                           (cdr kv)))
445                        instrument-def))
446       'Staff)))
447
448
449
450 keepWithTag =
451 #(define-music-function (parser location tag music) (symbol? ly:music?)
452    (_i "Include only elements of @var{music} that are tagged with @var{tag}.")
453    (music-filter
454     (lambda (m)
455       (let* ((tags (ly:music-property m 'tags))
456              (res (memq tag tags)))
457         (or
458          (eq? tags '())
459          res)))
460     music))
461
462 killCues =
463 #(define-music-function (parser location music) (ly:music?)
464    (_i "Remove cue notes from @var{music}.")
465    (music-map
466     (lambda (mus)
467       (if (and (string? (ly:music-property mus 'quoted-music-name))
468                (string=? (ly:music-property mus 'quoted-context-id "") "cue"))
469           (ly:music-property mus 'element)
470           mus))
471     music))
472
473
474
475 label =
476 #(define-music-function (parser location label) (symbol?)
477    (_i "Create @var{label} as a bookmarking label.")
478    (make-music 'EventChord
479                'page-marker #t
480                'page-label label
481                'elements (list (make-music 'LabelEvent
482                                            'page-label label))))
483
484
485 language =
486 #(define-scheme-function (parser location language) (string?)
487    (_i "Set note names for language @var{language}.")
488    (note-names-language parser language))
489
490 languageSaveAndChange =
491 #(define-scheme-function (parser location language) (string?)
492   (_i "Store the previous pitchnames alist, and set a new one.")
493   (set! previous-pitchnames pitchnames)
494   (note-names-language parser language))
495
496 languageRestore =
497 #(define-scheme-function (parser location) ()
498    (_i "Restore a previously-saved pitchnames alist.")
499    (if previous-pitchnames
500        (begin
501         (set! pitchnames previous-pitchnames)
502         (ly:parser-set-note-names parser pitchnames))
503       (ly:input-warning location (_ "No other language was defined previously. Ignoring."))))
504
505
506 makeClusters =
507 #(define-music-function (parser location arg) (ly:music?)
508    (_i "Display chords in @var{arg} as clusters.")
509    (music-map note-to-cluster arg))
510
511 modalInversion =
512 #(define-music-function (parser location around to scale music)
513     (ly:pitch? ly:pitch? ly:music? ly:music?)
514     (_i "Invert @var{music} about @var{around} using @var{scale} and
515 transpose from @var{around} to @var{to}.")
516     (let ((inverter (make-modal-inverter around to scale)))
517       (change-pitches music inverter)
518       music))
519
520 modalTranspose =
521 #(define-music-function (parser location from to scale music)
522     (ly:pitch? ly:pitch? ly:music? ly:music?)
523     (_i "Transpose @var{music} from pitch @var{from} to pitch @var{to}
524 using @var{scale}.")
525     (let ((transposer (make-modal-transposer from to scale)))
526       (change-pitches music transposer)
527       music))
528
529 inversion =
530 #(define-music-function
531    (parser location around to music) (ly:pitch? ly:pitch? ly:music?)
532    (_i "Invert @var{music} about @var{around} and
533 transpose from @var{around} to @var{to}.")
534    (music-invert around to music))
535
536 musicMap =
537 #(define-music-function (parser location proc mus) (procedure? ly:music?)
538    (_i "Apply @var{proc} to @var{mus} and all of the music it contains.")
539    (music-map proc mus))
540
541 %% noPageBreak and noPageTurn are music functions (not music indentifiers),
542 %% because music identifiers are not allowed at top-level.
543 noPageBreak =
544 #(define-music-function (location parser) ()
545    (_i "Forbid a page break.  May be used at toplevel (i.e., between scores or
546 markups), or inside a score.")
547    (make-music 'EventChord
548                'page-marker #t
549                'page-break-permission 'forbid
550                'elements (list (make-music 'PageBreakEvent
551                                            'break-permission '()))))
552
553 noPageTurn =
554 #(define-music-function (location parser) ()
555    (_i "Forbid a page turn.  May be used at toplevel (i.e., between scores or
556 markups), or inside a score.")
557    (make-music 'EventChord
558                'page-marker #t
559                'page-turn-permission 'forbid
560                'elements (list (make-music 'PageTurnEvent
561                                            'break-permission '()))))
562
563
564
565 octaveCheck =
566 #(define-music-function (parser location pitch) (ly:pitch?)
567    (_i "Octave check.")
568    (make-music 'RelativeOctaveCheck
569                'pitch pitch))
570
571 ottava =
572 #(define-music-function (parser location octave) (integer?)
573    (_i "Set the octavation.")
574    (make-music 'OttavaMusic
575                'ottava-number octave))
576
577 overrideTimeSignatureSettings =
578 #(define-music-function
579    (parser location time-signature base-moment beat-structure beam-exceptions)
580    (pair? pair? cheap-list? cheap-list?)
581
582    (_i "Override @code{timeSignatureSettings}
583 for time signatures of @var{time-signature} to have settings
584 of @var{base-moment}, @var{beat-structure}, and @var{beam-exceptions}.")
585
586    ;; TODO -- add warning if largest value of grouping is
587    ;;       greater than time-signature.
588   (let ((setting (make-setting base-moment beat-structure beam-exceptions)))
589     (override-time-signature-setting time-signature setting)))
590
591 overrideProperty =
592 #(define-music-function (parser location name property value)
593    (string? symbol? scheme?)
594
595    (_i "Set @var{property} to @var{value} in all grobs named @var{name}.
596 The @var{name} argument is a string of the form @code{\"Context.GrobName\"}
597 or @code{\"GrobName\"}.")
598
599    (let ((name-components (string-split name #\.))
600          (context-name 'Bottom)
601          (grob-name #f))
602
603      (if (> 2 (length name-components))
604          (set! grob-name (string->symbol (car name-components)))
605          (begin
606            (set! grob-name (string->symbol (list-ref name-components 1)))
607            (set! context-name (string->symbol (list-ref name-components 0)))))
608
609      (make-music 'ApplyOutputEvent
610                  'context-type context-name
611                  'procedure
612                  (lambda (grob orig-context context)
613                    (if (equal?
614                         (cdr (assoc 'name (ly:grob-property grob 'meta)))
615                         grob-name)
616                        (set! (ly:grob-property grob property) value))))))
617
618
619
620 %% pageBreak and pageTurn are music functions (iso music indentifiers),
621 %% because music identifiers are not allowed at top-level.
622 pageBreak =
623 #(define-music-function (location parser) ()
624    (_i "Force a page break.  May be used at toplevel (i.e., between scores or
625 markups), or inside a score.")
626    (make-music 'EventChord
627                'page-marker #t
628                'line-break-permission 'force
629                'page-break-permission 'force
630                'elements (list (make-music 'LineBreakEvent
631                                            'break-permission 'force)
632                                (make-music 'PageBreakEvent
633                                            'break-permission 'force))))
634
635 pageTurn =
636 #(define-music-function (location parser) ()
637    (_i "Force a page turn between two scores or top-level markups.")
638    (make-music 'EventChord
639                'page-marker #t
640                'line-break-permission 'force
641                'page-break-permission 'force
642                'page-turn-permission 'force
643                'elements (list (make-music 'LineBreakEvent
644                                            'break-permission 'force)
645                                (make-music 'PageBreakEvent
646                                            'break-permission 'force)
647                                (make-music 'PageTurnEvent
648                                            'break-permission 'force))))
649
650 parallelMusic =
651 #(define-scheme-function (parser location voice-ids music) (list? ly:music?)
652    (_i "Define parallel music sequences, separated by '|' (bar check signs),
653 and assign them to the identifiers provided in @var{voice-ids}.
654
655 @var{voice-ids}: a list of music identifiers (symbols containing only letters)
656
657 @var{music}: a music sequence, containing BarChecks as limiting expressions.
658
659 Example:
660
661 @verbatim
662   \\parallelMusic #'(A B C) {
663     c c | d d | e e |
664     d d | e e | f f |
665   }
666 <==>
667   A = { c c | d d | }
668   B = { d d | e e | }
669   C = { e e | f f | }
670 @end verbatim
671 ")
672    (let* ((voices (apply circular-list (make-list (length voice-ids) (list))))
673           (current-voices voices)
674           (current-sequence (list)))
675      ;;
676      ;; utilities
677      (define (push-music m)
678        "Push the music expression into the current sequence"
679        (set! current-sequence (cons m current-sequence)))
680      (define (change-voice)
681        "Stores the previously built sequence into the current voice and
682        change to the following voice."
683        (list-set! current-voices 0 (cons (make-music 'SequentialMusic
684                                                      'elements (reverse! current-sequence))
685                                          (car current-voices)))
686        (set! current-sequence (list))
687        (set! current-voices (cdr current-voices)))
688      (define (bar-check? m)
689        "Checks whether m is a bar check."
690        (eq? (ly:music-property m 'name) 'BarCheck))
691      (define (music-origin music)
692        "Recursively search an origin location stored in music."
693        (cond ((null? music) #f)
694              ((not (null? (ly:music-property music 'origin)))
695               (ly:music-property music 'origin))
696              (else (or (music-origin (ly:music-property music 'element))
697                        (let ((origins (remove not (map music-origin
698                                                        (ly:music-property music 'elements)))))
699                          (and (not (null? origins)) (car origins)))))))
700      ;;
701      ;; first, split the music and fill in voices
702      (for-each (lambda (m)
703                      (push-music m)
704                      (if (bar-check? m) (change-voice)))
705                    (ly:music-property music 'elements))
706      (if (not (null? current-sequence)) (change-voice))
707      ;; un-circularize `voices' and reorder the voices
708      (set! voices (map-in-order (lambda (dummy seqs)
709                                   (reverse! seqs))
710                                 voice-ids voices))
711      ;;
712      ;; set origin location of each sequence in each voice
713      ;; for better type error tracking
714      (for-each (lambda (voice)
715                  (for-each (lambda (seq)
716                              (set! (ly:music-property seq 'origin)
717                                    (or (music-origin seq) location)))
718                            voice))
719                voices)
720      ;;
721      ;; check sequence length
722      (apply for-each (lambda* (#:rest seqs)
723                               (let ((moment-reference (ly:music-length (car seqs))))
724                                 (for-each (lambda (seq moment)
725                                             (if (not (equal? moment moment-reference))
726                                                 (ly:music-warning seq
727                                                                   "Bars in parallel music don't have the same length")))
728                                           seqs (map-in-order ly:music-length seqs))))
729             voices)
730      ;;
731      ;; bind voice identifiers to the voices
732      (for-each (lambda (voice-id voice)
733             (ly:parser-define! parser voice-id
734                                (make-music 'SequentialMusic
735                                            'origin location
736                                            'elements voice)))
737           voice-ids voices)))
738
739 parenthesize =
740 #(define-music-function (parser loc arg) (ly:music?)
741    (_i "Tag @var{arg} to be parenthesized.")
742
743    (if (memq 'event-chord (ly:music-property arg 'types))
744        ;; arg is an EventChord -> set the parenthesize property
745        ;; on all child notes and rests
746        (for-each
747         (lambda (ev)
748           (if (or (memq 'note-event (ly:music-property ev 'types))
749                   (memq 'rest-event (ly:music-property ev 'types)))
750               (set! (ly:music-property ev 'parenthesize) #t)))
751         (ly:music-property arg 'elements))
752        ;; No chord, simply set property for this expression:
753        (set! (ly:music-property arg 'parenthesize) #t))
754    arg)
755
756 partcombine =
757 #(define-music-function (parser location part1 part2) (ly:music? ly:music?)
758    (_i "Take the music in @var{part1} and @var{part2} and typeset so
759 that they share a staff.")
760    (make-part-combine-music parser
761                             (list part1 part2)))
762
763 partcombineForce =
764 #(define-music-function (location parser type once) (symbol-or-boolean? boolean?)
765    (_i "Override the part-combiner.")
766    (make-music 'EventChord
767                'elements (list (make-music 'PartCombineForceEvent
768                                            'forced-type type
769                                            'once once))))
770 partcombineApart = \partcombineForce #'apart ##f
771 partcombineApartOnce = \partcombineForce #'apart ##t
772 partcombineChords = \partcombineForce #'chords ##f
773 partcombineChordsOnce = \partcombineForce #'chords ##t
774 partcombineUnisono = \partcombineForce #'unisono ##f
775 partcombineUnisonoOnce = \partcombineForce #'unisono ##t
776 partcombineSoloI = \partcombineForce #'solo1 ##f
777 partcombineSoloIOnce = \partcombineForce #'solo1 ##t
778 partcombineSoloII = \partcombineForce #'solo2 ##f
779 partcombineSoloIIOnce = \partcombineForce #'solo2 ##t
780 partcombineAutomatic = \partcombineForce ##f ##f
781 partcombineAutomaticOnce = \partcombineForce ##f ##t
782
783 partial =
784 #(define-music-function (parser location dur) (ly:duration?)
785   (_i "Make a partial measure.")
786
787   ;; We use `descend-to-context' here instead of `context-spec-music' to
788   ;; ensure \partial still works if the Timing_translator is moved
789     (descend-to-context
790      (context-spec-music (make-music 'PartialSet
791                                      'origin location
792                                      'partial-duration dur)
793                          'Timing)
794      'Score))
795
796 pitchedTrill =
797 #(define-music-function
798    (parser location main-note secondary-note)
799    (ly:music? ly:music?)
800    (_i "Print a trill with @var{main-note} as the main note of the trill and
801 print @var{secondary-note} as a stemless note head in parentheses.")
802    (let* ((get-notes (lambda (ev-chord)
803                        (filter
804                         (lambda (m) (eq? 'NoteEvent (ly:music-property m 'name)))
805                         (ly:music-property ev-chord 'elements))))
806           (sec-note-events (get-notes secondary-note))
807           (trill-events (filter (lambda (m) (music-has-type m 'trill-span-event))
808                                 (ly:music-property main-note 'elements))))
809
810      (if (pair? sec-note-events)
811          (begin
812            (let* ((trill-pitch (ly:music-property (car sec-note-events) 'pitch))
813                   (forced (ly:music-property (car sec-note-events) 'force-accidental)))
814
815              (if (ly:pitch? trill-pitch)
816                  (for-each (lambda (m)
817                              (ly:music-set-property! m 'pitch trill-pitch)) trill-events)
818                  (begin
819                    (ly:input-warning location (_ "Second argument of \\pitchedTrill should be single note: "))
820                    (display sec-note-events)))
821
822              (if (eq? forced #t)
823                  (for-each (lambda (m)
824                              (ly:music-set-property! m 'force-accidental forced))
825                            trill-events)))))
826      main-note))
827
828 quoteDuring =
829 #(define-music-function (parser location what main-music) (string? ly:music?)
830    (_i "Indicate a section of music to be quoted.  @var{what} indicates the name
831 of the quoted voice, as specified in an @code{\\addQuote} command.
832 @var{main-music} is used to indicate the length of music to be quoted;
833 usually contains spacers or multi-measure rests.")
834    (make-music 'QuoteMusic
835                'element main-music
836                'quoted-music-name what))
837
838 removeWithTag =
839 #(define-music-function (parser location tag music) (symbol? ly:music?)
840    (_i "Remove elements of @var{music} that are tagged with @var{tag}.")
841    (music-filter
842     (lambda (m)
843       (let* ((tags (ly:music-property m 'tags))
844              (res (memq tag tags)))
845         (not res)))
846     music))
847
848 resetRelativeOctave =
849 #(define-music-function (parser location pitch) (ly:pitch?)
850    (_i "Set the octave inside a \\relative section.")
851
852    (make-music 'SequentialMusic
853                'to-relative-callback
854                (lambda (music last-pitch) pitch)))
855
856 retrograde =
857 #(define-music-function (parser location music)
858     (ly:music?)
859     (_i "Return @var{music} in reverse order.")
860     (retrograde-music music))
861
862 revertTimeSignatureSettings =
863 #(define-music-function
864    (parser location time-signature)
865    (pair?)
866
867    (_i "Revert @code{timeSignatureSettings}
868 for time signatures of @var{time-signature}.")
869    (revert-time-signature-setting time-signature))
870
871 rightHandFinger =
872 #(define-music-function (parser location finger) (number-or-string?)
873    (_i "Apply @var{finger} as a fingering indication.")
874
875    (make-music
876             'StrokeFingerEvent
877             'origin location
878             (if (string? finger) 'text 'digit)
879             finger))
880
881 scaleDurations =
882 #(define-music-function (parser location fraction music)
883    (number-pair? ly:music?)
884    (_i "Multiply the duration of events in @var{music} by @var{fraction}.")
885    (ly:music-compress music
886                       (ly:make-moment (car fraction) (cdr fraction))))
887
888 shiftDurations =
889 #(define-music-function (parser location dur dots arg)
890    (integer? integer? ly:music?)
891    (_i "Scale @var{arg} up by a factor of 2^@var{dur}*(2-(1/2)^@var{dots}).")
892
893    (music-map
894     (lambda (x)
895       (shift-one-duration-log x dur dots)) arg))
896
897 skip =
898 #(define-music-function (parser location dur) (ly:duration?)
899   (_i "Skip forward by @var{dur}.")
900   (make-music 'SkipMusic
901               'duration dur))
902
903
904 slashedGrace =
905 #(def-grace-function startSlashedGraceMusic stopSlashedGraceMusic
906    (_i "Create slashed graces (slashes through stems, but no slur) from
907 the following music expression"))
908
909 spacingTweaks =
910 #(define-music-function (parser location parameters) (list?)
911    (_i "Set the system stretch, by reading the 'system-stretch property of
912 the `parameters' assoc list.")
913    #{
914      \overrideProperty #"Score.NonMusicalPaperColumn"
915      #'line-break-system-details
916      #$(list (cons 'alignment-extra-space (cdr (assoc 'system-stretch parameters)))
917              (cons 'system-Y-extent (cdr (assoc 'system-Y-extent parameters))))
918    #})
919
920 styledNoteHeads =
921 #(define-music-function (parser location style heads music)
922    (symbol? list-or-symbol? ly:music?)
923    (_i "Set @var{heads} in @var{music} to @var{style}.")
924    (style-note-heads heads style music))
925
926
927
928 tabChordRepetition =
929 #(define-music-function (parser location) ()
930    (_i "Include the string information in a chord repetition.")
931    (ly:parser-set-repetition-function parser tab-repeat-chord)
932    (make-music 'SequentialMusic 'void #t))
933
934 tag =
935 #(define-music-function (parser location tag arg) (symbol? ly:music?)
936
937    (_i "Add @var{tag} to the @code{tags} property of @var{arg}.")
938
939    (set!
940     (ly:music-property arg 'tags)
941     (cons tag
942           (ly:music-property arg 'tags)))
943    arg)
944
945 transpose =
946 #(define-music-function
947    (parser location from to music)
948    (ly:pitch? ly:pitch? ly:music?)
949
950    (_i "Transpose @var{music} from pitch @var{from} to pitch @var{to}.")
951    (make-music 'TransposedMusic
952                'element (ly:music-transpose music (ly:pitch-diff to from))))
953
954 transposedCueDuring =
955 #(define-music-function
956    (parser location what dir pitch main-music)
957    (string? ly:dir? ly:pitch? ly:music?)
958
959    (_i "Insert notes from the part @var{what} into a voice called @code{cue},
960 using the transposition defined by @var{pitch}.  This happens
961 simultaneously with @var{main-music}, which is usually a rest.  The
962 argument @var{dir} determines whether the cue notes should be notated
963 as a first or second voice.")
964
965    (make-music 'QuoteMusic
966                'element main-music
967                'quoted-context-type 'Voice
968                'quoted-context-id "cue"
969                'quoted-music-name what
970                'quoted-voice-direction dir
971                'quoted-transposition pitch))
972
973 transposition =
974 #(define-music-function (parser location pitch) (ly:pitch?)
975    (_i "Set instrument transposition")
976
977    (context-spec-music
978     (make-property-set 'instrumentTransposition
979                        (ly:pitch-negate pitch))
980     'Staff))
981
982 tweak =
983 #(define-music-function (parser location sym val arg)
984    (symbol? scheme? ly:music?)
985    (_i "Add @code{sym . val} to the @code{tweaks} property of @var{arg}.")
986
987    (if (equal? (object-property sym 'backend-type?) #f)
988        (begin
989          (ly:input-warning location (_ "cannot find property type-check for ~a") sym)
990          (ly:warning (_ "doing assignment anyway"))))
991    (set!
992     (ly:music-property arg 'tweaks)
993     (acons sym val
994            (ly:music-property arg 'tweaks)))
995    arg)
996
997
998
999 unfoldRepeats =
1000 #(define-music-function (parser location music) (ly:music?)
1001    (_i "Force any @code{\\repeat volta}, @code{\\repeat tremolo} or
1002 @code{\\repeat percent} commands in @var{music} to be interpreted
1003 as @code{\\repeat unfold}.")
1004    (unfold-repeats music))
1005
1006
1007
1008 withMusicProperty =
1009 #(define-music-function (parser location sym val music)
1010    (symbol? scheme? ly:music?)
1011    (_i "Set @var{sym} to @var{val} in @var{music}.")
1012
1013    (set! (ly:music-property music sym) val)
1014    music)