Valentin Petzel <valen...@petzel.at> 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