From 6e0f8d53951bfad582204df9a85a776463ac6614 Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Thu, 25 Oct 2012 14:46:15 +0200 Subject: [PATCH] Issue 2929: Allow \tweak to act as a stand-in for \once\override Making tweak optionally accept a grob specification instead of music to tweak makes it compatible with the behavior of functions such as \footnote and \shape, and actually serves to simplify their implementation. One slight complication occurs in lyrics mode, as demonstrated by the change necessary to input/regression/lyric-tweak.ly: with \tweak color #red reddish fish, LilyPond tries an override for a grob named "reddish" and fails. Tweaks in lyrics mode are highly unusual, have not been supported for long, and their effect can usually better be accomplished in markup mode instead. The fix here is to write \tweak color #red \markup reddish fish, since LilyPond does not consider explicit markup a candidate for conversion into symbols. The same problem is inherent with other commands using the same kind of symbol-list-or-music? interface, like \footnote, \hide, \omit. --- input/regression/lyric-tweak.ly | 10 ++++--- ly/music-functions-init.ly | 49 +++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/input/regression/lyric-tweak.ly b/input/regression/lyric-tweak.ly index 10631bd2d9..ccaad3d469 100644 --- a/input/regression/lyric-tweak.ly +++ b/input/regression/lyric-tweak.ly @@ -1,6 +1,8 @@ \header { - texidoc = "The @code{\\tweak} function can be used in Lyrics." + texidoc = "The @code{\\tweak} function can be used in Lyrics. Where +confusion of lyric words with grob names is possible, explicit use of +@code{\\markup} can be used for resolving the ambiguity." } \version "2.17.6" @@ -11,8 +13,8 @@ \new Lyrics \lyricmode { \markup \raise #1 \rotate #30 One 4 - \tweak extra-offset #'(0 . 2) fish, + \tweak extra-offset #'(0 . 2) \markup fish, \markup \raise #1 \rotate #-30 two fish, - \tweak color #red red fish, - \tweak color #blue blue fish. + \tweak color #red \markup red fish, + \tweak color #blue \markup blue fish. } diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index 469286a8ee..b060039322 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -1345,27 +1345,46 @@ transposition = 'Staff)) tweak = -#(define-music-function (parser location prop value music) - (symbol-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} +#(define-music-function (parser location 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} set to @var{value}. If @var{prop} has the form @samp{Grob.property}, like with @example \\tweak Accidental.color #red cis' @end example an indirectly created grob (@samp{Accidental} is caused by @samp{NoteHead}) can be tweaked; otherwise only directly created grobs -are affected.") - (if (symbol? prop) - (set! prop (list prop))) - (if (and (<= 1 (length prop) 2) - (object-property (last prop) 'backend-type?)) - (set! (ly:music-property music 'tweaks) - (acons (apply cons* prop) - value - (ly:music-property music 'tweaks))) - (ly:input-warning location (_ "cannot find property type-check for ~a") prop)) - music) +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 +creating tweaked music. This is mainly useful when using +@code{\\tweak} as as a component for building other functions.") + (if (ly:music? item) + (let ((p (check-grob-path prop parser location + #:start 1 + #:default #t + #:min 2 + #:max 2))) + (if p + (set! (ly:music-property item 'tweaks) + (acons (if (eq? (car p) #t) + (cadr p) + (cons (car p) (cadr p))) + value + (ly:music-property item 'tweaks)))) + item) + ;; 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 #} + (make-music 'Music))))) undo = #(define-music-function (parser location music) -- 2.39.2