Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-08 Thread David Kastrup
Thomas Morley  writes:

> Or with other words, the rhythm is wrong in the line labeled with  %% <==
>
> controlDivisi = {
>   \switchOn
>   s4 s s s
>   \switchOff
>   s %% <==
>   \switchOn
>   s1
> }
>
> And I'm blind ... at least today.

It's more like that I'm better at answering "how would this look to a
computer" kind of questions than "how would this look to a human" ones,
having spent so much more time in my life with the former.

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-08 Thread Thomas Morley
2018-08-09 0:09 GMT+02:00 David Kastrup :
> Thomas Morley  writes:
>
>> 2018-08-08 22:21 GMT+02:00 Thomas Morley :
>>
>>>
>>> Well, this whole post was meant to explain my thoughts while coding
>>> the example from my previous mail.
>>> I expected the code to fail like my previous.
>>> It doesn't.
>>> Though, even after your hints above, what's the essential difference?
>>>
>>> I'll investigate.
>>
>>
>> The essential difference is the rhythm of the control-voice.
>> The code below never prints single instrument staves.
>> But changing in controlDivisi
>> s4 s s s -> s1
>> works.
>>
>> Changing
>> s4 s s s -> $#{ s4 s s s #}
>> works as well.
>>
>> WTF?
>
> Bit of a red herring here.  Those two sequences produce the same music
> but the first one sets the default duration to 4 while the second one
> leaves it unchanged at the previous value of 1, and the next skip then,
> lacking a duration of its own, gets a duration of 4 and 1, respectively.
>
> Same with s4 s s s -> s1 .  That's one reason why it is a good idea to
> use an explicit duration for the first note of each line, making the
> line's meaning independent from how the last line ended (at least
> regarding the duration).
>
> --
> David Kastrup

Or with other words, the rhythm is wrong in the line labeled with  %% <==

controlDivisi = {
  \switchOn
  s4 s s s
  \switchOff
  s %% <==
  \switchOn
  s1
}

And I'm blind ... at least today.

Thanks,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-08 Thread David Kastrup
Thomas Morley  writes:

> 2018-08-08 22:21 GMT+02:00 Thomas Morley :
>
>>
>> Well, this whole post was meant to explain my thoughts while coding
>> the example from my previous mail.
>> I expected the code to fail like my previous.
>> It doesn't.
>> Though, even after your hints above, what's the essential difference?
>>
>> I'll investigate.
>
>
> The essential difference is the rhythm of the control-voice.
> The code below never prints single instrument staves.
> But changing in controlDivisi
> s4 s s s -> s1
> works.
>
> Changing
> s4 s s s -> $#{ s4 s s s #}
> works as well.
>
> WTF?

Bit of a red herring here.  Those two sequences produce the same music
but the first one sets the default duration to 4 while the second one
leaves it unchanged at the previous value of 1, and the next skip then,
lacking a duration of its own, gets a duration of 4 and 1, respectively.

Same with s4 s s s -> s1 .  That's one reason why it is a good idea to
use an explicit duration for the first note of each line, making the
line's meaning independent from how the last line ended (at least
regarding the duration).

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-08 Thread Thomas Morley
2018-08-08 22:21 GMT+02:00 Thomas Morley :

>
> Well, this whole post was meant to explain my thoughts while coding
> the example from my previous mail.
> I expected the code to fail like my previous.
> It doesn't.
> Though, even after your hints above, what's the essential difference?
>
> I'll investigate.


The essential difference is the rhythm of the control-voice.
The code below never prints single instrument staves.
But changing in controlDivisi
s4 s s s -> s1
works.

Changing
s4 s s s -> $#{ s4 s s s #}
works as well.

WTF?

\version "2.19.82"

