X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=ly%2Fmusic-functions-init.ly;h=11dcb53556c3ee229bfd75218b201882bdac687f;hb=0b544cfb7332615ef809b71b57ab656741311ae1;hp=379eb933ba192169821a9177991c19e52816ee96;hpb=74e4d219b24ec6d6f28d663c0285418e6c8e122e;p=lilypond.git diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index 379eb933ba..11dcb53556 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -2,7 +2,7 @@ %%%% This file is part of LilyPond, the GNU music typesetter. %%%% -%%%% Copyright (C) 2003--2012 Han-Wen Nienhuys +%%%% Copyright (C) 2003--2014 Han-Wen Nienhuys %%%% Jan Nieuwenhuizen %%%% %%%% LilyPond is free software: you can redistribute it and/or modify @@ -31,6 +31,14 @@ %% TODO: using define-music-function in a .scm causes crash. +absolute = +#(define-music-function (parser location music) + (ly:music?) + (_i "Make @var{music} absolute. This does not actually change the +music itself but rather hides it from surrounding @code{\\relative} +commands.") + (make-music 'RelativeOctaveMusic 'element music)) + acciaccatura = #(def-grace-function startAcciaccaturaMusic stopAcciaccaturaMusic (_i "Create an acciaccatura from the following music expression")) @@ -178,14 +186,16 @@ balloonGrobText = (symbol? number-pair? markup?) (_i "Attach @var{text} to @var{grob-name} at offset @var{offset} (use like @code{\\once})") - (make-music 'AnnotateOutputEvent - 'symbol grob-name - 'X-offset (car offset) - 'Y-offset (cdr offset) - 'text text)) + (make-event-chord + (list + (make-music 'AnnotateOutputEvent + 'symbol grob-name + 'X-offset (car offset) + 'Y-offset (cdr offset) + 'text text)))) balloonText = -#(define-music-function (parser location offset text) (number-pair? markup?) +#(define-event-function (parser location offset text) (number-pair? markup?) (_i "Attach @var{text} at @var{offset} (use like @code{\\tweak})") (make-music 'AnnotateOutputEvent 'X-offset (car offset) @@ -211,6 +221,14 @@ barNumberCheck = "Barcheck failed got ~a expect ~a" cbn n)))))) +beamExceptions = +#(define-scheme-function (parser location music) (ly:music?) + (_i "Extract a value suitable for setting +@code{Timing.beamExceptions} from the given pattern with explicit +beams in @var{music}. A bar check @code{|} has to be used between +bars of patterns in order to reset the timing.") + (extract-beam-exceptions music)) + bendAfter = #(define-event-function (parser location delta) (real?) (_i "Create a fall or doit of pitch interval @var{delta}.") @@ -235,7 +253,15 @@ bookOutputSuffix = breathe = #(define-music-function (parser location) () (_i "Insert a breath mark.") - (make-music 'BreathingEvent)) + (make-music 'BreathingEvent + 'midi-length + (lambda (len context) + ;;Shorten by half, or by up to a second, but always by a power of 2 + (let* ((desired (min (ly:moment-main (seconds->moment 1 context)) + (* (ly:moment-main len) 1/2))) + (scale (inexact->exact (ceiling (/ (log desired) (log 1/2))))) + (breath (ly:make-moment (expt 1/2 scale)))) + (ly:moment-sub len breath))))) clef = #(define-music-function (parser location type) (string?) @@ -297,7 +323,7 @@ cueDuring = in a CueVoice oriented by @var{dir}.") (make-music 'QuoteMusic 'element main-music - 'quoted-context-type 'Voice + 'quoted-context-type 'CueVoice 'quoted-context-id "cue" 'quoted-music-name what 'quoted-voice-direction dir)) @@ -309,7 +335,7 @@ cueDuringWithClef = in a CueVoice oriented by @var{dir}.") (make-music 'QuoteMusic 'element main-music - 'quoted-context-type 'Voice + 'quoted-context-type 'CueVoice 'quoted-context-id "cue" 'quoted-music-name what 'quoted-music-clef clef @@ -318,20 +344,32 @@ in a CueVoice oriented by @var{dir}.") displayLilyMusic = -#(define-music-function (parser location music) (ly:music?) +#(define-music-function (parser location port music) ((output-port?) ly:music?) (_i "Display the LilyPond input representation of @var{music} -to the console.") - (newline) - (display-lily-music music parser) +to @var{port}, defaulting to the console.") + (let ((port (or port (current-output-port)))) + (newline port) + (display-lily-music music parser port)) music) displayMusic = -#(define-music-function (parser location music) (ly:music?) - (_i "Display the internal representation of @var{music} to the console.") - (newline) - (display-scheme-music music) +#(define-music-function (parser location port music) ((output-port?) ly:music?) + (_i "Display the internal representation of @var{music} to +@var{port}, default to the console.") + (let ((port (or port (current-output-port)))) + (newline port) + (display-scheme-music music port)) music) +displayScheme = +#(define-scheme-function (parser location port expr) ((output-port?) scheme?) + (_i "Display the internal representation of @var{expr} to +@var{port}, default to the console.") + (let ((port (or port (current-output-port)))) + (newline port) + (display-scheme-music expr port)) + expr) + endSpanners = @@ -417,7 +455,7 @@ to the preceding note or rest as a post-event with @code{-}.") 'automatically-numbered (not mark) 'text (or mark (make-null-markup)) 'footnote-text footnote))) - #{ \tweak footnote-music #mus #item #})) + #{ \once \tweak footnote-music #mus #item #})) grace = #(def-grace-function startGraceMusic stopGraceMusic @@ -478,9 +516,7 @@ If @var{item} is a symbol list of form @code{GrobName} or @code{Context.GrobName}, the result is an override for the grob name specified by it. If @var{item} is a music expression, the result is the same music expression with an appropriate tweak applied to it.") - (if (ly:music? item) - #{ \tweak transparent ##t #item #} - #{ \override #item . transparent = ##t #})) + #{ \tweak transparent ##t #item #}) inStaffSegno = #(define-music-function (parser location) () @@ -677,6 +713,48 @@ octaveCheck = (make-music 'RelativeOctaveCheck 'pitch pitch)) +offset = +#(define-music-function (parser location property offsets item) + (symbol-list-or-symbol? scheme? symbol-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 +a music expression, the result is the same music expression with an +appropriate tweak applied.") + (if (ly:music? item) + ; In case of a tweak, grob property path is Grob.property + (let ((prop-path (check-grob-path + (if (symbol? property) + (list property) + property) + parser location + #:start 1 #:default #t #:min 2 #:max 2))) + (if prop-path + ; If the head of the grob property path is a symbol--i.e., + ; a grob name, produce a directed tweak. Otherwise, create + ; an ordinary tweak. + (if (symbol? (car prop-path)) + #{ + \tweak #prop-path #(offsetter (second prop-path) offsets) #item + #} + #{ + \tweak #(second prop-path) #(offsetter (second prop-path) offsets) #item + #}) + item)) + ; In case of an override, grob property path is Context.Grob.property. + (let ((prop-path (check-grob-path + (append item + (if (symbol? property) + (list property) + property)) + parser location + #:default 'Bottom #:min 3 #:max 3))) + (if prop-path + #{ + \override #prop-path = #(offsetter (third prop-path) offsets) + #} + (make-music 'Music))))) + omit = #(define-music-function (parser location item) (symbol-list-or-music?) (_i "Set @var{item}'s @samp{stencil} property to @code{#f}, @@ -686,21 +764,28 @@ If @var{item} is a symbol list of form @code{GrobName} or @code{Context.GrobName}, the result is an override for the grob name specified by it. If @var{item} is a music expression, the result is the same music expression with an appropriate tweak applied to it.") - (if (ly:music? item) - #{ \tweak stencil ##f #item #} - #{ \override #item . stencil = ##f #})) + #{ \tweak stencil ##f #item #}) once = #(define-music-function (parser location music) (ly:music?) - (_i "Set @code{once} to @code{#t} on all layout instruction events in @var{music}.") - (music-map - (lambda (m) - (cond ((music-is-of-type? m 'layout-instruction-event) - (set! (ly:music-property m 'once) #t)) - ((ly:duration? (ly:music-property m 'duration)) - (ly:music-warning m (_ "Cannot apply \\once to timed music")))) - m) - music)) + (_i "Set @code{once} to @code{#t} on all layout instruction events +in @var{music}. This will complain about music with an actual +duration. As a special exception, if @var{music} contains +@samp{tweaks} it will be silently ignored in order to allow for +@code{\\once \\tweak} to work as both one-time override and proper +tweak.") + (if (not (pair? (ly:music-property music 'tweaks))) + (for-some-music + (lambda (m) + (cond ((music-is-of-type? m 'layout-instruction-event) + (set! (ly:music-property m 'once) #t) + #t) + ((ly:duration? (ly:music-property m 'duration)) + (ly:music-warning m (_ "Cannot apply \\once to timed music")) + #t) + (else #f))) + music)) + music) ottava = #(define-music-function (parser location octave) (integer?) @@ -711,7 +796,7 @@ ottava = overrideTimeSignatureSettings = #(define-music-function (parser location time-signature base-moment beat-structure beam-exceptions) - (pair? pair? cheap-list? cheap-list?) + (fraction? fraction? list? list?) (_i "Override @code{timeSignatureSettings} for time signatures of @var{time-signature} to have settings @@ -966,7 +1051,7 @@ partial = (descend-to-context (context-spec-music (make-music 'PartialSet 'origin location - 'partial-duration dur) + 'duration dur) 'Timing) 'Score)) @@ -1022,9 +1107,23 @@ usually contains spacers or multi-measure rests.") relative = #(define-music-function (parser location pitch music) - ((ly:pitch? (ly:make-pitch 0 0 0)) ly:music?) - (_i "Make @var{music} relative to @var{pitch} (default @code{c'}).") - (ly:make-music-relative! music pitch) + ((ly:pitch?) ly:music?) + (_i "Make @var{music} relative to @var{pitch}. If @var{pitch} is +omitted, the first note in @var{music} is given in absolute pitch.") + ;; When \relative has no clear decision (can only happen with + ;; scales with an even number of steps), it goes down (see + ;; pitch.cc). The following formula puts out f for both the normal + ;; 7-step scale as well as for a "shortened" scale missing the + ;; final b. In either case, a first note of c will end up as c, + ;; namely pitch (-1, 0, 0). + (ly:make-music-relative! music + (or pitch + (ly:make-pitch + -1 + (quotient + ;; size of current scale: + (ly:pitch-steps (ly:make-pitch 1 0)) + 2)))) (make-music 'RelativeOctaveMusic 'element music)) @@ -1174,7 +1273,7 @@ appropriate tweak applied.") (if (>= total-found 2) (helper siblings offsets) (offset-control-points (car offsets))))) - #{ \tweak control-points #shape-curve #item #}) + #{ \once \tweak control-points #shape-curve #item #}) shiftDurations = #(define-music-function (parser location dur dots arg) @@ -1333,7 +1432,7 @@ as a first or second voice.") (make-music 'QuoteMusic 'element main-music - 'quoted-context-type 'Voice + 'quoted-context-type 'CueVoice 'quoted-context-id "cue" 'quoted-music-name what 'quoted-voice-direction dir @@ -1402,10 +1501,14 @@ an indirectly created grob (@samp{Accidental} is caused by are affected. As a special case, @var{item} may be a symbol list specifying a grob -path, in which case @code{\\once\\override} is called on it instead of +path, in which case @code{\\override} is called on it instead of creating tweaked music. This is mainly useful when using @code{\\tweak} as as a component for building other functions. +If this use case would call for @code{\\once \\override} rather than a +plain @code{\\override}, writing @code{\\once \\tweak @dots{}} can be +convenient. + @var{prop} can contain additional elements in which case a nested property (inside of an alist) is tweaked.") (if (ly:music? item) @@ -1425,12 +1528,12 @@ property (inside of an alist) is tweaked.") ;; We could just throw this at \override and let it sort this ;; out on its own, but this way we should get better error ;; diagnostics. - (let ((a (check-grob-path item parser location - #:default 'Bottom #:min 2 #:max 2)) - (b (check-grob-path prop parser location - #:start 2))) - (if (and a b) - #{ \once\override #(append a b) = #value #} + (let ((p (check-grob-path + (append item (if (symbol? prop) (list prop) prop)) + parser location + #:default 'Bottom #:min 3))) + (if p + #{ \override #p = #value #} (make-music 'Music))))) undo =