\version "2.19.15" %% => http://lists.gnu.org/archive/html/lilypond-user/2014-10/msg00446.html %% => http://lsr.di.unimi.it/LSR/Item?id=954 #(define (test-stencil grob text) (let* ((orig (ly:grob-original grob)) (siblings (ly:spanner-broken-into orig)) ; have we been split? (refp (ly:grob-system grob)) (left-bound (ly:spanner-bound grob LEFT)) (right-bound (ly:spanner-bound grob RIGHT)) (elts-L (ly:grob-array->list (ly:grob-object left-bound 'elements))) (elts-R (ly:grob-array->list (ly:grob-object right-bound 'elements))) (break-alignment-L (filter (lambda (elt) (grob::has-interface elt 'break-alignment-interface)) elts-L)) (break-alignment-R (filter (lambda (elt) (grob::has-interface elt 'break-alignment-interface)) elts-R)) (break-alignment-L-ext (ly:grob-extent (car break-alignment-L) refp X)) (break-alignment-R-ext (ly:grob-extent (car break-alignment-R) refp X)) (num (markup text)) (num (if (or (null? siblings) (eq? grob (car siblings))) num (make-parenthesize-markup num))) (num (grob-interpret-markup grob num)) (num-stil-ext-X (ly:stencil-extent num X)) (num-stil-ext-Y (ly:stencil-extent num Y)) (num (ly:stencil-aligned-to num X CENTER)) (num (ly:stencil-translate-axis num (+ (interval-length break-alignment-L-ext) (* 0.5 (- (car break-alignment-R-ext) (cdr break-alignment-L-ext)))) X)) (bracket-L (markup #:path 0.1 ; line-thickness `((moveto 0.5 ,(* 0.5 (interval-length num-stil-ext-Y))) (lineto ,(* 0.5 (- (car break-alignment-R-ext) (cdr break-alignment-L-ext) (interval-length num-stil-ext-X))) ,(* 0.5 (interval-length num-stil-ext-Y))) (closepath) (rlineto 0.0 ,(if (or (null? siblings) (eq? grob (car siblings))) -1.0 0.0))))) (bracket-R (markup #:path 0.1 `((moveto ,(* 0.5 (- (car break-alignment-R-ext) (cdr break-alignment-L-ext) (interval-length num-stil-ext-X))) ,(* 0.5 (interval-length num-stil-ext-Y))) (lineto 0.5 ,(* 0.5 (interval-length num-stil-ext-Y))) (closepath) (rlineto 0.0 ,(if (or (null? siblings) (eq? grob (last siblings))) -1.0 0.0))))) (bracket-L (grob-interpret-markup grob bracket-L)) (bracket-R (grob-interpret-markup grob bracket-R)) (num (ly:stencil-combine-at-edge num X LEFT bracket-L 0.4)) (num (ly:stencil-combine-at-edge num X RIGHT bracket-R 0.4))) num)) #(define (add-bound-item spanner item) (if (null? (ly:spanner-bound spanner LEFT)) (ly:spanner-set-bound! spanner LEFT item) (ly:spanner-set-bound! spanner RIGHT item))) #(define-public (Measure_attached_spanner_engraver context) (let ((span '()) (finished '()) (event-start '()) (event-stop '())) (make-engraver (listeners ((measure-counter-event engraver event) (if (= START (ly:event-property event 'span-direction)) (set! event-start event) (set! event-stop event)))) ((process-music trans) (if (ly:stream-event? event-stop) (if (null? span) (ly:warning "You're trying to end a measure-attached spanner but you haven't started one.") (begin (set! finished span) (ly:engraver-announce-end-grob trans finished event-start) (set! span '()) (set! event-stop '())))) (if (ly:stream-event? event-start) (begin (set! span (ly:engraver-make-grob trans 'MeasureCounter event-start)) (set! event-start '())))) ((stop-translation-timestep trans) (if (and (ly:spanner? span) (null? (ly:spanner-bound span LEFT)) (moment<=? (ly:context-property context 'measurePosition) ZERO-MOMENT)) ; NOTE: the following does not work--BUG? It will cause regtest ; scheme-text-spanner.ly to crash! ;(set! (ly:spanner-bound span LEFT) ; (ly:context-property context 'currentcommandColumn)) (ly:spanner-set-bound! span LEFT (ly:context-property context 'currentCommandColumn))) (if (and (ly:spanner? finished) (moment<=? (ly:context-property context 'measurePosition) ZERO-MOMENT)) (begin (if (null? (ly:spanner-bound finished RIGHT)) (ly:spanner-set-bound! finished RIGHT (ly:context-property context 'currentCommandColumn))) (set! finished '()) (set! event-start '()) (set! event-stop '())))) ((finalize trans) (if (ly:spanner? finished) (begin (if (null? (ly:spanner-bound finished RIGHT)) (set! (ly:spanner-bound finished RIGHT) (ly:context-property context 'currentCommandColumn))) (set! finished '()))) (if (ly:spanner? span) (begin (ly:warning "I think there's a dangling measure-attached spanner :-(") (ly:grob-suicide! span) (set! span '()))))))) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #(allow-volta-hook "|") \layout { \context { \Staff \consists #Measure_attached_spanner_engraver \override MeasureCounter.font-encoding = #'latin1 \override MeasureCounter.font-size = 0 } } \relative c'' { \key c \major \time 4/4 % Set details for later Text Spanner \override TextSpanner #'(bound-details left text) = \markup { \small \bold Slower } % Place dynamics above staff % Place following Ottava Bracket below Text Spanners \repeat volta 2 { \set Score.measureLength = #(ly:make-moment 5 8) %\once \override Staff.TextSpanner.outside-staff-priority = #650 \override Staff.MeasureCounter.stencil = #(lambda (grob) (test-stencil grob #{ \markup \italic %\raise #1 "Second time only." #} )) \startMeasureCount a16. g32 a16. f32 e8 \set Score.repeatCommands = #'((volta "S.")) c32 [ a16.] \once \hide Score.BarLine \once \hide Score.SpanBar \set Score.repeatCommands = #'((volta #f)(volta "D.") end-repeat) c32 [e16.] \set Score.measureLength = #(ly:make-moment 4/8) a,8 a'16. e32 f16. e32 c32 a16. \stopMeasureCount \set Score.repeatCommands = #'((volta #f)) b16.[ c32 d16. e32] f32 [ a16. e16. b32] c8 [a] a } %end repeat } %end relative