%%%% 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"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(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-skip-music (make-duration-of-length
+ (ly:music-length music)))))
+ #{
+ <<
+ \context Staff = "up" $(or clef-1 #{ \with { \clef "treble" } #})
+ <<
+ #(make-autochange-music pitch music)
+ \new Voice { #skip }
+ >>
+ \context Staff = "down" $(or clef-2 #{ \with { \clef "bass" } #})
+ \new Voice { #skip }
+ >>
+ #}))
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 () ()
@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
(car p))
(make-music 'Music))))
+propertyTweak =
+#(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.
+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)
+ (tweak prop value item)
+ (propertyOverride (append item (if (symbol? prop) (list prop) prop))
+ value)))
+
propertyUnset =
#(define-music-function (property-path)
(symbol-list-or-symbol?)
(if (>= total-found 2)
(helper siblings offsets)
(offset-control-points (car offsets)))))
- (once (tweak 'control-points shape-curve item)))
+ (once (propertyTweak '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)
+ (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}
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.
+ ((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)
+ ((symbol? (car p))
+ (cons (car p) (cadr p)))
+ (else (cadr p)))
+ value
+ (ly:music-property music 'tweaks)))))
+ music))
+
undo =
#(define-music-function (music)