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