Patch attached.

At 10:21 on 08 Sep 2016, pkx166h wrote:
>- **Patch**: countdown --> push
>- **Comment**:
>
>Patch counted down - please push.
>
>
>
>---
>
>** [issues:#4949] Keep a staff alive with multiple layers**
>
>**Status:** Started
>**Created:** Mon Aug 01, 2016 07:00 PM UTC by mkdev
>**Last Updated:** Mon Sep 05, 2016 04:29 PM UTC
>**Owner:** mkdev
>
>
>Keep a staff alive with multiple layers
>
>This allows the `VerticalAxisGroup.remove-layer' property to
>accept a list of values. The layer will stay alive with any
>other member of the Keep_alive_together_engrave group with a
>remove-layer value in that list.
>
>The principal reason for this patch was to allow the use of
>MarkLine contexts in a Frenched score, where the context should
>stay alive with any single staff in a StaffGroup. This
>implementation should also allow additional flexibility with ossia
>and divisi staves.
>
>http://codereview.appspot.com/308910043
>
>
>---
>
>Sent from sourceforge.net because you indicated interest in
><https://sourceforge.net/p/testlilyissues/issues/4949/>
>
>
>
>To unsubscribe from further messages, please visit
><https://sourceforge.net/auth/subscriptions/>


-- 
Mark Knoop
>From 2355f38784d00ce5da60f13ff98d32380a33be1e Mon Sep 17 00:00:00 2001
From: Mark Knoop <m...@markknoop.com>
Date: Wed, 3 Aug 2016 19:21:07 +0100
Subject: [PATCH] Issue 4949: Keep a context alive with respect to other
 contexts

This changes the `VerticalAxisGroup.remove-layer' property to
accept either a positive integer or a symbol. If equal to #'any,
the layer will be kept alive by any other member of the
Keep_alive_together_engrave group. This value is useful
particularly for a MarkLine context in a frenched score.

If equal to #'above or #'below the layer will be kept alive with
respect to the context immediately before or after it,
respectively. These values are useful for Lyrics, Dynamics, or
other supplementary contexts.
---
 .../new/using-marklines-in-a-frenched-score.ly     | 97 ++++++++++++++++++++++
 input/regression/remove-layer-symbol.ly            | 65 +++++++++++++++
 lily/hara-kiri-group-spanner.cc                    |  8 +-
 lily/keep-alive-together-engraver.cc               | 35 +++++++-
 scm/define-grob-properties.scm                     | 16 ++--
 5 files changed, 211 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/snippets/new/using-marklines-in-a-frenched-score.ly
 create mode 100644 input/regression/remove-layer-symbol.ly

diff --git a/Documentation/snippets/new/using-marklines-in-a-frenched-score.ly b/Documentation/snippets/new/using-marklines-in-a-frenched-score.ly
new file mode 100644
index 0000000..0fdefc9
--- /dev/null
+++ b/Documentation/snippets/new/using-marklines-in-a-frenched-score.ly
@@ -0,0 +1,97 @@
+\version "2.19.48"
+\header {
+  lsrtags = "contexts-and-engravers, staff-notation"
+  texidoc = "
+Using @{MarkLine} contexts (such as in
+@uref{http://lsr.di.unimi.it/LSR/Item?id=1010, LSR1010}) in a
+Frenched score can be problematic if all the staves between two
+@code{MarkLine}s are removed in one system. The
+@code{Keep_alive_together_engraver} can be used within each
+@code{StaffGroup} to keep the @code{MarkLine} alive only as long
+as the other staves in the group stay alive.
+"
+  doctitle = "Using marklines in a Frenched score"
+}
+bars = {
+  \tempo "Allegro" 4=120
+  s1*2
+  \repeat unfold 5 { \mark \default s1*2 }
+  \bar "||"
+  \tempo "Adagio" 4=40
+  s1*2
+  \repeat unfold 8 { \mark \default s1*2 }
+  \bar "|."
+}
+winds = \repeat unfold 120 { c''4 }
+trumpet = { \repeat unfold 8 g'2 R1*16 \repeat unfold 4 g'2 R1*8 }
+trombone = { \repeat unfold 4 c'1 R1*8 d'1 R1*17 }
+strings = \repeat unfold 240 { c''8 }
+
+#(set-global-staff-size 16)
+\paper {
+  systems-per-page = 5
+  ragged-last-bottom = ##f
+}
+
+\layout {
+  indent = 15\mm
+  short-indent = 5\mm
+  \context {
+    \name MarkLine
+    \type Engraver_group
+    \consists Output_property_engraver
+    \consists Axis_group_engraver
+    \consists Mark_engraver
+    \consists Metronome_mark_engraver
+    \override VerticalAxisGroup.remove-empty = ##t
+    \override VerticalAxisGroup.remove-layer = #'any
+    \override VerticalAxisGroup.staff-affinity = #DOWN
+    \override VerticalAxisGroup.nonstaff-relatedstaff-spacing.basic-distance = 1
+    keepAliveInterfaces = #'()
+  }
+  \context {
+    \Staff
+    \override VerticalAxisGroup.remove-empty = ##t
+    \override VerticalAxisGroup.remove-layer = ##f
+  }
+  \context {
+    \StaffGroup
+    \accepts MarkLine
+    \consists Keep_alive_together_engraver
+  }
+  \context {
+    \Score
+    \remove Mark_engraver
+    \remove Metronome_mark_engraver
+  }
+}
+
+\score {
+  <<
+    \new StaffGroup = "winds" \with {
+      instrumentName = "Winds"
+      shortInstrumentName = "Winds"
+    } <<
+      \new MarkLine \bars
+      \new Staff \winds
+    >>
+    \new StaffGroup = "brass" <<
+      \new MarkLine \bars
+      \new Staff = "trumpet" \with {
+        instrumentName = "Trumpet"
+        shortInstrumentName = "Tpt"
+      } \trumpet
+      \new Staff = "trombone" \with {
+        instrumentName = "Trombone"
+        shortInstrumentName = "Tbn"
+      } \trombone
+    >>
+    \new StaffGroup = "strings" \with {
+      instrumentName = "Strings"
+      shortInstrumentName = "Strings"
+    } <<
+      \new MarkLine \bars
+      \new Staff = "strings" { \strings }
+    >>
+  >>
+}
diff --git a/input/regression/remove-layer-symbol.ly b/input/regression/remove-layer-symbol.ly
new file mode 100644
index 0000000..d6fa93d
--- /dev/null
+++ b/input/regression/remove-layer-symbol.ly
@@ -0,0 +1,65 @@
+\version "2.19.48"
+
+\header {
+  texidoc = "The @code{VerticalAxisGroup.remove-layer} property
+  can be used to keep staves alive with reference to other staves
+  in the @code{Keep_alive_together_engraver} group."
+}
+
+\layout {
+  indent = 40\mm
+  short-indent = 15\mm
+}
+
+\score {
+  <<
+    \new Staff \with {
+      instrumentName = "Continuous"
+      shortInstrumentName = "cont"
+    } { \repeat unfold 104 g'4 \bar "|." }
+    \new StaffGroup \with {
+      \consists Keep_alive_together_engraver
+    } <<
+      \new Staff \with {
+        keepAliveInterfaces = #'()
+        instrumentName = \markup \center-column { "Alive with A or B" }
+        shortInstrumentName = "with A or B"
+        \override VerticalAxisGroup.remove-empty = ##t
+        \override VerticalAxisGroup.remove-first = ##t
+        \override VerticalAxisGroup.remove-layer = #'any
+      } { \repeat unfold 104 c''4 }
+      \new Staff \with {
+        instrumentName = "A"
+        shortInstrumentName = "A"
+        \override VerticalAxisGroup.remove-empty = ##t
+        \override VerticalAxisGroup.remove-first = ##t
+        \override VerticalAxisGroup.remove-layer = ##f
+      } {
+        \repeat unfold 16 c'4
+        R1*4
+        \repeat unfold 16 c'4
+        R1*14
+      }
+      \new Staff \with {
+        keepAliveInterfaces = #'()
+        instrumentName = \markup \center-column { "Alive with A" }
+        shortInstrumentName = "with A"
+        \override VerticalAxisGroup.remove-empty = ##t
+        \override VerticalAxisGroup.remove-first = ##t
+        \override VerticalAxisGroup.remove-layer = #'above
+      } { \repeat unfold 104 c''4 }
+      \new Staff \with {
+        instrumentName = "B"
+        shortInstrumentName = "B"
+        \override VerticalAxisGroup.remove-empty = ##t
+        \override VerticalAxisGroup.remove-first = ##t
+        \override VerticalAxisGroup.remove-layer = ##f
+      } {
+        R1*8
+        \repeat unfold 16 c'4
+        R1*13
+        c'1
+      }
+    >>
+  >>
+}
diff --git a/lily/hara-kiri-group-spanner.cc b/lily/hara-kiri-group-spanner.cc
index 0641078..76207a5 100644
--- a/lily/hara-kiri-group-spanner.cc
+++ b/lily/hara-kiri-group-spanner.cc
@@ -190,9 +190,11 @@ Hara_kiri_group_spanner::add_interesting_item (Grob *me, Grob *n)
 ADD_INTERFACE (Hara_kiri_group_spanner,
                "A group spanner that keeps track of interesting items.  If it"
                " doesn't contain any after line breaking, it removes itself"
-               " and all its children.  Children may be prioritized in layers"
-               " via @code{remove-layer}, in which case only the"
-               " lowest-numbered non-empty layer is retained.",
+               " and all its children.  Greater control can be exercised via"
+               " @code{remove-layer} which can prioritize layers so only the"
+               " lowest-numbered non-empty layer is retained; make the layer"
+               " independent of the group; or make it dependent on any other"
+               " member of the group",
 
                /* properties */
                "items-worth-living "
diff --git a/lily/keep-alive-together-engraver.cc b/lily/keep-alive-together-engraver.cc
index 9b1cbe4..8931a81 100644
--- a/lily/keep-alive-together-engraver.cc
+++ b/lily/keep-alive-together-engraver.cc
@@ -22,6 +22,7 @@
 #include "engraver.hh"
 #include "grob.hh"
 #include "grob-array.hh"
+#include "international.hh"
 
 #include "translator.icc"
 
@@ -64,12 +65,44 @@ Keep_alive_together_engraver::finalize ()
         {
           if (i == j)
             continue;
+
+          if (scm_is_symbol (this_layer))
+            {
+              if (scm_is_eq (this_layer, ly_symbol2scm ("any")))
+                {
+                  // layer is kept alive by any other layer
+                  live->add (group_spanners_[j]);
+                  continue;
+                }
+              else if (scm_is_eq (this_layer, ly_symbol2scm ("above")))
+                {
+                  // layer is kept alive by the layer preceding it
+                  if (i == j + 1)
+                    live->add (group_spanners_[j]);
+                  continue;
+                }
+              else if (scm_is_eq (this_layer, ly_symbol2scm ("below")))
+                {
+                  // layer is kept alive by the layer following it
+                  if (i == j - 1)
+                    live->add (group_spanners_[j]);
+                  continue;
+                }
+              else
+                {
+                  group_spanners_[i]->warning (_f ("unknown remove-layer value `%s'",
+                                                   ly_symbol2string (this_layer).c_str ()));
+                  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
+              // unset layers are kept alive by all but ignored layers
               live->add (group_spanners_[j]);
               continue;
             }
diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm
index 7ca44b6..d55ab4c 100644
--- a/scm/define-grob-properties.scm
+++ b/scm/define-grob-properties.scm
@@ -809,12 +809,16 @@ number, the quicker the slur attains its @code{height-limit}.")
 interesting items.")
      (remove-first ,boolean? "Remove the first staff of an orchestral
 score?")
-     (remove-layer ,integer? "The @code{Keep_alive_together_engraver}
-removes all @code{VerticalAxisGroup} grobs with a @code{remove-layer}
-larger than the smallest retained @code{remove-layer}.  Set to
-@code{#f} to make a layer invisible to the
-@code{Keep_alive_together_engraver}, set to @code{'()} to have it not
-participate in the layering decisions.")
+     (remove-layer ,key? "When set as a positive integer, the
+@code{Keep_alive_together_engraver} removes all
+@code{VerticalAxisGroup} grobs with a @code{remove-layer} larger than
+the smallest retained @code{remove-layer}. Set to @code{#f} to make a
+layer independent of the @code{Keep_alive_together_engraver}. Set to
+@code{'()}, the layer does not participate in the layering decisions.
+The property can also be set as a symbol for common behaviors:
+@code{#'any} to keep the layer alive with any other layer in the
+group; @code{#'above} or @code{#'below} to keep the layer alive with
+the context immediately before or after it, respectively.")
      (replacement-alist ,list? "Alist of strings.
 The key is a string of the pattern to be replaced.  The value is a
 string of what should be displayed.  Useful for ligatures.")
-- 
2.7.4

_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to