]> git.donarmstrong.com Git - lilypond.git/blob - ly/music-functions-init.ly
Define define-void-function and \void
[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-void-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-void-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-void-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-void-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-void-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-void-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-void-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-void-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) #f))
780
781 partcombineUp =
782 #(define-music-function (parser location part1 part2) (ly:music? ly:music?)
783    (_i "Take the music in @var{part1} and @var{part2} and typeset so
784 that they share a staff with stems directed upward.")
785    (make-part-combine-music parser
786                             (list part1 part2) UP))
787
788 partcombineDown =
789 #(define-music-function (parser location part1 part2) (ly:music? ly:music?)
790    (_i "Take the music in @var{part1} and @var{part2} and typeset so
791 that they share a staff with stems directed downward.")
792    (make-part-combine-music parser
793                             (list part1 part2) DOWN))
794
795 partcombineForce =
796 #(define-music-function (location parser type once) (symbol-or-boolean? boolean?)
797    (_i "Override the part-combiner.")
798    (make-music 'EventChord
799                'elements (list (make-music 'PartCombineForceEvent
800                                            'forced-type type
801                                            'once once))))
802 partcombineApart = \partcombineForce #'apart ##f
803 partcombineApartOnce = \partcombineForce #'apart ##t
804 partcombineChords = \partcombineForce #'chords ##f
805 partcombineChordsOnce = \partcombineForce #'chords ##t
806 partcombineUnisono = \partcombineForce #'unisono ##f
807 partcombineUnisonoOnce = \partcombineForce #'unisono ##t
808 partcombineSoloI = \partcombineForce #'solo1 ##f
809 partcombineSoloIOnce = \partcombineForce #'solo1 ##t
810 partcombineSoloII = \partcombineForce #'solo2 ##f
811 partcombineSoloIIOnce = \partcombineForce #'solo2 ##t
812 partcombineAutomatic = \partcombineForce ##f ##f
813 partcombineAutomaticOnce = \partcombineForce ##f ##t
814
815 partial =
816 #(define-music-function (parser location dur) (ly:duration?)
817   (_i "Make a partial measure.")
818
819   ;; We use `descend-to-context' here instead of `context-spec-music' to
820   ;; ensure \partial still works if the Timing_translator is moved
821     (descend-to-context
822      (context-spec-music (make-music 'PartialSet
823                                      'origin location
824                                      'partial-duration dur)
825                          'Timing)
826      'Score))
827
828 pitchedTrill =
829 #(define-music-function
830    (parser location main-note secondary-note)
831    (ly:music? ly:music?)
832    (_i "Print a trill with @var{main-note} as the main note of the trill and
833 print @var{secondary-note} as a stemless note head in parentheses.")
834    (let* ((get-notes (lambda (ev-chord)
835                        (filter
836                         (lambda (m) (eq? 'NoteEvent (ly:music-property m 'name)))
837                         (ly:music-property ev-chord 'elements))))
838           (sec-note-events (get-notes secondary-note))
839           (trill-events (filter (lambda (m) (music-has-type m 'trill-span-event))
840                                 (ly:music-property main-note 'elements))))
841
842      (if (pair? sec-note-events)
843          (begin
844            (let* ((trill-pitch (ly:music-property (car sec-note-events) 'pitch))
845                   (forced (ly:music-property (car sec-note-events) 'force-accidental)))
846
847              (if (ly:pitch? trill-pitch)
848                  (for-each (lambda (m)
849                              (ly:music-set-property! m 'pitch trill-pitch)) trill-events)
850                  (begin
851                    (ly:input-warning location (_ "Second argument of \\pitchedTrill should be single note: "))
852                    (display sec-note-events)))
853
854              (if (eq? forced #t)
855                  (for-each (lambda (m)
856                              (ly:music-set-property! m 'force-accidental forced))
857                            trill-events)))))
858      main-note))
859
860 pushToTag =
861 #(define-music-function (parser location tag more music)
862    (symbol? ly:music? ly:music?)
863    (_i "Add @var{more} to the front of @code{elements} of all music
864 expressions in @var{music} that are tagged with @var{tag}.")
865    (music-map (lambda (m)
866                 (if (memq tag (ly:music-property m 'tags))
867                     (set! (ly:music-property m 'elements)
868                           (cons more (ly:music-property m 'elements))))
869                 m)
870               music))
871
872 quoteDuring =
873 #(define-music-function (parser location what main-music) (string? ly:music?)
874    (_i "Indicate a section of music to be quoted.  @var{what} indicates the name
875 of the quoted voice, as specified in an @code{\\addQuote} command.
876 @var{main-music} is used to indicate the length of music to be quoted;
877 usually contains spacers or multi-measure rests.")
878    (make-music 'QuoteMusic
879                'element main-music
880                'quoted-music-name what))
881
882 relative =
883 #(define-music-function (parser location pitch music)
884    ((ly:pitch? (ly:make-pitch 0 0 0)) ly:music?)
885    (_i "Make @var{music} relative to @var{pitch} (default @code{c'}).")
886    (ly:make-music-relative! music pitch)
887    (make-music 'RelativeOctaveMusic
888                'element music))
889
890 removeWithTag =
891 #(define-music-function (parser location tag music) (symbol? ly:music?)
892    (_i "Remove elements of @var{music} that are tagged with @var{tag}.")
893    (music-filter
894     (lambda (m)
895       (let* ((tags (ly:music-property m 'tags))
896              (res (memq tag tags)))
897         (not res)))
898     music))
899
900 resetRelativeOctave =
901 #(define-music-function (parser location pitch) (ly:pitch?)
902    (_i "Set the octave inside a \\relative section.")
903
904    (make-music 'SequentialMusic
905                'to-relative-callback
906                (lambda (music last-pitch) pitch)))
907
908 retrograde =
909 #(define-music-function (parser location music)
910     (ly:music?)
911     (_i "Return @var{music} in reverse order.")
912     (retrograde-music music))
913
914 revertTimeSignatureSettings =
915 #(define-music-function
916    (parser location time-signature)
917    (pair?)
918
919    (_i "Revert @code{timeSignatureSettings}
920 for time signatures of @var{time-signature}.")
921    (revert-time-signature-setting time-signature))
922
923 rightHandFinger =
924 #(define-music-function (parser location finger) (number-or-string?)
925    (_i "Apply @var{finger} as a fingering indication.")
926
927    (make-music
928             'StrokeFingerEvent
929             'origin location
930             (if (string? finger) 'text 'digit)
931             finger))
932
933 scaleDurations =
934 #(define-music-function (parser location fraction music)
935    (number-pair? ly:music?)
936    (_i "Multiply the duration of events in @var{music} by @var{fraction}.")
937    (ly:music-compress music
938                       (ly:make-moment (car fraction) (cdr fraction))))
939
940 shiftDurations =
941 #(define-music-function (parser location dur dots arg)
942    (integer? integer? ly:music?)
943    (_i "Scale @var{arg} up by a factor of 2^@var{dur}*(2-(1/2)^@var{dots}).")
944
945    (music-map
946     (lambda (x)
947       (shift-one-duration-log x dur dots)) arg))
948
949 skip =
950 #(define-music-function (parser location dur) (ly:duration?)
951   (_i "Skip forward by @var{dur}.")
952   (make-music 'SkipMusic
953               'duration dur))
954
955
956 slashedGrace =
957 #(def-grace-function startSlashedGraceMusic stopSlashedGraceMusic
958    (_i "Create slashed graces (slashes through stems, but no slur) from
959 the following music expression"))
960
961 spacingTweaks =
962 #(define-music-function (parser location parameters) (list?)
963    (_i "Set the system stretch, by reading the 'system-stretch property of
964 the `parameters' assoc list.")
965    #{
966      \overrideProperty #"Score.NonMusicalPaperColumn"
967      #'line-break-system-details
968      #$(list (cons 'alignment-extra-space (cdr (assoc 'system-stretch parameters)))
969              (cons 'system-Y-extent (cdr (assoc 'system-Y-extent parameters))))
970    #})
971
972 styledNoteHeads =
973 #(define-music-function (parser location style heads music)
974    (symbol? list-or-symbol? ly:music?)
975    (_i "Set @var{heads} in @var{music} to @var{style}.")
976    (style-note-heads heads style music))
977
978
979
980 tabChordRepetition =
981 #(define-music-function (parser location) ()
982    (_i "Include the string information in a chord repetition.")
983    (ly:parser-set-repetition-function parser tab-repeat-chord)
984    (make-music 'SequentialMusic 'void #t))
985
986 tag =
987 #(define-music-function (parser location tag arg) (symbol? ly:music?)
988
989    (_i "Add @var{tag} to the @code{tags} property of @var{arg}.")
990
991    (set!
992     (ly:music-property arg 'tags)
993     (cons tag
994           (ly:music-property arg 'tags)))
995    arg)
996
997 transpose =
998 #(define-music-function
999    (parser location from to music)
1000    (ly:pitch? ly:pitch? ly:music?)
1001
1002    (_i "Transpose @var{music} from pitch @var{from} to pitch @var{to}.")
1003    (make-music 'TransposedMusic
1004                'element (ly:music-transpose music (ly:pitch-diff to from))))
1005
1006 transposedCueDuring =
1007 #(define-music-function
1008    (parser location what dir pitch main-music)
1009    (string? ly:dir? ly:pitch? ly:music?)
1010
1011    (_i "Insert notes from the part @var{what} into a voice called @code{cue},
1012 using the transposition defined by @var{pitch}.  This happens
1013 simultaneously with @var{main-music}, which is usually a rest.  The
1014 argument @var{dir} determines whether the cue notes should be notated
1015 as a first or second voice.")
1016
1017    (make-music 'QuoteMusic
1018                'element main-music
1019                'quoted-context-type 'Voice
1020                'quoted-context-id "cue"
1021                'quoted-music-name what
1022                'quoted-voice-direction dir
1023                'quoted-transposition pitch))
1024
1025 transposition =
1026 #(define-music-function (parser location pitch) (ly:pitch?)
1027    (_i "Set instrument transposition")
1028
1029    (context-spec-music
1030     (make-property-set 'instrumentTransposition
1031                        (ly:pitch-negate pitch))
1032     'Staff))
1033
1034 tweak =
1035 #(define-music-function (parser location sym val arg)
1036    (symbol? scheme? ly:music?)
1037    (_i "Add @code{sym . val} to the @code{tweaks} property of @var{arg}.")
1038
1039    (if (equal? (object-property sym 'backend-type?) #f)
1040        (begin
1041          (ly:input-warning location (_ "cannot find property type-check for ~a") sym)
1042          (ly:warning (_ "doing assignment anyway"))))
1043    (set!
1044     (ly:music-property arg 'tweaks)
1045     (acons sym val
1046            (ly:music-property arg 'tweaks)))
1047    arg)
1048
1049
1050
1051 unfoldRepeats =
1052 #(define-music-function (parser location music) (ly:music?)
1053    (_i "Force any @code{\\repeat volta}, @code{\\repeat tremolo} or
1054 @code{\\repeat percent} commands in @var{music} to be interpreted
1055 as @code{\\repeat unfold}.")
1056    (unfold-repeats music))
1057
1058 void =
1059 #(define-void-function (parser location arg) (scheme?)
1060    (_i "Accept a scheme argument, return a void expression.
1061 Use this if you want to have a scheme expression evaluated
1062 because of its side-effects, but its value ignored."))
1063
1064
1065 withMusicProperty =
1066 #(define-music-function (parser location sym val music)
1067    (symbol? scheme? ly:music?)
1068    (_i "Set @var{sym} to @var{val} in @var{music}.")
1069
1070    (set! (ly:music-property music sym) val)
1071    music)