Le 18/05/2022 à 22:37, David Kastrup a écrit :
Valentin Petzel <valen...@petzel.at> writes:
Jean is correct in telling you why your approach does not work. The
system is not something that is created in a certain timestep, but
rather as a single grob at the begin of translation and then broken
down afterward, basically copying the properties of the original
System grob.
That makes for the thought experiment: what would the cost be for
retaining the per-time properties? Essentially one would have to keep a
copy of the grob-properties for each breakable column until the final
breakpoints are established.
How useful would that be? How expensive would that be? Frankly, I am
fuzzy about either. Could it be used as a basis for something like
line-break dependent accident rules?
Could it provide a more user-accessible way of doing things than
\alterBroken ?
Interestingly, our thoughts crossed. It's not unthinkable.
My wonder is whether it is going to be more convenient
than \alterBroken in the general case. With that approach,
if the break points change, you likely need to move your special
overrides around. With the current incarnation of \alterBroken,
you might not need to adjust the invocation at all. You do
need it if the number of broken pieces changes, or if the
override is intrinsically dependent on layout details (e.g.
extra-offset). I don't have enough experience with real-world
use of \alterBroken to judge whether the intuitiveness of (say)
\overrideMidBrokenSpanner Context.Grob.property = ... will offset the
possible inconvenience of having to move this command around.
Here's a hasty and dirty proof of concept, in case anyone wants
to play around with the principle.
\version "2.22.2"
#(set-object-property! 'Broken 'translation-type? ly:grob-properties?)
#(set-object-property! 'Broken 'is-grob? #t)
#(set-object-property! 'broken-info 'backend-type? list?)
#(set-object-property! 'origin-context 'backend-type? ly:context?)
#(define grob-names (map car all-grob-descriptions))
#(for-each
(lambda (name)
(set-object-property! name 'backend-type? scheme?))
grob-names)
\layout {
\context {
\Global
Broken = #(ly:make-grob-properties '())
}
\context {
\Score
\consists
#(lambda (context)
(let ((all-contexts '()))
(make-engraver
(acknowledgers
((grob-interface engraver grob source-engraver)
(let ((grob-context (ly:translator-context source-engraver)))
(set! all-contexts (cons grob-context all-contexts))
(ly:grob-set-property! grob 'origin-context
grob-context))))
((stop-translation-timestep engraver)
(let ((column (ly:context-property context
'currentCommandColumn)))
(ly:grob-set-property!
column
'broken-info
(map (lambda (ctx)
(cons ctx
(ly:context-grob-definition ctx 'Broken)))
all-contexts)))))))
\override NonMusicalPaperColumn.after-line-breaking =
#(lambda (column)
(let* ((sys (ly:grob-system column))
(all (ly:grob-array->list (ly:grob-object sys
'all-elements)))
(info (ly:grob-property column 'broken-info)))
(for-each
(lambda (grob)
(if (and (ly:spanner? grob)
(eq? column (ly:spanner-bound grob LEFT)))
(let* ((origin-context (ly:grob-property grob
'origin-context))
(origin-alist (assq-ref info origin-context))
(origin-def (assq-ref origin-alist (grob::name
grob))))
(if origin-def
(for-each
(lambda (pair)
(ly:grob-set-property! grob
(car pair)
(cdr pair)))
origin-def)))))
all)))
}
}
{
c'1\<
\break
\override Broken.Hairpin.color = red
1 1\!
}
Jean