one = { e'1 f'4 g' a' f' g'1 }
two = { c'1 d'1 e'1 }
breaks = { s1 \break s1 \break s1 }

switchOff = \set Staff.keepAliveInterfaces = #'()
switchOn = \unset Staff.keepAliveInterfaces

controlDivisi = {
  \switchOn
%  s1
%  s4 s s s
  $#{ s4 s s s #}
  \switchOff
  s
  \switchOn
  s1
}
\new StaffGroup \with { \consists "Keep_alive_together_engraver" }
  <<
  \new Staff = "single1"
\with {
  \override VerticalAxisGroup.remove-layer = 2
}
<< \breaks \one >>
  \new Staff = "single2"
\with {
  \override VerticalAxisGroup.remove-layer = 2
}
<< \breaks \two >>
  \new Staff = "divisi"
\with {
  \RemoveAllEmptyStaves
  \override VerticalAxisGroup.remove-layer = 1
}
<<
  \controlDivisi
  \new Voice { \voiceOne \one } \new Voice { \voiceTwo \two }
>>
>>

Cheers,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-08 Thread Thomas Morley
2018-08-08 15:25 GMT+02:00 David Kastrup :
> Thomas Morley  writes:
>
>> 2018-08-07 21:42 GMT+02:00 David Kastrup :
>>> Thomas Morley  writes:
>>>
 2018-08-07 20:28 GMT+02:00 David Kastrup :
> Thomas Morley  writes:

>>> Ok, let me chime in: I've basically developed some of the low-level
>>> mechanisms for divisi staves.
>>
>> You mean that 'make-dead-when stuff?
>
> Well, that's the internal part of the low end.  But it's usually driven
> by the remove-layer property.  You are not actually using it?

 Nope.
 I'll have a closer look at it, though.
>>>
>>> Maybe it's a failure.  It may well have problems scaling since it
>>> creates a single hierarchy.  I know that one tenet or inspiration for
>>> that kind of numerical hierarchy was that it was reasonably certain to
>>> avoid creating strange loops.
>>
>>
>> I've started trying to understand 'remove-layer by reading the IR,
>> doc-strings and playing with /input/regression/divisi-staves.ly
>> Afaik no further documentation exists.
>>
>> As mentioned earlier in this thread I think divisi-Staffs should be
>> controled from inside themselves, not from the content for the single
>> voices.
>
> What does "from inside themselves" even mean?  You need three different
> versions: what should appear in the non-divided staves, what should
> appear in the upper staff of a division, what should appear in the lower
> staff of a division.  All of these need to be present in source, likely
> employing the help of tags.
>
> I think one problem here may be what we consider "divisi staves":
> I suspect that your approach considers two voices to be identical
> outside of a divisi stave passage.  However, divisi passages rarely
> require divisi staves unless the division becomes too complex to be
> representable in a single staff.
>
> So for me the principal division is not as much one of unison
> vs. divided rather than monophonic vs polyphonic (the former usually
> lends itself to single-staff notation reasonably well).  Which means
> that the content in "does not need divisi staves" passages still
> fundamentally contains three different versions to work with rather than
> a single one.
>
>> Thus I changed the regtest like below.
>> While it works starting with single Staffs, switching to divisi and
>> back later, from a divisiVoice
>> It fails the other way round, i.e. single Staffs are never printed.
>>
>> switchOff = \set Staff.keepAliveInterfaces = #'()
>> switchOn = \unset Staff.keepAliveInterfaces
>>
>> violI=\relative d' {
>>   \repeat unfold 44 d4
>>   2
>>   \repeat unfold 58 d4
>>   \bar "|."
>> }
>>
>> violII=\relative g {
>>   \repeat unfold 44 g4
>>   2
>>   \repeat unfold 58 g4
>>   \bar "|."
>> }
>>
>> %% start with single Staffs, switch to divisi and back later
>> tstI = {
>>   \switchOff
>>   \repeat unfold 44 s4
>>   \switchOn
>>   s2
>>   \switchOff
>>   \repeat unfold 58 s4
>> }
>>
>> %% start with divisi, switch to single Staffs and back later
>> tstII = {
>>   \switchOn
>>   \repeat unfold 44 s4
>>   \switchOff
>>   s2
>>   \switchOn
>>   \repeat unfold 58 s4
>> }
>>
>> divisiVoiceI =
>>   \new Voice << \tstI \violII \violI >>
>>
>> divisiVoiceII =
>>   \new Voice << \tstII \violII \violI >>
>>
>> \score {
>>   \new StaffGroup \with { \consists "Keep_alive_together_engraver" }
>>   <<
>> \new Staff \with { instrumentName = "Violin I"
>>shortInstrumentName = "V I"
>>\RemoveAllEmptyStaves
>>\override VerticalAxisGroup.remove-layer = 2
>>  }
>> \violI
>> \new Staff \with { instrumentName = "Violin II"
>>shortInstrumentName = "V II"
>>\RemoveAllEmptyStaves
>>\override VerticalAxisGroup.remove-layer = 2
>>  }
>> \violII
>> \new Staff \with { instrumentName = "Violins"
>>shortInstrumentName = "V I"
>>\override VerticalAxisGroup.remove-layer = 1
>>\RemoveAllEmptyStaves
>>  }
>> %% control divisi:
>> %\divisiVoiceI
>> \divisiVoiceII
>
> This is a total mess.  The point of remove-layers is that lower layer
> numbers override higher layer numbers, so your divisi control has to be
> applied to the lower layer number only, making the higher layer number
> appear as fallback when the lower layer number has no motivation to do
> so.
>
> But you switched around the layer numbering, making the divisi staves
> the _higher_ numbers (which only appear when the non-divisi staff
> suicides).  And then instead of applying the divisi controls to a
> selected group, you just apply it to everything, meaning that when you
> use "\switchOff", none of the contexts retain a reason to appear.
>
>>   >>
>>   \layout {
>> short-indent = 2\cm
>> indent = 3\cm
>>   }
>> }
>>
>> Am I doing something wrong?
>
> Definitely.  First start with the given example.  Then put your divisi
> controls _only_ in the divisi staff. 

Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-08 Thread David Kastrup
Thomas Morley  writes:

> 2018-08-07 21:42 GMT+02:00 David Kastrup :
>> Thomas Morley  writes:
>>
>>> 2018-08-07 20:28 GMT+02:00 David Kastrup :
 Thomas Morley  writes:
>>>
>> Ok, let me chime in: I've basically developed some of the low-level
>> mechanisms for divisi staves.
>
> You mean that 'make-dead-when stuff?

 Well, that's the internal part of the low end.  But it's usually driven
 by the remove-layer property.  You are not actually using it?
>>>
>>> Nope.
>>> I'll have a closer look at it, though.
>>
>> Maybe it's a failure.  It may well have problems scaling since it
>> creates a single hierarchy.  I know that one tenet or inspiration for
>> that kind of numerical hierarchy was that it was reasonably certain to
>> avoid creating strange loops.
>
>
> I've started trying to understand 'remove-layer by reading the IR,
> doc-strings and playing with /input/regression/divisi-staves.ly
> Afaik no further documentation exists.
>
> As mentioned earlier in this thread I think divisi-Staffs should be
> controled from inside themselves, not from the content for the single
> voices.

What does "from inside themselves" even mean?  You need three different
versions: what should appear in the non-divided staves, what should
appear in the upper staff of a division, what should appear in the lower
staff of a division.  All of these need to be present in source, likely
employing the help of tags.

I think one problem here may be what we consider "divisi staves":
I suspect that your approach considers two voices to be identical
outside of a divisi stave passage.  However, divisi passages rarely
require divisi staves unless the division becomes too complex to be
representable in a single staff.

So for me the principal division is not as much one of unison
vs. divided rather than monophonic vs polyphonic (the former usually
lends itself to single-staff notation reasonably well).  Which means
that the content in "does not need divisi staves" passages still
fundamentally contains three different versions to work with rather than
a single one.

