On 2021-10-28 11:27 am, Kieren MacMillan wrote:
2. Maybe even better: Would a Scheme engraver be able to extract (and
“delete”/omit) *all* dynamics from one context (e.g., the piano_upper
context) and inject them into a second context (e.g., piano_dynamics)?
If so, what would be the most elegant way of indicating that a
single/particular dynamic marking *shouldn’t* be extracted/pushed by
the engraver?
Not an engraver, but a dispatcher trick could be a first step:
%%%%
\version "2.22.0"
#(define event-transfer-sink (ly:make-dispatcher))
eventTransferSink = \applyContext
#(lambda (ctxt)
(ly:connect-dispatchers
(ly:context-event-source ctxt)
event-transfer-sink))
#(define event-transfer-source (ly:make-dispatcher))
eventTransferSource =
#(define-music-function (event-type) (symbol?)
(define (event-proc ev)
(ly:broadcast event-transfer-sink (ly:event-deep-copy ev)))
(define (context-proc ctxt)
(ly:connect-dispatchers
event-transfer-source
(ly:context-events-below ctxt)))
(ly:add-listener event-proc event-transfer-source event-type)
#{ \applyContext #context-proc #})
piano_upper = {
c'4\p d' e' f'
g'1\mp
g'4\f f' e' d'
c'1
}
piano_lower = {
\clef bass
c1
g,1
g,1
c1\ff
}
\score {
<<
\new PianoStaff <<
\new Staff \with { \eventTransferSource dynamic-event }
\piano_upper
\new Dynamics \with { \eventTransferSink } { #(skip-of-length
piano_upper) }
\new Staff \with { \eventTransferSource dynamic-event }
\piano_lower
>>
>>
}
%%%%
This duplicates events by necessity, because I do not believe you can
guarantee that the event transfer process is first to intercept an
event. As such, it may have already been processed by another engraver.
In the above example, you can \omit DynamicText within the two staves
and get what looks to be the desired goal, but that would mean losing
all such grobs in those contexts.
-- Aaron Hill