as promised, here is my unsuccessful attempt based on a closure preserving state information between invocations.
\version "2.19.32"
#(define (contains-slur-event-with-direction? lst direction)
(if (null-list? lst)
#f
(if (music-is-of-type? (car lst) 'slur-event)
(eq? (ly:music-property (car lst) 'span-direction) direction)
(contains-slur-event-with-direction? (cdr lst) direction))))
#(define (notehead-articulations notehead)
(let ((noteevent (ly:event-property (event-cause notehead) 'music-cause)))
(ly:music-property noteevent 'articulations)))
#(define (slur-opener? notehead)
(contains-slur-event-with-direction? (notehead-articulations notehead) 1))
#(define (slur-closer? notehead)
(contains-slur-event-with-direction? (notehead-articulations notehead) -1))
#(define (make-in-slur-callback inSlur notInSlur)
(let ((slursOpen 0))
(display "+++ Factory executed")
; this closure will be executed for each NoteHead
(lambda (grob)
(begin
(display "+++ Closure executed")
; to see the order of NoteHead the callback is called for
(display-scheme-music (ly:event-property (event-cause grob) 'origin))
(cond
((slur-opener? grob) (set! slursOpen (+ slursOpen 1)))
((slur-closer? grob) (set! slursOpen (- slursOpen 1))))
(if (> slursOpen 0)
(inSlur grob)
(notInSlur grob)))
)))
\score {
\relative c' {
\override NoteHead #'color = #(make-in-slur-callback
(lambda (grob) red)
(lambda (grob) black))
d e( f) g( a b c)
}
}