From: hanwen <hanwen>
Date: Tue, 17 Feb 2004 01:48:35 +0000 (+0000)
Subject: * input/test/piano-staff-distance.ly: new file.
X-Git-Tag: release/2.1.27~47
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=4c92544cec214764702f9c7794cc277916511e43;p=lilypond.git

* input/test/piano-staff-distance.ly: new file.

* lily/translator-group.cc (recurse_down_translators): use
Direction for bottom-up/top-down.

* lily/include/translator.hh (class Translator): add
process_music() and do_announces(). This obviates
recurse_down_{engravers,performers}.

* ly/declarations-init.ly (melismaEnd): use ManualMelismaEvent for
\melisma and \melismaEnd

* lily/melisma-engraver.cc (process_music): change to
Melisma_translator, unify with performer. Accept
ManualMelismaEvent.

* ly/engraver-init.ly: add Font_size_engraver.
---

diff --git a/ChangeLog b/ChangeLog
index 2ad319e919..aadd667f3d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2004-02-17  Han-Wen Nienhuys   <hanwen@xs4all.nl>
+
+	* input/test/piano-staff-distance.ly: new file.
+
+	* lily/translator-group.cc (recurse_down_translators): use
+	Direction for bottom-up/top-down.
+
+	* lily/include/translator.hh (class Translator): add
+	process_music() and do_announces(). This obviates
+	recurse_down_{engravers,performers}.
+
+	* ly/declarations-init.ly (melismaEnd): use ManualMelismaEvent for
+	\melisma and \melismaEnd
+
+	* lily/melisma-engraver.cc (process_music): change to
+	Melisma_translator, unify with performer. Accept
+	ManualMelismaEvent.
+
+	* ly/engraver-init.ly: add Font_size_engraver.
+
 2004-02-16  Heikki Junes  <hjunes@cc.hut.fi>
 
 	* lily/align-interface.cc, lily/axis-group-engraver.cc: spell
