Hi,

I have a question about using a custom engraver to modify how grace notes 
appear when LilyPond’s new string bending is applied to them. This is the first 
custom engraver I’ve attempted to write, so I think I’ve overlooked something 
rather basic. The repository for the engraver is at 
https://github.com/nwhetsell/lilypond-bending-additions, and the current 
engraver is at

https://github.com/nwhetsell/lilypond-bending-additions/blob/0bbfdaa9a76bef10c4b23cc97b1edede8fde2f2a/bending-additions.ily

Conceptually, I’m trying to do three things:

1. If a string bend starts on a grace note, don’t reduce the size of the fret 
number in a TabStaff.

2. If, in addition, the bent grace note is a pre-bend, put the notehead in 
parentheses, and don’t draw ledger lines, flags, or stems.

3. If a string bend ends on a grace note, don’t draw the notehead, ledger 
lines, accidentals, flags, or stems (don’t draw anything, basically).

Bearing in mind that there’s a lot about writing engravers that I don’t know, 
where I think I’m having difficulty is determining whether a note is a grace 
note. In short, I’m getting a notehead grob using an acknowledger and then 
checking the value of its ly:moment-grace 
<https://lilypond.org/doc/v2.24/Documentation/internals/scheme-functions#index-ly_003amoment_002dgrace>
 in the engraver’s stop-translation-timestep method. However, this doesn’t work 
directly. In stop-translation-timestep, the moment of a notehead created in 
that timestep appears to always be null. As workaround, I’m saving the notehead 
and then getting its moment in the next call to stop-translation-timestep, at 
which point the notehead’s moment is no longer null.

The issue here is that there are some properties that appear to only have an 
effect when they’re applied to a notehead in the same timestep in which it’s 
created. For example, setting no-ledgers to #t has no affect when applied to 
noteheads from a previous timestep.

There’s some simplified code that attempts to illustrate this below. Is there 
another way for a custom engraver to determine whether a note is a grace note?

Thanks in advance!
Nate

\version "2.24.0"

#(define (Grace_reporting_engraver context)
  (let (
      (current-note-head '())
      (previous-note-head '()))

    (make-engraver
      (acknowledgers
        ((note-head-interface engraver grob source-engraver)
          (set! current-note-head grob)))

      ((stop-translation-timestep engraver)
        (if (not (null? current-note-head))
          (let (
              (moment (grob::when current-note-head)))
            (if (not (null? moment))
              (if (not (eq? (ly:moment-grace moment) 0))
                (begin (newline)(display "==> current-note-head is for a grace 
note")))
              (begin (newline)(display "==> current-note-head has null 
moment")))))

        (if (not (null? previous-note-head))
          (let (
              (moment (grob::when previous-note-head)))
            (if (not (null? moment))
              (if (not (eq? (ly:moment-grace moment) 0))
                (begin (newline)(display "==> previous-note-head is for a grace 
note")))
              (begin (newline)(display "==> previous-note-head has null 
moment")))))

        (set! previous-note-head current-note-head)
        (set! current-note-head '())))))

{
  \new Voice \with {
    \consists #Grace_reporting_engraver
  } {
    \grace c' \grace d' \grace e'
  }
}

#(define (Current_note_ledger_hider context)
  (let (
      (current-note-head '()))

    (make-engraver
      (acknowledgers
        ((note-head-interface engraver grob source-engraver)
          (set! current-note-head grob)))

      ((stop-translation-timestep engraver)
        (if (not (null? current-note-head))
          (ly:grob-set-property! current-note-head 'no-ledgers #t))))))

{
  \new Voice \with {
    \consists #Current_note_ledger_hider
  } {
    \grace c''' \grace c'''
  }
}

#(define (Previous_note_ledger_hider context)
  (let (
      (current-note-head '())
      (previous-note-head '()))

    (make-engraver
      (acknowledgers
        ((note-head-interface engraver grob source-engraver)
          (set! current-note-head grob)))

      ((stop-translation-timestep engraver)
        (if (not (null? previous-note-head))
          (ly:grob-set-property! previous-note-head 'no-ledgers #t))

        (set! previous-note-head current-note-head)
        (set! current-note-head '())))))

{
  \new Voice \with {
    \consists #Previous_note_ledger_hider
  } {
    \grace c''' \grace c'''
  }
}

Reply via email to