lilypond-user
[Top][All Lists]
Advanced

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

Re: Getting grob Y position (spacing error)


From: Gregory Evans
Subject: Re: Getting grob Y position (spacing error)
Date: Sat, 31 Dec 2022 13:43:25 -0500

Hi Jean,
I tried experimenting with your engraver in order to better learn how it works and also to see if I could recreate some of the functionality of the Johnston example I showed previously. In this engraver, based on the interruption engraver, the VoiceFollower stencil is written as usual. I wanted to give this version functionality a little more similar to the way text spanners work by creating a start and a stop command. So, as the following note is chosen, it is not the immediately following non-rest which is selected, rather the first item with a followable value set to ##t.

#(define (Follow_lines_engraver context)
   (let ((followed (make-hash-table)))
     (make-engraver
      (acknowledgers
       ((note-column-interface engraver grob source-engraver)
        (when
            (assoc-get 'followable (ly:grob-property grob 'details '()))
          (for-each
           (match-lambda
            ((mom . elt)
             (when (and (grob::has-interface elt 'note-head-interface)
                        (assoc-get 'follow (ly:grob-property elt 'details '()))
                        (not (hashq-ref followed elt))
                        )
               (hashq-set! followed elt #t)
               (let ((follower (ly:engraver-make-grob engraver 'VoiceFollower '())))
                 (ly:spanner-set-bound! follower LEFT elt)
                 (ly:spanner-set-bound! follower RIGHT grob)
                 (ly:grob-set-property! follower 'color (assoc-get 'follow-color (ly:grob-property elt 'details '())))
                 ))
            ))
           (ly:context-property context 'busyGrobs))))))))

The start and stop commands look like this:

start-follow = \once \override Staff.NoteHead.details.follow = ##t
stop-follow = \once \override Staff.NoteColumn.details.followable = ##t

But I seem to be learning something about lilypond and note columns which I previously did not understand, which leads to a question. Why is it that some notes cannot be selected on the right side? Take the following example:
arbitrary-lines.png
It appears to be the case that there is a limitation to how far to the right notes can be checked. Let’s call the starting note A and the stopping note B. It seems like the boundary is if the start-offset of B is further forward than the stop-offset of A. In the above image, a line cannot be drawn between the 2nd note of the top staff and the 8th note of the middle staff. Can you explain why this is? Is this a situation where the note columns are not finished being spaced, similar to my initial confusion about the timing of skyline calculation? Anyway, the ability to draw lines between any arbitrary location is not precisely necessary for what I’m trying to accomplish, I would just like to understand what I don’t know!

regards,
GR

p.s. In the Johnston example, notes are able to be used as line anchors more than once. Would there be a way to include something like a spanner ID?


On Tue, Dec 27, 2022 at 6:24 PM Jean Abou Samra <jean@abou-samra.fr> wrote:
Le 26/12/2022 à 19:18, Gregory Evans a écrit :
> Hi Jean,
> I apologize for my delayed reply.
>
> I do not think I can use the VoiceFollower grob because I am not using
> staff changes.



You can. A VoiceFollower won't be created automatically without a staff
change, but you can create it yourself in your Scheme engraver.



> Attached is a pdf of what I am trying to do. It works successfully if
> I input the y-position by hand but ideally it would be calculated
> automatically. You see, they are completely unrelated voices. Also see
> this image of hocket indications in Ben Johnston's 3rd string quartet
> which I think would not be done with VoiceFollower:
>
>  I have also included the lilypond file for my interruptive polyphony
> example if that is of any use to you even though it is quite large.
> While it's true that certain aspects of the process could be
> simplified (such as removing the use of 'meta as you suggest), there
> is little reason to revise it if the callback cannot be delayed until
> after the skyline calculation. Is there no way to simply trigger
> callback at a later time?


"Trigger callback at a later time" sounds like you are thinking
too much in imperative programming terms of "get parameters, set
stencil to what I want". That's not how most of LilyPond's backend
works, with the exception of after-line-breaking and a few other
properties. Instead, you build callbacks that compute the initial
values of properties (instead of getting their values and changing
them). See also this recent discussion:

https://lists.gnu.org/archive/html/lilypond-user/2022-12/msg00001.html

Thus, the question is not "how to trigger this callback at a later
time, so it knows everything" but "how to ensure that nothing this
callback depends on also depends on it, so there are no cyclic
dependencies". The answer is the cross-staff property, as I explained
previously, on a grob that supports it like VoiceFollower (but
not NoteHead).

See the attached file for an implementation of your graphical
notation. I basically started from scratch because it was simpler,
so its exact behavior might deviate from what you wanted (there
were some oddities in your original code and I don't know which
of them were intentional), but it outputs the same thing on the
excerpt you give, and it should get you going.

By the way, not sure if you or Piaras is the author of the PostScript
code, but if you are, please read the documentation of \postscript
<https://lilypond.org/doc/v2.24/Documentation/notation/graphic>
on why you should only use embedded PostScript code if you absolutely
need it, which is not the case here (make-path-stencil does the job).

Best,
Jean



--
gregory rowland evans

reply via email to

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