Good point, I didn’t think of that! Also I know that using a callback on bound-details would work as well, but I’m not sure if this is the best way to replace a single value in an alist (what if you want to change other parts of the alist independently?).
Maybe the whole transformer thing should be something that Lilypond supports in it’s core? Like, any grob property may also have a list of transformers that get evaluated on getting the property. This would then even allow to chain transforms, which could for example be relevant on functions that change the stencil to include some annotation (e.g. accidentals on ornaments) where you could then easily add multiple annotation to one stencil (e.g. upper accidental, lower accidental). Cheers, Valentin Am Mittwoch, 19. Juli 2023, 21:57:08 CEST schrieb Jean Abou Samra: > > ``` > > (let* ((bound-details (ly:grob-property grob 'bound-details)) > > (left (assoc-get 'left bound-details)) > > (left (assoc-set! > > left > > ``` > > If you add another red text spanner, you will see that it gets the text > "foo" in spite of \once. The reason is that you're mutating the default > 'bound-details value shared by all TextSpanner grobs. > > In fact, nothing guarantees that the default value is even mutable. Mutating > a constant, as created by a quote expression, is disallowed. (In recent > Guile versions, it can even lead to true "nasal demons" undefined behavior > — when you enable byte-compilation and optimizations, `(set-car! '(1 . 2) > 3)` outright segfaults. The time I looked at the bug, I couldn't understand > where it was coming from.) > > Better use alist-copy here. Also, there is no need for mutating the grob in > before-line-breaking, you can use the more functional approach with > grob-transformer: > > ``` > \version "2.24" > > { > \once \override TextSpanner.bound-details = > #(grob-transformer > 'bound-details > (lambda (grob orig) > (assoc-set! (alist-copy orig) > 'left > (assoc-set! (alist-copy (assoc-ref orig 'left)) > 'text > (if (equal? red (ly:grob-property grob > 'color)) "foo" "bar"))))) > c'1 > - \tweak color #red > \startTextSpan > c'1 > \stopTextSpan > c'1\tweak color #red \startTextSpan c'1\stopTextSpan > } > ``` > > > Best, > > Jean
signature.asc
Description: This is a digitally signed message part.