X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=ly%2Fmusic-functions-init.ly;h=d41da5b5b6c925c8332ba498875d8b6deaffbdb0;hb=97a0169312a260933246ab224e4f8b0969871dd5;hp=5e04d325cfd1ea15fe6c7d29a02553e62683dd8d;hpb=9f6bdb44216682cfe924aca49b1c87ada661d628;p=lilypond.git diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index 5e04d325cf..d41da5b5b6 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -56,27 +56,31 @@ addQuote = (add-quotable name music)) %% keep these two together -afterGraceFraction = #(cons 6 8) +afterGraceFraction = 3/4 afterGrace = -#(define-music-function (main grace) (ly:music? ly:music?) - (_i "Create @var{grace} note(s) after a @var{main} music expression.") +#(define-music-function (fraction main grace) ((fraction?) ly:music? ly:music?) + (_i "Create @var{grace} note(s) after a @var{main} music expression. + +The musical position of the grace expression is after a +given fraction of the main note's duration has passed. If +@var{fraction} is not specified as first argument, it is taken from +@code{afterGraceFraction} which has a default value of @code{3/4}.") (let ((main-length (ly:music-length main)) - (fraction (ly:parser-lookup 'afterGraceFraction))) - (make-simultaneous-music - (list - main - (make-sequential-music - (list - - (make-music 'SkipMusic - 'duration (ly:make-duration - 0 0 - (* (ly:moment-main-numerator main-length) - (car fraction)) - (* (ly:moment-main-denominator main-length) - (cdr fraction)))) - (make-music 'GraceMusic - 'element grace))))))) + (fraction (or fraction (ly:parser-lookup 'afterGraceFraction)))) + (descend-to-context + (make-simultaneous-music + (list + main + (make-sequential-music + (list + (make-music 'SkipMusic + 'duration (ly:make-duration + 0 0 + (* (ly:moment-main main-length) + (/ (car fraction) (cdr fraction))))) + (make-music 'GraceMusic + 'element grace))))) + 'Bottom))) %% music identifiers not allowed at top-level, @@ -93,7 +97,7 @@ markups), or inside a score.") alterBroken = #(define-music-function (property arg item) - (symbol-list-or-symbol? list? symbol-list-or-music?) + (key-list-or-symbol? list? key-list-or-music?) (_i "Override @var{property} for pieces of broken spanner @var{item} with values @var{arg}. @var{item} may either be music in the form of a starting spanner event, or a symbol list in the form @@ -101,7 +105,8 @@ a starting spanner event, or a symbol list in the form form of a spanner event, @var{property} may also have the form @samp{Grob.property} for specifying a directed tweak.") (if (ly:music? item) - (if (eq? (ly:music-property item 'span-direction) START) + (if (or (eqv? (ly:music-property item 'span-direction) START) + (music-is-of-type? item 'tie-event)) (tweak property (value-for-spanner-piece arg) item) (begin (ly:music-warning item (_ "not a spanner")) @@ -825,20 +830,11 @@ transpose from @var{around} to @var{to}.") (music-invert around to music)) mark = -#(define-music-function - (label) ((number-or-markup?)) - "Make the music for the \\mark command." - (let* ((set (and (integer? label) - (context-spec-music (make-property-set 'rehearsalMark label) - 'Score))) - (ev (make-music 'MarkEvent - 'origin (*location*)))) - - (if set - (make-sequential-music (list set ev)) - (begin - (if label (set! (ly:music-property ev 'label) label)) - ev)))) +#(define-music-function (label) ((number-or-markup?)) + "Make the music for the \\mark command." + (if label + (make-music 'MarkEvent 'label label) + (make-music 'MarkEvent))) markupMap = #(define-music-function (path markupfun music) @@ -908,7 +904,7 @@ octaveCheck = offset = #(define-music-function (property offsets item) - (symbol-list-or-symbol? scheme? symbol-list-or-music?) + (symbol-list-or-symbol? scheme? key-list-or-music?) (_i "Offset the default value of @var{property} of @var{item} by @var{offsets}. If @var{item} is a string, the result is @code{\\override} for the specified grob type. If @var{item} is @@ -996,7 +992,7 @@ of @var{base-moment}, @var{beat-structure}, and @var{beam-exceptions}.") overrideProperty = #(define-music-function (grob-property-path value) - (symbol-list? scheme?) + (key-list? scheme?) (_i "Set the grob property specified by @var{grob-property-path} to @var{value}. @var{grob-property-path} is a symbol list of the form @@ -1014,13 +1010,10 @@ creation.") (if p (make-music 'ApplyOutputEvent 'context-type (first p) + 'symbol (second p) 'procedure (lambda (grob orig-context context) - (if (equal? - (cdr (assoc 'name (ly:grob-property grob 'meta))) - (second p)) - (ly:grob-set-nested-property! - grob (cddr p) value)))) + (ly:grob-set-nested-property! grob (cddr p) value))) (make-music 'Music)))) @@ -1075,9 +1068,9 @@ Example: d d | e e | f f | } <==> - A = { c c | d d | } - B = { d d | e e | } - C = { e e | f f | } + A = { c c | d d } + B = { d d | e e } + C = { e e | f f } @end verbatim The last bar checks in a sequence are not copied to the result in @@ -1294,25 +1287,7 @@ that they share a staff with stems directed downward.") #{ \with { \voiceTwo \override DynamicLineSpanner.direction = #DOWN } #} #{ \with { \voiceTwo \override DynamicLineSpanner.direction = #DOWN } #} )) -partcombineForce = -#(define-music-function (type once) (boolean-or-symbol? boolean?) - (_i "Override the part-combiner.") - (make-music 'EventChord - 'elements (list (make-music 'PartCombineForceEvent - 'forced-type type - 'once once)))) -partcombineApart = \partcombineForce #'apart ##f -partcombineApartOnce = \partcombineForce #'apart ##t -partcombineChords = \partcombineForce #'chords ##f -partcombineChordsOnce = \partcombineForce #'chords ##t -partcombineUnisono = \partcombineForce #'unisono ##f -partcombineUnisonoOnce = \partcombineForce #'unisono ##t -partcombineSoloI = \partcombineForce #'solo1 ##f -partcombineSoloIOnce = \partcombineForce #'solo1 ##t -partcombineSoloII = \partcombineForce #'solo2 ##f -partcombineSoloIIOnce = \partcombineForce #'solo2 ##t -partcombineAutomatic = \partcombineForce ##f ##f -partcombineAutomaticOnce = \partcombineForce ##f ##t +%% Part combine forcing to be found in ly/property-init.ly partial = #(define-music-function (dur) (ly:duration?) @@ -1357,7 +1332,7 @@ print @var{secondary-note} as a stemless note head in parentheses.") propertyOverride = #(define-music-function (grob-property-path value) - (symbol-list? scheme?) + (key-list? scheme?) (_i "Set the grob property specified by @var{grob-property-path} to @var{value}. @var{grob-property-path} is a symbol list of the form @code{Context.GrobName.property} or @code{GrobName.property}, possibly @@ -1380,7 +1355,7 @@ command.") propertyRevert = #(define-music-function (grob-property-path) - (symbol-list?) + (key-list?) (_i "Revert the grob property specified by @var{grob-property-path} to its previous value. @var{grob-property-path} is a symbol list of the form @code{Context.GrobName.property} or @code{GrobName.property}, possibly @@ -1417,7 +1392,7 @@ Scheme as a substitute for the built-in @code{\\set} command.") propertyTweak = #(define-music-function (prop value item) - (symbol-list-or-symbol? scheme? symbol-list-or-music?) + (key-list-or-symbol? scheme? key-list-or-music?) (_i "Add a tweak to the following @var{item}, usually music. This generally behaves like @code{\\tweak} but will turn into an @code{\\override} when @var{item} is a symbol list. @@ -1443,7 +1418,47 @@ property (inside of an alist) is tweaked.") ;; should only be attempted when the simple uses don't match the ;; given predicate. (if (ly:music? item) - (tweak prop value item) + (if (music-is-of-type? item 'context-specification) + ;; This is essentially dealing with the case + ;; \propertyTweak color #red \propertyTweak font-size #3 NoteHead + ;; namely when stacked tweaks end in a symbol list + ;; rather than a music expression. + ;; + ;; We have a tweak here to convert into an override, + ;; so we need to know the grob to apply it to. That's + ;; easy if we have a directed tweak, and otherwise we + ;; need to find the symbol in the expression itself. + (let* ((p (check-grob-path prop (*location*) + #:start 1 + #:default #t + #:min 2)) + (elt (ly:music-property item 'element)) + (seq (if (music-is-of-type? elt 'sequential-music) + elt + (make-sequential-music (list elt)))) + (elts (ly:music-property seq 'elements)) + (symbol (if (symbol? (car p)) + (car p) + (and (pair? elts) + (ly:music-property (car elts) + 'symbol))))) + (if (symbol? symbol) + (begin + (set! (ly:music-property seq 'elements) + (cons (make-music 'OverrideProperty + 'symbol symbol + 'grob-property-path (cdr p) + 'pop-first #t + 'grob-value value + 'origin (*location*)) + elts)) + (set! (ly:music-property item 'element) seq)) + (begin + (ly:parser-error (_ "Cannot \\propertyTweak") + (*location*)) + (ly:music-message item (_ "untweakable")))) + item) + (tweak prop value item)) (propertyOverride (append item (if (symbol? prop) (list prop) prop)) value))) @@ -1484,6 +1499,12 @@ usually contains spacers or multi-measure rests.") 'element main-music 'quoted-music-name what)) +reduceChords = +#(define-music-function (music) (ly:music?) + (_i "Reduce chords contained in @var{music} to single notes, +intended mainly for reusing music in RhythmicStaff. Does not +reduce parallel music.") + (event-chord-reduce music)) relative = #(define-music-function (pitch music) @@ -1529,7 +1550,12 @@ retrograde = #(define-music-function (music) (ly:music?) (_i "Return @var{music} in reverse order.") - (retrograde-music music)) + (retrograde-music + (expand-repeat-notes! + (expand-repeat-chords! + (cons 'rhythmic-event + (ly:parser-lookup '$chord-repeat-events)) + music)))) revertTimeSignatureSettings = #(define-music-function @@ -1608,7 +1634,7 @@ a context modification duplicating their effect.") shape = #(define-music-function (offsets item) - (list? symbol-list-or-music?) + (list? key-list-or-music?) (_i "Offset control-points of @var{item} by @var{offsets}. The argument is a list of number pairs or list of such lists. Each element of a pair represents an offset to one of the coordinates of a @@ -1616,21 +1642,15 @@ control-point. If @var{item} is a string, the result is @code{\\once\\override} for the specified grob type. If @var{item} is a music expression, the result is the same music expression with an appropriate tweak applied.") - (define (shape-curve grob) + (define (shape-curve grob coords) (let* ((orig (ly:grob-original grob)) (siblings (if (ly:spanner? grob) (ly:spanner-broken-into orig) '())) - (total-found (length siblings)) - (function (assoc-get 'control-points - (reverse (ly:grob-basic-properties grob)))) - (coords (function grob))) - + (total-found (length siblings))) (define (offset-control-points offsets) (if (null? offsets) coords - (map - (lambda (x y) (coord-translate x y)) - coords offsets))) + (map coord-translate coords offsets))) (define (helper sibs offs) (if (pair? offs) @@ -1647,7 +1667,9 @@ appropriate tweak applied.") (if (>= total-found 2) (helper siblings offsets) (offset-control-points (car offsets))))) - (once (propertyTweak 'control-points shape-curve item))) + (once (propertyTweak 'control-points + (grob-transformer 'control-points shape-curve) + item))) shiftDurations = #(define-music-function (dur dots arg) @@ -1867,7 +1889,7 @@ command without explicit @samp{tuplet-span}, use tweak = #(define-music-function (prop value music) - (symbol-list-or-symbol? scheme? ly:music?) + (key-list-or-symbol? scheme? ly:music?) (_i "Add a tweak to the following @var{music}. Layout objects created by @var{music} get their property @var{prop} set to @var{value}. If @var{prop} has the form @samp{Grob.property}, like with @@ -1888,41 +1910,6 @@ property (inside of an alist) is tweaked.") ;; p now contains at least two elements. The first ;; element is #t when no grob has been explicitly ;; specified, otherwise it is a grob name. - ((music-is-of-type? music 'context-specification) - ;; This is essentially dealing with the case - ;; \tweak color #red \propertyTweak font-size #3 NoteHead - ;; namely when stacked tweaks end in a symbol list - ;; rather than a music expression. - ;; - ;; We have a tweak here to convert into an override, - ;; so we need to know the grob to apply it to. That's - ;; easy if we have a directed tweak, and otherwise we - ;; need to find the symbol in the expression itself. - (let* ((elt (ly:music-property music 'element)) - (seq (if (music-is-of-type? elt 'sequential-music) - elt - (make-sequential-music (list elt)))) - (elts (ly:music-property seq 'elements)) - (symbol (if (symbol? (car p)) - (car p) - (and (pair? elts) - (ly:music-property (car elts) - 'symbol))))) - (if (symbol? symbol) - (begin - (set! (ly:music-property seq 'elements) - (cons (make-music 'OverrideProperty - 'symbol symbol - 'grob-property-path (cdr p) - 'pop-first #t - 'grob-value value - 'origin (*location*)) - elts)) - (set! (ly:music-property music 'element) seq)) - (begin - (ly:parser-error (_ "Cannot \\tweak") - (*location*)) - (ly:music-message music (_ "untweakable")))))) (else (set! (ly:music-property music 'tweaks) (acons (cond ((pair? (cddr p)) p) @@ -1988,11 +1975,38 @@ unsets already in @var{music} cause a warning. Non-property-related music is ig (else (make-sequential-music lst)))))) unfoldRepeats = -#(define-music-function (music) (ly:music?) - (_i "Force any @code{\\repeat volta}, @code{\\repeat tremolo} or +#(define-music-function (types music) + ((symbol-list-or-symbol? '()) ly:music?) + (_i "Force @code{\\repeat volta}, @code{\\repeat tremolo} or @code{\\repeat percent} commands in @var{music} to be interpreted -as @code{\\repeat unfold}.") - (unfold-repeats music)) +as @code{\\repeat unfold}, if specified in the optional symbol-list @var{types}. +The default for @var{types} is an empty list, which will force any of those +commands in @var{music} to be interpreted as @code{\\repeat unfold}. Possible +entries are @code{volta}, @code{tremolo} or @code{percent}. Multiple entries +are possible.") + (unfold-repeats types music)) + +voices = +#(define-music-function (ids music) (key-list? ly:music?) + (_i "Take the given key list of numbers (indicating the use of +@samp{\\voiceOne}@dots{}) or symbols (indicating voice names, +typically converted from strings by argument list processing) +and assign the following @code{\\\\}-separated music to +contexts according to that list. Named rather than numbered +contexts can be used for continuing one voice (for the sake of +spanners and lyrics), usually requiring a @code{\\voiceOne}-style +override at the beginning of the passage and a @code{\\oneVoice} +override at its end. + +The default +@example +<< @dots{} \\\\ @dots{} \\\\ @dots{} >> +@end example +construct would correspond to +@example +\\voices 1,2,3 << @dots{} \\\\ @dots{} \\\\ @dots{} >> +@end example") + (voicify-music music ids)) void = #(define-void-function (arg) (scheme?)