Hi Carren,

I don't see another possibility. But I'm willing to implement 2) if it fits your need.

Maybe something like this?

\version "2.25.23"

keysig-colors =
#(list
  (cons #{ as #} blue)
  (cons #{ es #} green)
  (cons #{ ges #} red)
  )

%{
keysig stencils have the form:
(translate-stencil (horizontal...)
  (combine-stencil
     [all the individual accidentals]
  ))
the individual accidentals have the form
(translate-stencil [...]
  (translate-stencil [...]
    (...)
where the innermost translation (it's two layers or one layer) is the Y translation
responsible for the pitch.
%}

% todo: replace cdadaddr overkill by match structure!

#(define (cadaddr lst) (car (cdaddr lst)))
#(define (cdadaddr lst) (cdr (cadaddr lst)))

#(define (translation? lst)
   (and (pair? lst)
        (eq? (car lst) 'translate-stencil)))

#(define (innermost-translation stencil-expr)
   (if (translation? stencil-expr)
       (let ((inner-stencil-expr (caddr stencil-expr)))
         (if (translation? inner-stencil-expr)
             (innermost-translation inner-stencil-expr)
             (cadr stencil-expr)))))

colouredKeySignature =
#(define-music-function (pitch-color-alist) (alist?)
   #{
     \override Staff.KeySignature.stencil =
     #(grob-transformer
       'stencil
       (lambda (grob keysig)
         (define notename-color-alist
           (map (lambda (pitch-color-pair)
                  (cons (ly:pitch-notename (car pitch-color-pair))
                        (cdr pitch-color-pair)))
                pitch-color-alist))
         (define (colourise-single-accidental stencil-expr Y-position)
           (let*
            ((c0-position (ly:grob-property grob 'c0-position))
             (Y-notename (modulo (inexact->exact (- (* Y-position 2)
                                                    c0-position))
                                 7))
             (color (assq-ref notename-color-alist Y-notename)))
            (if (color? color)
                `(color ,(normalize-color color) ,stencil-expr)
                stencil-expr)))

         (let*
          ((keysig-expr (ly:stencil-expr keysig))
           (keysig-xext (ly:stencil-extent keysig X))
           (keysig-yext (ly:stencil-extent keysig Y))
           (translation (cadr keysig-expr))
           (accidentals (cdaddr keysig-expr))
           (accidentals-Y (map cdr (map innermost-translation accidentals)))
           (coloured-accidentals (map colourise-single-accidental
                                      accidentals
                                      accidentals-Y)))
          (ly:make-stencil
           (list 'translate-stencil
                 translation
                 (cons 'combine-stencil coloured-accidentals))
           keysig-xext
           keysig-yext))))
   #})

{
  \colouredKeySignature \keysig-colors
  \key des \major
  c'1
  \clef bass \break
  c1
}

Reply via email to