\version "2.19.17" #(define (remove-first symbol alist) "Remove the first key-value pair of association list @var{alist} whose key matches @var{symbol}." (let loop ((alist alist) (result '())) (cond ((null? alist) result) ((eq? (caar alist) symbol) (append result (cdr alist))) (else (loop (cdr alist) (append result (list (car alist)))))))) #(define (grob::has-default-prop grob prop) "Check all-grob-descriptions to see if symbol @var{grob} has a default setting for symbol @var{prop}. Either return the setting or @code{#f}." (let ((description (assoc-get grob all-grob-descriptions))) (if description (assoc-get 'stencil description)))) #(define (mark-tweak grob) (let* ((default (assoc-get (grob::name grob) all-grob-descriptions)) (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)) ;; We're using after-line-breaking to set color of stencil, but ;; let's preserve its last setting (after-line-return (assoc-get 'after-line-breaking props)) ;; Clef.glyph doesn't appear in all-grob-descriptions, but it ;; is set at some point automatically. Don't mark it unless ;; it genuinely is a user override. There may be other ;; such grobs. (props (if (eq? (grob::name grob) 'Clef) (reverse (remove-first 'glyph (reverse 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)) colorTweaksEngraver = #(lambda (context) (make-engraver (acknowledgers ((grob-interface engraver grob source-engraver) (if (grob::has-default-prop grob 'stencil) (set! (ly:grob-property grob 'after-line-breaking) (mark-tweak grob))))))) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% { \voiceOne \once \override Staff.Clef.extra-offset = #'(0 . 2) c^"hi"_1 \clef "bass_8" c, \oneVoice \key d \major c, } { \override NoteHead.X-extent = #'(-1 . 1) \override NoteHead.font-size = 3 \override NoteHead.stencil = #ly:note-head::print c1 \revert NoteHead.X-extent c1 \revert NoteHead.font-size c1 \revert NoteHead.stencil c1 } { %\voiceTwo \tweak font-size 3 c'1 \tweak NoteHead.font-size 3 \tweak Stem.thickness 5 c'2 <\tweak NoteHead.font-size 3 c' e'>1 \override NoteHead.font-size = 4 c'1 \temporary \override NoteHead.font-size = 12 c'1 \revert NoteHead.font-size \revert Score.BarLine.X-extent \revert Staff.Clef.after-line-breaking \clef alto c'1 } \layout { \context { \Score { \override BarLine.X-extent = #'(-2 . 2) } } \context { \Staff \override Clef.after-line-breaking = #(lambda (grob) (set! (ly:grob-property grob 'stencil) (ly:stencil-rotate (ly:clef::print grob) -15 0 0))) } } \layout { \context { \Score \consists \colorTweaksEngraver } }