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

Reply via email to