]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix 65.
authorJoe Neeman <joeneeman@gmail.com>
Wed, 4 Jun 2008 13:11:32 +0000 (23:11 +1000)
committerJoe Neeman <joeneeman@gmail.com>
Wed, 4 Jun 2008 14:07:04 +0000 (00:07 +1000)
Use the accepts_list_ of a context (not just the accepts_list_ of the
associated context def) to determine which children may be added to a
context. This allows the accepts list to be modified using \with
instead of just in \layout.

lily/context-def.cc
lily/context.cc
lily/include/context-def.hh
lily/include/context.hh
lily/output-def.cc

index f4023a09a110833cb56ad13f83d8c2dbf75a4059..2d7cace9bf9ba3b04b2ebe537529fd6f12a5f387 100644 (file)
@@ -193,12 +193,24 @@ Context_def::get_default_child (SCM user_mod) const
   return name;
 }
 
+/*
+  Given a name of a context that we want to create, finds a list of context
+  definitions such that:
+   - the first element in the list defines a context that is a valid child of
+     the context defined by this Context_def
+   - each subsequent element in the list defines a context that is a valid child
+     of the the context defined by the preceding element in the list
+   - the last element in the list defines a context with the given name
+
+  The ADDITIONAL_ACCEPTS parameter is a list of additional contexts that this
+  specific output def (but not and of the child output defs) should accept.
+*/
 vector<Context_def*>
-Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef) const
+Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef, SCM additional_accepts) const
 {
   assert (scm_is_symbol (type_sym));
 
-  SCM accepted = get_accepted (SCM_EOL);
+  SCM accepted = get_accepted (additional_accepts);
 
   vector<Context_def*> accepteds;
   for (SCM s = accepted; scm_is_pair (s); s = scm_cdr (s))
@@ -224,7 +236,7 @@ Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef) const
       Context_def *g = accepteds[i];
 
       vector<Context_def*> result
-       = g->path_to_acceptable_context (type_sym, odef);
+       = g->path_to_acceptable_context (type_sym, odef, SCM_EOL);
       if (result.size () && result.size () < best_depth)
        {
          best_depth = result.size ();
index 3c982751fd6635e1822ad525a54471a2fb893a07..dc6216403fe3caaf42aaf8f1dac54272627293d5 100644 (file)
@@ -104,17 +104,12 @@ Context::create_unique_context (SCM name, string id, SCM operations)
   if (gthis && gthis->get_score_context ())
     return gthis->get_score_context ()->create_unique_context (name, id, operations);
 
-  /*
-    TODO: use accepts_list_.
-  */
-  vector<Context_def*> path
-    = unsmob_context_def (definition_)->path_to_acceptable_context (name, get_output_def ());
-
+  vector<Context_def*> path = path_to_acceptable_context (name);
   if (path.size ())
     {
       Context *current = this;
 
-      // start at 1.  The first one (index 0) will be us.
+      // Iterate through the path and create all of the implicit contexts.
       for (vsize i = 0; i < path.size (); i++)
        {
          SCM ops = SCM_EOL;
@@ -170,8 +165,7 @@ Context::find_create_context (SCM n, string id, SCM operations)
   /*
     TODO: use accepts_list_.
   */
-  vector<Context_def*> path
-    = unsmob_context_def (definition_)->path_to_acceptable_context (n, get_output_def ());
+  vector<Context_def*> path = path_to_acceptable_context (n);
 
   if (path.size ())
     {
@@ -261,8 +255,8 @@ Context::create_context_from_event (SCM sev)
   SCM type_scm = ev->get_property ("type");
   string type = ly_symbol2string (type_scm);
   
-  vector<Context_def*> path
-    = unsmob_context_def (definition_)->path_to_acceptable_context (type_scm, get_output_def ());
+  vector<Context_def*> path = path_to_acceptable_context (type_scm);
+
   if (path.size () != 1)
     {
       programming_error (_f ("Invalid CreateContext event: Cannot create %s context", type.c_str ()));
@@ -312,6 +306,25 @@ Context::create_context_from_event (SCM sev)
                     ly_symbol2scm ("creator"), sev);
 }
 
+vector<Context_def*>
+Context::path_to_acceptable_context (SCM name) const
+{
+  // definition_mods_ is a list of (symbol string), but the Context_def expects
+  // to see a list of (symbol symbol).
+  SCM accepts = SCM_EOL;
+  for (SCM s = scm_reverse (definition_mods_); scm_is_pair (s); s = scm_cdr (s))
+    if (scm_caar (s) == ly_symbol2scm ("accepts"))
+      {
+       SCM elt = scm_list_2 (scm_caar (s), scm_string_to_symbol (scm_cadar (s)));
+       accepts = scm_cons (elt, accepts);
+      }
+
+  return unsmob_context_def (definition_)->path_to_acceptable_context (name,
+                                                                      get_output_def (),
+                                                                      accepts);
+                                                                      
+}
+
 Context *
 Context::create_context (Context_def *cdef,
                         string id,
index dd4df4c802061b355fe7ae44b2c104b20c67753a..ea81eb1295be8f55aab47b8fa6c7ada6e3b93dd0 100644 (file)
@@ -49,7 +49,7 @@ public:
   VIRTUAL_COPY_CONSTRUCTOR(Context_def, Context_def);
 
   vector<Context_def*> path_to_acceptable_context (SCM type_string,
-                                                     Output_def *) const;
+                                                  Output_def *, SCM) const;
   Context *instantiate (SCM extra_ops);
 
   SCM to_alist () const;
index 88019f4b88929324e051f3d563921b7e8a249bc1..648a52ae3b7f089a2f9d6248ca1c1507f7660464 100644 (file)
@@ -114,8 +114,7 @@ public:
                                string id, SCM ops);
   Context *create_unique_context (SCM context_name, string context_id,
                                  SCM ops);
-  vector<Context*> path_to_acceptable_context (SCM alias,
-                                                 Output_def *) const;
+  vector<Context_def*> path_to_acceptable_context (SCM alias) const;
 };
 
 /*
index 853704c5c98d478442499b28f2ea3ad22f367192..0e0259f128d699c3635bfb51c6a5418fda07e1b0 100644 (file)
@@ -81,7 +81,7 @@ assign_context_def (Output_def * m, SCM transdef)
 /* find the translator for NAME. NAME must be a symbol. */
 SCM
 find_context_def (Output_def const *m, SCM name)
-{  
+{
   Context_def *cd = unsmob_context_def (m->lookup_variable (name));
   return cd ? cd->self_scm () : SCM_EOL;
 }