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