\version "2.23.3" %% Set 'stencil as side-effect from 'Y-offset %% A hack ... #(define-public ((system-start-text::calc-y-offset-harm stencil-proc) grob) (define (live-elements-list me) (let ((elements (ly:grob-object me 'elements))) (filter! grob::is-live? (ly:grob-array->list elements)))) (let* ((left-bound (ly:spanner-bound grob LEFT)) (live-elts (live-elements-list grob)) (system (ly:grob-system grob)) (extent empty-interval)) (if (and (pair? live-elts) (interval-sane? (ly:grob-extent grob system Y))) (let get-extent ((lst live-elts)) (if (pair? lst) (let ((axis-group (car lst))) (if (and (ly:spanner? axis-group) (equal? (ly:spanner-bound axis-group LEFT) left-bound)) (set! extent (add-point extent (ly:grob-relative-coordinate axis-group system Y)))) (get-extent (cdr lst))))) ;; no live axis group(s) for this instrument name -> remove from system (ly:grob-suicide! grob)) (if (procedure? stencil-proc) (let* ((staff-space (ly:staff-symbol-staff-space grob)) ;; `extend' is from top zero-line to bottom zero-line (widened-extent (interval-widen extent (* 2 staff-space))) (y-length (interval-length widened-extent)) (custom-stencil (stencil-proc y-length grob))) (if (ly:stencil? custom-stencil) (ly:grob-set-property! grob 'stencil (ly:stencil-add (ly:stencil-translate-axis (ly:stencil-rotate (grob-interpret-markup grob (ly:grob-property grob 'long-text)) 90 0 0) ;; hmmm, hardcoded -6 X) custom-stencil))))) (+ (ly:self-alignment-interface::y-aligned-on-self grob) (interval-center extent)))) #(define boolean-or-procedure? (lambda (x) (or (procedure? x)(boolean? x)))) groups = #(define-scheme-function (proc)(boolean-or-procedure?) #{ \override InstrumentName.Y-offset = #(system-start-text::calc-y-offset-harm proc) #}) %%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXAMPLE %%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Example stencils, we always need `y-length' and `grob' #(define (bracket-stencil y-length grob) (ly:stencil-translate-axis (centered-stencil (make-connected-path-stencil (list '(1 0) '(0 0) (list 0 y-length) (list 1 y-length)) 0.1 1 1 #f #f)) ;; TODO why 0.75? 0.75 Y)) #(define (brace-stencil y-length grob) (ly:stencil-translate-axis (centered-stencil (grob-interpret-markup grob ;; TODO why `5' ? (make-left-brace-markup (* 5 y-length)))) ;; TODO why 0.75? 0.75 Y)) %% Some score << \new Staff \with { instrumentName = "Piccolo " } { R1 \break R } \new StaffGroup \with { \groups #bracket-stencil instrumentName = "Flutes" } << \new Staff \with { \groups ##f instrumentName = "I" \override VerticalAxisGroup.staff-staff-spacing.padding = 10 } { R1 \break R } \new Staff \with { \groups ##f instrumentName = "II" } { R1 \break R } \new Staff \with { \groups ##f instrumentName = "III" } { R1 \break R } >> \new Staff \with { instrumentName = "Timpani " } { R1 \break R } \new GrandStaff \with { \override InstrumentName.Y-offset = #(system-start-text::calc-y-offset-harm brace-stencil) instrumentName = "Violins" } << \new Staff \with { \groups ##f instrumentName = "I" \override VerticalAxisGroup.staff-staff-spacing.padding = 15 } { R1 \break R } \new Staff \with { \groups ##f instrumentName = "II" } { R1 \break R } >> >>