\version "2.19.82" \pointAndClickOff %% relies on: %% %% VerticalAxisGroup.details.catch-me %% VerticalAxisGroup.details.combined %% %% see inline comments below %% %% %% Limitations: %% Staves can't be started/ended mid-line. #(define (divisis divisi-groups) ;; Kill selected other Staffs, if divisi-Staffs are alive. ;; Do it separatly for every instrument-group specified by `divisi-groups`. (lambda (grob) ;; `grob` is supposed to be `VerticalAlignment`, per default living in ;; Score-context ;; ;; Apply the procedure to every element of `divisi-groups`, ;; p.e. '("flutes" "trumpets") (for-each (lambda (group) (let* ( ;; Get all `VerticalAxisGroup`s from `VerticalAlignment` ;; Those are the relevant grobs to look at to make others dead ;; or not (vags-array (ly:grob-object grob 'elements)) (vags-list (if (null? vags-array) '() (ly:grob-array->list vags-array))) ;; Select only those `VerticalAxisGroup`s related to current ;; `group` ;; Done by comparing the property `details.catch-me` with `group` (relevant-vags-list (filter (lambda (vag) (equal? group (assoc-get 'catch-me (ly:grob-property vag 'details)))) vags-list)) ;; Split them into those supposed to contain combinations and ;; others. ;; Done by reading the property `details.combined`. Which is ;; supposed to be a list, containing numbers, representing the ;; combined voices. ;; I.e. if we have 4 flutes, all combined, `details.combined` ;; should be '(1 2 3 4) ;; (splitted (call-with-values (lambda () (partition (lambda (vag) (pair? (assoc-get 'combined (ly:grob-property vag 'details) '()))) relevant-vags-list)) (lambda (x y) (list x y))))) (if (pair? (car splitted)) (for-each (lambda (i) ;; if divisi staves are alive, kill selected other staves ;; relying on the combined-values (for-each (lambda (x) (ly:pointer-group-interface::add-grob x 'make-dead-when (list-ref (car splitted) i))) ;; get a list of VerticalAxisGroups used with divisi-staves (map (lambda (index) (list-ref (cadr splitted) (1- index))) ;; get the 'combined-value from 'details, which is ;; supposed to be a list. (assoc-get 'combined (ly:grob-property (list-ref (car splitted) i) 'details) '())))) (iota (length (car splitted))))))) divisi-groups))) %% Short-cuts to switch on/off Staves %% They should be inserted at line-breaks. switchOff = \set Staff.keepAliveInterfaces = #'() switchOn = \unset Staff.keepAliveInterfaces %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXAMPLE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #(set-default-paper-size "a2") #(set-global-staff-size 15) \paper { indent = 20 short-indent = 20 } %% %% the actual music %% fluteI = \repeat unfold 12 c''2 fluteII = \repeat unfold 12 e'2 trumpetI = \repeat unfold 6 { g'4 c'' e'' c'' } trumpetII = \repeat unfold 6 { e'4 g' c'' g' } trumpetIII = \repeat unfold 6 { c'4 e' g' e' } corI = \repeat unfold 6 { c''2 c''4 c'' } corII = \repeat unfold 6 { g'2 g'4 g' } corIII = \repeat unfold 6 { e'2 e'4 e' } corIV = \repeat unfold 6 { c'2 c'4 c' } %% %% controlling divisis %% colors only for better viewing; ofcourse coding could be more concise %% p.e. deleting redundant \break-commands, they should likely be part of an %% own voice anyway; using s1*x etc %% %% divisi-Staffs are switched off per default, they may be switched on as wished %% %% flutes combined-flutes-I-II = { %% 1 \switchOff s1 \break %% 2 \switchOn \override NoteHead.color = #green s1 \break %% 3 s1 \break %% 4 \revert NoteHead.color \switchOff s1 \break %% 5 \switchOn \override NoteHead.color = #green s1 \break %% 6 s1 \break \revert NoteHead.color } %% trumpets combined-trumpets-I-II-III = { %% 1 \switchOff s1 \break %% 2 s1 \break %% 3 \switchOn \override NoteHead.color = #red s1 \break %% 4 \revert NoteHead.color \switchOff s1 \break %% 5 s1 \break %% 6 s1 \break } combined-trumpets-I-II = { %% 1 \switchOff s1 \break %% 2 s1 \break %% 3 s1 \break %% 4 \switchOn \override NoteHead.color = #(x11-color 'orange) s1 \break %% 5 \revert NoteHead.color \switchOff s1 \break %% 6 s1 \break } combined-trumpets-II-III = { %% 1 \switchOff s1 \break %% 2 s1 \break %% 3 s1 \break %% 4 s1 \break %% 5 s1 \break %% 6 \switchOn \override NoteHead.color = #yellow s1 \break } %% cors combined-cors-I-II-III-IV = { %% 1 \switchOff s1 \break %% 2 s1 \break %% 3 \switchOn \override NoteHead.color = #red s1 \break %% 4 \revert NoteHead.color \switchOff s1 \break %% 5 s1 \break %% 6 s1 \break } combined-cors-I-II = { %% 1 \switchOff \switchOn \override NoteHead.color = #(x11-color 'orange) s1 \break %% 2 \revert NoteHead.color \switchOff s1 \break %% 3 s1 \break %% 4 \switchOn \override NoteHead.color = #(x11-color 'orange) s1 \break %% 5 \revert NoteHead.color \switchOff s1 \break %% 6 s1 \break } combined-cors-II-III = { %% 1 \switchOff s1 \break %% 2 s1 \break %% 3 s1 \break %% 4 s1 \break %% 5 s1 \break %% 6 \switchOn \override NoteHead.color = #yellow s1 \break } combined-cors-III-IV = { %% 1 \switchOff s1 \break %% 2 s1 \break %% 3 s1 \break %% 4 \switchOn \override NoteHead.color = #(x11-color 'orange) s1 \break %% 5 \revert NoteHead.color \switchOff s1 \break %% 6 s1 \break } combined-cors-II-III-IV = { %% 1 \switchOff s1 \break %% 2 s1 \break %% 3 s1 \break %% 4 \switchOn \override NoteHead.color = #cyan s1 \break %% 5 s1 \break %% 6 \revert NoteHead.color \switchOff s1 \break } %% For divisi instruments initiate Staff-contexts for every single instrument. %% Set `VerticalAxisGroup.details.catch-me` and %% `VerticalAxisGroup.details.greediness` appropiate. The latter may left unset, %% if only two instruments participate. %% Initiate every desired divisi-Staff. %% Staves meant for divisi should be labed with %% `VerticalAxisGroup.details.combined = ##t`, appropriate `catch-me` and %% `greediness'. %% Again, the latter may left unset, if only two instruments participate. %% Apply \RemoveAllEmptyStaves to every divisi-Staff. %%{ \score { << %% A Staff which should not becomes part of any divisi \new Staff = "up" \with { instrumentName = "Picc" shortInstrumentName = "picc" } { \repeat unfold 48 c''8 } %% FLUTES \new StaffGroup \with { \override SystemStartBracket.collapse-height = 1 instrumentName = \markup { \rotate #90 "FLUTES" \hspace #16 } shortInstrumentName = \markup { \rotate #90 "FLUTES" \hspace #16 } } << \new Staff = "fl1" \with { instrumentName = "Fl 1" shortInstrumentName = "Fl 1" \override VerticalAxisGroup.details.catch-me = "flutes" } \fluteI \new Staff = "fl2" \with { instrumentName = "Fl 2" shortInstrumentName = "Fl 2" \override VerticalAxisGroup.details.catch-me = "flutes" } \fluteII \new Staff = "fl1+2" \with { instrumentName = "Fl 1+2" shortInstrumentName = "Fl 1+2" \RemoveAllEmptyStaves \override VerticalAxisGroup.details.catch-me = "flutes" \override VerticalAxisGroup.details.combined = #'(1 2) } \new Voice << \combined-flutes-I-II \fluteI \fluteII >> >> %% TRUMPETS \new StaffGroup \with { \override SystemStartBracket.collapse-height = 1 instrumentName = \markup { \rotate #90 "TUMPETS" \hspace #16 } shortInstrumentName = \markup { \rotate #90 "TRUMPETS" \hspace #16 } } << \new Staff = "tr1" \with { instrumentName = "Tr 1" shortInstrumentName = "Tr 1" \override VerticalAxisGroup.details.catch-me = "trumpets" } \trumpetI \new Staff = "tr2" \with { instrumentName = "Tr 2" shortInstrumentName = "Tr 2" \override VerticalAxisGroup.details.catch-me = "trumpets" } \trumpetII \new Staff = "tr3" \with { instrumentName = "Tr 3" shortInstrumentName = "Tr 3" \override VerticalAxisGroup.details.catch-me = "trumpets" } \trumpetIII \new Staff = "tr1+2+3" \with { instrumentName = "Tr 1+2+3" shortInstrumentName = "Tr 1+2+3" \RemoveAllEmptyStaves \override VerticalAxisGroup.details.combined = #'(1 2 3) \override VerticalAxisGroup.details.catch-me = "trumpets" } \new Voice << \combined-trumpets-I-II-III \trumpetI \trumpetII \trumpetIII >> \new Staff = "tr1+2" \with { instrumentName = "Tr 1+2" shortInstrumentName = "Tr 1+2" \RemoveAllEmptyStaves \override VerticalAxisGroup.details.catch-me = "trumpets" \override VerticalAxisGroup.details.combined = #'(1 2) alignAboveContext = "tr3" } \new Voice << \combined-trumpets-I-II \trumpetI \trumpetII >> \new Staff = "tr2+3" \with { instrumentName = "Tr 2+3" shortInstrumentName = "Tr 2+3" \RemoveAllEmptyStaves \override VerticalAxisGroup.details.catch-me = "trumpets" \override VerticalAxisGroup.details.combined = #'(2 3) alignBelowContext = "tr1+2" } \new Voice << \combined-trumpets-II-III \trumpetII \trumpetIII >> >> %% CORS \new StaffGroup \with { \override SystemStartBracket.collapse-height = 1 instrumentName = \markup { \rotate #90 "CORS" \hspace #16 } shortInstrumentName = \markup { \rotate #90 "CORS" \hspace #16 } } << \new Staff = "c1" \with { instrumentName = "Cor 1" shortInstrumentName = "Cor 1" \override VerticalAxisGroup.details.catch-me = "cors" } \corI \new Staff = "c2" \with { instrumentName = "Cor 2" shortInstrumentName = "Cor 2" \override VerticalAxisGroup.details.catch-me = "cors" } \corII \new Staff = "c3" \with { instrumentName = "Cor 3" shortInstrumentName = "Cor 3" \override VerticalAxisGroup.details.catch-me = "cors" } \corIII \new Staff = "c4" \with { instrumentName = "Cor 4" shortInstrumentName = "Cor 4" \override VerticalAxisGroup.details.catch-me = "cors" } \corIV \new Staff = "c1+2+3+4" \with { instrumentName = "Cors 1+2+3+4" shortInstrumentName = "Cors 1+2+3+4" \RemoveAllEmptyStaves \override VerticalAxisGroup.details.combined = #'(1 2 3 4) \override VerticalAxisGroup.details.catch-me = "cors" } \new Voice << \combined-cors-I-II-III-IV \corI \corII \corIII \corIV >> \new Staff = "c1+2" \with { instrumentName = "Cors 1+2" shortInstrumentName = "Cors 1+2" \RemoveAllEmptyStaves \override VerticalAxisGroup.details.catch-me = "cors" \override VerticalAxisGroup.details.combined = #'(1 2) alignAboveContext = "c3" } \new Voice << \combined-cors-I-II \corI \corII >> \new Staff = "c2+3" \with { instrumentName = "Cors 2+3" shortInstrumentName = "Cors 2+3" \RemoveAllEmptyStaves \override VerticalAxisGroup.details.catch-me = "cors" \override VerticalAxisGroup.details.combined = #'(2 3) alignAboveContext = "c4" } \new Voice << \combined-cors-II-III \corII \corIII >> \new Staff = "c3+4" \with { instrumentName = "Cors 3+4" shortInstrumentName = "Cors 3+4" \RemoveAllEmptyStaves \override VerticalAxisGroup.details.catch-me = "cors" \override VerticalAxisGroup.details.combined = #'(3 4) alignBelowContext = "c1+2" } \new Voice << \combined-cors-III-IV \corIII \corIV >> \new Staff = "c2+3+4" \with { instrumentName = "Cors 2+3+4" shortInstrumentName = "Cors 2+3+4" \RemoveAllEmptyStaves \override VerticalAxisGroup.details.catch-me = "cors" \override VerticalAxisGroup.details.combined = #'(2 3 4) alignBelowContext = "c1" } \new Voice << \combined-cors-II-III-IV \corII \corIII \corIV >> >> %% A Staff which should not becomes part of any divisi \new Staff = "bass" \with { instrumentName = "Bass" shortInstrumentName = "Bass" } { \clef bass \repeat unfold 6 c1 } >> \layout { \context { \Score \override VerticalAlignment.before-line-breaking = #(divisis '("flutes" "trumpets" "cors")) } } }