diff --git a/input/test/piano-staff-distance.ly b/input/test/piano-staff-distance.ly
new file mode 100644
index 0000000000..556d68ccc8
--- /dev/null
+++ b/input/test/piano-staff-distance.ly
@@ -0,0 +1,69 @@
+
+\header
+{
+
+ texidoc = "It is possible to have different staff distances across
+piano systems, but it requires some advanced magic. Kids don't try this at home.
+
+"
+
+}
+
+\version "2.1.24"
+
+#(define ((futz-alignment-callback distance count) grob axis)
+
+   "Check if we're the system number COUNT, and if yes, set fixed distance to
+DISTANCE; then call the original callback.  "
+   (let*
+       ((a (ly:get-parent grob axis))
+	(o (ly:get-original a))
+	(bs (if (ly:grob? o)
+		(ly:get-broken-into o)
+		#f))
+	)
+
+
+     (if (and (list? bs)
+	      (< count (length bs))
+	      (equal? (list-ref bs count) a)
+	 )
+	 (ly:set-grob-property! a 'forced-distance distance))
+     
+     (Align_interface::fixed_distance_alignment_callback grob axis)) )
+
+\score {
+    \notes \relative c''  \context PianoStaff
+    \with {
+	verticalAlignmentChildCallback = #(futz-alignment-callback 20 1)
+
+	%% Every cross staff beam will trigger
+	%% alignment unless autokneeing is switched off 
+	\override Beam #'auto-knee-gap = #'()
+    } <<
+
+	\context Staff  = up {
+	    
+	    \time 2/4 
+	    c8[
+		\change Staff = down
+		\once \override Stem #'direction = #UP
+		c8
+		\change Staff = up
+		c c ](
+	    |
+	    \break
+	    
+	    c8[)
+		\change Staff = down
+		\once \override Stem #'direction = #UP
+		c8
+		\change Staff = up
+		c c ](
+	}
+	\context Staff = down {
+	    \skip 1 }
+
+    >>
+    \paper { raggedright = ##T } 
+}
diff --git a/lily/completion-note-heads-engraver.cc b/lily/completion-note-heads-engraver.cc
index bbe14d260d..33908639a9 100644
--- a/lily/completion-note-heads-engraver.cc
+++ b/lily/completion-note-heads-engraver.cc
@@ -300,7 +300,6 @@ Completion_heads_engraver::stop_translation_timestep ()
   for (int i = scratch_note_reqs_.size(); i--;)
     {
       scm_gc_unprotect_object (scratch_note_reqs_[i]->self_scm () );
-      
     }
   
   scratch_note_reqs_.clear();
diff --git a/lily/context-def.cc b/lily/context-def.cc
index d91c60a03b..05c19af47a 100644
--- a/lily/context-def.cc
+++ b/lily/context-def.cc
@@ -286,16 +286,20 @@ SCM
 Context_def::clone_scm () const
 {
   Context_def * t = new Context_def (*this);
-  scm_gc_unprotect_object (t->self_scm());
-  return t->self_scm();
+
+  SCM x = t->self_scm();
+  scm_gc_unprotect_object (x);
+  return x;
 }
 
 SCM
 Context_def::make_scm ()
 {
   Context_def* t = new Context_def;
-  scm_gc_unprotect_object (t->self_scm());
-  return t->self_scm();
+
+  SCM x  =t->self_scm();
+  scm_gc_unprotect_object (x);
+  return x;
 }
 
 void
diff --git a/lily/context.cc b/lily/context.cc
index 0374885195..4503d1cf7c 100644
--- a/lily/context.cc
+++ b/lily/context.cc
@@ -35,7 +35,7 @@ Context::check_removal ()
       trg->check_removal ();
       if (trg->is_removable ())
 	{
-	  recurse_down_translators (trg, &Translator::finalize, false);
+	  recurse_down_translators (trg, &Translator::finalize, DOWN);
 	  remove_context (trg);
 	}
     }
@@ -73,7 +73,7 @@ Context::add_context (Context*t)
       */
       td->apply_default_property_operations (t);
 
-      recurse_down_translators (t, &Translator::initialize, true);
+      recurse_down_translators (t, &Translator::initialize, DOWN);
     }
 }
 
@@ -90,9 +90,8 @@ Context::Context ()
   
   smobify_self ();
 
-  Scheme_hash_table *tab = new Scheme_hash_table ;
-  properties_scm_ = tab->self_scm ();
-  scm_gc_unprotect_object (tab->self_scm ());
+  properties_scm_ = (new Scheme_hash_table)->self_scm ();
+  scm_gc_unprotect_object (properties_scm_);
 }
 
 Context *
diff --git a/lily/engraver.cc b/lily/engraver.cc
index 201f44655f..87cb246d6f 100644
--- a/lily/engraver.cc
+++ b/lily/engraver.cc
@@ -63,11 +63,6 @@ Engraver::typeset_grob (Grob*p)
 
 
 
-void
-Engraver::process_music ()
-{
-  
-}
 Engraver::Engraver()
 {
 }
@@ -81,11 +76,6 @@ Engraver::get_score_engraver () const
 }
 
 
-void
-Engraver::do_announces ()
-{
-}
-
 ENTER_DESCRIPTION(Engraver,
 		   "", "",
 		  "",
diff --git a/lily/include/engraver-group-engraver.hh b/lily/include/engraver-group-engraver.hh
index f18a60f15f..23c6719fb0 100644
--- a/lily/include/engraver-group-engraver.hh
+++ b/lily/include/engraver-group-engraver.hh
@@ -36,7 +36,6 @@ private:
 
 typedef void (Engraver::*Engraver_method) (void);
 
-void recurse_down_engravers (Context * c, Engraver_method ptr, bool context_first);
 void engraver_each (SCM list, Engraver_method method);
 
 #endif // ENGRAVERGROUP_HH
diff --git a/lily/include/engraver.hh b/lily/include/engraver.hh
index b7dcefb83f..76f2a122bf 100644
--- a/lily/include/engraver.hh
+++ b/lily/include/engraver.hh
@@ -47,8 +47,6 @@ protected:
     */
   virtual void announce_grob (Grob*, SCM cause);
   virtual void announce_grob (Grob_info);
-  virtual void process_music ();
-  virtual void do_announces ();
   Engraver_group_engraver*get_daddy_engraver () const;
 
 public:
diff --git a/lily/include/performer-group-performer.hh b/lily/include/performer-group-performer.hh
index a8d607526e..b7d2575f5c 100644
--- a/lily/include/performer-group-performer.hh
+++ b/lily/include/performer-group-performer.hh
@@ -28,8 +28,6 @@ private:
   void acknowledge_audio_elements ();
 };
 
