Am Mo., 1. Nov. 2021 um 15:35 Uhr schrieb Kieren MacMillan
<kieren_macmil...@sympatico.ca>:
>
> Hi all,
>
> Having struggled with this for almost a decade (see, e.g., 
> https://lists.gnu.org/archive/html/lilypond-user/2013-03/msg00314.html)… Is 
> this something that could be handled really well with an engraver? Or at 
> least a bunch of helpful syntactic sugar? Surely all of this manual work 
> (offset, calculate height, etc.) can be automagically handled…?
>
> I’d love to pursue A Real Solution™ for this problem, if anyone out there is 
> interested in collaborating with me.
>
> Cheers,
> Kieren.
> ________________________________
>
> Kieren MacMillan, composer (he/him/his)
> ‣ website: www.kierenmacmillan.info
> ‣ email: kie...@kierenmacmillan.info
>
>

Hi Kieren,

attached code hacks Instrument.Y-offset.
This is a proof of concept, please test thoroughly before using it in
serious work.

Cheers,
  Harm
\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 }
  >>
>>

Attachment: instrument-group-brackets-01.pdf
Description: Adobe PDF document

Reply via email to