Hello Antonie, hello Werner,

> > I've noticed that Lilypond left-aligns figured bass figures with
> > respect to their notes. This works well enough for note values up to
> > a minim, but I've noticed it looks off for the wider note heads of
> > semibreves and breves.  [...]
> > It seems that none of the relevant figured bass grobs support the
> > self-alignment-interface, which is how you'd usually configure
> > horizontal alignment.  Is there something I'm missing, or is this a
> > shortcoming in Lilypond?
> 
> It's a shortcoming, as the report describes.  I fear you have to cook
> up a manual solution right now, i.e., encapsulating the suggested
> changes into a macro and applying it to whole notes only.
> 
> Of course, any fixes are more than welcome :-)

Find attached a file that solves alignment of Figured Bass on note heads under 
reasonable assumptions (like, in cases where we find figured bass we’d expect 
there to be a single relevant note/notecolumn).

What this does:

- Modify `figuredBassFormatter` to center the base digit
- Create a small engraver that changes X-parent of bass figures to note column
- Sets Bass Figures to center align on main noteheads

This only works though if the `figures-to-note-column-engraver` is given in a 
sufficiently specific parent-context to the one where the note column engraver 
and the bass figure engraver live. So if you want to use a separate 
`FiguredBass` context you might want to encapsule them in a StaffGroup

    \new StaffGroup { \with \consists #figures-to-note-column-engraver }
    << \new Staff ... \new FiguredBass ... >>

and if you want to be very specific (say you actually have multiple voices in 
the bass staff you might want to move the `Figured_bass_engraver` to Voice.

Cheers,
Tina
#(define-public (c-format-bass-figure figure event context)
  (let* (;; User properties controlling the figured bass layout.
         (figbass-alist
          (ly:context-property context 'figuredBassPlusStrokedAlist))
         (alt-dir
          (ly:context-property context 'figuredBassAlterationDirection))
         (plus-dir
          (ly:context-property context 'figuredBassPlusDirection))

         (augmented (ly:event-property event 'augmented))

         (number-one (make-number-markup "1"))

         ;; The digit(s), horizontally positioned, or #f.
         (fig-markup
          (if (number? figure)
              (make-center-align-markup
               (cond
                ((eq? #t (ly:event-property event 'diminished))
                 (make-slashed-digit-markup figure))
                ((eq? #t (ly:event-property event 'augmented-slash))
                 ;; Use specially stroked digit if available and wanted.
                 (or (and-let* (((<= 6 figure 9))
                                (glyph (assv-ref figbass-alist figure)))
                       (make-musicglyph-markup glyph))
                     (make-backslashed-digit-markup figure)))
                ((eq? #t augmented)
                 ;; Use special digit with plus if available and wanted.
                 (or (and-let* (((>= 5 figure 2))
                                ((eqv? plus-dir RIGHT))
                                (glyph (assv-ref figbass-alist figure)))
                       (set! augmented #f)
                       (make-musicglyph-markup glyph))
                     (make-number-markup (number->string figure 10))))
                (else (make-number-markup (number->string figure 10)))))
              #f))

         (alt (ly:event-property event 'alteration))
         (alt-bracket (ly:event-property event 'alteration-bracket #f))
         ;; The alteration, probably bracketed but not positioned yet,
         ;; or #f.
         (alt-markup
          (if (number? alt)
              (let* ((acc (assoc-get alt (@@ (lily) figbass-accidental-alist)))
                     (acc-markup
                      (if acc
                          (make-number-markup (ly:wide-char->utf-8 acc))
                          (begin
                            (ly:warning
                             (G_ "no accidental glyph found for alteration ~a")
                             alt)
                            ;; fallback
                            "?"))))
                (if alt-bracket
                    (make-bracket-markup acc-markup)
                    acc-markup))
              #f))

         (plus-markup (if (eq? #t augmented)
                          (make-number-markup "+")
                          #f)))

    (if (and (not alt-markup) alt-bracket)
        (ly:programming-error
         "Cannot put brackets around non-existent bass figure alteration."))

    ;; We treat a solitary alteration similarly to digits.
    (if (and (not fig-markup) alt-markup)
        (begin
          (set! fig-markup
                (make-center-align-markup alt-markup))
          (set! alt-markup #f)))

    ;; We treat a solitary plus similarly to digits (but enlarged).
    (if (and (not fig-markup) plus-markup)
        (begin
          (set! fig-markup
                (make-align-on-other-markup
                 Y
                 CENTER number-one
                 CENTER (make-center-align-markup (make-fontsize-markup 3 plus-markup))))
          (set! plus-markup #f)))

    ;; The alteration gets attached either to the left or the right of
    ;; the digit(s).
    (if alt-markup
        (set! fig-markup
              (make-put-adjacent-markup
               X (if (number? alt-dir)
                     alt-dir
                     LEFT)
               fig-markup
               (make-pad-x-markup 0.1 alt-markup))))

    ;; Ditto for the plus mark.
    (if plus-markup
        (set! fig-markup
              (if fig-markup
                  (make-put-adjacent-markup
                   X (if (number? plus-dir)
                         plus-dir
                         LEFT)
                   fig-markup plus-markup)
                  plus-markup)))

    (if (markup? fig-markup)
        (make-fontsize-markup -5 fig-markup)
        (make-null-markup))))

#(define (figures-to-note-column-engraver context)
   (let ((figs '()) (nc #f))
     (make-engraver
      (acknowledgers
       ((bass-figure-interface engraver grob source)
        (set! figs (cons grob figs)))
       ((note-column-interface engraver grob source)
        (set! nc grob)))
      ((process-acknowledged engraver)
       (if nc
           (for-each
            (lambda (g)
              (ly:grob-set-parent! g X nc))
            figs))
       (set! nc #f)
       (set! figs '())))))

\layout {
  \context {
    \Staff
    \consists #figures-to-note-column-engraver
    \override BassFigure.X-align-on-main-noteheads = ##t
    \override BassFigure.parent-alignment-X = #CENTER
    \override BassFigure.X-offset = #ly:self-alignment-interface::aligned-on-x-parent
    figuredBassFormatter = #c-format-bass-figure
  }
}

\new Voice <<
  { c'1 4 8 8 }
  \figuremode {
    <15- 7+ 6/ 4\+ 3- _+ _\+>1 4 8 8
  }
>>

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to