lilypond-user
[Top][All Lists]
Advanced

[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




reply via email to

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