> Thus I changed the regtest like below.
> While it works starting with single Staffs, switching to divisi and
> back later, from a divisiVoice
> It fails the other way round, i.e. single Staffs are never printed.
>
> switchOff = \set Staff.keepAliveInterfaces = #'()
> switchOn = \unset Staff.keepAliveInterfaces
>
> violI=\relative d' {
>   \repeat unfold 44 d4
>   2
>   \repeat unfold 58 d4
>   \bar "|."
> }
>
> violII=\relative g {
>   \repeat unfold 44 g4
>   2
>   \repeat unfold 58 g4
>   \bar "|."
> }
>
> %% start with single Staffs, switch to divisi and back later
> tstI = {
>   \switchOff
>   \repeat unfold 44 s4
>   \switchOn
>   s2
>   \switchOff
>   \repeat unfold 58 s4
> }
>
> %% start with divisi, switch to single Staffs and back later
> tstII = {
>   \switchOn
>   \repeat unfold 44 s4
>   \switchOff
>   s2
>   \switchOn
>   \repeat unfold 58 s4
> }
>
> divisiVoiceI =
>   \new Voice << \tstI \violII \violI >>
>
> divisiVoiceII =
>   \new Voice << \tstII \violII \violI >>
>
> \score {
>   \new StaffGroup \with { \consists "Keep_alive_together_engraver" }
>   <<
> \new Staff \with { instrumentName = "Violin I"
>shortInstrumentName = "V I"
>\RemoveAllEmptyStaves
>\override VerticalAxisGroup.remove-layer = 2
>  }
> \violI
> \new Staff \with { instrumentName = "Violin II"
>shortInstrumentName = "V II"
>\RemoveAllEmptyStaves
>\override VerticalAxisGroup.remove-layer = 2
>  }
> \violII
> \new Staff \with { instrumentName = "Violins"
>shortInstrumentName = "V I"
>\override VerticalAxisGroup.remove-layer = 1
>\RemoveAllEmptyStaves
>  }
> %% control divisi:
> %\divisiVoiceI
> \divisiVoiceII

This is a total mess.  The point of remove-layers is that lower layer
numbers override higher layer numbers, so your divisi control has to be
applied to the lower layer number only, making the higher layer number
appear as fallback when the lower layer number has no motivation to do
so.

But you switched around the layer numbering, making the divisi staves
the _higher_ numbers (which only appear when the non-divisi staff
suicides).  And then instead of applying the divisi controls to a
selected group, you just apply it to everything, meaning that when you
use "\switchOff", none of the contexts retain a reason to appear.

>   >>
>   \layout {
> short-indent = 2\cm
> indent = 3\cm
>   }
> }
>
> Am I doing something wrong?

Definitely.  First start with the given example.  Then put your divisi
controls _only_ in the divisi staff.  That's the one that is interested
in forcing its appearance.

If you really want to have the same source without tags, you could
override DivisiStaff.keepAliveInterfaces and distribute context aliases
in a manner 

Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-08 Thread Thomas Morley
2018-08-07 21:42 GMT+02:00 David Kastrup :
> Thomas Morley  writes:
>
>> 2018-08-07 20:28 GMT+02:00 David Kastrup :
>>> Thomas Morley  writes:
>>
> Ok, let me chime in: I've basically developed some of the low-level
> mechanisms for divisi staves.

 You mean that 'make-dead-when stuff?
>>>
>>> Well, that's the internal part of the low end.  But it's usually driven
>>> by the remove-layer property.  You are not actually using it?
>>
>> Nope.
>> I'll have a closer look at it, though.
>
> Maybe it's a failure.  It may well have problems scaling since it
> creates a single hierarchy.  I know that one tenet or inspiration for
> that kind of numerical hierarchy was that it was reasonably certain to
> avoid creating strange loops.


I've started trying to understand 'remove-layer by reading the IR,
doc-strings and playing with /input/regression/divisi-staves.ly
Afaik no further documentation exists.

As mentioned earlier in this thread I think divisi-Staffs should be
controled from inside themselves, not from the content for the single
voices.

Thus I changed the regtest like below.
While it works starting with single Staffs, switching to divisi and
back later, from a divisiVoice
It fails the other way round, i.e. single Staffs are never printed.

switchOff = \set Staff.keepAliveInterfaces = #'()
switchOn = \unset Staff.keepAliveInterfaces

violI=\relative d' {
  \repeat unfold 44 d4
  2
  \repeat unfold 58 d4
  \bar "|."
}

violII=\relative g {
  \repeat unfold 44 g4
  2
  \repeat unfold 58 g4
  \bar "|."
}

%% start with single Staffs, switch to divisi and back later
tstI = {
  \switchOff
  \repeat unfold 44 s4
  \switchOn
  s2
  \switchOff
  \repeat unfold 58 s4
}

%% start with divisi, switch to single Staffs and back later
tstII = {
  \switchOn
  \repeat unfold 44 s4
  \switchOff
  s2
  \switchOn
  \repeat unfold 58 s4
}

divisiVoiceI =
  \new Voice << \tstI \violII \violI >>

divisiVoiceII =
  \new Voice << \tstII \violII \violI >>

\score {
  \new StaffGroup \with { \consists "Keep_alive_together_engraver" }
  <<
\new Staff \with { instrumentName = "Violin I"
   shortInstrumentName = "V I"
   \RemoveAllEmptyStaves
   \override VerticalAxisGroup.remove-layer = 2
 }
\violI
\new Staff \with { instrumentName = "Violin II"
   shortInstrumentName = "V II"
   \RemoveAllEmptyStaves
   \override VerticalAxisGroup.remove-layer = 2
 }
\violII
\new Staff \with { instrumentName = "Violins"
   shortInstrumentName = "V I"
   \override VerticalAxisGroup.remove-layer = 1
   \RemoveAllEmptyStaves
 }
%% control divisi:
%\divisiVoiceI
\divisiVoiceII
  >>
  \layout {
short-indent = 2\cm
indent = 3\cm
  }
}

Am I doing something wrong?


Cheers,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-07 Thread Saul Tobin
Super glad to see this conversation happening! David I'm so glad you've
been working on the backend for divisi. Divisi staves have long been my
biggest headache.

Thomas, thanks for writing the improved version. I haven't had a chance to
look at the code deeply yet — I will play around with it this weekend.

One observation about the user interface: logically, if the combined 1+2
staff is hidden, both the staff for 1 and the staff for 2 should be
printed. IMO one of the design goals for a divisi user interface should be
to manage this automatically without the need to write separate
simultaneous commands to hide or unhide each staff. There are only two
possible states for a two-part divisi: combined or separate staves. Only a
single command should be needed to toggle that state. Extrapolate for 3, 4
way divisi etc.

