\version "2.19.30" % repeatBracket snippet % will add .----Nx----. above a bar, where N is the number of repetitions % based on the wonderful spanner by David Nalesnik (see: http://lists.gnu.org/archive/html/lilypond-user/2014-10/msg00446.html ) #(define (measure-attached-spanner::print grob text) (let* ((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)) (bracket-ref-L (cdr break-alignment-L-ext)) (bracket-ref-R (car break-alignment-R-ext)) (bracket-full-length (- bracket-ref-R bracket-ref-L)) (num (markup text)) (orig (ly:grob-original grob)) (siblings (ly:spanner-broken-into orig)) ; have we been split? (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 (ly:stencil-aligned-to num X CENTER)) (num (ly:stencil-translate-axis num (* 0.5 bracket-full-length) X)) (num-width (interval-length num-stil-ext-X)) (num-stil-ext-Y (ly:stencil-extent num Y)) (num-midpoint (* 0.5 (interval-length num-stil-ext-Y))) ;; space between number and bracket (num-padding 0.4) ;; adjoining brackets (edge-padding 0.5) (bracket-piece-R (- (* 0.5 (- bracket-full-length num-width)) num-padding)) ;; left bracket line ;; For older versions uncomment the following and ;; comment definition of bracket-stil below it ;(bracket-stil ;(make-line-stencil 0.1 ; edge-padding num-midpoint ;bracket-piece-R num-midpoint)) (bracket-stil (ly:line-interface::line grob edge-padding num-midpoint bracket-piece-R num-midpoint)) ;; add right bracket line (bracket-stil (ly:stencil-combine-at-edge bracket-stil X RIGHT bracket-stil (+ num-width (* 2 num-padding)))) ;; add number (bracket-stil (ly:stencil-add bracket-stil num)) ;; For older versions uncomment the following line and ;; comment the definition of protrusion following it: ;(protrusion (make-line-stencil 0.1 0 num-midpoint 0 0)) (protrusion (ly:line-interface::line grob 0 num-midpoint 0 0)) ;; add left protrusion (bracket-stil (if (or (null? siblings) (eq? grob (car siblings))) (ly:stencil-combine-at-edge bracket-stil X LEFT protrusion 0.0) bracket-stil)) ;; add right protrusion (bracket-stil (if (or (null? siblings) (eq? grob (last siblings))) (ly:stencil-combine-at-edge bracket-stil X RIGHT protrusion 0.0) bracket-stil)) (grob-X (ly:grob-relative-coordinate grob refp X)) (bracket-stil (ly:stencil-translate-axis bracket-stil (- bracket-ref-L grob-X) X))) bracket-stil)) #(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 '()))) (if (and (ly:spanner? span) (null? (ly:spanner-bound span LEFT)) (moment<=? (ly:context-property context 'measurePosition) ZERO-MOMENT)) (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 '())))) ((finalize trans) (if (ly:spanner? span) (begin (ly:warning "unfinished measure-attached spanner") (ly:grob-suicide! span) (set! span '()))))))) % necessary layout options % note that you can have more than one single layout block (some of them may even be outside and some inside \score) \layout { \context { \Staff \consists #Measure_attached_spanner_engraver \override MeasureCounter.font-encoding = #'latin1 \override MeasureCounter.font-size = 0 \override MeasureCounter.outside-staff-padding = 2 \override MeasureCounter.outside-staff-horizontal-padding = #0 } } % function itself repeatBracket = #(define-music-function (parser location N note) (number? ly:music?) #{ \override Staff.MeasureCounter.stencil = #(lambda (grob) (measure-attached-spanner::print grob #{ #(string-append(number->string N) "×") #} )) \startMeasureCount \repeat volta #N { $note } \stopMeasureCount #} ) textedMeasureBracket = #(define-music-function (parser location str mus) (markup? ly:music?) #{ \override Staff.MeasureCounter.stencil = #(lambda (grob) (measure-attached-spanner::print grob str)) \startMeasureCount #mus \stopMeasureCount #} ) %%%%%%%%%%%%%%%%%%%%%% EXAMPLE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% twice = \markup \pad-x #2 { \italic "bis" } { \time 3/4 c''-> g'-> e'-> c'8 b16 a g8 g c'4 \once \override Staff.MeasureCounter.outside-staff-padding = 0.4 %\once \override Staff.MeasureCounter.style = #'dashed-line \textedMeasureBracket \twice { g'16 c'' e'' c'' g' c'' e'' c'' c''8 b' b'16 d'' f'' d'' g' g'' f'' d'' c'' b' a' g' } }