[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: How to get bounding NoteColumns of the first of consecutive TextSpan
From: |
Jean Abou Samra |
Subject: |
Re: How to get bounding NoteColumns of the first of consecutive TextSpanners |
Date: |
Wed, 3 Mar 2021 23:05:11 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 |
Le 03/03/2021 à 13:55, Thomas Morley a écrit :
Hi,
please have a look at the following minimal, producing three staves,
the middle one with consecutive TextSpanners:
mus = { bes \startTextSpan b\stopTextSpan \startTextSpan bis\stopTextSpan }
<< { a4 a a } \mus { c' c' c' } >>
Now I want to know the starting and ending NoteColumns of the _first_
TextSpanner.
Though, the first TextSpanner is left-bounded by NoteColumn and
right-bounded by PaperColumn.
How to get the NoteColumn at first TextSpanner's end?
Below some test-code.
Obviously I can filter PaperColumn's elements for NoteColumns, but
PaperColumn is a Score-grob, thus I get all three.
How to select?
(I may not know the position of the Staff with the TextSpanners)
#(define tst
(lambda (grob)
(let* ((left-bound (ly:spanner-bound grob LEFT))
(right-bound (ly:spanner-bound grob RIGHT))
(ncs-from-grob
(ly:grob-array->list (ly:grob-object grob 'note-columns)))
(right-bound-elts
(ly:grob-array->list
(ly:grob-object right-bound 'elements)))
(ncs-from-right-bound
(filter
(lambda (elt) (grob::has-interface elt 'note-column-interface))
right-bound-elts))
)
(pretty-print
(list
left-bound
right-bound
ncs-from-grob
(equal? left-bound (car ncs-from-grob))
ncs-from-right-bound
)))))
mus = {
bes4-\tweak #'after-line-breaking #tst
\startTextSpan
b\stopTextSpan
\startTextSpan
bis\stopTextSpan
}
<<
{ a4 a a }
\mus
{ c' c' c' }
Thanks,
Harm
Hi,
This looks tricky indeed.
Maybe an engraver operating in Voice context? Here's my attempt:
\version "2.23.1"
#(set-object-property! 'bounding-note-columns 'backend-type? pair?)
Set_bounding_note_columns_engraver =
#(lambda (context)
(let ((spanner-starting #f)
(spanner-ending #f)
(note-column #f))
(make-engraver
(acknowledgers
((line-spanner-interface engraver grob source-engraver)
(set! spanner-starting grob)
(ly:grob-set-property! grob
'bounding-note-columns
; Huh, '(#f . #f) makes a unique object?
(cons #f #f)))
((note-column-interface engraver grob source-engraver)
(set! note-column grob)))
(end-acknowledgers
((line-spanner-interface engraver grob source-engraver)
(set! spanner-ending grob)))
((stop-translation-timestep engraver)
(if spanner-starting
(set-car! (ly:grob-property spanner-starting
'bounding-note-columns)
note-column))
(if spanner-ending
(set-cdr! (ly:grob-property spanner-ending
'bounding-note-columns)
note-column))
(set! spanner-starting #f)
(set! spanner-ending #f)
(set! note-column #f)))))
% For testing
#(use-modules (srfi srfi-26))
#(define (visualize-note-column-bounds grob)
(let* ((cols (ly:grob-property grob 'bounding-note-columns))
(left-col (car cols))
(right-col (cdr cols))
(left-note-heads (ly:grob-array->list (ly:grob-object
left-col 'note-heads)))
(right-stem (ly:grob-object right-col 'stem)))
(for-each
(cute ly:grob-set-property! <> 'color red)
left-note-heads)
(ly:grob-set-property! right-stem 'color blue)))
\layout {
\context {
\Voice
\consists \Set_bounding_note_columns_engraver
\override TextSpanner.after-line-breaking =
#visualize-note-column-bounds
}
}
mus = {
bes4\startTextSpan
b\stopTextSpan
\startTextSpan
bis\stopTextSpan\startTextSpan
b\stopTextSpan
}
<<
{ a4 a a }
\mus
{ c' c' c' }
>>
Like David's solution, this of course won't give you the note columns
for each of the broken pieces. Well, I am in fact not sure that a notion
of the bounding note columns for a broken text spanner can even be
defined. Thoughts?
Cheers,
Jean