Hi Jean,
I’m revisiting the engraver you defined for me above. I don’t understand
how to pass a particular value from one place to another. Hopefully this
can be answered without you studying up on what you developed back in
December. We have

1.) a line drawing function

#(define (make-switch-butt-line-stencil width start-x start-y end-x end-y)
   (let ((path `(moveto ,start-x ,start-y lineto ,end-x ,end-y)))
     (make-path-stencil path width 1 1 #t #:line-cap-style 'butt)))

2.) a stencil drawn from properties of a VoiceFollower grob

#(define (switching-bracket grob)
   (let* ((left (ly:spanner-bound grob LEFT))
          (right (ly:spanner-bound grob RIGHT))
          (x-proportion (assoc-get 'used-proportion (ly:grob-property
grob 'details '())))
          (sys (ly:grob-system grob))
          (start-x (interval-end (ly:grob-extent left sys X)))
          (start-y (interval-center (ly:grob-extent left sys Y)))
          (right-stem (ly:grob-object right 'stem))
          (right-stem-dir (ly:grob-property right-stem 'direction))
          (right-head (reduce (lambda (head prev)
                                (if ((if (eqv? UP right-stem-dir) not identity)
                                     (ly:grob-vertical<? head prev))
                                    head
                                    prev))
                              'dummy
                              (ly:grob-array->list (ly:grob-object
right 'note-heads))))
          (end-x (interval-index (interval-widen (ly:grob-extent
right-head sys X) -0.07)
                                 (- right-stem-dir)))
          (x-distance-total (- end-x start-x))
          (x-distance-proportion (* x-distance-total x-proportion))
          (new-calculated-end-x (+ start-x x-distance-proportion))
          (end-y (interval-center (ly:grob-extent right-head sys Y))))
     (ly:stencil-translate
      (ly:stencil-add
       (make-switch-butt-line-stencil 0.5 (- start-x 0.2) start-y (+
new-calculated-end-x 0.05) start-y)
       (make-switch-butt-line-stencil 0.1 new-calculated-end-x start-y
new-calculated-end-x end-y)
       (make-switch-butt-line-stencil 0.5 (- new-calculated-end-x
0.05) end-y (- end-x 2.5) end-y)
       )
      (cons (- (ly:grob-relative-coordinate grob sys X))
            (- (ly:grob-relative-coordinate grob sys Y))))))

3.) an engraver which manages the process

#(define (Switch_heads_engraver context)
   (let ((switched (make-hash-table)))
     (make-engraver
      (acknowledgers
       ((note-column-interface engraver grob source-engraver)
        (when (assoc-get 'switchable (ly:grob-property grob 'details '()))
          (for-each
           (match-lambda
            ((mom . elt)
             (when (and (grob::has-interface elt 'note-head-interface)
                        (assoc-get 'switch (ly:grob-property elt 'details '()))
                        (not (hashq-ref switched elt))
                        (not (equal? mom (ly:context-current-moment context))))
               (hashq-set! switched 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
'switch-color (ly:grob-property elt 'details '())))
                 (ly:grob-set-property! follower 'stencil switching-bracket)
                 (ly:grob-set-property! follower 'details
'((used-proportion . 0.5))) ;;; HERE I would like to have user-input
instead of 0.5
                 ;; would prefer the above line to read something like:
                 ;; (ly:grob-set-property! follower 'details
'((used-proportion . (assoc-get 'used-proportion (ly:grob-property elt
'details '())))))
                 ))))
           (ly:context-property context 'busyGrobs))))))))

and 4.) some commands to locate the start and stop of the voice follower

start-switch = \once \override Staff.NoteHead.details.switch = ##t
switch-proportion = \once \override Staff.NoteHead.details.used-proportion = 0.5
stop-switch = \once \override Staff.NoteColumn.details.switchable = ##t

I am trying to pass user-input to shorten an X-position by a proportion as
you might see in the commented line. However any time I try to replace 0.5
with a variable or a returned value from a function, an error is returned.
So I think I might not understand something about association lists in
Scheme. Do you have advice for passing in this value?

regards,
greg evans

On Sun, Jan 1, 2023 at 6:47 AM Jean Abou Samra <j...@abou-samra.fr> wrote:

> Le 31/12/2022 à 19:43, Gregory Evans a écrit :
> >
> > 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!
> >
>
>
> The engraver iterates over busyGrobs (maintained by Grob_pq_engraver),
> which is precisely, by definition, the set of grobs with a cause in events
> that tells they are still "active" at the current moment.
>
> If you want different behavior, acknowledge note-head-interface yourself
> and store the grobs in a variable in the engraver (adding a new binding
> in (let ((followed ...) [here]) ...)).
>
>
> > 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?
> >
>
>
> What about using a details.spanner-ids symbol list property?
> You'd read it on the note column to know which spanners to start/stop.
>
> Best,
> Jean
>
>
>

-- 
gregory rowland evans
http://www.gregoryrowlandevans.com
https://github.com/GregoryREvans
https://soundcloud.com/gregory-rowland-evans

Reply via email to