On 2024-03-25 4:13 am, Jean Abou Samra wrote:
No, this doesn't exist OOTB. It could be implemented with a
Scheme engraver, but that would probably be overkill, unless
for some reason it's really important for what you're trying
to do?
Here's a simple non-engraver way to potentially get close:
%%%%
\version "2.25.13"
#(define context-stack '())
#(define (context-stack-find property)
(ly:assoc-get property context-stack '()))
#(define (context-stack-push! property value)
(set! context-stack
(assoc-set! context-stack property
(cons value (context-stack-find property)))))
#(define (context-stack-pop! property)
(let ((stack (context-stack-find property)))
(if (null? stack) '()
(let ((value (car stack)) (rest (cdr stack)))
(set! context-stack
(if (null? rest)
(assoc-remove! context-stack property)
(assoc-set! context-stack property rest)))
value))))
push =
#(define-music-function
(property value)
(symbol? scheme?)
(define (proc ctxt)
(let ((value (ly:context-property ctxt property '())))
(or (null? value)
(context-stack-push! property value)))
(ly:context-set-property! ctxt property value)
;; (format #t "~a\n" context-stack)
)
#{ \applyContext #proc #})
pop =
#(define-music-function
(property)
(symbol?)
(define (proc ctxt)
(let ((value (context-stack-pop! property)))
(if (null? value)
(ly:context-unset-property ctxt property)
(ly:context-set-property! ctxt property value)))
;; (format #t "~a\n" context-stack)
)
#{ \applyContext #proc #})
{
\repeat unfold 8 b'8
%% This example involves a property
%% that already has a value set...
\push autoBeaming ##f
\repeat unfold 8 b'8
\pop autoBeaming
\repeat unfold 8 b'8
}
{
\repeat unfold 2 { <a' c''>4( <g' b'>) }
%% This example involves a property
%% that was unset initially...
\push doubleSlurs ##t
\repeat unfold 2 { <a' c''>4( <g' b'>) }
\pop doubleSlurs
\repeat unfold 2 { <a' c''>4( <g' b'>) }
}
%%%%
It is probably missing some edge case handling, and certainly the
`context-stack` should itself be stored within the context rather than
just some arbitrary global variable. Another issue would be not
handling the extended \set syntax as in, say, `\set Score.skipBars =
##t`. The property argument would need to become a `key-list?` with the
appropriate handling to redirect to another named context.
-- Aaron Hill