-void recurse_down_performers (Context * c, Performer_method ptr,
-			       bool context_first);
 void performer_each (SCM list, Performer_method method);
 
 #endif // PERFORMER_GROUP_PERFORMER_HH
diff --git a/lily/include/performer.hh b/lily/include/performer.hh
index 2fc46d3a1d..04ecba2d55 100644
--- a/lily/include/performer.hh
+++ b/lily/include/performer.hh
@@ -31,8 +31,6 @@ protected:
   virtual void create_audio_elements ();
   virtual int get_tempo () const;
   virtual void play_element (Audio_element * elem );
-  virtual void process_music ();
-  virtual void do_announces ();
 };
 
 
diff --git a/lily/include/translator-group.hh b/lily/include/translator-group.hh
index 851c8f5a57..b302aefcdb 100644
--- a/lily/include/translator-group.hh
+++ b/lily/include/translator-group.hh
@@ -34,7 +34,7 @@ public:
 
 
 SCM names_to_translators (SCM namelist, Context*tg);
-void recurse_down_translators (Context * c, Translator_method ptr, bool context_first);
+void recurse_down_translators (Context * c, Translator_method ptr, Direction);
 void translator_each (SCM list, Translator_method method);
 
 
diff --git a/lily/include/translator.hh b/lily/include/translator.hh
index 3178beff9e..923cf2f639 100644
--- a/lily/include/translator.hh
+++ b/lily/include/translator.hh
@@ -61,6 +61,8 @@ public:
   virtual void stop_translation_timestep ();
   virtual void start_translation_timestep ();
   virtual void initialize () ;
+  virtual void process_music ();
+  virtual void do_announces ();
   virtual void finalize ();
 };
 
