lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Pedal cautionary continuations and other bracket decorations


From: Thomas Morley
Subject: Re: Pedal cautionary continuations and other bracket decorations
Date: Sun, 13 Nov 2016 10:36:42 +0100

2016-11-13 1:39 GMT+01:00 Andrew Bernard <address@hidden>:
> Hi Harm,
>
> When there is a sustain on event followed by a sustain off event, the label 
> 1/2 ped should not occur - it's only for the start of the lines, and when 
> these events occur very close together with short notes there would not be 
> room.
>
> I cannot see a way of getting at the grob that represents the next bit after 
> the ^ to and to not draw the text on it, for to my limited knowledge there 
> appears to be no distinguishing property in the set of broken grob parts that 
> can identify this.
>
> Andrew

Hi Andrew,

if I understand correctly the code below may do what you want.
Basically I go for the left bound of the PedalBracket and check
whether two of them are bounded there (which would then be an ending
and a starting spanner).
Please test thoroughly, I'm not entirely sure it is sufficient
already. More comments inline.

You are aware an unbroken PedalBracket is not affected by your code?
I didn't touch this behaviour, though.


\version "2.19.50"

#(define (make-arrow-path arrow-length arrowhead-height arrowhead-width)
   "Arrow with triangular arrowhead."
   (list
    'moveto 0 0
    'lineto arrow-length 0
    'lineto arrow-length (/ arrowhead-width 2)
    'lineto (+ arrow-length arrowhead-height) 0
    'lineto arrow-length (- (/ arrowhead-width 2))
    'lineto arrow-length 0
    'closepath
    ))

pedalWithArrowsAndText =
\override Score.PianoPedalBracket.after-line-breaking =
#(lambda (grob)

   ;; function to modify the individual grob part
   (define add-decorations
     (lambda (g list-length)
       (let* (
               ;; unpack the argument
               (index (car g))
               (grobber (cadr g))
               (last (= index list-length))

               ;; Get the default-stencil and its x-dimension and x-length.
               (stil (ly:piano-pedal-bracket::print grobber))
               (stil-x-extent (ly:stencil-extent stil X))
               (stil-x-length (interval-length stil-x-extent))


               ;; make arrow for the rhs end
               (thickness 0.1)
               (arrowhead-height 1.0)
               (arrowhead-width 1.0)
               (arrow-length 1.0)
               (arrow
                 (make-path-stencil
                   (make-arrow-path
                     arrow-length
                     arrowhead-height
                     arrowhead-width)
                   thickness 1 1 #t))
               (new-stil (if (not last)
                             (ly:stencil-combine-at-edge stil X RIGHT arrow -2)
                             stil))

               ;; make text for the lhs end
               (text-stil
                (grob-interpret-markup grobber
                  (markup
                   #:line
                   (#:abs-fontsize
                    6
                    (#:sans
                     (#:upright
                      (#:whiteout (#:box (#:pad-markup 0.3 "½ ped")))))))))
               ;; get a list of spanners bounded by PianoPedalBrackets
               ;; left-bound, which is PaperColumn or NonMusicalPaperColumn
               (left-bound-spanners
                 (ly:grob-array->list
                   (ly:grob-object
                     (ly:spanner-bound grobber LEFT)
                     'bounded-by-me)))
               ;; filter left-bound-spanners for PianoPedalBrackets
               (piano-pedal-brackets
                 (filter
                   (lambda (gr)
                     (grob::has-interface gr 'piano-pedal-bracket-interface))
                     left-bound-spanners))
               ;; delete identical PianoPedalBracket from piano-pedal-brackets
               ;; TODO `delete-duplicates' may be expensive, see guile-manual
               ;;      find another method
               (bounded-piano-brackets-per-column
                 (delete-duplicates piano-pedal-brackets))
               ;; only add text-stil, if current Column has not two
               ;; PianoPedalBrackets
               ;; TODO is this condition really sufficient?
               (new-stil
                 (if (= (length bounded-piano-brackets-per-column) 2)
                     new-stil
                     (ly:stencil-stack new-stil X LEFT text-stil -6))))

         (ly:grob-set-property! grobber 'stencil new-stil))))

   (let* (
           (stil (ly:piano-pedal-bracket::print grob))
           (orig (ly:grob-original grob))
           (pieces (if (ly:grob? orig)
                       (ly:spanner-broken-into orig)
                       '()))
           (pieces-indexed-list (zip (iota (length pieces) 1) pieces))
           (pieces-length (length pieces)))

     ;; We want arrows on all segments but the last, and text on all segments,
     ;; so we have to pass some notion of list index to the function doing the
     ;; decorating. Hence the ziplist combining grob segment and index in pairs.

     (let loop ((x 1)
                (count 0))
       (if (< count pieces-length)
           (begin
            (add-decorations (list-ref pieces-indexed-list count) pieces-length)
            (loop x (+ count 1))
            )))
     #t
     ))

%==========================================================================

treble = {
  \clef treble
  \time 4/4
  c'4 c' c' c'
  c' c' c' c'
}

bass = {
  \clef bass
  \time 4/4

  c4
  \pedalWithArrowsAndText
  c\sustainOn c c
  c c c c
  \break
  c c c c
  \break
  c c c^\sustainOff\sustainOn c
  \break
  c c c c
  \break
  c c\sustainOff\sustainOn c c

  \break
  c c c c
  \break
  c c c c\sustainOff

}

\score {

  \new PianoStaff
  <<
    \new Staff = "treble"  { \treble }
    \new Staff = "bass" { \bass }
  >>

  \layout {
    \context {
      \Score
      pedalSustainStyle = #'bracket
    }
  }
}



HTH,
  Harm



reply via email to

[Prev in Thread] Current Thread [Next in Thread]