2018-08-05 18:14 GMT+02:00 Thomas Morley <thomasmorle...@gmail.com>:

> Inspired by your work I come up with the attached.

Attached an improved and simplified version.
It's tested with 2/3/4-voices divisi, all in one score.
Although not tested, I see no reason why it shouldn't work with even
more voices.

HTH,
  Harm
\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"))
    }
  }
}
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to