diff --git a/lily/lyric-phrasing-engraver.cc b/lily/lyric-phrasing-engraver.cc
index 3396fe1940..5c087ff18d 100644
--- a/lily/lyric-phrasing-engraver.cc
+++ b/lily/lyric-phrasing-engraver.cc
@@ -98,9 +98,9 @@ String
 Lyric_phrasing_engraver::get_voice_name_for_lyric (Context *tr)
 {
   SCM voice_context = tr->get_property ("associatedVoiceContext");
-  if (Translator *vc = unsmob_translator (voice_context))
+  if (Context *vc = unsmob_context (voice_context))
     {
-      return dynamic_cast<Context *> (vc)->id_string_;
+      return vc->id_string_;
     }
   
   SCM voice = tr->get_property ("associatedVoice");
diff --git a/lily/melisma-engraver.cc b/lily/melisma-engraver.cc
deleted file mode 100644
index f8b9a5e68b..0000000000
--- a/lily/melisma-engraver.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-/*   
-  melisma-engraver.cc --  implement Melisma_engraver
-  
-  source file of the GNU LilyPond music typesetter
-  
-  (c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-  
- */
-
-/*
-  duplicated in melisma-performer
- */
-#include "engraver.hh"
-#include "event.hh"
-#include "grob.hh"
-#include "context.hh"
-
-
-/**
-   Signal existence of melismas.
- */
-class Melisma_engraver : public Engraver
-{
-public:
-  TRANSLATOR_DECLARATIONS(Melisma_engraver);
-  bool try_music (Music *);
-};
-
-
-bool
-Melisma_engraver::try_music (Music *) 
-{
-  /*
-    This can only be melisma-playing-event.
-   */
-  return melisma_busy (this);
-}
-
-Melisma_engraver::Melisma_engraver()
-{
-}
-
-ENTER_DESCRIPTION(Melisma_engraver,
-/* descr */       "This engraver collects melisma information about ties, beams, and user settings (@code{melismaBusy}, and signals it to the @code{\addlyrics} code.  ",
-/* creats*/       "",
-/* accepts */     "melisma-playing-event",
-/* acks  */      "",
-/* reads */       "melismaBusy melismaBusyProperties slurMelismaBusy tieMelismaBusy beamMelismaBusy",
-/* write */       "");
diff --git a/lily/melisma-performer.cc b/lily/melisma-performer.cc
deleted file mode 100644
index 2ad44badf9..0000000000
--- a/lily/melisma-performer.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-
-/*   
-  melisma-performer.cc --  implement Melisma_performer
-  
-  source file of the GNU LilyPond music typesetter
-  
-  (c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-  
- */
-
-/*
-  copy of melisma-engraver - see there.
- */
-#include "performer.hh"
-#include "event.hh"
-#include "grob.hh"
-#include "translator-group.hh"
-
-/**
-   Signal existence of melismas.
- */
-class Melisma_performer : public Performer
-{
-public:
-  TRANSLATOR_DECLARATIONS(Melisma_performer);
-  bool try_music (Music *);
-};
-
-
-bool
-Melisma_performer::try_music (Music *) 
-{
-  /*
-    This can only be melisma-playing-event.
-   */
-  return melisma_busy (this);
-}
-
-Melisma_performer::Melisma_performer()
-{
-}
-
-ENTER_DESCRIPTION(Melisma_performer,
-/* descr */       "This performer collects melisma information about ties, beams, and user settings (@code{melismaBusy}, and signals it to the @code{\addlyrics} code.  ",
-/* creats*/       "",
-/* accepts */     "melisma-playing-event",
-/* acks  */      "",
-/* reads */       "melismaBusy melismaBusyProperties slurMelismaBusy tieMelismaBusy beamMelismaBusy",
-/* write */       "");
diff --git a/lily/melisma-translator.cc b/lily/melisma-translator.cc
new file mode 100644
index 0000000000..6bcdd216d8
--- /dev/null
+++ b/lily/melisma-translator.cc
@@ -0,0 +1,81 @@
+/*   
+  melisma-engraver.cc --  implement Melisma_engraver
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+/*
+  duplicated in melisma-performer
+ */
+#include "engraver.hh"
+#include "event.hh"
+#include "grob.hh"
+#include "context.hh"
+
+
+/**
+   Signal existence of melismas.
+ */
+class Melisma_translator : public Translator
+{
+public:
+  TRANSLATOR_DECLARATIONS(Melisma_translator);
+protected:
+  virtual bool try_music (Music *);
+  virtual void process_music ();
+  virtual void start_translation_timestep ();
+  Music * event_;
+};
+
+
+bool
+Melisma_translator::try_music (Music *m) 
+{
+  if (m->is_mus_type ("melisma-playing-event"))
+    {
+      return melisma_busy (this);
+    }
+  else if (m->is_mus_type ("melisma-span-event"))
+    {
+      event_ = m;
+      return true;
+    }
+
+  return false;
+}
+
+void
+Melisma_translator::process_music ()
+{
+  if (event_)
+    {
+      SCM sd = event_->get_mus_property ("span-direction");
+      Direction d = to_dir (sd);
+      if (d == START)
+	daddy_context_->set_property ("melismaBusy", SCM_BOOL_T);
+      else
+	daddy_context_->unset_property (ly_symbol2scm ("melismaBusy"));
+    }
+      
+}
+
+void
+Melisma_translator::start_translation_timestep ()
+{
+  event_ =0;
+}
+  
+Melisma_translator::Melisma_translator()
+{
+}
+
+ENTER_DESCRIPTION(Melisma_translator,
+/* descr */       "This translator collects melisma information about ties, beams, and user settings (@code{melismaBusy}, and signals it to the @code{\addlyrics} code.  ",
+/* creats*/       "",
+/* accepts */     "melisma-playing-event melisma-span-event",
+/* acks  */      "",
+/* reads */       "melismaBusy melismaBusyProperties slurMelismaBusy tieMelismaBusy beamMelismaBusy",
+/* write */       "");
diff --git a/lily/music-output-def.cc b/lily/music-output-def.cc
index e1f86f7387..ab651a45c7 100644
--- a/lily/music-output-def.cc
+++ b/lily/music-output-def.cc
@@ -25,9 +25,9 @@ Music_output_def::Music_output_def ()
   translator_tab_ = new Scheme_hash_table;
   scope_ = SCM_EOL;
   smobify_self ();
-  scm_gc_unprotect_object (translator_tab_->self_scm ());
 
-  scope_ =   ly_make_anonymous_module();
+  scm_gc_unprotect_object (translator_tab_->self_scm ());
+  scope_ = ly_make_anonymous_module();
 }
 
 Music_output_def::~Music_output_def ()
