Jump to content

Extended position fingering for string instruments

From LilyPond wiki

String instruments (for example the cello) may require special notation for extended fingerings, situations where one finger has to reach beyond its usual pitch in the current position. Some editions indicate that with a tie or a glissando line between the two fingerings, whilst others use a cross mark between the two fingerings. Here is a way to print the latter.

\version "2.24.0"

%%LSR see https://lists.gnu.org/archive/html/lilypond-user-fr/2020-06/msg00119.html

%%%%%% 2.18 compatibility -- remove for 2.20 onwards %%%%%%

#(define-public (music-type-predicate types)
  "Returns a predicate function that can be used for checking
music to have one of the types listed in @var{types}."
  (if (cheap-list? types)
      (lambda (m)
        (any (lambda (t) (music-is-of-type? m t)) types))
      (lambda (m) (music-is-of-type? m types))))

#(define-public (get-tweakable-music mus)
  "When tweaking music, returns a list of music expressions where the
tweaks should be applied.  Relevant for music wrappers and event
chords."
  (cond ((music-is-of-type? mus 'music-wrapper-music)
         (get-tweakable-music (ly:music-property mus 'element)))
        ((music-is-of-type? mus 'event-chord)
         (filter (music-type-predicate 'rhythmic-event)
                 (ly:music-property mus 'elements)))
        (else (list mus))))

%%%%%%        End 2.18 compatibility definitions     %%%%%%

extend =
#(define-music-function (m) (ly:music?)
   (let* ((x-markup (markup #:normal-text #:fontsize 5 #:bold "×"))
          (x-fingering (make-music 'FingeringEvent 'text x-markup))
          (m-note (car (get-tweakable-music m)))
          (n (make-music 'NoteEvent
                         'duration (ly:music-property m-note 'duration)
                         'pitch (ly:music-property m-note 'pitch)
                         'articulations (list x-fingering)))
          (x-id (format #f "\"~a\"" (+ 100 (random 899)))))
     (or (eq? m m-note)
         (set! n (make-event-chord (list n))))
     #{
       \applyContext #(lambda (ctx)
                        (ly:context-set-property!
                         (ly:context-parent ctx) 'fingeringOrientations
                         (ly:context-property ctx 'fingeringOrientations)))
       \context Voice <<
         $m \new Voice = $x-id \scaleDurations 1/2 {
           \hideNotes \textLengthOn \omit Flag \omit Dots
           \applyContext #(lambda (ctx)
                            (ly:context-set-property!
                             ctx 'fingeringOrientations
                             (ly:context-property
                              (ly:context-parent ctx)
                              'fingeringOrientations)))
           s $n }
       >> #}))

{
  \clef bass
  \extend e'2-3 fis'-4
  \set fingeringOrientations = #'(down)
  \extend <e,-1> <fis,-2>
}