-%% Do not edit this file; it is automatically
-%% generated from LSR http://lsr.dsi.unimi.it
+%% DO NOT EDIT this file manually; it is automatically
+%% generated from LSR http://lsr.di.unimi.it
+%% Make any changes in LSR itself, or in Documentation/snippets/new/ ,
+%% and then run scripts/auxiliar/makelsr.py
+%%
%% This file is in the public domain.
-\version "2.13.16"
+\version "2.18.0"
\header {
- lsrtags = "text, tweaks-and-overrides"
+ lsrtags = "contexts-and-engravers, text, tweaks-and-overrides"
texidoc = "
For technical reasons, text scripts attached to note heads cannot
easily be centered on a note head's width, unlike articulations.
-Instead of using trial-and-error offset tweaks, this snippet accesses a
-note head (or rest) from the @code{TextScript} object's horizontal
-parent (a paper column), using its extent to correct the positioning.
+Instead of using trial-and-error offset tweaks, this snippet uses a
+Scheme engraver to reset the horizontal parent of each markup to a
+@code{NoteColumn}. This also allows text to follow note heads which
+have been shifted via @code{force-hshift}.
doctitle = "Centering markup on note heads automatically"
} % begin verbatim
-textScriptCenterOnNote = \override TextScript #'X-offset =
-#(lambda (grob)
- (let* ((paper-col (ly:grob-parent grob X))
- (elts (ly:grob-object paper-col 'elements))
- (rhythmic-head grob))
-
- (for-each
- (lambda (idx)
- (let ((elt (ly:grob-array-ref elts idx)))
- (if (grob::has-interface elt
- 'rhythmic-grob-interface)
- (set! rhythmic-head elt))))
- (reverse (iota (ly:grob-array-length elts))))
-
- (+
- (ly:self-alignment-interface::x-aligned-on-self grob)
- (interval-center
- (ly:grob-robust-relative-extent rhythmic-head rhythmic-head X)))))
-
-\relative c' {
- \override TextScript #'self-alignment-X = #CENTER
- \textScriptCenterOnNote
- <c e g c>1-\markup \arrow-head #Y #UP ##t
- <c e g c>1-\markup \huge "^"
+#(define (Text_align_engraver ctx)
+ (let ((scripts '())
+ (note-column #f))
+ (make-engraver
+ (acknowledgers
+ ((note-column-interface trans grob source)
+ ;; cache NoteColumn in this Voice context
+ (set! note-column grob))
+ ((text-script-interface trans grob source)
+ ;; whenever a TextScript is acknowledged,
+ ;; add it to `scripts' list
+ (set! scripts (cons grob scripts))))
+ ((stop-translation-timestep trans)
+ ;; if any TextScript grobs exist,
+ ;; set NoteColumn as X-parent
+ (for-each (lambda (script)
+ (set! (ly:grob-parent script X) note-column))
+ scripts)
+ ;; clear scripts ready for next timestep
+ (set! scripts '())))))
+
+\layout {
+ \context {
+ \Voice
+ \consists #Text_align_engraver
+ \override TextScript.X-offset =
+ #ly:self-alignment-interface::aligned-on-x-parent
+ \override TextScript.self-alignment-X = #CENTER
+ }
}
+\new Staff <<
+ \relative c'' {
+ \override NoteColumn.force-hshift = #3
+ c1-\markup { \arrow-head #Y #DOWN ##t }
+ }
+ \\
+ \relative c' {
+ a4 a-\markup { \huge ^ } a a
+ }
+>>