@@ -37,11 +37,11 @@ Music_output_def::~Music_output_def ()
 Music_output_def::Music_output_def (Music_output_def const &s)
 {
   scope_ = SCM_EOL;
-  translator_tab_ = new Scheme_hash_table (*s.translator_tab_);
-
+  translator_tab_ = 0;
   scaled_fonts_ = SCM_EOL;
-
   smobify_self ();
+
+  translator_tab_ =   new Scheme_hash_table (*s.translator_tab_);  
   scm_gc_unprotect_object (translator_tab_->self_scm ());  
   
   scaled_fonts_ = scm_list_copy (s.scaled_fonts_);  
@@ -59,7 +59,8 @@ SCM
 Music_output_def::mark_smob (SCM m)
 {
   Music_output_def * mo = (Music_output_def*) SCM_CELL_WORD_1 (m);
-  scm_gc_mark (mo->translator_tab_->self_scm ());
+  if (mo->translator_tab_)
+    scm_gc_mark (mo->translator_tab_->self_scm ());
   scm_gc_mark (mo->scope_);
 
   return mo->scaled_fonts_;
diff --git a/lily/paper-def.cc b/lily/paper-def.cc
index 27de71fa44..c9386c2e41 100644
--- a/lily/paper-def.cc
+++ b/lily/paper-def.cc
@@ -117,8 +117,9 @@ Paper_def::find_font (SCM fn, Real m)
       f = all_fonts_global->find_font (ly_scm2string (fn));
       SCM val = Scaled_font_metric::make_scaled_font_metric (f, m);
       scaled_fonts_ = scm_acons (key, val, scaled_fonts_);
-      f = unsmob_metrics (val);
       scm_gc_unprotect_object (val);
+      
+      f = unsmob_metrics (val);
     }
 
   return f;
diff --git a/lily/performer-group-performer.cc b/lily/performer-group-performer.cc
index 9002977250..6844cce7a6 100644
--- a/lily/performer-group-performer.cc
+++ b/lily/performer-group-performer.cc
@@ -71,36 +71,6 @@ Performer_group_performer::Performer_group_performer()
 {
 }
 
-/* c&p engraver-group.cc */
-void
-recurse_down_performers (Context * c, Performer_method ptr, bool context_first)
-{
-  Performer_group_performer * tg
-    = dynamic_cast<Performer_group_performer*> (unsmob_translator (c->implementation_));
-
-
-  if (!context_first)
-    {
-      performer_each (tg->get_simple_trans_list (),
-		     ptr);
-
-      (tg->*ptr) ();
-    }
-
-  for (SCM s = c->context_list_ ; gh_pair_p (s);
-       s =gh_cdr (s))
-    {
-      recurse_down_performers (unsmob_context (gh_car (s)), ptr, context_first);
-    }
-
-  if (context_first)
-    {
-      performer_each (tg->get_simple_trans_list (),
-		     ptr);
-      (tg->*ptr) ();
-    }
-}
-
 
 void
 performer_each (SCM list, Performer_method method)
diff --git a/lily/performer.cc b/lily/performer.cc
index ebf5a030fb..14a4239c1f 100644
--- a/lily/performer.cc
+++ b/lily/performer.cc
@@ -11,11 +11,6 @@
 #include "performer-group-performer.hh"
 #include "warn.hh"
 
-void
-Performer::do_announces ()
-{
-}
-
 void 
 Performer::play_element (Audio_element* p) 
 { 
@@ -53,9 +48,3 @@ Performer::announce_element (Audio_element_info i)
     i.origin_trans_= this;
   get_daddy_performer ()->announce_element (i);
 }
-
-void
-Performer::process_music ()
-{
-  
-}
diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc
index 55dd5ad32e..c66301c608 100644
--- a/lily/score-engraver.cc
+++ b/lily/score-engraver.cc
@@ -80,7 +80,7 @@ Score_engraver::prepare (Moment m)
   command_column_->set_grob_property ("when", w);
   musical_column_->set_grob_property ("when", w);
   
-  recurse_down_translators (daddy_context_, &Translator::start_translation_timestep, false);
+  recurse_down_translators (daddy_context_, &Translator::start_translation_timestep, DOWN);
 }
 
 void
