> ``` > (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