]> git.donarmstrong.com Git - lilypond.git/blobdiff - ly/music-functions-init.ly
Doc: NR - input.itely - TOC customization
[lilypond.git] / ly / music-functions-init.ly
index 7699d638d44a832a8a63100377723d519ae4cf6b..5c6fb24e6ed04e773d5f41bc22d40d0a6c13b046 100644 (file)
@@ -18,7 +18,7 @@
 %%%% 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"
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -29,8 +29,6 @@
 #(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?)
@@ -182,27 +180,24 @@ assertBeamSlope =
    (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)
@@ -495,7 +490,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)))
-     (once (tweak 'footnote-music mus item))))
+     (once (propertyTweak 'footnote-music mus item))))
 
 grace =
 #(def-grace-function startGraceMusic stopGraceMusic
@@ -554,7 +549,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.")
-   (tweak 'transparent #t item))
+   (propertyTweak 'transparent #t item))
 
 inStaffSegno =
 #(define-music-function () ()
@@ -845,6 +840,37 @@ mark =
           (if label (set! (ly:music-property ev 'label) label))
           ev))))
 
+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?)
    (_i "Apply @var{proc} to @var{mus} and all of the music it contains.")
@@ -925,7 +951,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.")
-   (tweak 'stencil #f item))
+   (propertyTweak 'stencil #f item))
 
 once =
 #(define-music-function (music) (ly:music?)
@@ -933,7 +959,7 @@ once =
 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
@@ -1049,9 +1075,9 @@ Example:
     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
@@ -1268,25 +1294,7 @@ that they share a staff with stems directed downward.")
     #{ \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?)
@@ -1389,6 +1397,38 @@ Scheme as a substitute for the built-in @code{\\set} command.")
           (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?)
@@ -1558,15 +1598,11 @@ control-point.  If @var{item} is a string, the result is
 @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
@@ -1589,7 +1625,9 @@ appropriate tweak applied.")
        (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)
@@ -1808,10 +1846,10 @@ command without explicit @samp{tuplet-span}, use
        #{ \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'
@@ -1820,71 +1858,61 @@ an indirectly created grob (@samp{Accidental} is caused by
 @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)))
-         (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? item 'context-specification)
-                ;; This is essentially dealing with the case
-                ;; \tweak color #red \tweak 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 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 \\tweak")
-                                         (*location*))
-                        (ly:music-message item (_ "untweakable"))))))
-               (else
-                (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)