The problem here is that TextScript
grobs use by default ly:side-position-interface::y-aligned-side
for Y-offset
, so they are treated as side position elements, that is, positioned either over or under the parent.
To get a different behaviour simply override Y-offset
. If you use for example self-alignment-interface::y-aligned-on-self
you can set the Y-offset
to 0 with alignment determined by self-alignment-Y
. So you can use a callback for self-alignment-Y
to use the value of direction
to be able to use -"text"
for center, ^"text"
for up and _"text"
for down.
Of course you can do other things with Y-offset
as well, but this is what I described above:
\version "2.22.0"
right = \relative c'' {
c1 c c c
}
left = \relative c' {
c1 c c c
}
dynamics = {
s1\f s-"text" s^"text" s_"text"
}
\score {
\new PianoStaff <<
\new Staff = "right" \right
\new Dynamics = "dynamics" \with {
% Will use self-alignment-Y to place element
\override TextScript.Y-offset = #self-alignment-interface::y-aligned-on-self
% Use negative value of direction, i.e. CENTER -> align to center, UP -> align to bottom, DOWN -> align to top
\override TextScript.self-alignment-Y = #(lambda (grob) (- (ly:grob-property grob 'direction)))
% use CENTER as default direction instead of DOWN
\override TextScript.direction = #CENTER
} \dynamics
\new Staff = "left" \left
>>
\layout { }
}