]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/music-functions.scm
Reformat some files to let emacs do its work correctly.
[lilypond.git] / scm / music-functions.scm
index 42102a1ee80226f4164c9ceb48a31a2a081bf069..95d4c80f3c92e172a1ffaa51e51460e7525a16ff 100644 (file)
@@ -16,7 +16,7 @@
 ;;;; You should have received a copy of the GNU General Public License
 ;;;; along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
-; for define-safe-public when byte-compiling using Guile V2
+;; for define-safe-public when byte-compiling using Guile V2
 (use-modules (scm safe-utility-defs))
 
 (use-modules (ice-9 optargs))
@@ -491,6 +491,7 @@ in @var{grob}."
     Fingering
     LaissezVibrerTie
     LigatureBracket
+    MultiMeasureRest
     PhrasingSlur
     RepeatTie
     Rest
@@ -526,8 +527,8 @@ in @var{grob}."
                          (Voice Fingering font-size -8)
                          (Voice StringNumber font-size -8)))
 
-     (make-grob-property-set 'NoteColumn 'horizontal-shift (quotient n 2))
-     (make-grob-property-set 'MultiMeasureRest 'staff-position (if (odd? n) -4 4))))))
+     (make-grob-property-set 'NoteColumn 'horizontal-shift (quotient n 2))))))
+
 
 (define-safe-public (make-voice-props-override n)
   (make-sequential-music
@@ -806,7 +807,7 @@ NUMBER is 0-base, i.e., Voice=1 (upstems) has number 0.
     (if (ly:music? e)
        (set! (ly:music-property m 'element)  (voicify-music e)))
     (if (and (equal? (ly:music-property m 'name) 'SimultaneousMusic)
-            (reduce (lambda (x y ) (or x y)) #f (map music-separator? es)))
+            (any music-separator? es))
        (set! m (context-spec-music (voicify-chord m) 'Staff)))
     m))
 
@@ -843,17 +844,37 @@ NUMBER is 0-base, i.e., Voice=1 (upstems) has number 0.
 (define-public (music-has-type music type)
   (memq type (ly:music-property music 'types)))
 
-(define-public (music-clone music)
-  (define (alist->args alist acc)
-    (if (null? alist)
-       acc
-       (alist->args (cdr alist)
-                    (cons (caar alist) (cons (cdar alist) acc)))))
-
-  (apply
-   make-music
-   (ly:music-property music 'name)
-   (alist->args (ly:music-mutable-properties music) '())))
+(define-public (music-clone music . music-properties)
+  "Clone @var{music} and set properties according to
+@var{music-properties}, a list of alternating property symbols and
+values:
+@example\n(music-clone start-span 'span-direction STOP)
+@end example
+Only properties that are not overriden by @var{music-properties} are
+actually fully cloned."
+  (let ((old-props (list-copy (ly:music-mutable-properties music)))
+        (new-props '())
+        (m (ly:make-music (ly:prob-immutable-properties music))))
+    (define (set-props mus-props)
+      (if (and (not (null? mus-props))
+               (not (null? (cdr mus-props))))
+          (begin
+            (set! old-props (assq-remove! old-props (car mus-props)))
+            (set! new-props
+                  (assq-set! new-props
+                             (car mus-props) (cadr mus-props)))
+            (set-props (cddr mus-props)))))
+    (set-props music-properties)
+    (for-each
+     (lambda (pair)
+       (set! (ly:music-property m (car pair))
+             (ly:music-deep-copy (cdr pair))))
+     old-props)
+    (for-each
+     (lambda (pair)
+       (set! (ly:music-property m (car pair)) (cdr pair)))
+     new-props)
+    m))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; warn for bare chords at start.
@@ -1849,9 +1870,43 @@ yourself."
   (map (lambda (x) (ly:music-property x 'pitch))
        (event-chord-notes event-chord)))
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; The following functions are all associated with the crossStaff
-;  function
+(defmacro-public make-relative (pitches last-pitch music)
+  "The list of pitch-carrying variables in @var{pitches} is used as a
+sequence for creating relativable music from @var{music}.
+The variables in @var{pitches} are, when considered inside of
+@code{\\relative}, all considered to be specifications to the preceding
+variable.  The first variable is relative to the preceding musical
+context, and @var{last-pitch} specifies the pitch passed as relative
+base onto the following musical context."
+
+  ;; pitch and music generator might be stored instead in music
+  ;; properties, and it might make sense to create a music type of its
+  ;; own for this kind of construct rather than using
+  ;; RelativeOctaveMusic
+  (define ((make-relative::to-relative-callback pitches p->m p->p) music pitch)
+    (let* ((chord (make-event-chord
+                   (map
+                    (lambda (p)
+                      (make-music 'NoteEvent
+                                  'pitch p))
+                    pitches)))
+           (pitchout (begin
+                       (ly:make-music-relative! chord pitch)
+                       (event-chord-pitches chord))))
+      (set! (ly:music-property music 'element)
+            (apply p->m pitchout))
+      (apply p->p pitchout)))
+  `(make-music 'RelativeOctaveMusic
+               'to-relative-callback
+               (,make-relative::to-relative-callback
+                (list ,@pitches)
+                (lambda ,pitches ,music)
+                (lambda ,pitches ,last-pitch))
+               'element ,music))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; The following functions are all associated with the crossStaff
+;;  function
 
 (define (close-enough? x y)
   "Values are close enough to ignore the difference"
@@ -1865,13 +1920,13 @@ yourself."
 
 (define ((stem-connectable? ref root) stem)
   "Check if the stem is connectable to the root"
-  ; The root is always connectable to itself
+  ;; The root is always connectable to itself
   (or (eq? root stem)
       (and
-      ; Horizontal positions of the stems must be almost the same
+      ;; Horizontal positions of the stems must be almost the same
         (close-enough? (car (ly:grob-extent root ref X))
           (car (ly:grob-extent stem ref X)))
-        ; The stem must be in the direction away from the root's notehead
+        ;; The stem must be in the direction away from the root's notehead
         (positive? (* (ly:grob-property root 'direction)
                      (- (car (ly:grob-extent stem ref Y))
                        (car (ly:grob-extent root ref Y))))))))
@@ -1888,13 +1943,13 @@ yourself."
                 (yextent (extent-combine yextents))
                 (layout (ly:grob-layout root))
                 (blot (ly:output-def-lookup layout 'blot-diameter)))
-           ; Hide spanned stems
+           ;; Hide spanned stems
            (map (lambda (st)
-                  (set! (ly:grob-property st 'transparent) #t))
+                  (set! (ly:grob-property st 'stencil) #f))
              stems)
-           ; Draw a nice looking stem with rounded corners
+           ;; Draw a nice looking stem with rounded corners
            (ly:round-filled-box (ly:grob-extent root root X) yextent blot))
-         ; Nothing to connect, don't draw the span
+         ;; Nothing to connect, don't draw the span
          #f)))
 
 (define ((make-stem-span! stems trans) root)
@@ -1902,7 +1957,7 @@ yourself."
   (let ((span (ly:engraver-make-grob trans 'Stem '())))
     (ly:grob-set-parent! span X root)
     (set! (ly:grob-object span 'stems) stems)
-    ; Suppress positioning, the stem code is confused by this weird stem
+    ;; Suppress positioning, the stem code is confused by this weird stem
     (set! (ly:grob-property span 'X-offset) 0)
     (set! (ly:grob-property span 'stencil) stem-span-stencil)))
 
@@ -1919,8 +1974,8 @@ other stems just because of that."
 
 (define (make-stem-spans! ctx stems trans)
   "Create stem spans for cross-staff stems"
-  ; Cannot do extensive checks here, just make sure there are at least
-  ; two stems at this musical moment
+  ;; Cannot do extensive checks here, just make sure there are at least
+  ;; two stems at this musical moment
   (if (<= 2 (length stems))
     (let ((roots (filter stem-is-root? stems)))
     (map (make-stem-span! stems trans) roots))))
@@ -1929,11 +1984,11 @@ other stems just because of that."
   "Connect cross-staff stems to the stems above in the system"
   (let ((stems '()))
     (make-engraver
-      ; Record all stems for the given moment
+      ;; Record all stems for the given moment
       (acknowledgers
         ((stem-interface trans grob source)
         (set! stems (cons grob stems))))
-      ; Process stems and reset the stem list to empty
+      ;; Process stems and reset the stem list to empty
       ((process-acknowledged trans)
         (make-stem-spans! ctx stems trans)
         (set! stems '())))))
@@ -1971,8 +2026,8 @@ Broken measures are numbered in parentheses."
          (siblings (ly:spanner-broken-into orig)) ; have we been split?
          (bounds (ly:grob-array->list (ly:grob-object grob 'columns)))
          (refp (ly:grob-system grob))
-         ; we use the first and/or last NonMusicalPaperColumn grob(s) of
-         ; a system in the event that a MeasureCounter spanner is broken
+         ;; we use the first and/or last NonMusicalPaperColumn grob(s) of
+         ;; a system in the event that a MeasureCounter spanner is broken
          (all-cols (ly:grob-array->list (ly:grob-object refp 'columns)))
          (all-cols
            (filter