Valentin Petzel <[email protected]> writes:
> Hello Kevin,
>
> When you call a music expression like \music Lilypond will allways pass a
> copy
> of that music object. Thus some music functions assume it is safe to modify
> the original music object. So when you do
>
> \keepWithTag ... #music
>
> you will first remove everything tagged without v1, then everything tagged
> without v2 and so on. So in the end only untagged and tagged with everything
> will persist. Then you get multiple references to that music object.
>
> What you need to do is to copy the music object passed using ly:music-deep-
> copy:
>
> %%%
> repeat-verses =
> #(define-music-function ( count music )
> ( index? ly:music? )
> (make-music 'SequentialMusic 'elements
> (map-in-order
> (lambda (verse)
> (begin
> (define versenum
> (string->symbol (string-join (list "v" (number->string verse)) "" )))
> #{ \keepWithTag #versenum #(ly:music-deep-copy music) #}))
> (iota count 1))))
Out of shere laziness, I'd be using
$music here instead of #(ly:music-deep-copy music). $music is the
Scheme equivalent of \music (including making a copy and suffering from
an early evaluation effect).
It is also possible to replace
#{ \keepWithTag #versenum #(ly:music-deep-copy music) #}
with
(keepWithTag versenum (ly:music-deep-copy music))
but there is a slight difference regarding point-and-click behavior and
typesetting-time error messages. A closer equivalent would be
(ly:set-origin! (keepWithTag versenum (ly:music-deep-copy music (*location*))))
So the #{ ... $xxx #} variant keeps track of a few details behind the
scene that are not relevant for the function itself but that might come
in handy eventually.
> %%%
> repeat-verses =
> #(define-music-function ( count music )
> ( index? ly:music? )
> (make-music 'SequentialMusic 'elements
> (map-in-order
> (lambda (verse)
> (let ((versenum (string->symbol (format #f "v~a" verse))))
> (keepWithTag versenum (ly:music-deep-copy music))))
> (iota count 1))))
>
> \repeat-verses 3 { \tag #'v1 c' \tag #'v2 d' \tag #'v3 e' f' }
> %%%
There actually is no reason to use `map-in-order' over just `map' here
since the loop body has no side effects.
Your Scheme inner construct does not touch the
point-and-click/error-location data. That may or may not be what is
desired. The guesses that #{ $... #} takes in that regard have a
certain chance of being what the user would prefer.
--
David Kastrup