lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: engraver to change staff name based on visibility of related staff?


From: Shevek
Subject: Re: engraver to change staff name based on visibility of related staff?
Date: Thu, 6 Jul 2017 16:31:01 -0700 (MST)

Making some progress on this. I've managed to figure out how to use
ly:grob-get-vertical-axis-group-index to only look at the current Staff and
the next one below. That's clunkier than finding the VerticalAxisGroups that
belong to the same StaffGroup, but it's a start.

My problem now is finding a way to grab the InstrumentName grob that belongs
to the current Staff, not just the list of all the InstrumentName grobs on
the current system. Once you start hiding staves, it's no longer guaranteed
that the list of InstrumentNames will line up correctly with the list of
VerticalAxisGroups.

Here's the code I'm working with now, modified from Harm's:

\version "2.18.2"

%% NB
%% It's a proof of concept, nothing more!!
%% Currently it will fail for various reasons with extended examples
#(define change-instr-names
  (lambda (grob)
    (let* ((sys (ly:grob-system grob))
           (sys-all-elts (ly:grob-object sys 'all-elements))
           (sys-all-elts-list
             (if (ly:grob-array? sys-all-elts)
                 (ly:grob-array->list sys-all-elts)
                 '()))
           ;; get all VerticalAxisGroup-grobs per System
           (vertical-axis-group-list
             (filter
               (lambda (g)
                 (grob::has-interface g 'hara-kiri-group-spanner-interface))
               sys-all-elts-list))

           ;; get all InstrumentName-grobs per System
           (instrument-names-list
             (filter
               (lambda (g)
                 (grob::has-interface g 'system-start-text-interface))
               sys-all-elts-list))
           
           ;; Make a list of pairs of VerticalAxisGroup and InstrumentName
grobs
           ;; This assumes the correspondence will be correct, 
           ;; but that is NOT guaranteed to be true
           (instr-axis-list
            (zip vertical-axis-group-list instrument-names-list))
           
           ;; Check if a VerticalAxisGroup is me or the next one below me
           ;; Keep if yes, ignore the rest
           (my-vindex (ly:grob-get-vertical-axis-group-index grob))
           (cousin-vaxis? (lambda (v)
                          (let ((vindex
(ly:grob-get-vertical-axis-group-index v)))
                            (or (equal? my-vindex vindex)
                                (equal? (+ 1 my-vindex) vindex)))
                          ))
           
           (cousin-instr-list
            (filter
             (lambda (x)
               (cousin-vaxis? (car x)))
             instr-axis-list))
           
            ;; construct a nested list like
            ;;   ((#t #<Grob InstrumentName >)
            ;;    (#f #<Grob InstrumentName >))
            ;; the boolean indicates whether the Staff is alive, derived
from
            ;; VerticalAxisGroup.Y-extent
            (alive?-instr-list
              (map
                (lambda (x)
                  (list (interval-sane? (ly:grob-property (car x)
'Y-extent)) (cadr x))
                  )
                cousin-instr-list))
           )

;            (display alive?-instr-list)
;            (display (map-in-order ly:grob-get-vertical-axis-group-index
instrument-names-list))
;            (display (map-in-order (lambda (g) (ly:grob-property (cadr g)
'text)) instr-axis-list))
;            (display "\n\n")
           

        ;; First constructing a list and then fragmenting it in various ways
is
        ;; not elegant, to say the least.
        ;; Just a proof of concept...
        (if (any not (map car alive?-instr-list))
            (let* ((instr-to-set
                     (filter car alive?-instr-list)
                     ))
              (for-each (lambda (inst) (ly:grob-set-property! (cadr inst)
'text
                (make-column-markup
                  (map
                    (lambda (arg)
                      (ly:grob-property arg 'text))
                    (map cadr alive?-instr-list)))))
                instr-to-set
                          )))
      )))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Example
%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\layout {
  \context {
    \Staff
    \RemoveEmptyStaves
  }
}
<<
  \new StaffGroup = "foo" <<
    \new Staff = "1" \with { 
      \override VerticalAxisGroup.after-line-breaking = #change-instr-names
      instrumentName = "One" shortInstrumentName = "1" 
    }
      { R1 \break c \break c }
    \new Staff = "2" \with { 
      instrumentName = "Two" shortInstrumentName = "2" 
    }
      { c1 c c }
  >>
  \new StaffGroup = "baz" <<
    \new Staff = "3" \with { 
      \override VerticalAxisGroup.after-line-breaking = #change-instr-names
      instrumentName = "One" shortInstrumentName = "3" }
      { R1 \break c \break c }
    \new Staff = "4" \with { instrumentName = "Two" shortInstrumentName =
"4" }
      { c1 R c }
  >>
>>



--
View this message in context: 
http://lilypond.1069038.n5.nabble.com/engraver-to-change-staff-name-based-on-visibility-of-related-staff-tp203905p204290.html
Sent from the Dev mailing list archive at Nabble.com.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]