Am Fr., 30. Jan. 2026 um 15:22 Uhr schrieb Gabriel Ellsworth
<[email protected]>:

> %%%  BEGIN DRAFT LANGUAGE
>
> The self-alignment-interface defines objects’ alignment points. This 
> interface applies to many graphical objects in LilyPond (see the list at 
> self-alignment-interface).
>
>
> An “alignment point” is a point associated with an object, along either the X 
> axis or the Y axis, that LilyPond uses when aligning that object with other 
> objects. “Self” alignment points are within the object itself. “Parent” 
> alignment points are within the object’s parent. For example, 
> LyricText.parent-alignment-X is the property of a lyric that specifies the 
> alignment point along the X axis of that lyric’s parent, which is the note 
> head linked to that lyric.
>
> %%%  END DRAFT EXPLANATION

Some remarks:
- The “alignment point” must not be _within_ the object.
'self/parent-aligment-x accepts values greater than 1 or below -1.
- I'd use not LyricText as example. Per default a NoteHead is never
parent-X of LyricText. For assigned lyrics it is NoteColumn and for
unassigned it is PaperColumn.

Below a snippet which may be helpful. It uses TextScript to
demonstrate alignments and prints several values to terminal.

#(define alignment-demo
  ;; Supposed to be applied for TextScript.after-line-breaking.
  ;; Demonstrates 'self-alignment-X and 'parent-alignment-X.
  (lambda (grob)
    (let* ((stil (ly:grob-property grob 'stencil))
           (stil-x-ext (ly:stencil-extent stil X))
           (x-off (ly:grob-property grob 'X-offset))
           (self-align-x (ly:grob-property grob 'self-alignment-X))
           (par-align-x (ly:grob-property grob 'parent-alignment-X -1))
           (stil-x-ext (ly:stencil-extent stil X))
           (grob-grob-x-ext (ly:grob-extent grob grob X))
           (sys (ly:grob-system grob))
           (grob-sys-x-ext (ly:grob-extent grob sys X))
           (grob-sys-x-coord (ly:grob-relative-coordinate grob sys X)))

      ;; Prints to terminal
      (pretty-print
        (list
          (cons 'par-align-x par-align-x)
          (cons 'self-align-x self-align-x)
          (cons 'x-off x-off)
          (cons 'grob-grob-x-ext grob-grob-x-ext)
          (cons 'stil-x-ext stil-x-ext)
          (cons 'grob-sys-x-ext grob-sys-x-ext)
          (cons 'grob-sys-x-coord grob-sys-x-coord)))

      ;; Adds a red dot to TextScript, representing the alignment X of
      ;; 'self-alignment-X
      (let* ((font (ly:grob-default-font grob))
             (dot (centered-stencil (ly:font-get-glyph font "dots.dot")))
             (red-dot (stencil-with-color dot red))
             (stil-center (interval-center stil-x-ext))
             (translated-red-dot
               (ly:stencil-translate-axis
                 red-dot
                 (* stil-center (1+ self-align-x)) X)))
        (ly:grob-set-property! grob 'stencil
          (ly:stencil-add stil translated-red-dot)))

      ;; Adds a vertical line to parent (NoteColumn), representing the
      ;; alignment X of 'parent-alignment-X
      (let* ((par-x (ly:grob-parent grob X)) ;; NoteColumn
             (nhds (ly:grob-object par-x 'note-heads #f))
             (nhds-x-ext (ly:relative-group-extent nhds sys X))
             (nhds-x-center (/ (interval-length nhds-x-ext) 2))
             (line-stil
               (ly:stencil-aligned-to
                 (make-line-stencil 0.1 0 -5 0 5) X CENTER))
             (translated-line-stil
               (ly:stencil-translate-axis
                 line-stil
                 (* nhds-x-center (1+ (or par-align-x -1)))
                 X)))
        (ly:grob-set-property! par-x 'stencil translated-line-stil)))))

#(define aligment-values '(-1 0 1))

\score {
  \new Staff {
    $@(map
       (lambda (x)
         #{
            \mark $(format #f "parent-alignment-X: ~a" x)
            \override TextScript.parent-alignment-X = #x
            $@(map
               (lambda (i)
                 #{
                    \override TextScript.self-alignment-X = #i
                    b'1_$(format #f "self-alignment-X: ~a" i)
                 #})
               aligment-values)
            \break
         #})
       aligment-values)
  }
  \layout {
    indent = 0
    \textLengthOn
    \context {
      \Score
      \omit TimeSignature
      \override RehearsalMark.padding = 4
    }
    \context {
      \Voice
      \override TextScript.after-line-breaking = #alignment-demo
    }
  }
}

HTH,
  Harm

Reply via email to