On Fri, Feb 17, 2017 at 4:06 PM, David Nalesnik
<david.nales...@gmail.com> wrote:
> On Fri, Feb 17, 2017 at 1:22 PM, Peter Toye <lilyp...@ptoye.com> wrote:
>> David,
>>
>> That looks fantastic. Thanks ever so much. Haven’t had time to try it out in
>> anger yet
>>
>> Best regards,
>>
>> Peter
>> mailto:lilyp...@ptoye.com
>> www.ptoye.com
>>
>> -------------------------
>> Friday, February 17, 2017, 6:34:56 PM, you wrote:
>>
>>
>>> Attached is my take. It's based on a combinations of Jeffery's
>>> functions and http://lsr.di.unimi.it/LSR/Snippet?id=954. Note that it
>>> will work for multi-measure repeated spans.
>>
>
> At the moment, it will mess up if the number of repetitions is less
> than the number of bars in the repeated pattern!
>
This fixes that problem.
David
% 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 (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-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))
(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 '())))))))
repeatSect =
#(define-music-function (parser location num mus)
(number? ly:music?)
(define startBar #f)
#{
#(make-apply-context
(lambda (context)
(let ((currentBar (ly:context-property context 'currentBarNumber)))
(set! startBar currentBar))))
\override Staff.MeasureCounter.stencil =
#(lambda (grob)
(test-stencil grob #{ #(string-append (number->string num) "×") #}))
\set Score.barNumberVisibility = #(lambda (barnum mp) (= barnum startBar))
\startMeasureCount
\repeat volta #num { #mus }
\stopMeasureCount
#(context-spec-music
(make-apply-context
(lambda (context)
(let* ((endBar (ly:context-property context 'currentBarNumber))
(repLength (- endBar startBar))
(lenScaled (* repLength num))
(nextBar (+ startBar lenScaled)))
(ly:context-set-property! context 'currentBarNumber nextBar))))
'Score)
#})
% 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
}
}
%%%%%%%%%%%%%%%%%%%%%% EXAMPLE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\score {
\new Staff {
\override Score.BarNumber.break-visibility = #'#(#f #t #t)
\repeatSect 7 { c'1 }
\repeatSect 32 { d' g }
\repeatSect 2 { e' f g }
\repeatSect 29 { f' a bes \break cis' e'' }
\repeatSect 1048 { g'1 }
}
}
\language "english"
rhPatternA =
{
\relative
{
f,16 f r af af r ef ef r c ef c ef bf' af ef |
}
}
rhPatternB =
{
\relative {
bf,16-> bf af bf-> r4 r2 |
}
}
lhPatternA =
{ \relative
{
f,,16 f r af af r ef ef r c ef c ef bf' af ef |
}
}
lhPatternB =
{
\relative {
bf,,16-> bf af bf-> r4 r2 |
}
}
\score {
\new Staff {
\clef bass
\override Score.BarNumber.break-visibility = #'#(#f #t #t)
\barNumberCheck #1
\repeatSect 4 { \rhPatternA }
% adds 4 bars ... (1 + 4 = 5)
\barNumberCheck #5
\repeatSect 16 { \rhPatternA }
% adds 16 bars ... (5 + 16 = 21)
\barNumberCheck #21
\repeatSect 4 { \rhPatternB }
% adds 4 bars ... (21 + 4 = 25)
\barNumberCheck #25
\repeatSect 2 { \rhPatternA }
}
}
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user