@@ -89,7 +89,7 @@ Score_engraver::finish ()
   if ((breaks_%8))
     progress_indication ("[" + to_string (breaks_) + "]");
 
-  recurse_down_translators (daddy_context_, &Translator::finalize, true);
+  recurse_down_translators (daddy_context_, &Translator::finalize, UP);
 }
 
 /*
@@ -139,11 +139,11 @@ Score_engraver::one_time_step ()
 {
   if (!to_boolean (get_property ("skipTypesetting")))
     {
-      recurse_down_engravers (daddy_context_, &Engraver::process_music, true);
-      recurse_down_engravers (daddy_context_, &Engraver::do_announces, true);
+      recurse_down_translators (daddy_context_, &Engraver::process_music, UP);
+      recurse_down_translators (daddy_context_, &Engraver::do_announces, UP);
     }
   
-  recurse_down_translators (daddy_context_, &Translator::stop_translation_timestep, true);
+  recurse_down_translators (daddy_context_, &Translator::stop_translation_timestep, UP);
 }
 
 void
diff --git a/lily/score-performer.cc b/lily/score-performer.cc
index d44a836e35..1e8cd4794e 100644
--- a/lily/score-performer.cc
+++ b/lily/score-performer.cc
@@ -58,16 +58,16 @@ Score_performer::prepare (Moment m)
 {
   audio_column_ = new Audio_column (m);
   play_element (audio_column_);
-  recurse_down_translators (daddy_context_, &Translator::start_translation_timestep, true);
+  recurse_down_translators (daddy_context_, &Translator::start_translation_timestep, UP);
 }
 
 
 void 
 Score_performer::one_time_step ()
 {
-  recurse_down_performers (daddy_context_, &Performer::process_music, false);
-  recurse_down_performers (daddy_context_, &Performer::do_announces, true);
-  recurse_down_translators (daddy_context_, &Translator::stop_translation_timestep, false);
+  recurse_down_translators (daddy_context_, &Performer::process_music, UP);
+  recurse_down_translators (daddy_context_, &Performer::do_announces, UP);
+  recurse_down_translators (daddy_context_, &Translator::stop_translation_timestep, UP);
 }
 
 int
diff --git a/lily/translator-group.cc b/lily/translator-group.cc
index 10806b34c0..f26842df02 100644
--- a/lily/translator-group.cc
+++ b/lily/translator-group.cc
@@ -128,13 +128,16 @@ Translator_group::get_simple_trans_list ()
 
 
 void
-recurse_down_translators (Context * c, Translator_method ptr, bool context_first)
+recurse_down_translators (Context * c, Translator_method ptr, Direction dir)
 {
   Translator_group * tg
     = dynamic_cast<Translator_group*> (unsmob_translator (c->implementation_));
 
 
-  if (!context_first)
+  /*
+    Top down: 
+   */
+  if (dir == DOWN)
     {
       translator_each (tg->get_simple_trans_list (),
 			  ptr);
@@ -145,10 +148,10 @@ recurse_down_translators (Context * c, Translator_method ptr, bool context_first
   for (SCM s = c->context_list_ ; gh_pair_p (s);
        s =gh_cdr (s))
     {
-      recurse_down_translators (unsmob_context (gh_car (s)), ptr, context_first);
+      recurse_down_translators (unsmob_context (gh_car (s)), ptr, dir);
     }
 
-  if (context_first)
+  if (dir == UP)
     {
       translator_each (tg->get_simple_trans_list (),
 		     ptr);
diff --git a/lily/translator.cc b/lily/translator.cc
index ee0709fbe1..62b5a6c450 100644
--- a/lily/translator.cc
+++ b/lily/translator.cc
@@ -30,6 +30,17 @@ Translator::init ()
   smobify_self ();
 }
 
+void
+Translator::do_announces ()
+{
+}
+
+void
+Translator::process_music ()
+{
+  
+}
+
 Translator::Translator ()
 {
   init ();
diff --git a/ly/declarations-init.ly b/ly/declarations-init.ly
index 0f55ad98e5..736fef3a87 100644
--- a/ly/declarations-init.ly
+++ b/ly/declarations-init.ly
@@ -32,9 +32,8 @@ noBreak = #(make-event-chord (list (make-penalty-music 10001)))
 
 \include "scale-definitions-init.ly"
 
-melisma = \set Staff.melismaBusy = ##t
-melismaEnd = \set Staff.melismaBusy = ##f
-
+melisma = #(make-span-event 'ManualMelismaEvent START)
+melismaEnd = #(make-span-event 'ManualMelismaEvent STOP)
 
 \include "grace-init.ly"
 
diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly
index 2cc1c0b46b..4581cd6115 100644
--- a/ly/engraver-init.ly
+++ b/ly/engraver-init.ly
@@ -188,7 +188,7 @@
     \consists "Chord_tremolo_engraver"
     \consists "Percent_repeat_engraver"
     \consists "Slash_repeat_engraver"
-    \consists "Melisma_engraver"
+    \consists "Melisma_translator"
     \consists "Part_combine_engraver"
 
 %{
@@ -333,6 +333,7 @@ printing of a single line of lyrics.  "
     \consists "Stanza_number_engraver"
     \consists "Vocal_name_engraver"
     \consists "Skip_event_swallow_translator"
+    \consists "Font_size_engraver"
     \override SeparationItem #'padding = #0.2
 }
 
diff --git a/ly/performer-init.ly b/ly/performer-init.ly
index 26b04348f6..09ae94969b 100644
--- a/ly/performer-init.ly
+++ b/ly/performer-init.ly
@@ -46,7 +46,7 @@
     \consists "Note_performer"
     \consists "Beam_performer"
     \consists "Slur_performer"
-    \consists "Melisma_performer"
+    \consists "Melisma_translator"
 }
 
 \translator {
diff --git a/scm/define-music-types.scm b/scm/define-music-types.scm
index a85ea9bc11..178efa4743 100644
--- a/scm/define-music-types.scm
+++ b/scm/define-music-types.scm
@@ -250,10 +250,18 @@ e.g. @code{\\mark \"A\"}.")
 	))
     (MelismaPlayingEvent
      . (
-	(description .  "Used internally to signal melismas")
+	(description .  "Used internally to signal melismas.")
 	(internal-class-name . "Event")
 	(types . (general-music melisma-playing-event event))
 	))
+    (ManualMelismaEvent
+     . (
+	(description .  "Start or stop a melisma.
+
+Syntax:@code{c4\\melisma d\\melismaEnd}.")
+	(internal-class-name . "Event")
+	(types . (general-music melisma-span-event event))
+	))
     
     (MultiMeasureRestEvent
      . (