At 10:52 on 28 Jul 2016, Mark Knoop wrote:
>At 09:59 on 28 Jul 2016, David Kastrup wrote:
>>It seems like an ad-hoc band-aid with limited utility.  I'd rather see
>>something covering more use cases.
>
>Regardless of the merits of this solution, I not sure about it
>having limited utility. Repeating a mark line is fairly common in
>modern orchestral scores and vocal/choral piano reductions, and is
>currently not achievable (whilst also removing empty staves) in
>Lilypond (please correct me if I'm wrong).
>
>Examples:
>
>- http://imslp.org/wiki/The_Dream_of_Gerontius,_Op.38_(Elgar,_Edward)
>  (Vocal Score)
>- http://imslp.org/wiki/Elektra,_Op.58_(Strauss,_Richard)
>
>>The current setup is intended mostly to cater with various ways of
>>typesetting split voices and by the user manually clearing
>>items-worth-living on the more spacious variants.
>>
>>So you'd have something like
>>voice1+voice2 in two systems : layer 0
>>voice1+voice2 in one system, split voices : layer 1
>>unisono : layer 2
>>
>>For your use case, you'd add a mark track into _each_ layer and clear
>>out its items-worth-living so that it does not keep its layer alive
>>on its own.
>>
>>Now this gets a bit combinatorially awkward since we get something
>>like
>>
>>mark+voice1+voice2 : layer 0
>>mark+voice1 : layer 1
>>mark+voice2 : layer 2
>>
>>and you need to manually mark all passages where there is only one
>>voice (clearing the items-worth-living on the voice contexts used in
>>layer 0 so that they don't keep the double layer active
>>unnecessarily).  That's clumsy for two voices, and it will become
>>worse for more.
>>
>>So while remove-layer is a reasonably workable mechanism for switching
>>out and back divisi staves (and relies on managing your
>>items-worth-living in the more divided variants to merge them as
>>feasible), it does not really map convincingly to your use case,
>
>Indeed - I couldn't find a way to make it work within the existing
>remove-layer functionality.
>
>>and I'd like to see something more general than your proposed band-aid
>>just catering for one specific additional case.
>>
>>So how should this roll?
>
>Another annoying quirk of my solution is that it highlights the
>somewhat counter-intuitive nature of the remove-layer property:
>setting it to false makes the layer invisible to the
>Keep_alive_together_engraver which actually *does* allow it to be
>removed rather than the opposite.

OK, here's a patch using only the remove-layer property with these
values:

- #f: ignored by Keep_alive_together_engraver
- -1: kept alive by any other layer
- integer != -1: current usage
- unspecified: kept alive by all but ignored layers

The prior comment at lily/keep-alive-together-engraver.cc, line 72:
"Unspecified layers are kept alive by anything else" was not quite true -
unspecified layers are not kept alive by ignored layers, i.e. those with
remove-layer = ##f.

I still wonder whether it might be more intuitive to swap the meanings
of #f and -1.

I've not included any documentation beyond the regression/example at
this stage.

-- 
Mark Knoop
>From 2cf7db9ee6d7bfdfa9358a889b6210f2b71cb6dd Mon Sep 17 00:00:00 2001
From: Mark Knoop <[email protected]>
Date: Thu, 28 Jul 2016 15:47:46 +0100
Subject: [PATCH] Keep a staff alive if any other staff in the group is alive

This uses the `VerticalAxisGroup.remove-layer' property, when set to -1, to keep
the context alive within a `Keep_alive_together_engraver' only while any other
context is alive, even if those contexts have `VerticalAxisGroup.remove-layer'
set to false.
---
 input/regression/keep-alive-with-any-other.ly | 56 +++++++++++++++++++++++++++
 lily/keep-alive-together-engraver.cc          |  8 +++-
 2 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 input/regression/keep-alive-with-any-other.ly

diff --git a/input/regression/keep-alive-with-any-other.ly b/input/regression/keep-alive-with-any-other.ly
new file mode 100644
index 0000000..ecc4868
--- /dev/null
+++ b/input/regression/keep-alive-with-any-other.ly
@@ -0,0 +1,56 @@
+\version "2.19.47"
+
+\header {
+  texidoc = "The @code{VerticalAxisGroup.remove-layer} property can be set to
+  @code{-1} to keep it alive only while any other VerticalAxisGroup layer
+  controlled by the same Keep_alive_together_engraver is alive."
+}
+
+\score {
+  <<
+    \new StaffGroup \with {
+      \consists Keep_alive_together_engraver
+    } <<
+      \new Staff \with {
+        keepAliveInterfaces = #'()
+        instrumentName = "With 2 or 3"
+        shortInstrumentName = "w"
+		    \override VerticalAxisGroup.remove-empty = ##t
+		    \override VerticalAxisGroup.remove-first = ##t
+        \override VerticalAxisGroup.remove-layer = -1
+      } {
+        \repeat unfold 200 c''4
+      }
+      \new Staff \with {
+        instrumentName = "2"
+        shortInstrumentName = "2"
+		    \override VerticalAxisGroup.remove-empty = ##t
+		    \override VerticalAxisGroup.remove-first = ##t
+        \override VerticalAxisGroup.remove-layer = ##f
+      } {
+        \repeat unfold 20 c'4
+        R1*20
+        \repeat unfold 20 c'4
+        R1*20
+      }
+      \new Staff \with {
+        instrumentName = "3"
+        shortInstrumentName = "3"
+		    \override VerticalAxisGroup.remove-empty = ##t
+		    \override VerticalAxisGroup.remove-first = ##t
+        \override VerticalAxisGroup.remove-layer = ##f
+      } {
+        R1*10
+        \repeat unfold 40 c'4
+        \repeat unfold 40 c'4
+        R1*20
+      }
+    >>
+    \new Staff \with {
+      instrumentName = "Continuous"
+      shortInstrumentName = "c"
+    } {
+      \repeat unfold 200 g'4
+    }
+  >>
+}
diff --git a/lily/keep-alive-together-engraver.cc b/lily/keep-alive-together-engraver.cc
index 9b1cbe4..5125854 100644
--- a/lily/keep-alive-together-engraver.cc
+++ b/lily/keep-alive-together-engraver.cc
@@ -64,12 +64,18 @@ Keep_alive_together_engraver::finalize ()
         {
           if (i == j)
             continue;
+          if (scm_is_integer (this_layer) and (scm_to_int (this_layer) == -1))
+            {
+              // if remove-layer == -1, layer is kept alive by any other layer
+              live->add (group_spanners_[j]);
+              continue;
+            }
           SCM that_layer = group_spanners_[j]->get_property ("remove-layer");
           if (scm_is_false (that_layer))
             continue;
           if (!scm_is_integer (this_layer))
             {
-              // Unspecified layers are kept alive by anything else
+              // unspecified layers are kept alive by all but ignored layers
               live->add (group_spanners_[j]);
               continue;
             }
-- 
2.7.4

_______________________________________________
lilypond-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to