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