%%%% You should have received a copy of the GNU General Public License
%%%% along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-\version "2.19.22"
+\version "2.19.25"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#(use-modules (srfi srfi-1)
(ice-9 optargs))
-%% TODO: using define-music-function in a .scm causes crash.
-
absolute =
#(define-music-function (music)
(ly:music?)
(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,
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
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"))
(make-grob-property-override 'Beam 'positions (check-slope-callbacks comp)))
autochange =
-#(define-music-function (music) (ly:music?)
- (_i "Make voices that switch between staves automatically")
- (let ;; keep the contexts alive for the full duration
- ((skip (make-skip-music (make-duration-of-length
- (ly:music-length music)))))
- #{
- <<
- \context Staff = "up" <<
- #(make-autochange-music music)
- \new Voice { #skip }
- >>
- \context Staff = "down" \with {
- clefGlyph = "clefs.F"
- clefPosition = 2
- middleCPosition = 6
- middleCClefPosition = 6
- } {
- \new Voice { #skip }
- }
- >>
- #} ))
+#(define-music-function (pitch clef-1 clef-2 music)
+ ((ly:pitch? (ly:make-pitch 0 0)) (ly:context-mod?)(ly:context-mod?) ly:music?)
+ (_i "Make voices that switch between staves automatically. As an option the
+pitch where to switch staves may be specified. The clefs for the staves are
+optional as well. Setting clefs works only for implicitly instantiated
+staves.")
+ (let ;; keep the contexts alive for the full duration
+ ((skip (make-duration-of-length (ly:music-length music)))
+ (clef-1 (or clef-1 #{ \with { \clef "treble" } #}))
+ (clef-2 (or clef-2 #{ \with { \clef "bass" } #})))
+ (make-simultaneous-music
+ (list
+ (descend-to-context (make-autochange-music pitch music) 'Staff
+ "up" clef-1)
+ (context-spec-music (make-skip-music skip) 'Staff
+ "up" clef-1)
+ (context-spec-music (make-skip-music skip) 'Staff
+ "down" clef-2)))))
balloonGrobText =
#(define-music-function (grob-name offset text)
'automatically-numbered (not mark)
'text (or mark (make-null-markup))
'footnote-text footnote)))
- (once (tweak 'footnote-music mus item))))
+ (once (propertyTweak 'footnote-music mus item))))
grace =
#(def-grace-function startGraceMusic stopGraceMusic
@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.")
- (tweak 'transparent #t item))
+ (propertyTweak 'transparent #t item))
inStaffSegno =
#(define-music-function () ()
(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)
+ (symbol-list-or-symbol? markup-function? ly:music?)
+ (_i "This applies the given markup function @var{markupfun} to all markup
+music properties matching @var{path} in @var{music}.
+
+For example,
+@example
+\\new Voice @{ g'2 c'' @}
+\\addlyrics @{
+ \\markupMap LyricEvent.text
+ \\markup \\with-color #red \\etc
+ @{ Oh yes! @}
+@}
+@end example
+")
+ (let* ((p (check-music-path path (*location*)))
+ (name (and p (car p)))
+ (prop (and p (cadr p))))
+ (if p
+ (for-some-music
+ (lambda (m)
+ (if (or (not name) (eq? (ly:music-property m 'name) name))
+ (let ((text (ly:music-property m prop)))
+ (if (markup? text)
+ (set! (ly:music-property m prop)
+ (list markupfun text)))))
+ #f)
+ music)))
+ music)
musicMap =
#(define-music-function (proc mus) (procedure? ly:music?)
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
@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.")
- (tweak 'stencil #f item))
+ (propertyTweak 'stencil #f item))
once =
#(define-music-function (music) (ly:music?)
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
+@code{\\once \\propertyTweak} to work as both one-time override and proper
tweak.")
(if (not (pair? (ly:music-property music 'tweaks)))
(for-some-music
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
(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))))
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
#{ \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?)
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
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
(car p))
(make-music 'Music))))
+propertyTweak =
+#(define-music-function (prop value item)
+ (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.
+
+In that case, @var{item} specifies the grob path to override. This is
+mainly useful when using @code{\\propertyTweak} as as a component for
+building other functions like @code{\\omit}. It is not the default
+behavior for @code{\\tweak} since many input strings in
+@code{\\lyricmode} can serve equally as music or as symbols which
+causes surprising behavior when tweaking lyrics using the less
+specific semantics of @code{\\propertyTweak}.
+
+@var{prop} can contain additional elements in which case a nested
+property (inside of an alist) is tweaked.")
+ ;; Why not instead make the parser treat strings preferably as
+ ;; music in lyrics mode rather than as symbol? Because then
+ ;;
+ ;; \tweak text "whatever" mylyrics
+ ;;
+ ;; will try putting a lyric event with text "whatever" in the text
+ ;; property of lyrics. So we want expressions allowing both
+ ;; strings and lyrics to deliver strings: more complex conversions
+ ;; should only be attempted when the simple uses don't match the
+ ;; given predicate.
+ (if (ly:music? 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)))
+
propertyUnset =
#(define-music-function (property-path)
(symbol-list-or-symbol?)
'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)
#(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
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
@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)
(if (>= total-found 2)
(helper siblings offsets)
(offset-control-points (car offsets)))))
- (once (tweak 'control-points shape-curve item)))
+ (once (propertyTweak 'control-points
+ (grob-transformer 'control-points shape-curve)
+ item)))
shiftDurations =
#(define-music-function (dur dots arg)
#{ \unset tupletSpannerDuration #}))
tweak =
-#(define-music-function (prop value item)
- (symbol-list-or-symbol? scheme? symbol-list-or-music?)
- (_i "Add a tweak to the following @var{item}, usually music.
-Layout objects created by @var{item} get their property @var{prop}
+#(define-music-function (prop value 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
@example
\\tweak Accidental.color #red cis'
@samp{NoteHead}) can be tweaked; otherwise only directly created grobs
are affected.
-As a special case, @var{item} may be a symbol list specifying a grob
-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)
- (let ((p (check-grob-path prop (*location*)
- #:start 1
- #:default #t
- #:min 2)))
- (if p
- (set! (ly:music-property item 'tweaks)
- (acons (cond ((pair? (cddr p)) p)
- ((symbol? (car p))
- (cons (car p) (cadr p)))
- (else (cadr p)))
- value
- (ly:music-property item 'tweaks))))
- item)
- (propertyOverride (append item (if (symbol? prop) (list prop) prop)) value)))
+ (let ((p (check-grob-path prop (*location*)
+ #:start 1
+ #:default #t
+ #:min 2)))
+ (cond ((not p))
+ ;; 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.
+ (else
+ (set! (ly:music-property music 'tweaks)
+ (acons (cond ((pair? (cddr p)) p)
+ ((symbol? (car p))
+ (cons (car p) (cadr p)))
+ (else (cadr p)))
+ value
+ (ly:music-property music 'tweaks)))))
+ music))
+
undo =
#(define-music-function (music)
(let
((lst
(fold-some-music
- (lambda (m) (or (music-is-of-type? m 'layout-instruction-event)
- (music-is-of-type? m 'context-specification)
- (music-is-of-type? m 'apply-context)
- (music-is-of-type? m 'time-signature-music)))
+ (music-type-predicate '(layout-instruction-event
+ context-specification
+ apply-context
+ time-signature-music))
(lambda (m overrides)
(case (ly:music-property m 'name)
((OverrideProperty)
(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?)