\version "2.13.32" #(define (dynamic-align-engraver context) (let ((line '()) (ended '()) (started '()) (scripts '()) (support '()) (running '()) (early-end #f)) `((acknowledgers (dynamic-interface . ,(lambda (engraver grob source-engraver) (if (null? line) (set! line (ly:engraver-make-grob engraver 'DynamicLineSpanner (event-cause grob)))) (cond ((ly:spanner? grob) (set! started (cons grob started)) (if (and (grob::has-interface grob 'dynamic-text-spanner-interface) (eq? (ly:grob-property grob 'style) 'none)) (set! early-end #t))) ((ly:item? grob) (set! scripts (cons grob scripts))) (else (ly:programming-error "Unknown dynamic grob: ~a" grob))) (ly:axis-group-interface::add-element line grob) (if (ly:stream-event? (event-cause grob)) (let ((dir (ly:event-property (event-cause grob) 'direction))) (and (ly:dir? dir) (set! (ly:grob-property line 'direction) dir)))))) (note-column-interface . ,(lambda (engraver grob source-engraver) (set! support (cons grob support))))) (end-acknowledgers (dynamic-interface . ,(lambda (engraver grob source-engraver) (if (ly:spanner? grob) (set! ended (cons grob ended)))))) (listeners (break-dynamic-span-event . ,(lambda (trans ev) (set! early-end #t)))) (stop-translation-timestep . ,(lambda (engraver) (set! running (append running started)) (and (pair? ended) (for-each (lambda (x) (if (member x running) (set! running (delete x running)) (ly:programming-error "Lost track of this dynamic spanner."))) ended)) (let ((end (and (ly:grob? line) (or (null? running) early-end)))) (for-each (lambda (dir) (and (ly:grob? line) (or (and (= dir LEFT) (null? (ly:spanner-bound line LEFT))) (and end (= dir RIGHT) (null? (ly:spanner-bound line RIGHT)))) (let ((spanners (if (= dir LEFT) started ended)) (bound #f)) (cond ((pair? scripts) (set! bound (car scripts))) ((pair? spanners) (set! bound (ly:spanner-bound (car spanners) dir))) (else (if (not early-end) (ly:programming-error "Started DynamicLineSpanner but have no left bound.")) (set! bound (ly:context-property context 'currentMusicalColumn)))) (ly:spanner-set-bound! line dir bound)))) (list LEFT RIGHT)) (and (ly:grob? line) (pair? support) (for-each (lambda (col) (ly:pointer-group-interface::add-grob line 'side-support-elements col)) support)) (if end (set! line '())) (set! ended '()) (set! started '()) (set! scripts '()) (set! support '()))))))) \layout { \context { \Voice \remove Dynamic_align_engraver \consists #dynamic-align-engraver } } \relative c' { c4\< d e f g1\!^\ff \dimTextDim g1\> a1 b1 a,1\!\p c4\< d e f \breakDynamicSpan g1\!^\ff \override DynamicTextSpanner #'style = #'none \dimTextDim g1\> a1 b1 a,4\!\p }