As an aside, for what it's worth, from my perspective as a composer who
uses a lot of divisi staves, I want to minimize separation of divisi
commands from musical content, because the choice to divide or not depends
on the musical content, which I may revise frequently. I recognize that
many other Lilypond users prefer the style you used in your example, but I
just thought I'd mention it, since if this is moving towards an officially
supported interface, IMO it needs to support both styles.

Saul

On Tue, Aug 7, 2018 at 12:42 PM David Kastrup  wrote:

> Thomas Morley  writes:
>
> > 2018-08-07 20:28 GMT+02:00 David Kastrup :
> >> Thomas Morley  writes:
> >
>  Ok, let me chime in: I've basically developed some of the low-level
>  mechanisms for divisi staves.
> >>>
> >>> You mean that 'make-dead-when stuff?
> >>
> >> Well, that's the internal part of the low end.  But it's usually driven
> >> by the remove-layer property.  You are not actually using it?
> >
> > Nope.
> > I'll have a closer look at it, though.
>
> Maybe it's a failure.  It may well have problems scaling since it
> creates a single hierarchy.  I know that one tenet or inspiration for
> that kind of numerical hierarchy was that it was reasonably certain to
> avoid creating strange loops.
>
> --
> David Kastrup
>
> ___
> lilypond-user mailing list
> lilypond-user@gnu.org
> https://lists.gnu.org/mailman/listinfo/lilypond-user
>
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-07 Thread David Kastrup
Thomas Morley  writes:

> 2018-08-07 20:28 GMT+02:00 David Kastrup :
>> Thomas Morley  writes:
>
 Ok, let me chime in: I've basically developed some of the low-level
 mechanisms for divisi staves.
>>>
>>> You mean that 'make-dead-when stuff?
>>
>> Well, that's the internal part of the low end.  But it's usually driven
>> by the remove-layer property.  You are not actually using it?
>
> Nope.
> I'll have a closer look at it, though.

Maybe it's a failure.  It may well have problems scaling since it
creates a single hierarchy.  I know that one tenet or inspiration for
that kind of numerical hierarchy was that it was reasonably certain to
avoid creating strange loops.

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-07 Thread Thomas Morley
2018-08-07 20:28 GMT+02:00 David Kastrup :
> Thomas Morley  writes:

>>> Ok, let me chime in: I've basically developed some of the low-level
>>> mechanisms for divisi staves.
>>
>> You mean that 'make-dead-when stuff?
>
> Well, that's the internal part of the low end.  But it's usually driven
> by the remove-layer property.  You are not actually using it?

Nope.
I'll have a closer look at it, though.

Cheers,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-07 Thread David Kastrup
Thomas Morley  writes:

> 2018-08-07 19:48 GMT+02:00 David Kastrup :
>> Thomas Morley  writes:
>>
>>> 2018-08-06 21:40 GMT+02:00 Thomas Morley :
 2018-08-05 18:14 GMT+02:00 Thomas Morley :

> 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.
>>>
>>>
>>> Further improvements.
>>>
>>> It's now possible to omit 'catch-me, _iff_ single instrument-staves
>>> and divisi-staves belong exculsively to the same container-context
>>> like StaffGroup, GrandStaff, ChoirStaff or PianoStaff with removed
>>> "Keep_alive_together_engraver", which is most likely always the case.
>>> For ungrouped single/divisi 'catch-me is still neccesary.
>>
>> Ok, let me chime in: I've basically developed some of the low-level
>> mechanisms for divisi staves.
>
> You mean that 'make-dead-when stuff?

Well, that's the internal part of the low end.  But it's usually driven
by the remove-layer property.  You are not actually using it?

> It does not work in 2.18.2.

Sure.

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-07 Thread Thomas Morley
2018-08-07 19:48 GMT+02:00 David Kastrup :
> Thomas Morley  writes:
>
>> 2018-08-06 21:40 GMT+02:00 Thomas Morley :
>>> 2018-08-05 18:14 GMT+02:00 Thomas Morley :
>>>
 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.
>>
>>
>> Further improvements.
>>
>> It's now possible to omit 'catch-me, _iff_ single instrument-staves
>> and divisi-staves belong exculsively to the same container-context
>> like StaffGroup, GrandStaff, ChoirStaff or PianoStaff with removed
>> "Keep_alive_together_engraver", which is most likely always the case.
>> For ungrouped single/divisi 'catch-me is still neccesary.
>
> Ok, let me chime in: I've basically developed some of the low-level
> mechanisms for divisi staves.

You mean that 'make-dead-when stuff? It does not work in 2.18.2.
The 'staff-grouper grob-object?

> There are no user-level commands or music
> functions or Scheme abstractions making use of them.  There is no parser
> support (like for << \\ >>) but it's likely that isn't really required.

Up to now I can't think of any parser-supported syntax.
Seems all works so far with simple overrides.

