\version "2.19.17" #(define (remove-first symbol alist) (let loop ((alist alist) (result '())) (cond ((null? alist) result) ((eq? (caar alist) symbol) (append result (cdr alist))) (else (loop (cdr alist) (append result (car alist))))))) #(define (grobs-with-stencils) (let loop ((all all-grob-descriptions) (result '())) (if (null? all) result (if (assoc-get 'stencil (cdar all)) (loop (cdr all) (cons (caar all) result)) (loop (cdr all) result))))) #(define (mark-tweak grob) (let* ((default (assoc-get (grob::name grob) all-grob-descriptions)) (after-line-return (assoc-get 'after-line-breaking default)) (props (ly:grob-basic-properties grob)) ;; Our procedure has been added to the head of grob's basic ;; properties. Let's not count it as a tweak! (props (remove (lambda (p) (and (procedure? (cdr p)) (eq? (procedure-name (cdr p)) 'mark-tweak))) props)) ;; Yuck. We should remove the _last_ entry in the alist. Good ;; enough for now. Just don't override Clef.glyph. (props (if (eq? (grob::name grob) 'Clef) (remove-first 'glyph props) props)) (diff (lset-difference eq? props default))) ;; Tweaks will not appear in the "basic properties" alist of our grob, but ;; we can find them through the music event which led to the grob. This ;; is available through the stream-event which caused our grob. (if (null? diff) (let* ((cause (event-cause grob)) (tweaks (and cause (ly:music-property (ly:event-property cause 'music-cause) 'tweaks)))) (if (pair? tweaks) (set! (ly:grob-property grob 'color) red))) (set! (ly:grob-property grob 'color) green)) ;; Return any default setting of after-line-breaking. after-line-return)) markAllAlteredGrobs = #(define-music-function (parser location) () (let loop ((grobs (grobs-with-stencils))) (if (null? grobs) #{ #} #{ \override #(list 'Score (car grobs) 'after-line-breaking) = #mark-tweak #(loop (cdr grobs)) #}))) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \displayMusic { \voiceOne c-"hi"-1 \clef "bass_8" c, } \layout { \context { \Score \markAllAlteredGrobs } }