> That is indeed a problem, but note that the same problem exists with before- > line-breaking (you can't write two independent before-line-breaking > overrides, you need to combine them).
Sure, that is also something where it would be nice to actually have a list of procedures. Of course one could hack together something like this extendGrobProcedure = #(define-music-function (path proc) (symbol-list-or-symbol? procedure?) (let* ((path (check-grob-path path #:default 'Default)) (ctx (car path)) (grob (cadr path)) (property (caddr path))) #{ \applyContext #(lambda (context) (let* ((context (if (equal? ctx 'Default) context (ly:context-find context ctx))) (grob-def (ly:context-grob-definition context grob)) (prop (assoc-get property grob-def)) (combined-proc (if (procedure? prop) (lambda (. args) (apply prop args) (apply proc args)) proc))) (ly:context-pushpop-property context grob property combined- proc))) #})) \new Voice { \extendGrobProcedure NoteHead.before-line-breaking #(lambda (x) (ly:grob- set-property! x 'font-size 3)) \extendGrobProcedure NoteHead.before-line-breaking #(lambda (x) (ly:grob- set-property! x 'color red)) c } but that is rather ugly. > > 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. > > Yes, it would be quite nice to be able to stack transformers. Defining good > semantics (e.g., interaction with \temporary and \revert) is not really > trivial though. A simple showcase implementation: #(define ((property-with-transformers property) grob) (let* ((details (ly:grob-property grob 'details '())) (property (assoc-get property details '())) (baseprop (assoc-get 'baseprop property '())) (baseprop (if (procedure? baseprop) (baseprop grob) baseprop)) (transformers (assoc-get 'transformers property '()))) (fold (lambda (proc prop) (if (procedure? (cdr proc)) ((cdr proc) grob prop) prop)) baseprop transformers))) { \override NoteHead.details.stencil.baseprop = #ly:note-head::print \override NoteHead.stencil = #(property-with-transformers 'stencil) \override NoteHead.details.stencil.transformers.rotate = #(lambda (grob orig) (ly:stencil-rotate orig 90 0 0)) \override NoteHead.details.stencil.transformers.stretch = #(lambda (grob orig) (ly:stencil-scale orig 1 2)) c d \revert NoteHead.details.stencil.transformers.rotate e \override NoteHead.details.stencil.baseprop = #ly:text-interface::print \override NoteHead.text = \markup \vcenter "o" f % Reset all transformers, \revert does not work here \override NoteHead.details.stencil.transformers = #'() g } although that one does not handle things like execution order intelligently, which is also something that could be handled with little effort. > Relatedly, it would be nice at some point to gain support for callbacks in > subproperties. I think for this Lilypond would first need to actually have a concept of subproperties rather than just alist entries. Cheers, Valentin
signature.asc
Description: This is a digitally signed message part.