> But there certainly is a need for a user level interface, and from the
> description this sounds like you are off to a good start.
>
> Think you can turn this (assuming it isn't already) into something
> obvious and general enough that it would be satisfying to document and
> use it without having to meddle with the low-level mechanisms at least,
> say, 85% of the time?

With my most recent coding the user has to do three things:
(1)
Initiate a divisi-Staff, applying p.e.
\override VerticalAxisGroup.details.combined = #'(1 2)
(2)
Awake the divisi-Staff via \switchOn in the musical-content
(3)
Let it all happen with
  \override VerticalAlignment.before-line-breaking =
%#(divisis "flutes" "trumpets" "cors")
%#(divisis)
#(divisis "flutes")
at Score level.

That's all. The whole scheme-coding could be included.

Though, there are some points I don't like or have concerns.

@(1)
The argument '(1 2) will result in: combine voices 1 and 2 and kill
the the single printing of them.
But it relies on unchanged order of the lists processed. I'm currently
not sure this is warrented, although testings didn't fail so far.
Ofcourse I used details.combined to avoid a real custom-grob-property,
some for 'catch-me. If we think of implementing something like this
coding we should probably turn those in own grob-properties

@(2)
It's done by
switchOff = \set Staff.keepAliveInterfaces = #'()
switchOn = \unset Staff.keepAliveInterfaces
I'm not sure I like this, it feels clumsy.

@(3)
Here I'm fine so far, having a procedure doing all automagically,
unless container-contexts are missing.


Currently I'm a bit at a loss how to proceed.
Ideas?


Cheers,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-07 Thread David Kastrup
Thomas Morley  writes:

> 2018-08-06 21:40 GMT+02:00 Thomas Morley :
>> 2018-08-05 18:14 GMT+02:00 Thomas Morley :
>>
>>> 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.
>
>
> Further improvements.
>
> It's now possible to omit 'catch-me, _iff_ single instrument-staves
> and divisi-staves belong exculsively to the same container-context
> like StaffGroup, GrandStaff, ChoirStaff or PianoStaff with removed
> "Keep_alive_together_engraver", which is most likely always the case.
> For ungrouped single/divisi 'catch-me is still neccesary.

Ok, let me chime in: I've basically developed some of the low-level
mechanisms for divisi staves.  There are no user-level commands or music
functions or Scheme abstractions making use of them.  There is no parser
support (like for << \\ >>) but it's likely that isn't really required.

But there certainly is a need for a user level interface, and from the
description this sounds like you are off to a good start.

Think you can turn this (assuming it isn't already) into something
obvious and general enough that it would be satisfying to document and
use it without having to meddle with the low-level mechanisms at least,
say, 85% of the time?

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-07 Thread Thomas Morley
2018-08-06 21:40 GMT+02:00 Thomas Morley :
> 2018-08-05 18:14 GMT+02:00 Thomas Morley :
>
>> 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.


Further improvements.

It's now possible to omit 'catch-me, _iff_ single instrument-staves
and divisi-staves belong exculsively to the same container-context
like StaffGroup, GrandStaff, ChoirStaff or PianoStaff with removed
"Keep_alive_together_engraver", which is most likely always the case.
For ungrouped single/divisi 'catch-me is still neccesary.

Cheers,
  Harm
\version "2.19.82"

\pointAndClickOff

%% relies on:
%%
%% VerticalAxisGroup.details.catch-me
%% VerticalAxisGroup.details.combined
%%
%% About `catch-me`
%%   Inside of container-contexts like StaffGroup, GrandStaff, ChoirStaff or
%%   PianoStaff with removed "Keep_alive_together_engraver"
%%   `catch-me` may be omitted.
%%   To get divisis work outside of such containers `catch-me` needs to be set
%%   to a value matching one of the optional arguments of the divisis-procedure
%% Currently we use strings for `catch-me` and the arguments of the
%% divisis-procedure, a symbol would work as well.
%%
%% About `combined`
%%   `combined` labels divisi-staffs. It is supposed to be a list of positive
%%   integers, representing the combined instruments.
%%   p.e. To combine flute-III and flute-IV, set `combined` to '(3 4)
%%
%%
%% More inline comments below
%%
%%
%% Limitations:
%%   Staves can't be started/ended mid-line.
%% TODOs
%%   Killing/awakening relies on the order single instrument-staves are entered.
%%   Is it safe to assume the order of lists with VerticalAxisGroups will
%%   not be confused?

%% c/p from lily-library.scm
#(define (split-at-predicate pred lst)
  "Split LST into two lists at the first element that returns #f for
  (PRED previous_element element).  Return the two parts as a pair.
  Example: (split-at-predicate < '(1 2 3 2 1)) ==> ((1 2 3) . (2 1))"
  (let ((i (and (pair? lst)
(list-index (lambda (x y) (not (pred x y)))
lst
(cdr lst)
(if i
(call-with-values
(lambda () (split-at lst (1+ i)))
  cons)
(list lst

#(define (sort-vags vags)
  ;; Returns sublists of VAGs in same StaffGrouper
  (define (helper l1 l2)
(if (null? l1)
(reverse l2)
(let ((splitted-l1
(split-at-predicate
  (lambda (x y)
(equal?
  (ly:grob-object x 'staff-grouper)
  (ly:grob-object y 'staff-grouper)))
   l1)))
  (helper (cdr splitted-l1) (cons (car splitted-l1) l2)
  (helper vags '()))

#(define (select-vags vags)
  ;; Return two sublists containing VerticalAxisGroups with and without
  ;; setted 'combined.
  (call-with-values
(lambda ()
  (partition
(lambda (vag)
  (pair?
(assoc-get
  'combined (ly:grob-property vag 'details) '(
vags))
(lambda (x y) (list x y

#(define (kill-selected-vags sorted-vags)
  ;; `sorted-vags` is supposed to be a list of two sublists, containing
  ;; VerticalAxisGroups for divisi and non-divisi-staves
  (if (pair? (car sorted-vags))
  (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 sorted-vags) i)))
;; get a list of VerticalAxisGroups used with
;; divisi-staves
(map
  (lambda (index) (list-ref (cadr sorted-vags) (1- index)))
  ;; get the 'combined-value from 'details, which is
  ;; supposed to be a list.
  ;; TODO 'combined is read here and in `splitted` above.
  ;;  Find a method to spare one go
  (assoc-get
'combined
(ly:grob-property
  (list-ref (car sorted-vags) i) 'details)
'()
(iota (length (car sorted-vags))

#(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
(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 ;; empty lists removed
 (if (null? vags-array)
 '()
 (remove 

Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-06 Thread Thomas Morley
2018-08-06 21:40 GMT+02:00 Thomas Morley :
> 2018-08-05 18:14 GMT+02:00 Thomas Morley :
>
>> 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.


I forgot to update the explaining comment before the \score.
It should now read:

%% For divisi instruments initiate Staff-contexts for every single instrument.
%% Set `VerticalAxisGroup.details.catch-me` appropiate.
%%
%% Initiate every desired divisi-Staff.
%% Staves meant for divisi should be labed with
%% `VerticalAxisGroup.details.combined` set to a list of positive integers,
%% representing the combined voices. Set appropriate `catch-me` as well.
%% Apply \RemoveAllEmptyStaves to every divisi-Staff.
\score {

Cheers,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-06 Thread Thomas Morley
2018-08-05 18:14 GMT+02:00 Thomas Morley :

> 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 

Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-05 Thread Thomas Morley
2018-08-03 23:14 GMT+02:00 Saul Tobin :
> Hi all,
>
> I just put together a snippet to make managing shared wind staves more
> automatic, particularly with triple winds that may be combined in different
> ways.
>
> \version "2.19.82"
>
> #(define remove-if-sibling
>(lambda (offsets)
>  (lambda (grob)
>(let* (
>;; The parent of a VerticalAxisGroup is a VerticalAlignment
>(parent (ly:grob-parent grob 1))
>;; Get the children VerticalAxisGroups of the parent
>(siblings (ly:grob-object parent 'elements))
>(siblings-list
> (if (ly:grob-array? siblings)
> (ly:grob-array->list siblings)
> '()))
>;; Find the siblings above or below me by offsets
>(my-vindex (ly:grob-get-vertical-axis-group-index grob))
>(enemy-indices (map (lambda (offset) (+ offset my-vindex))
> offsets))
>(enemy-vaxis? (lambda (v) (member
> (ly:grob-get-vertical-axis-group-index v)
>enemy-indices)))
>(enemy-vaxes
> (filter enemy-vaxis? siblings-list))
>)
>  ;; Suicide if an enemy sibling is alive
>  (map
>   (lambda (enemy-vaxis)
> (ly:pointer-group-interface::add-grob grob 'make-dead-when
> enemy-vaxis))
>   enemy-vaxes)
>  )
>)
>  )
>)
>
> %% Two Staff Example
>
> global = {
>   s1
>   \break
>   s1
>   \break
>   s1*2
> }
>
> I = {
>   c'''1
>   \context Staff = "1" { \set Staff.keepAliveInterfaces = #'() }
>   c'''1
>   c'''1
>   \context Staff = "1" { \unset Staff.keepAliveInterfaces }
>   c'''1
> }
>
> II = {
>   e''1
>   e''1
>   e''1
>   e''1
> }
>
> <<
>   \new Staff = "1+2" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(1))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \partcombine \I \II >>
>   \new Staff = "1" \with {
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \I >>
>   \new Staff = "2" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(-2))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \II >>
>>>
>
> %% Three Staff Example
>
> global = {
>   s1
>   \break
>   s1
>   \break
>   s1
>   \break
>   s1*2
> }
>
> I = {
>   c'''1
>   \context Staff = "1" { \set Staff.keepAliveInterfaces = #'() }
>   c'''1
>   c'''1
>   c'''1
>   \context Staff = "1" { \unset Staff.keepAliveInterfaces }
>   c'''1
> }
>
> II = {
>   e''1
>   e''1
>   e''1
>   e''1
>   e''1
> }
>
> III = {
>   a'1
>   a'1
>   \context Staff = "3" { \set Staff.keepAliveInterfaces = #'() }
>   a'1
>   a'1
>   a'1
> }
>
> <<
>   \new Staff = "1+2+3" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(2 5))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \I \II \III >>
>   \new Staff = "1+2" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(1 -1))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \partcombine \I \II >>
>   \new Staff = "1" \with {
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \I >>
>   \new Staff = "2+3" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(2 -3))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \partcombine \II \III >>
>   \new Staff = "2" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(-1 -3 -4))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \II >>
>   \new Staff = "3" \with {
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \III >>
>>>
>
> ___
> lilypond-user mailing list
> lilypond-user@gnu.org
> https://lists.gnu.org/mailman/listinfo/lilypond-user
>

Hi,

I had a closer look at your code.

You select via vertical-axis-group-index. This makes for a not
intuitive argument of your `remove-if-sibling`-procedure. Even worse,
the needed arguments may need to be changed if other staves are added
to the score.
Also I think divisis should be controlled, well, from the divisi-staves.

Inspired by your work I come up with the attached.

Cheers,
  Harm


divisi-saul-02-test.pdf
Description: Adobe PDF document
\version "2.19.82"


Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-03 Thread Saul Tobin
Those errors are from this expression in the three staff example: <<
\global \I \II \III >>. Lilypond is implicitly creating three Voices
instead of treating it as a single Voice with simultaneous music. If you
replace that expression with { <> << \global \I \II \III >> }, the errors
go away.

Since the partcombiner doesn't currently support more than 2 arguments,
this is something that requires a workaround if you want to do three parts
on a single staff.

Anyway, it doesn't affect the point of this snippet, which is automatically
hiding staves based on which other staves are alive on each system.

On Fri, Aug 3, 2018 at 2:23 PM Ben  wrote:

> On 8/3/2018 5:14 PM, Saul Tobin wrote:
>
> Hi all,
>
> I just put together a snippet to make managing shared wind staves more
> automatic, particularly with triple winds that may be combined in different
> ways.
>
> \version "2.19.82"
>
> #(define remove-if-sibling
>(lambda (offsets)
>  (lambda (grob)
>(let* (
>;; The parent of a VerticalAxisGroup is a VerticalAlignment
>(parent (ly:grob-parent grob 1))
>;; Get the children VerticalAxisGroups of the parent
>(siblings (ly:grob-object parent 'elements))
>(siblings-list
> (if (ly:grob-array? siblings)
> (ly:grob-array->list siblings)
> '()))
>;; Find the siblings above or below me by offsets
>(my-vindex (ly:grob-get-vertical-axis-group-index grob))
>(enemy-indices (map (lambda (offset) (+ offset my-vindex))
> offsets))
>(enemy-vaxis? (lambda (v) (member
> (ly:grob-get-vertical-axis-group-index v)
>enemy-indices)))
>(enemy-vaxes
> (filter enemy-vaxis? siblings-list))
>)
>  ;; Suicide if an enemy sibling is alive
>  (map
>   (lambda (enemy-vaxis)
> (ly:pointer-group-interface::add-grob grob 'make-dead-when
> enemy-vaxis))
>   enemy-vaxes)
>  )
>)
>  )
>)
>
> %% Two Staff Example
>
> global = {
>   s1
>   \break
>   s1
>   \break
>   s1*2
> }
>
> I = {
>   c'''1
>   \context Staff = "1" { \set Staff.keepAliveInterfaces = #'() }
>   c'''1
>   c'''1
>   \context Staff = "1" { \unset Staff.keepAliveInterfaces }
>   c'''1
> }
>
> II = {
>   e''1
>   e''1
>   e''1
>   e''1
> }
>
> <<
>   \new Staff = "1+2" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(1))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \partcombine \I \II >>
>   \new Staff = "1" \with {
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \I >>
>   \new Staff = "2" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(-2))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \II >>
> >>
>
> %% Three Staff Example
>
> global = {
>   s1
>   \break
>   s1
>   \break
>   s1
>   \break
>   s1*2
> }
>
> I = {
>   c'''1
>   \context Staff = "1" { \set Staff.keepAliveInterfaces = #'() }
>   c'''1
>   c'''1
>   c'''1
>   \context Staff = "1" { \unset Staff.keepAliveInterfaces }
>   c'''1
> }
>
> II = {
>   e''1
>   e''1
>   e''1
>   e''1
>   e''1
> }
>
> III = {
>   a'1
>   a'1
>   \context Staff = "3" { \set Staff.keepAliveInterfaces = #'() }
>   a'1
>   a'1
>   a'1
> }
>
> <<
>   \new Staff = "1+2+3" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(2 5))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \I \II \III >>
>   \new Staff = "1+2" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(1 -1))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \partcombine \I \II >>
>   \new Staff = "1" \with {
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \I >>
>   \new Staff = "2+3" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(2 -3))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \partcombine \II \III >>
>   \new Staff = "2" \with {
> \override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
> '(-1 -3 -4))
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \II >>
>   \new Staff = "3" \with {
> \override VerticalAxisGroup.remove-empty = ##t
> \override VerticalAxisGroup.remove-first = ##t
>   } << \global \III >>
> 

Re: New snippet: remove staff if another is alive (for wind divisi)

2018-08-03 Thread Ben

On 8/3/2018 5:14 PM, Saul Tobin wrote:

Hi all,

I just put together a snippet to make managing shared wind staves more 
automatic, particularly with triple winds that may be combined in 
different ways.


\version "2.19.82"

#(define remove-if-sibling
   (lambda (offsets)
     (lambda (grob)
       (let* (
               ;; The parent of a VerticalAxisGroup is a VerticalAlignment
               (parent (ly:grob-parent grob 1))
               ;; Get the children VerticalAxisGroups of the parent
               (siblings (ly:grob-object parent 'elements))
               (siblings-list
                (if (ly:grob-array? siblings)
                    (ly:grob-array->list siblings)
                    '()))
               ;; Find the siblings above or below me by offsets
               (my-vindex (ly:grob-get-vertical-axis-group-index grob))
               (enemy-indices (map (lambda (offset) (+ offset 
my-vindex)) offsets))
               (enemy-vaxis? (lambda (v) (member 
(ly:grob-get-vertical-axis-group-index v)

 enemy-indices)))
               (enemy-vaxes
                (filter enemy-vaxis? siblings-list))
               )
         ;; Suicide if an enemy sibling is alive
         (map
          (lambda (enemy-vaxis)
            (ly:pointer-group-interface::add-grob grob 'make-dead-when 
enemy-vaxis))

          enemy-vaxes)
         )
       )
     )
   )

%% Two Staff Example

global = {
  s1
  \break
  s1
  \break
  s1*2
}

I = {
  c'''1
  \context Staff = "1" { \set Staff.keepAliveInterfaces = #'() }
  c'''1
  c'''1
  \context Staff = "1" { \unset Staff.keepAliveInterfaces }
  c'''1
}

II = {
  e''1
  e''1
  e''1
  e''1
}

<<
  \new Staff = "1+2" \with {
    \override VerticalAxisGroup.before-line-breaking = 
#(remove-if-sibling '(1))

    \override VerticalAxisGroup.remove-empty = ##t
    \override VerticalAxisGroup.remove-first = ##t
  } << \global \partcombine \I \II >>
  \new Staff = "1" \with {
    \override VerticalAxisGroup.remove-empty = ##t
    \override VerticalAxisGroup.remove-first = ##t
  } << \global \I >>
  \new Staff = "2" \with {
    \override VerticalAxisGroup.before-line-breaking = 
#(remove-if-sibling '(-2))

    \override VerticalAxisGroup.remove-empty = ##t
    \override VerticalAxisGroup.remove-first = ##t
  } << \global \II >>
>>

%% Three Staff Example

global = {
  s1
  \break
  s1
  \break
  s1
  \break
  s1*2
}

I = {
  c'''1
  \context Staff = "1" { \set Staff.keepAliveInterfaces = #'() }
  c'''1
  c'''1
  c'''1
  \context Staff = "1" { \unset Staff.keepAliveInterfaces }
  c'''1
}

II = {
  e''1
  e''1
  e''1
  e''1
  e''1
}

III = {
  a'1
  a'1
  \context Staff = "3" { \set Staff.keepAliveInterfaces = #'() }
  a'1
  a'1
  a'1
}

<<
  \new Staff = "1+2+3" \with {
    \override VerticalAxisGroup.before-line-breaking = 
#(remove-if-sibling '(2 5))

    \override VerticalAxisGroup.remove-empty = ##t
    \override VerticalAxisGroup.remove-first = ##t
  } << \global \I \II \III >>
  \new Staff = "1+2" \with {
    \override VerticalAxisGroup.before-line-breaking = 
#(remove-if-sibling '(1 -1))

    \override VerticalAxisGroup.remove-empty = ##t
    \override VerticalAxisGroup.remove-first = ##t
  } << \global \partcombine \I \II >>
  \new Staff = "1" \with {
    \override VerticalAxisGroup.remove-empty = ##t
    \override VerticalAxisGroup.remove-first = ##t
  } << \global \I >>
  \new Staff = "2+3" \with {
    \override VerticalAxisGroup.before-line-breaking = 
#(remove-if-sibling '(2 -3))

    \override VerticalAxisGroup.remove-empty = ##t
    \override VerticalAxisGroup.remove-first = ##t
  } << \global \partcombine \II \III >>
  \new Staff = "2" \with {
    \override VerticalAxisGroup.before-line-breaking = 
#(remove-if-sibling '(-1 -3 -4))

    \override VerticalAxisGroup.remove-empty = ##t
    \override VerticalAxisGroup.remove-first = ##t
  } << \global \II >>
  \new Staff = "3" \with {
    \override VerticalAxisGroup.remove-empty = ##t
    \override VerticalAxisGroup.remove-first = ##t
  } << \global \III >>
>>



Hello,

Thanks for sharing this with us! One question...

When I just copy and paste your snippet into Frescobaldi as is, I get a 
few errors.  ?


=

Interpreting music...

Interpreting music...

Interpreting music...

Interpreting music...

Interpreting music...

Preprocessing graphical objects...

Interpreting music...

Preprocessing graphical objects...


document.ly:103:3: warning: this Voice needs a \voiceXx or \shiftXx setting

e''1


document.ly:102:3: warning: this Voice needs a \voiceXx or \shiftXx setting

e''1


document.ly:101:3: warning: this Voice needs a \voiceXx or \shiftXx setting

e''1


document.ly:100:3: warning: this Voice needs a \voiceXx or \shiftXx setting

e''1


document.ly:99:3: warning: this Voice needs a \voiceXx or \shiftXx setting

e''1


Finding the ideal number of pages...

Fitting music on 1 page...

Drawing systems...

Layout output to `./tmp-lilypond-BWUill'...

Converting to `document.pdf'...

Deleting 

New snippet: remove staff if another is alive (for wind divisi)

2018-08-03 Thread Saul Tobin
Hi all,

I just put together a snippet to make managing shared wind staves more
automatic, particularly with triple winds that may be combined in different
ways.

\version "2.19.82"

#(define remove-if-sibling
   (lambda (offsets)
 (lambda (grob)
   (let* (
   ;; The parent of a VerticalAxisGroup is a VerticalAlignment
   (parent (ly:grob-parent grob 1))
   ;; Get the children VerticalAxisGroups of the parent
   (siblings (ly:grob-object parent 'elements))
   (siblings-list
(if (ly:grob-array? siblings)
(ly:grob-array->list siblings)
'()))
   ;; Find the siblings above or below me by offsets
   (my-vindex (ly:grob-get-vertical-axis-group-index grob))
   (enemy-indices (map (lambda (offset) (+ offset my-vindex))
offsets))
   (enemy-vaxis? (lambda (v) (member
(ly:grob-get-vertical-axis-group-index v)
   enemy-indices)))
   (enemy-vaxes
(filter enemy-vaxis? siblings-list))
   )
 ;; Suicide if an enemy sibling is alive
 (map
  (lambda (enemy-vaxis)
(ly:pointer-group-interface::add-grob grob 'make-dead-when
enemy-vaxis))
  enemy-vaxes)
 )
   )
 )
   )

%% Two Staff Example

global = {
  s1
  \break
  s1
  \break
  s1*2
}

I = {
  c'''1
  \context Staff = "1" { \set Staff.keepAliveInterfaces = #'() }
  c'''1
  c'''1
  \context Staff = "1" { \unset Staff.keepAliveInterfaces }
  c'''1
}

II = {
  e''1
  e''1
  e''1
  e''1
}

<<
  \new Staff = "1+2" \with {
\override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
'(1))
\override VerticalAxisGroup.remove-empty = ##t
\override VerticalAxisGroup.remove-first = ##t
  } << \global \partcombine \I \II >>
  \new Staff = "1" \with {
\override VerticalAxisGroup.remove-empty = ##t
\override VerticalAxisGroup.remove-first = ##t
  } << \global \I >>
  \new Staff = "2" \with {
\override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
'(-2))
\override VerticalAxisGroup.remove-empty = ##t
\override VerticalAxisGroup.remove-first = ##t
  } << \global \II >>
>>

%% Three Staff Example

global = {
  s1
  \break
  s1
  \break
  s1
  \break
  s1*2
}

I = {
  c'''1
  \context Staff = "1" { \set Staff.keepAliveInterfaces = #'() }
  c'''1
  c'''1
  c'''1
  \context Staff = "1" { \unset Staff.keepAliveInterfaces }
  c'''1
}

II = {
  e''1
  e''1
  e''1
  e''1
  e''1
}

III = {
  a'1
  a'1
  \context Staff = "3" { \set Staff.keepAliveInterfaces = #'() }
  a'1
  a'1
  a'1
}

<<
  \new Staff = "1+2+3" \with {
\override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
'(2 5))
\override VerticalAxisGroup.remove-empty = ##t
\override VerticalAxisGroup.remove-first = ##t
  } << \global \I \II \III >>
  \new Staff = "1+2" \with {
\override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
'(1 -1))
\override VerticalAxisGroup.remove-empty = ##t
\override VerticalAxisGroup.remove-first = ##t
  } << \global \partcombine \I \II >>
  \new Staff = "1" \with {
\override VerticalAxisGroup.remove-empty = ##t
\override VerticalAxisGroup.remove-first = ##t
  } << \global \I >>
  \new Staff = "2+3" \with {
\override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
'(2 -3))
\override VerticalAxisGroup.remove-empty = ##t
\override VerticalAxisGroup.remove-first = ##t
  } << \global \partcombine \II \III >>
  \new Staff = "2" \with {
\override VerticalAxisGroup.before-line-breaking = #(remove-if-sibling
'(-1 -3 -4))
\override VerticalAxisGroup.remove-empty = ##t
\override VerticalAxisGroup.remove-first = ##t
  } << \global \II >>
  \new Staff = "3" \with {
\override VerticalAxisGroup.remove-empty = ##t
\override VerticalAxisGroup.remove-first = ##t
  } << \global \III >>
>>
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user