> 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.
