Hi,

Here's another hack that enables proper relative handling of function 
arguments.

The solution is a bit hairy, and it does not scale (it is only a workaround 
for the current implementation of \relative). The function is called twice if 
there is a \relative around it, therefore this solution is inefficient, and 
it also doesn't work well with functions that have side-effects.

The positive thing about this hack, is that it doesn't touch any existing 
code, so if you reject it, I can use it privately.

Here's a test:

partcombine =
#(def-rel-music-function (parser location part1 part2) (ly:music? ly:music?)
                (make-part-combine-music (list part1 part2)))

\relative \new Staff \partcombine { c' e } { g b }

-- 
Erik
===================================================================
RCS file: /sources/lilypond/lilypond/scm/define-music-types.scm,v
retrieving revision 1.72
diff -u -r1.72 define-music-types.scm
--- scm/define-music-types.scm	2 Feb 2006 20:26:36 -0000	1.72
+++ scm/define-music-types.scm	8 Feb 2006 12:39:06 -0000
@@ -542,6 +542,14 @@
 	(to-relative-callback . ,ly:relative-octave-music::no-relative-callback)
 	(types . (music-wrapper-music general-music transposed-music))
 	))
+    (MusicWrapper
+     . (
+	(description .	"Custom music that has a child.")
+	(iterator-ctor . ,ly:music-wrapper-iterator::constructor)
+	(start-callback . ,ly:music-wrapper::start-callback)
+	(length-callback . ,ly:music-wrapper::length-callback)
+	(types . (music-wrapper-music general-music))
+	))
 
     (UnrelativableMusic
      . (
Index: scm/music-functions.scm
===================================================================
RCS file: /sources/lilypond/lilypond/scm/music-functions.scm,v
retrieving revision 1.163
diff -u -r1.163 music-functions.scm
--- scm/music-functions.scm	4 Feb 2006 13:39:18 -0000	1.163
+++ scm/music-functions.scm	8 Feb 2006 12:39:06 -0000
@@ -676,6 +676,33 @@
 						      music
 						      (ly:music-deep-copy ,stop))))))
 
+(define-public (make-rel-music-function sig fun)
+  (let ((newfun (lambda args
+(make-music 'MusicWrapper
+ 'element (primitive-eval (cons fun args))
+ 'arguments args
+ 'to-relative-callback (lambda (m r)
+   (ly:music-set-property! m 'elements (ly:music-property m 'arguments))
+   (let (
+(ret (ly:music-sequence::simultaneous-relative-callback m r)))
+     (ly:music-set-property! m 'element (primitive-eval (cons fun (ly:music-property m 'elements))))
+     (ly:music-set-property! m 'elements '())
+     ret)))
+)))
+(ly:make-music-function sig newfun)
+))
+
+(defmacro-public def-rel-music-function (args signature . body)
+  "As def-music-function, but the function arguments are affected by
+\\relative.
+
+The function may NOT have any side-effects.
+"
+  `(make-rel-music-function (list ,@signature)
+			   (lambda (,@args)
+			     ,@body)))
+
+
 (defmacro-public def-music-function (args signature . body)
   "Helper macro for `ly:make-music-function'.
 Syntax:
_______________________________________________
lilypond-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to