]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/unfolded-repeat-iterator.cc
release: 1.3.92
[lilypond.git] / lily / unfolded-repeat-iterator.cc
index 9a4155f54da58f9d0aa4b0b91045d233ca67258c..6e6b665f011d82a642422b3b4997ff7525fe58d1 100644 (file)
@@ -38,28 +38,45 @@ the  alternative just set.
    
  */
 void
-Unfolded_repeat_iterator::next_element () 
+Unfolded_repeat_iterator::next_element (bool side_effect
 {
-  Repeated_music * mus =dynamic_cast<Repeated_music *> (music_l_);
+  Repeated_music * repmus =dynamic_cast<Repeated_music *> (music_l_);
   delete current_iter_p_;
   current_iter_p_ =0;
 
-
+  bool do_repcommands = side_effect && repmus->volta_fold_b_;
+  
   if (do_main_b_)
     {
-      done_mom_ += mus->body ()->length_mom ();
+      /*
+       we were busy doing the main body, so
+
+       - go to alternative if we're a volta
+
+       - do something intelligent when we're fully unfolding (fixcomment)
+       */
+      
+      here_mom_ += repmus->body ()->length_mom ();
 
-      if (!mus->volta_fold_b_)
+      if (!repmus->volta_fold_b_)
        done_count_ ++;
      
       if (gh_pair_p (alternative_cons_))
        {
          current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
          do_main_b_ = false;
+
+         if (repmus->volta_fold_b_)
+           {
+             String repstr = to_str (done_count_ + 1);
+             if (do_repcommands)
+               add_repeat_command (gh_list (ly_symbol2scm ("volta"),
+                                            gh_str02scm (repstr.ch_C()), SCM_UNDEFINED));
+           }     
        }
-      else if (done_count_ <  mus->repeats_i_ && !mus->volta_fold_b_) 
+      else if (done_count_ <  repmus->repeats_i_ && !repmus->volta_fold_b_) 
        {
-         current_iter_p_ = get_iterator_p (mus->body ());
+         current_iter_p_ = get_iterator_p (repmus->body ());
          do_main_b_ = true;
        }
     }
@@ -69,28 +86,55 @@ Unfolded_repeat_iterator::next_element ()
        we're not in the main part. So we're either in an alternative, or
        we just finished.
       */
+
+      /*
+       we're in the alternatives.  We move the pointer to the
+       next alternative.
+       */
       if (alternative_cons_)
        {
-         done_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom ();
+         here_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom ();
 
-         if (mus->volta_fold_b_ || 
-             mus->repeats_i_ - done_count_  < alternative_count_i_)
+         if (repmus->volta_fold_b_ || 
+             repmus->repeats_i_ - done_count_  < alternative_count_i_)
            alternative_cons_ = gh_cdr (alternative_cons_);
          
+         if (do_repcommands)
+           add_repeat_command (gh_list (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED));
+
+         
+         
          /*
            we've done the main body as well, but didn't go over the other
            increment.  */
-         if (mus->volta_fold_b_)
+         if (repmus->volta_fold_b_)
            done_count_ ++;
        }
+
+      /*
+       We still have alternatives left, so
+
+       if we're volta: traverse them
+
+       if we're full unfold: go back to main body.
+       */
       
-      if (done_count_ < mus->repeats_i_ && gh_pair_p (alternative_cons_))
+      if (done_count_ < repmus->repeats_i_ && gh_pair_p (alternative_cons_))
        {
-         if (mus->volta_fold_b_)
+         if (do_repcommands)
+           {
+             String repstr = to_str (done_count_ + 1);
+             add_repeat_command (gh_list (ly_symbol2scm ("volta"),
+                                          gh_str02scm (repstr.ch_C()), SCM_UNDEFINED));
+             add_repeat_command (ly_symbol2scm ("end-repeat"));
+           }
+
+         
+         if (repmus->volta_fold_b_)
            current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
          else
            {
-             current_iter_p_ = get_iterator_p (mus->body ());
+             current_iter_p_ = get_iterator_p (repmus->body ());
              do_main_b_ = true;
            }
        }
@@ -107,7 +151,7 @@ Unfolded_repeat_iterator::ok () const
 Moment
 Unfolded_repeat_iterator::pending_moment () const
 {
-  return done_mom_ + current_iter_p_->pending_moment ();
+  return here_mom_ + current_iter_p_->pending_moment ();
 }
 
 void
@@ -134,34 +178,95 @@ Unfolded_repeat_iterator::construct_children ()
     }
 }
 
+void
+Unfolded_repeat_iterator::add_repeat_command (SCM what)
+{
+  SCM reps = ly_symbol2scm ("repeatCommands");
+  SCM current_reps = report_to_l ()->get_property(reps);
+
+  Translator_group * where = report_to_l ()->where_defined (reps);
+  if (where
+      && current_reps == SCM_EOL || gh_pair_p (current_reps))
+    {
+      current_reps = gh_cons (what, current_reps);
+      where->set_property (reps, current_reps);
+    }
+}
+
 void
 Unfolded_repeat_iterator::process (Moment m) 
 {
   if (!m)
     {
-      Music_iterator *yeah = try_music (music_l_);
-      if (yeah)
-       set_translator (yeah->report_to_l ());
-      else
-       music_l_->origin ()->warning ( _("no one to print a volta bracket"));
+      if (dynamic_cast<Repeated_music*> (music_l_)->volta_fold_b_)
+       add_repeat_command (ly_symbol2scm ("start-repeat"));
     }
   while (1)
     {
       while (!current_iter_p_->ok ())
        {
-         next_element();
+         next_element(true);
 
          if (!current_iter_p_)
            return;
        }
       
-      if (m - done_mom_ >= current_iter_p_->pending_moment ())
-       current_iter_p_->process (m - done_mom_);
+      if (m - here_mom_ >= current_iter_p_->pending_moment ())
+       current_iter_p_->process (m - here_mom_);
       else
        return;
     }
 }
 
+void
+Unfolded_repeat_iterator::skip (Moment until)
+{
+  while (current_iter_p_)
+    {
+      Moment l =current_iter_p_->music_length_mom ();
+      if (l >= until - here_mom_)
+       current_iter_p_->skip (until - here_mom_);
+
+      if (current_iter_p_->ok ())
+       return ; 
+
+      next_element (false);
+    }
+}
+
+SCM
+Unfolded_repeat_iterator::get_music (Moment until)const
+{
+  SCM s = SCM_EOL;
+  if (until <  pending_moment ())
+    return s;
+
+
+  Unfolded_repeat_iterator * me
+    = dynamic_cast<Unfolded_repeat_iterator*> (this->clone ());
+  
+  while (me->ok ())
+    {
+      SCM nm = me->current_iter_p_->get_music (until -
+                                              me->here_mom_);
+      
+      s = gh_append2 (nm, s);
+      
+      Moment m = 0;
+      for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
+       m = m >? unsmob_music (gh_car (i))->length_mom ();
+
+      if (m > Moment (0))
+       break ;
+      else
+       me->next_element (false);
+    }
+
+  delete me;
+  
+  return s;
+}
+
 
 Music_iterator* 
 Unfolded_repeat_iterator::try_music_in_children (Music  * m) const