I don't have much experience with custom engravers, but I think one
can define a new context property and upgrade the \voiceX / \oneVoice
commands to also set this context property:
... I'm sorry, there's a superfluous (let ((fontSize .... ))) in my
code, a relic from a snippet by Harm that I started from. Please
simplify to:
\version "2.21.0"
% tool for defining new context properties
% (from https://www.mail-archive.com/[email protected]/msg133263.html)
#(define (define-translator-property symbol type? description)
(if (not (and (symbol? symbol)
(procedure? type?)
(string? description)))
(ly:error "error in call of define-translator-property"))
(if (not (equal? (object-property symbol 'translation-doc) #f))
(ly:error (_ "symbol ~S redefined") symbol))
(set-object-property! symbol 'translation-type? type?)
(set-object-property! symbol 'translation-doc description)
symbol)
% define a new context property "structuralVoice"
#(for-each
(lambda (x)
(apply define-translator-property x))
`((structuralVoice
,integer?
"The current voice is a first/second/... voice (1,2,3,4) or single
voice (empty list)")))
setStructuralVoice =
#(define-scheme-function (num) (integer?)
(make-apply-context
(lambda (context)
(ly:context-set-property! context 'structuralVoice (if (> num 0)
num '())))))
oneVoice = { \setStructuralVoice 0 \oneVoice }
voiceOne = { \setStructuralVoice 1 \voiceOne }
voiceTwo = { \setStructuralVoice 2 \voiceTwo }
voiceThree = { \setStructuralVoice 3 \voiceThree }
voiceFour = { \setStructuralVoice 4 \voiceFour }
displayCurrentStructuralVoice = \applyContext
#(lambda (context)
(pretty-print
(ly:context-property context 'structuralVoice)))
\relative {
\displayCurrentStructuralVoice % not yet defined
a'4
\voiceTwo e f
\displayCurrentStructuralVoice % should be 2
\voiceOne e' f
\displayCurrentStructuralVoice % should be 1
\oneVoice e d c b a g f
\displayCurrentStructuralVoice
}