On 2024-05-28 10:43 am, Fennel wrote:
indicating a “fork”, or the use of two different fingers across
strings at the same “fret”. Is attaching lines like this a
supported feature at the moment, and if not, does anyone have any
ideas on what writing scripts to support this behavior would look
like?


Spent some time working on your "fork" scenario. Not sure if I got it entirely correct. Attached is the source. Hope this either gives you something you can use directly, or at a minimum gives you something to work from.


-- Aaron Hill
\version "2.25.13"


#(define (finger-glide-fork::print grob)
  (let* ((thickness (* (ly:grob-property grob 'thickness 1)
                       (ly:staff-symbol-line-thickness grob)))
         (left-bound-info (ly:grob-property grob 'left-bound-info))
         (right-bound-info (ly:grob-property grob 'right-bound-info))
         (left-padding (assoc-get 'padding left-bound-info 0.5))
         (right-padding (assoc-get 'padding right-bound-info 0.5))
         (left-bound (ly:spanner-bound grob LEFT))
         (system (ly:grob-system grob))
         (left-relative-coord (ly:grob-relative-coordinate left-bound system X))
         (left-X (assoc-get 'X left-bound-info))
         (x-start (- left-X left-relative-coord (- left-padding)))
         (right-X (assoc-get 'X right-bound-info))
         (x-end (- right-X left-relative-coord (+ right-padding)))
         (y-start (assoc-get 'Y left-bound-info))
         (y-end (assoc-get 'Y right-bound-info))

         (details (ly:grob-property grob 'details '()))
         (fork-height (assoc-get 'fork-height details 0.5))
         (direction (ly:grob-property left-bound 'direction))
         (minmax (if (< 0 direction) max min))
         (apex-delta (* direction fork-height))
         (fork-apex-x (/ (+ x-start x-end) 2))
         (fork-apex-y (minmax (+ y-start apex-delta)
                              (+ y-end apex-delta))))
    (ly:stencil-add
      (make-line-stencil
        thickness x-start y-start fork-apex-x fork-apex-y)
      (make-line-stencil
        thickness fork-apex-x fork-apex-y x-end y-end))
))

#(define (ly:pitch=? p q) (not (or (ly:pitch<? p q) (ly:pitch<? q p))))

makeGlide =
#(define-music-function
  (first     second    duration    )
  (ly:pitch? ly:pitch? ly:duration?)
  (if (ly:pitch=? first second)
    #{ <$first \glide -1>$duration <$second -1> #}
    #{ <$first \glide -1>$duration <$second -1>
       <$second \glide -1> <$first -1> #}))

testCases =
{
  \cadenzaOn
  \set fingeringOrientations = #'(up)
  \makeGlide e'' e'' 4
  \makeGlide e'' f'' 4
  \makeGlide e'' g'' 4
  \makeGlide e'' a'' 4
  \makeGlide e'' b'' 4
  \bar "."
  \set fingeringOrientations = #'(down)
  \makeGlide f' f' 4
  \makeGlide f' e' 4
  \makeGlide f' d' 4
  \makeGlide f' c' 4
  \makeGlide f' b 4
  \bar "|."
}

\paper {
  #(set-paper-size "ledger")
  indent = 0 ragged-right = ##f line-width = 13\in
}

\markup \huge { "Test cases using original" \concat { \bold \typewriter 
"finger-glide::print" : } }
\new Staff { \testCases }
\markup \vspace #1

\markup \huge { "Test cases using custom" \concat { \bold \typewriter 
"finger-glide-fork::print" : } }
\new Staff {
  \override FingerGlideSpanner.details.fork-height = 1.5
  \override FingerGlideSpanner.thickness = 2.5
  \override FingerGlideSpanner.stencil = #finger-glide-fork::print
  \testCases
}
\markup \vspace #1

Reply via email to