Hi,

On Fri, Sep 25, 2015 at 2:28 PM, David Kastrup <d...@gnu.org> wrote:

> Kieren MacMillan <kieren_macmil...@sympatico.ca> writes:
>
> > Hi David,
> >
> >>> I’m currently working on a solution for Schenker graphs,
> >>> and the “one-slur-per-voice” limitation is killing me.
> >>
> >> There is no such limitation.  Just use \tweak to give each of your slurs
> >> a unique spanner-id setting.  That's used, for example, for allowing
> >> \appoggiatura slurs in parallel with normal slurs.  Version 2.15.5,
> >> issues 75 and 1256.
> >
> > Amazing! Can’t wait to use this.
> > I’m assuming it’s the same with everything -spanner (e.g., TextSpanner)?
>
> That would have been the long-term idea.  At the current moment, it is
> only implemented for slurs and phrasing slurs I think.
>
>
Here's an alternate engraver for TextSpanner which works with spanner-id.

One problem I encounter is preserving the proper order over line breaks.
 (Uncomment the \break to see what I mean.)

HTH,
David

%%%%%%%%%%%
\version "2.19"

%% Based on the rewrite of Text_spanner_engraver in
%% input/regression/scheme-text-spanner.ly

#(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 (axis-offset-symbol axis)
   (if (eq? axis X) 'X-offset 'Y-offset))

#(define (set-axis! grob axis)
   (if (not (number? (ly:grob-property grob 'side-axis)))
       (begin
        (set! (ly:grob-property grob 'side-axis) axis)
        (ly:grob-chain-callback
         grob
         (if (eq? axis X)
             ly:side-position-interface::x-aligned-side
             side-position-interface::y-aligned-side)
         (axis-offset-symbol axis)))))

schemeTextSpannerEngraver =
#(lambda (context)
   (let ((span '())
         (finished '())
         (event-start '())
         (event-stop '()))
     (make-engraver

      (listeners
       ((text-span-event engraver event)
        (if (= START (ly:event-property event 'span-direction))
            (set! event-start (cons event event-start))
            (set! event-stop (cons event event-stop)))))

      (acknowledgers
       ((note-column-interface engraver grob source-engraver)
        (for-each (lambda (s)
                    (ly:pointer-group-interface::add-grob
                     s 'note-columns grob)
                    (add-bound-item s grob))
          span)
        (for-each (lambda (f)
                    (ly:pointer-group-interface::add-grob
                     f 'note-columns grob)
                    (add-bound-item f grob))
          finished)))

      ((process-music trans)
       (for-each
        (lambda (es)
          (let ((es-id (ly:event-property es 'spanner-id)))
            (let loop ((sp span))
              (let ((sp-id (ly:event-property
                            (event-cause (car sp)) 'spanner-id)))
                (cond
                 ((null? sp) (ly:warning "No spanner to end!!"))
                 ((and
                   (string? sp-id)
                   (string? es-id)
                   (string=? sp-id es-id))
                  (set! finished (cons (car sp) finished))
                  (set! span (remove (lambda (s) (eq? s (car sp))) span)))
                 ((and
                   (null? sp-id)
                   (null? es-id))
                  (set! finished (cons (car sp) finished))
                  (set! span (remove (lambda (s) (eq? s (car sp))) span)))
                 (else (loop (cdr sp))))))))
        event-stop)

       (for-each
        (lambda (f)
          (ly:engraver-announce-end-grob trans f (event-cause f)))
        finished)

       (set! event-stop '())

       (for-each
        (lambda (es)
          (set! span
                (cons
                 (ly:engraver-make-grob trans 'TextSpanner es)
                 span))
          (set-axis! (car span) Y))
        event-start)

       (set! event-start '()))

      ((stop-translation-timestep trans)
       (for-each
        (lambda (s)
          (if (null? (ly:spanner-bound s LEFT))
              (ly:spanner-set-bound! s LEFT)
              (ly:context-property context 'currentMusicalColumn)))
        span)

       (for-each
        (lambda (f)
          (if (null? (ly:spanner-bound f RIGHT))
              (ly:spanner-set-bound! f RIGHT
                (ly:context-property context 'currentMusicalColumn))))
        finished)

       (set! finished '()))

      ((finalize trans)
       (for-each
        (lambda (f)
          (if (null? (ly:spanner-bound f RIGHT))
              (ly:spanner-set-bound! f RIGHT
                (ly:context-property context 'currentMusicalColumn))))
        finished)
       (set! finished '())
       (for-each
        (lambda (sp)
          (ly:warning "incomplete spanner removed!")
          (ly:grob-suicide! sp))
        span)
       (set! span '())))))

startTextSpan =
#(make-span-event 'TextSpanEvent START)

stopTextSpan =
#(make-span-event 'TextSpanEvent STOP)

startTextSpanOne =
#(make-music 'TextSpanEvent 'span-direction START 'spanner-id "1")

stopTextSpanOne =
#(make-music 'TextSpanEvent 'span-direction STOP 'spanner-id "1")

startTextSpanTwo =
#(make-music 'TextSpanEvent 'span-direction START 'spanner-id "2")

stopTextSpanTwo =
#(make-music 'TextSpanEvent 'span-direction STOP 'spanner-id "2")

startTextSpanThree =
#(make-music 'TextSpanEvent 'span-direction START 'spanner-id "3")

stopTextSpanThree =
#(make-music 'TextSpanEvent 'span-direction STOP 'spanner-id "3")

%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EXAMPLE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\layout {
  \context {
    \Voice
    \remove #"Text_spanner_engraver"
    \consists \schemeTextSpannerEngraver
  }
}

\relative c' {
  \override TextSpanner.outside-staff-padding = 2
  a4
  -\tweak direction #DOWN
  -\tweak style ##f
  -\tweak color #darkgreen
  -\tweak thickness 4
  \startTextSpanOne
  -\tweak bound-details.left.text "rit."
  -\tweak bound-details.right.text \markup \upright \bold { A tempo }
  -\tweak bound-details.left-broken.text ##f
  -\tweak bound-details.right-broken.text ##f
  \startTextSpanTwo
  b c d

  a4
  -\tweak bound-details.left.text "foo"
  -\tweak bound-details.right.text "bar"
  -\tweak bound-details.left-broken.text ##f
  -\tweak bound-details.right-broken.text ##f
  \startTextSpan
  b c d
  %\break %% ugh--order not preserved!
  a4
  -\tweak style #'zigzag
  \startTextSpanThree b c d\stopTextSpan

  a4 b
  -\tweak bound-details.left.text "foo"
  -\tweak bound-details.right.text "bar"
  -\tweak bound-details.left-broken.text ##f
  -\tweak bound-details.right-broken.text ##f
  \startTextSpan
  c d

  a4\stopTextSpanTwo\stopTextSpanThree
  b c d\stopTextSpan\stopTextSpanOne
}
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to