Hi, all -- Attached is a function which started out as an attempt to get tempo indications to line up with the left edge of the time signature. It's been generalized so that you can left-align any grob responsive to 'extra-offset to the closest grob of a specified type in that system (as far as I can tell so far -- you could even left-align a notehead to a barline, if you were so inclined...)
It locates the closest grob by first searching all of the grobs in a system for every instance of the target type, then selecting the one that is closest horizontally. (For example, if you want to align something to a barline, the function would determine where all the barlines are, then choose the nearest one). I have several questions: (1) Is there a way to locate the nearest grob more efficiently, so the routine doesn't have to search the entire system? (2) Is there a way to exclude grobs that are in the same system, but on a different staff? I've looked at the 'staff-symbol property, but it's empty in some cases. (3) Does anybody have any suggestions how to improve the coding? I'm enjoying learning Scheme, but my approach is rather hit-and-miss! Best, David
\version "2.12.3" leftAlignGrob = #(define-music-function (parser location grob-to-align reference-grob) (string? symbol?) #{ \overrideProperty $grob-to-align #'after-line-breaking #(lambda (grob) (let* ((sys (ly:grob-system grob)) (array (ly:grob-object sys 'all-elements)) (len (ly:grob-array-length array)) (current-grob-in-search (lambda (q) (assq-ref (ly:grob-property (ly:grob-array-ref array q) 'meta) 'name))) (default-coord (ly:grob-relative-coordinate grob sys X)) (lst '())) ;; find all instances in a system of the grob we want to use for alignment ;; returns list of X-coordinates, minus duplicates (let lp ((x len)) (if (positive? x) (begin (if (eq? $reference-grob (current-grob-in-search (1- x))) (set! lst (uniq-list (append lst (list (ly:grob-relative-coordinate (ly:grob-array-ref array (1- x)) sys X)))))) (lp (1- x))))) ;; find the value in the list closest to the X-coordinate of object to be aligned (let ((ref (car lst))) (define closest (lambda (x) (if (< (abs (- default-coord (car x))) (abs (- default-coord ref))) (set! ref (car x))) (if (not (null? (cdr x))) (closest (cdr x))))) (closest lst) (ly:grob-set-property! grob 'extra-offset `(,(- ref default-coord) . 0))))) #} ) \relative c' { %% bar 1 \time 3/4 \key d \major \leftAlignGrob #"Score.MetronomeMark" #'TimeSignature \tempo 4 = 120 \once \override TextScript #'padding = #2 \leftAlignGrob #"TextScript" #'Clef d_"clef" \leftAlignGrob #"TextScript" #'KeySignature e_"key sig." fis %% bar 2 e \once \override Hairpin #'X-offset = #-1 \leftAlignGrob #"TextScript" #'Hairpin d\<_"hairpin (offset)" e %% bar 3 \leftAlignGrob #"TextScript" #'BarLine \time 2/4 fis^"bar" d %% bar 4 \time 4/4 \leftAlignGrob #"TextScript" #'TimeSignature e^"meter" fis d \once \override DynamicText #'X-offset = #0.5 \leftAlignGrob #"TextScript" #'DynamicText fis\f_"dynamic (offset)" %% bar 5 \leftAlignGrob #"TextScript" #'Stem \time 3/4 e^"stem" fis d %% bar 6 \leftAlignGrob #"Score.RehearsalMark" #'TimeSignature \mark #1 \time 2/4 fis d }
<<attachment: image.png>>
_______________________________________________ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user