]> git.donarmstrong.com Git - lilypond.git/blobdiff - ly/music-functions-init.ly
Use new music-clone arguments in \endSpanners
[lilypond.git] / ly / music-functions-init.ly
index b5af930f1d60016d384e76e703747c75898ae4d1..6b5bd6ece82a93dc9b9faf0173bf69c0f180d7bf 100644 (file)
@@ -86,24 +86,38 @@ markups), or inside a score.")
                                           'break-permission 'allow))))
 
 alterBroken =
-#(define-music-function (parser location name property arg)
-  (symbol-list? symbol? list?)
-  (_i "Override @var{property} for pieces of broken spanner @var{name} with
-values @var{arg}.")
-    ;; only apply override if grob is a spanner
-  (let ((description
-         (assoc-get (last name) all-grob-descriptions)))
-    (if (and description
-             (member 'spanner-interface
-                     (assoc-get 'interfaces
-                                (assoc-get 'meta description))))
-        #{
-          \override $name $property =
-          #(value-for-spanner-piece arg)
-        #}
-        (begin
-          (ly:input-warning location (_ "not a spanner name, `~a'") name)
-          (make-music 'SequentialMusic 'void #t)))))
+#(define-music-function (parser location property arg item)
+  (symbol-list-or-symbol? list? symbol-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
+@samp{Context.Grob} or just @samp{Grob}.  Iff @var{item} is in the
+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)
+          #{ \tweak #property #(value-for-spanner-piece arg) #item #}
+          (begin
+            (ly:music-warning item (_ "not a spanner"))
+            item))
+      (let* ((p (check-grob-path item parser location
+                                 #:default 'Bottom
+                                 #:min 2
+                                 #:max 2))
+             (name (and p (second p)))
+             (description
+              (and name (assoc-get name all-grob-descriptions))))
+        (if (and description
+                 (member 'spanner-interface
+                         (assoc-get 'interfaces
+                                    (assoc-get 'meta description))))
+            #{
+              \override #item . #property =
+              #(value-for-spanner-piece arg)
+            #}
+            (begin
+              (ly:input-warning location (_ "not a spanner name, `~a'") name)
+              (make-music 'Music))))))
 
 appendToTag =
 #(define-music-function (parser location tag more music)
@@ -246,24 +260,24 @@ as @code{\\compoundMeter #'((3 2 8))} or shorter
          (timesig (cons (ly:moment-main-numerator mlen)
                         (ly:moment-main-denominator mlen))))
   #{
-    \once \override Staff.TimeSignature #'stencil = #(lambda (grob)
+    \once \override Staff.TimeSignature.stencil = #(lambda (grob)
       (grob-interpret-markup grob (format-compound-time args)))
-    \set Timing.timeSignatureFraction = $timesig
-    \set Timing.baseMoment = $beat
-    \set Timing.beatStructure = $beatGrouping
+    \set Timing.timeSignatureFraction = #timesig
+    \set Timing.baseMoment = #beat
+    \set Timing.beatStructure = #beatGrouping
     \set Timing.beamExceptions = #'()
-    \set Timing.measureLength = $mlen
+    \set Timing.measureLength = #mlen
   #} ))
 
 crossStaff =
 #(define-music-function (parser location notes) (ly:music?)
   (_i "Create cross-staff stems")
   #{
-  \temporary \override Stem #'cross-staff = #cross-staff-connect
-  \temporary \override Flag #'style = #'no-flag
-  $notes
-  \revert Stem #'cross-staff
-  \revert Flag #'style
+  \temporary \override Stem.cross-staff = #cross-staff-connect
+  \temporary \override Flag.style = #'no-flag
+  #notes
+  \revert Stem.cross-staff
+  \revert Flag.style
 #})
 
 cueClef =
@@ -330,10 +344,8 @@ without the need of a specific end spanner.")
                                  (extract-typed-music music 'span-event)))
          (stop-span-evs
           (map (lambda (m)
-                 (let ((c (music-clone m)))
-                   (set! (ly:music-property c 'span-direction) STOP)
-                   c))
-               start-span-evs))
+                 (music-clone m 'span-direction STOP))
+                start-span-evs))
          (end-ev-chord (make-music 'EventChord
                                    'elements stop-span-evs))
          (total (make-music 'SequentialMusic
@@ -396,9 +408,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)))
-     (if (ly:music? item)
-         #{ \tweak #'footnote-music #mus #item #}
-         #{ \once\override $item #'footnote-music = #mus #})))
+     #{ \tweak footnote-music #mus #item #}))
 
 grace =
 #(def-grace-function startGraceMusic stopGraceMusic
@@ -418,18 +428,18 @@ harmonicByFret = #(define-music-function (parser location fret music) (number? l
 harmonics played on a fretted instrument by touching the strings at @var{fret}.")
   #{
     \set harmonicDots = ##t
-    \temporary \override TabNoteHead #'stencil = #(tab-note-head::print-custom-fret-label (number->string fret))
-    \temporary \override NoteHead #'Y-extent = #(ly:make-unpure-pure-container ly:grob::stencil-height
+    \temporary \override TabNoteHead.stencil = #(tab-note-head::print-custom-fret-label (number->string fret))
+    \temporary \override NoteHead.Y-extent = #(ly:make-unpure-pure-container ly:grob::stencil-height
                                        (lambda (grob start end)
                                                (ly:grob::stencil-height grob)))
-    \temporary \override NoteHead #'stencil = #(lambda (grob) (ly:grob-set-property! grob 'style 'harmonic-mixed)
+    \temporary \override NoteHead.stencil = #(lambda (grob) (ly:grob-set-property! grob 'style 'harmonic-mixed)
                                             (ly:note-head::print grob))
-    $(make-harmonic
+    #(make-harmonic
        (calc-harmonic-pitch (fret->pitch (number->string fret)) music))
     \unset harmonicDots
-    \revert TabNoteHead #'stencil
-    \revert NoteHead #'Y-extent
-    \revert NoteHead #'stencil
+    \revert TabNoteHead.stencil
+    \revert NoteHead.Y-extent
+    \revert NoteHead.stencil
   #})
 
 harmonicByRatio = #(define-music-function (parser location ratio music) (number? ly:music?)
@@ -438,18 +448,18 @@ harmonics played on a fretted instrument by touching the strings at the point
 given through @var{ratio}.")
   #{
     \set harmonicDots = ##t
-    \temporary \override TabNoteHead #'stencil = #(tab-note-head::print-custom-fret-label (ratio->fret ratio))
-    \temporary \override NoteHead #'Y-extent = #(ly:make-unpure-pure-container ly:grob::stencil-height
+    \temporary \override TabNoteHead.stencil = #(tab-note-head::print-custom-fret-label (ratio->fret ratio))
+    \temporary \override NoteHead.Y-extent = #(ly:make-unpure-pure-container ly:grob::stencil-height
                                        (lambda (grob start end)
                                                (ly:grob::stencil-height grob)))
-    \temporary \override NoteHead #'stencil = #(lambda (grob) (ly:grob-set-property! grob 'style 'harmonic-mixed)
+    \temporary \override NoteHead.stencil = #(lambda (grob) (ly:grob-set-property! grob 'style 'harmonic-mixed)
                                             (ly:note-head::print grob))
-    $(make-harmonic
+    #(make-harmonic
       (calc-harmonic-pitch (ratio->pitch ratio) music))
     \unset harmonicDots
-    \revert TabNoteHead #'stencil
-    \revert NoteHead #'Y-extent
-    \revert NoteHead #'stencil
+    \revert TabNoteHead.stencil
+    \revert NoteHead.Y-extent
+    \revert NoteHead.stencil
   #})
 
 hide =
@@ -462,8 +472,8 @@ If @var{item} is a symbol list of form @code{GrobName} or
 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 #}
+       #{ \override #item . transparent = ##t #}))
 
 inStaffSegno =
 #(define-music-function (parser location) ()
@@ -670,8 +680,8 @@ If @var{item} is a symbol list of form @code{GrobName} or
 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 #}
+       #{ \override #item . stencil = ##f #}))
 
 once =
 #(define-music-function (parser location music) (ly:music?)
@@ -706,33 +716,26 @@ of @var{base-moment}, @var{beat-structure}, and @var{beam-exceptions}.")
     (override-time-signature-setting time-signature setting)))
 
 overrideProperty =
-#(define-music-function (parser location name property-path value)
-   (symbol-list? symbol-list-or-symbol? scheme?)
-
-   (_i "Set @var{property-path} to @var{value} in all grobs named @var{name}.
-The @var{name} argument is a symbol list of the form @code{Context.GrobName}
-or @code{GrobName}.")
-   (if (<= 1 (length name) 2)
-       (make-music 'ApplyOutputEvent
-                   'context-type (if (null? (cdr name)) 'Bottom
-                                     (car name))
-                   'procedure
-                   (lambda (grob orig-context context)
-                     (if (equal?
-                          (cdr (assoc 'name (ly:grob-property grob 'meta)))
-                          (last name))
-                         (if (symbol? property-path)
-                             (ly:grob-set-property! grob property-path value)
-                             (case (length property-path)
-                               ((0) *unspecified*)
-                               ((1)
-                                (ly:grob-set-property!
-                                 grob (car property-path) value))
-                               (else
-                                (ly:grob-set-nested-property!
-                                 grob property-path value)))))))
-       (begin
-         (ly:parser-error parser (_ "bad grob name") location)
+#(define-music-function (parser location grob-property-path value)
+   (symbol-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
+with subproperties given as well.")
+   (let ((p (check-grob-path grob-property-path parser location
+                             #:default 'Bottom
+                             #:min 3)))
+     (if p
+         (make-music 'ApplyOutputEvent
+                     'context-type (first 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))))
          (make-music 'Music))))
 
 
@@ -1156,13 +1159,7 @@ appropriate tweak applied.")
        (if (>= total-found 2)
            (helper siblings offsets)
            (offset-control-points (car offsets)))))
-   (if (ly:music? item)
-       #{
-         \tweak #'control-points #shape-curve $item
-       #}
-       #{
-         \once \override $item #'control-points = #shape-curve
-       #}))
+   #{ \tweak control-points #shape-curve #item #})
 
 shiftDurations =
 #(define-music-function (parser location dur dots arg)
@@ -1178,8 +1175,7 @@ single =
 #(define-music-function (parser location overrides music)
    (ly:music? ly:music?)
    (_i "Convert @var{overrides} to tweaks and apply them to @var{music}.
-This does not convert @code{\\revert}, @code{\\set} or @code{\\unset}
-and ignores nested overrides.")
+This does not convert @code{\\revert}, @code{\\set} or @code{\\unset}.")
    (set! (ly:music-property music 'tweaks)
          (fold-some-music
           (lambda (m) (eq? (ly:music-property m 'name)
@@ -1189,12 +1185,12 @@ and ignores nested overrides.")
                       ((ly:music-property m 'grob-property #f) => list)
                       (else
                        (ly:music-property m 'grob-property-path)))))
-              (if (pair? (cdr p))
-                  tweaks ;ignore nested properties
-                  (acons (cons (ly:music-property m 'symbol) ;grob name
-                               (car p)) ;grob property
-                         (ly:music-property m 'grob-value)
-                         tweaks))))
+              (acons (cons (ly:music-property m 'symbol) ;grob name
+                           (if (pair? (cdr p))
+                               p ;grob property path
+                               (car p))) ;grob property
+                     (ly:music-property m 'grob-value)
+                     tweaks)))
           (ly:music-property music 'tweaks)
           overrides))
    music)
@@ -1216,8 +1212,7 @@ spacingTweaks =
    (_i "Set the system stretch, by reading the 'system-stretch property of
 the `parameters' assoc list.")
    #{
-     \overrideProperty Score.NonMusicalPaperColumn
-     #'line-break-system-details
+     \overrideProperty Score.NonMusicalPaperColumn.line-break-system-details
      #(list (cons 'alignment-extra-space (cdr (assoc 'system-stretch parameters)))
             (cons 'system-Y-extent (cdr (assoc 'system-Y-extent parameters))))
    #})
@@ -1229,15 +1224,17 @@ styledNoteHeads =
    (style-note-heads heads style music))
 
 tag =
-#(define-music-function (parser location tag arg) (symbol? ly:music?)
-
-   (_i "Add @var{tag} to the @code{tags} property of @var{arg}.")
+#(define-music-function (parser location tag music) (symbol-list-or-symbol? ly:music?)
+   (_i "Tag the following @var{music} with @var{tag} and return the
+result, by adding the single symbol or symbol list @var{tag} to the
+@code{tags} property of @var{music}.")
 
    (set!
-    (ly:music-property arg 'tags)
-    (cons tag
-         (ly:music-property arg 'tags)))
-   arg)
+    (ly:music-property music 'tags)
+    ((if (symbol? tag) cons append)
+     tag
+     (ly:music-property music 'tags)))
+   music)
 
 temporary =
 #(define-music-function (parser location music)
@@ -1337,27 +1334,49 @@ 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.
+
+@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 parser 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)
+       ;; 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)