From: Neil Puttock Date: Sun, 16 Nov 2008 00:58:06 +0000 (+0000) Subject: Allow for nested contexts of any depth. X-Git-Tag: release/2.11.65-1~51^2~11 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=432f8eedc35f0fa3efd570d66f185a02928adbfa;p=lilypond.git Allow for nested contexts of any depth. Use a set to keep track of visited contexts. Remove InnerChoirStaff and InnerStaffGroup. Add convert-ly rules, News entry and regtest. --- diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index 6de795eb34..5f640098d2 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -62,6 +62,19 @@ which scares away people. @end ignore +@item +Nested contexts of the same type are now allowed. +This deprecates @code{InnerStaffGroup} and @code{InnerChoirStaff}. +@lilypond[relative=1] +\new StaffGroup << + \new Staff { c1 } + \new StaffGroup << + \new Staff { c1 } + \new Staff { c1 } + >> +>> +@end lilypond + @item In addition to the already existing @code{showLastLength} property, @code{showFirstLength} can now be set as well, rendering only the first @@ -145,7 +158,9 @@ testnotes = { (yext (if is-up (cons (* log -0.8) 0) (cons 0 (* log 0.8)))) (flag-stencil (make-filled-box-stencil '(-0.4 . 0.4) yext)) (stroke-style (ly:grob-property stem-grob 'stroke-style)) - (stroke-stencil (if (equal? stroke-style "grace") (make-line-stencil 0.2 -0.9 -0.4 0.9 -0.4) empty-stencil))) + (stroke-stencil (if (equal? stroke-style "grace") + (make-line-stencil 0.2 -0.9 -0.4 0.9 -0.4) + empty-stencil))) (ly:stencil-add flag-stencil stroke-stencil))) { @@ -371,14 +386,12 @@ The environment variable @code{LILYPONDPREFIX} has been renamed Notes or rests, such as a typical end note, that fill an entire measure are preceded by some more space. -@lilypond[] -\relative c' { - \time 4/4 - s1 - c2. c4 - \time 3/4 - c2. -} +@lilypond[relative=1] +\time 4/4 +s1 +c2. c4 +\time 3/4 +c2. @end lilypond @item diff --git a/input/regression/context-nested-staffgroup.ly b/input/regression/context-nested-staffgroup.ly new file mode 100644 index 0000000000..2093afff97 --- /dev/null +++ b/input/regression/context-nested-staffgroup.ly @@ -0,0 +1,15 @@ +\version "2.11.64" +\header { + texidoc = "Contexts of the same type can be nested." +} + +\new StaffGroup \relative c' << + \new Staff { c1 } + \new StaffGroup << + \new Staff { c1 } + \new StaffGroup << + \new Staff { c1 } + \new Staff { c1 } + >> + >> +>> diff --git a/lily/context-def.cc b/lily/context-def.cc index a810159aa3..47abcd3655 100644 --- a/lily/context-def.cc +++ b/lily/context-def.cc @@ -1,5 +1,5 @@ /* - translator-def.cc -- implement Context_def + context-def.cc -- implement Context_def source file of the GNU LilyPond music typesetter @@ -205,8 +205,24 @@ Context_def::get_default_child (SCM user_mod) const The ADDITIONAL_ACCEPTS parameter is a list of additional contexts that this specific context def (but not any of the child context defs) should accept. */ +vector +Context_def::path_to_acceptable_context (SCM type_sym, + Output_def *odef, + SCM additional_accepts) const +{ + set seen; + return internal_path_to_acceptable_context (type_sym, odef, additional_accepts, &seen); +} + +/* +The SEEN parameter is a set which keeps track of visited contexts, allowing +contexts of the same type to be nested. +*/ vector -Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef, SCM additional_accepts) const +Context_def::internal_path_to_acceptable_context (SCM type_sym, + Output_def *odef, + SCM additional_accepts, + set *seen) const { assert (scm_is_symbol (type_sym)); @@ -230,20 +246,25 @@ Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef, SCM add } } + seen->insert (this); vsize best_depth = INT_MAX; for (vsize i = 0; i < accepteds.size (); i++) { Context_def *g = accepteds[i]; - vector result - = g->path_to_acceptable_context (type_sym, odef, SCM_EOL); - if (result.size () && result.size () < best_depth) + if (!seen->count (g)) { - best_depth = result.size (); - result.insert (result.begin (), g); - best_result = result; + vector result + = g->internal_path_to_acceptable_context (type_sym, odef, SCM_EOL, seen); + if (result.size () && result.size () < best_depth) + { + best_depth = result.size (); + result.insert (result.begin (), g); + best_result = result; + } } } + seen->erase (this); return best_result; } diff --git a/lily/include/context-def.hh b/lily/include/context-def.hh index ea81eb1295..21af176327 100644 --- a/lily/include/context-def.hh +++ b/lily/include/context-def.hh @@ -14,6 +14,7 @@ #include "smobs.hh" #include "input.hh" #include "virtual-methods.hh" +#include /* @@ -49,7 +50,12 @@ public: VIRTUAL_COPY_CONSTRUCTOR(Context_def, Context_def); vector path_to_acceptable_context (SCM type_string, - Output_def *, SCM) const; + Output_def *, + SCM) const; + vector internal_path_to_acceptable_context (SCM type_string, + Output_def *, + SCM, + set *seen) const; Context *instantiate (SCM extra_ops); SCM to_alist () const; diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index b1be75d1cb..7688912f6a 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -106,7 +106,7 @@ \context { \type "Engraver_group" - \name "InnerChoirStaff" + \name "ChoirStaff" \consists "System_start_delimiter_engraver" systemStartDelimiter = #'SystemStartBracket vocalName = #'() @@ -119,19 +119,11 @@ \accepts "PianoStaff" \accepts "Lyrics" \accepts "ChordNames" + \accepts "ChoirStaff" + \accepts "StaffGroup" \defaultchild "Staff" -} - -\context { - \InnerChoirStaff - \name ChoirStaff - - \defaultchild "Staff" - \accepts "InnerChoirStaff" - \accepts "InnerStaffGroup" \description "Identical to @code{StaffGroup} except that the contained staves are not connected vertically." - } \context{ @@ -314,7 +306,7 @@ instrument names at the start of each system." \context { \type "Engraver_group" - \name InnerStaffGroup + \name "StaffGroup" \consists "Span_bar_engraver" \consists "Span_arpeggio_engraver" @@ -332,24 +324,16 @@ instrument names at the start of each system." \accepts "TabStaff" \accepts "Lyrics" \accepts "ChordNames" -} - -\context { - \InnerStaffGroup - \name StaffGroup + \accepts "FiguredBass" + \accepts "ChoirStaff" + \accepts "StaffGroup" \description "Groups staves while adding a bracket on the left side, grouping the staves together. The bar lines of the contained staves are connected vertically. @code{StaffGroup} only consists of a collection of staves, with a bracket in front and spanning bar lines." - - \accepts "InnerChoirStaff" - \accepts "ChoirStaff" - \accepts "InnerStaffGroup" - \accepts "FiguredBass" } - \context{ \type "Engraver_group" \override VerticalAxisGroup #'minimum-Y-extent = #'(-0.75 . 2.0) diff --git a/python/convertrules.py b/python/convertrules.py index 842d6fb8bd..c0ae536a02 100644 --- a/python/convertrules.py +++ b/python/convertrules.py @@ -2823,9 +2823,25 @@ def conv (str): str = re.sub (r"\\bigger", r"\\larger", str) return str -@rule ((2, 11, 64), "systemSeparatorMarkup -> system-separator-markup") +@rule ((2, 11, 64), "systemSeparatorMarkup -> system-separator-markup, \n\ +InnerStaffGroup -> StaffGroup, InnerChoirStaff -> ChoirStaff") def conv (str): str = re.sub (r'systemSeparatorMarkup', r'system-separator-markup', str) + if re.search (r'\\InnerStaffGroup', str): + stderr_write ("\n") + stderr_write (NOT_SMART % _("re-definition of InnerStaffGroup.\n")) + stderr_write (FROM_TO % ("InnerStaffGroup", "StaffGroup.\n")) + stderr_write (UPDATE_MANUALLY) + raise FatalConversionError () + if re.search (r'\\InnerChoirStaff', str): + stderr_write ("\n") + stderr_write (NOT_SMART % _("re-definition of InnerChoirStaff.\n")) + stderr_write (FROM_TO % ("InnerChoirStaff", "ChoirStaff.\n")) + stderr_write (UPDATE_MANUALLY) + raise FatalConversionError () + else: + str = re.sub ('InnerStaffGroup', 'StaffGroup', str) + str = re.sub ('InnerChoirStaff', 'ChoirStaff', str) return str # Guidelines to write rules (please keep this at the end of this file) diff --git a/scripts/musicxml2ly.py b/scripts/musicxml2ly.py index 12e9ee29ab..0dcaf10ab3 100644 --- a/scripts/musicxml2ly.py +++ b/scripts/musicxml2ly.py @@ -424,8 +424,6 @@ def extract_score_structure (part_list, staffinfo): del staves[pos] # replace the staves with the whole group for j in staves[(prev_start + 1):pos]: - if j.is_group: - j.stafftype = "InnerStaffGroup" group.append_staff (j) del staves[(prev_start + 1):pos] staves.insert (prev_start + 1, group)