bool
Hara_kiri_group_spanner::request_suicide (Grob *me, int start, int end)
{
+ extract_grob_set (me, "make-dead-when", foes);
+ for (vsize i = 0; i < foes.size (); i++)
+ if (foes[i]->is_live () && !request_suicide_alone (foes[i], start, end))
+ return true;
+
if (!request_suicide_alone (me, start, end))
return false;
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.",
+ " 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.",
/* properties */
"items-worth-living "
"important-column-ranks "
"keep-alive-with "
+ "make-dead-when "
"remove-empty "
"remove-first "
+ "remove-layer "
);
-
{
for (vsize i = 0; i < group_spanners_.size (); ++i)
{
- SCM grob_array_scm = Grob_array::make_array ();
- Grob_array *ga = Grob_array::unsmob (grob_array_scm);
-
- // It would make Hara_kiri_group_spanner::request_suicide a _little_
- // faster if we removed each grob from its own array. It seems
- // unnecessary for now, though.
- ga->set_array (group_spanners_);
- group_spanners_[i]->set_object ("keep-alive-with", grob_array_scm);
+ SCM this_layer = group_spanners_[i]->get_property ("remove-layer");
+ if (scm_is_false (this_layer))
+ continue;
+
+ SCM live_scm = Grob_array::make_array ();
+ Grob_array *live = Grob_array::unsmob (live_scm);
+ SCM dead_scm = Grob_array::make_array ();
+ Grob_array *dead = Grob_array::unsmob (dead_scm);
+
+ for (vsize j = 0; j < group_spanners_.size (); ++j)
+ {
+ if (i == 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
+ live->add (group_spanners_[j]);
+ continue;
+ }
+ // an explicit layer is only affected by explicit layers
+ if (!scm_is_integer (that_layer))
+ continue;
+ if (scm_is_true (scm_num_eq_p (that_layer, this_layer)))
+ live->add (group_spanners_[j]);
+ else if (scm_is_true (scm_less_p (that_layer, this_layer)))
+ dead->add (group_spanners_[j]);
+ }
+ if (!live->empty ())
+ group_spanners_[i]->set_object ("keep-alive-with", live_scm);
+ if (!dead->empty ())
+ group_spanners_[i]->set_object ("make-dead-when", dead_scm);
}
}
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.")
(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.")
(left-neighbor ,ly:grob? "The right-most column that has a spacing-wish
for this column.")
+ (make-dead-when ,ly:grob-array? "An array of other
+@code{VerticalAxisGroup}s. If any of them are alive, then we will turn dead.")
(melody-spanner ,ly:grob? "The @code{MelodyItem} object for a stem.")
(minimum-translations-alist ,list? "An list of translations for a given
start and end point.")