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