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