From 3581d92bb1aa0075b2dc721d304666589c2e5d02 Mon Sep 17 00:00:00 2001
From: fred <fred>
Date: Tue, 26 Mar 2002 22:24:22 +0000
Subject: [PATCH] lilypond-1.1.65

---
 Documentation/man/lilypond.yo              |   3 +
 NEWS                                       |  27 +++-
 input/test/abbreviation-beam.sly           |   6 +
 input/test/hara-kiri-switch.ly             |  52 +++++++
 lily/abbreviation-beam-engraver.cc         | 157 +++++++++++++++------
 lily/abbreviation-beam.cc                  |   2 -
 lily/auto-beam-engraver.cc                 |  72 +++++-----
 lily/beam.cc                               |  45 ++++--
 lily/include/abbreviation-beam-engraver.hh |   6 +-
 lily/include/musical-request.hh            |  13 ++
 lily/include/my-lily-parser.hh             |   2 +
 lily/key-engraver.cc                       |   2 +-
 lily/musical-request.cc                    |  12 ++
 lily/my-lily-parser.cc                     |  10 +-
 lily/parser.yy                             |  39 ++++-
 lily/slur-engraver.cc                      |  19 ++-
 ly/declarations.ly                         |   3 +-
 ly/engraver.ly                             |   2 +-
 ly/params.ly                               |  57 ++++++--
 ly/property.ly                             |   4 +-
 ly/spanners.ly                             |   7 +
 ly/textscripts.ly                          |  28 ++++
 mutopia/Coriolan/viola-1.ly                |   1 -
 mutopia/Coriolan/viola-2.ly                |   8 +-
 scripts/convert-mudela.py                  |  12 ++
 25 files changed, 466 insertions(+), 123 deletions(-)
 create mode 100644 input/test/abbreviation-beam.sly
 create mode 100644 input/test/hara-kiri-switch.ly
 create mode 100644 ly/spanners.ly
 create mode 100644 ly/textscripts.ly

diff --git a/Documentation/man/lilypond.yo b/Documentation/man/lilypond.yo
index c26ca52f0f..ed4c14180c 100644
--- a/Documentation/man/lilypond.yo
+++ b/Documentation/man/lilypond.yo
@@ -24,6 +24,9 @@ includefile(../BLURB.in)
 
 manpageoptions()
 description(
+dit(-f,--format=)
+	Output format for sheet music. Choices are tex (for TeX
+	output), ps (for PostScript) and scm (for GUILE)
 dit(-I,--include=)
     add file(FILE) to the search path for input files.
 dit(-m,--midi)
diff --git a/NEWS b/NEWS
index 8936143ef0..8ac7d5e991 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,30 @@
+pl 64.jcn1
+	- resurrected abbreviation beam
+	- coriolan fixes
+
+pl 64.hwn1
+	- reference-manual updates.
+	- slurdash -> slurDash, keyoctaviation -> keyOctaviation
+
+pl 64.uu1
+	- \property forceHorizontalShift
+	- bf: denneboom.ly
+	- warn if translator switching  to self.
+	- warn if brace at end of lyric syllable.
+	- bf: Repeated_music::alternatives_length_mom ()
+	- \property automaticMelismas: if slur then melisma
+	- \property noVoltaBraces
+	- bf: star-spangled-banner
+
+pl 63.lu2
+	- very tight: hinterfleisch -> 0 : input/bugs/spacing-very-tight.ly
+	- bfs: neutral beam and tie directions (daar was ik al bang voor:-)
+	- bf: abe: may beam over skip, as long as note present too
+	- bf: scsii-prelude: added slurs using skips
+
+*********
 pl 63.uu1
-	- mutopia updates  courtesy Peter Chubb
+	- mutopia updates courtesy Peter Chubb
 	- Don't make Time_scaled_music for c4*2/3 entry, only do the
 time compression.  Should cure spurious Tuplet_brace/spanner warnings.
 
diff --git a/input/test/abbreviation-beam.sly b/input/test/abbreviation-beam.sly
new file mode 100644
index 0000000000..88cc140de0
--- /dev/null
+++ b/input/test/abbreviation-beam.sly
@@ -0,0 +1,6 @@
+[:16 c'1 d]
+[:8 c2 d]
+[:16 c4 d]
+[:32 c16 d]
+[:32 c16 d]
+[:16 c8 d]
diff --git a/input/test/hara-kiri-switch.ly b/input/test/hara-kiri-switch.ly
new file mode 100644
index 0000000000..0009eb1e42
--- /dev/null
+++ b/input/test/hara-kiri-switch.ly
@@ -0,0 +1,52 @@
+\version "1.1.64";
+
+voiceOne = \notes \relative c'' {
+	a1 a a
+	a2 a2
+	a2 a8 a a a
+}
+
+staffOne = \context Staff = one <
+	\notes \context Voice=one < 
+		\voiceOne
+	>
+>
+
+voiceTwo = \notes \relative c' {
+	% we must have a Thread context before we can switch staffs
+	% in this case, the notes before the switching  will do that 
+	% implicitely
+	\context Thread
+
+	R1*3
+	c2 c2
+	\translator Staff=one
+	\translator Voice=one
+	c2
+	c8 c c c
+}
+
+staffTwo = \context Staff = two <
+	% notes must go to Staff context: we want to switch Staff translators
+	%\notes \context Voice=one < 
+		\voiceTwo
+	%>
+>
+
+grandstaff = \context GrandStaff = one <
+	\staffOne
+	\staffTwo
+>
+
+\score{
+	\grandstaff
+	\paper{
+		linewidth=80.0\mm;
+		castingalgorithm = \Wordwrap;
+		\translator { \VoiceContext beamAuto=0; }
+		\translator { \HaraKiriStaffContext }
+		\translator { \OrchestralScoreContext skipBars = 1; }
+	}
+}
+
+
diff --git a/lily/abbreviation-beam-engraver.cc b/lily/abbreviation-beam-engraver.cc
index 2313f13a44..d264169f9f 100644
--- a/lily/abbreviation-beam-engraver.cc
+++ b/lily/abbreviation-beam-engraver.cc
@@ -1,5 +1,3 @@
-#if 0
-
 /*
   abbreviation-beam-engraver.cc -- implement Abbreviation_beam_engraver
 
@@ -16,84 +14,151 @@
 #include "abbreviation-beam.hh"
 #include "musical-request.hh"
 #include "misc.hh"
+#include "warn.hh"
+#include "score-engraver.hh"
 
-
-ADD_THIS_TRANSLATOR(Abbreviation_beam_engraver);
+ADD_THIS_TRANSLATOR (Abbreviation_beam_engraver);
 
 Abbreviation_beam_engraver::Abbreviation_beam_engraver ()
 {
-  span_reqs_drul_[LEFT] = span_reqs_drul_[RIGHT] = 0;
+  reqs_drul_[LEFT] = reqs_drul_[RIGHT] = 0;
   abeam_p_ = 0;
+  finished_abeam_p_ = 0;
+  prev_start_req_ = 0;
 }
 
 bool
-Abbreviation_beam_engraver::do_try_music (Music*r)
+Abbreviation_beam_engraver::do_try_music (Music* m)
+{
+  if (Abbreviation_beam_req* b = dynamic_cast <Abbreviation_beam_req *> (m))
+    {
+      Direction d = b->span_dir_;
+      if (reqs_drul_[d] && !reqs_drul_[d]->equal_b (b))
+	return false;
+
+      if ((d == STOP) && !abeam_p_)
+	{
+	  m->warning (_ ("No abbreviation beam to end"));
+	  return false;
+	}
+
+      reqs_drul_[d] = b;
+      return true;
+    }
+
+  return false;
+}
+
+void
+Abbreviation_beam_engraver::do_process_requests ()
 {
-  Abbreviation_beam_req * b = dynamic_cast <Abbreviation_beam_req *> (r);
+  if (reqs_drul_[STOP])
+    {
+      if (!abeam_p_)
+	reqs_drul_[STOP]->warning (_("No abbreviation beam to end"));
+      prev_start_req_ = 0;
+      finished_abeam_p_ = abeam_p_;
+      abeam_p_ = 0;
+    }
 
-  if (!b)
-    return false;
+  if (abeam_p_)
+    {
+      Score_engraver * e = 0;
+      Translator * t  =  daddy_grav_l ();
+      for (; !e && t;  t = t->daddy_trans_l_)
+	{
+	  e = dynamic_cast<Score_engraver*> (t);
+	}
+      
+      if (!e)
+	programming_error ("No score engraver!");
+      else
+	e->forbid_breaks ();
+    }
 
-  if (bool (abeam_p_) == bool (b->span_dir_ == START))
-    return false;
+  if (reqs_drul_[START])
+    {
+      if (abeam_p_)
+	{
+	  reqs_drul_[START]->warning (_ ("Already have an abbreviation beam"));
+	  return;
+	}
 
-  Direction d = (!abeam_p_) ? LEFT : RIGHT;
-  if (span_reqs_drul_[d] && !span_reqs_drul_[d]->equal_b (b))
-    return false;
+      prev_start_req_ = reqs_drul_[START];
 
-  span_reqs_drul_[d] = b;
-  return true;
+      abeam_p_ = new Abbreviation_beam;
+      announce_element (Score_element_info (abeam_p_, reqs_drul_[LEFT]));
+  }
 }
 
 void
-Abbreviation_beam_engraver::do_process_requests ()
+Abbreviation_beam_engraver::do_post_move_processing ()
 {
-  if (!abeam_p_ && span_reqs_drul_[LEFT]) {
-    abeam_p_ = new Abbreviation_beam;
-    announce_element (Score_element_info (abeam_p_, span_reqs_drul_[LEFT]));
-  }
+  reqs_drul_ [START] = 0;
 }
 
 void
 Abbreviation_beam_engraver::do_pre_move_processing ()
 {
-  if (abeam_p_ && span_reqs_drul_[RIGHT]) {
-    typeset_element (abeam_p_);
-    abeam_p_ = 0;
+  typeset_beam ();
+}
 
-    span_reqs_drul_[RIGHT] =
-      span_reqs_drul_[LEFT] = 0;
-  }
+void
+Abbreviation_beam_engraver::typeset_beam ()
+{
+  if (finished_abeam_p_)
+    {
+      typeset_element (finished_abeam_p_);
+      finished_abeam_p_ = 0;
+
+      reqs_drul_[STOP] = 0;
+    }
 }
 
 void
 Abbreviation_beam_engraver::do_removal_processing ()
 {
+  typeset_beam ();
   if (abeam_p_)
     {
-      span_reqs_drul_[LEFT]->warning (_("unterminated beam"));
-      typeset_element (abeam_p_);
-      abeam_p_ = 0;
+      prev_start_req_->warning (_ ("Unfinished abbreviation beam"));
+      finished_abeam_p_ = abeam_p_;
+      typeset_beam ();
     }
 }
 
 void
 Abbreviation_beam_engraver::acknowledge_element (Score_element_info i)
 {
-  Stem* s = dynamic_cast<Stem *> (i.elem_l_);
-  if (!abeam_p_ || !s)
-    return;
-
-  int type_i = span_reqs_drul_[LEFT]->type_i_;
-  s->flag_i_ = intlog2 (type_i) - 2;
-  s->beams_i_drul_[(span_reqs_drul_[RIGHT]) ? LEFT: RIGHT] = s->flag_i_;
-
-  abeam_p_->multiple_i_ = s->flag_i_;
-  if (s->type_i () != 1) // no abbrev gaps on half note
-    s->set_elt_property (beam_gap_scm_sym,
-			 gh_int2scm(s->flag_i_ - ((s->type_i () >? 2) - 2)));
-
-  abeam_p_->add_stem (s);
-}
-
+  if (abeam_p_)
+    {
+      if (Stem* s = dynamic_cast<Stem *> (i.elem_l_))
+	{
+	  int type_i = prev_start_req_->type_i_;
+	  s->flag_i_ = intlog2 (type_i) - 2;
+
+	  s->beams_i_drul_[LEFT] = s->flag_i_;
+	  s->beams_i_drul_[RIGHT] = s->flag_i_;
+	  
+	  abeam_p_->multiple_i_ = s->flag_i_;
+	  /*
+	    abbrev gaps on all but half note
+	  */
+#if 0
+	  if (s->type_i () != 1)
+	    {
+	      int gap_i =s->flag_i_ - ((s->type_i () >? 2) - 2);
+	      s->set_elt_property (beam_gap_scm_sym, gh_int2scm(gap_i));
+	    }
+#else
+	  if (s->type_i () != 1)
+	    {
+	      int gap_i =s->flag_i_ - ((s->type_i () >? 2) - 2);
+	      abeam_p_->set_elt_property (beam_gap_scm_sym, gh_int2scm(gap_i));
+	    }
 #endif
+	  
+	  abeam_p_->add_stem (s);
+	}
+    }
+}
diff --git a/lily/abbreviation-beam.cc b/lily/abbreviation-beam.cc
index cc10968278..b0307f2e6f 100644
--- a/lily/abbreviation-beam.cc
+++ b/lily/abbreviation-beam.cc
@@ -1,4 +1,3 @@
-#if 0
 /*
   abbreviation-beam.cc -- implement Abbreviation_beam
 
@@ -59,4 +58,3 @@ Abbreviation_beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
    */
   return Beam::stem_beams (here, next, prev);
 }
-#endif
diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc
index 672da02f63..c539e883c6 100644
--- a/lily/auto-beam-engraver.cc
+++ b/lily/auto-beam-engraver.cc
@@ -11,6 +11,7 @@
 #include "musical-request.hh"
 #include "bar.hh"
 #include "beam.hh"
+#include "abbreviation-beam.hh"
 #include "rest.hh"
 #include "stem.hh"
 #include "debug.hh"
@@ -37,18 +38,8 @@ Auto_beam_engraver::do_creation_processing ()
 }
 
 bool
-Auto_beam_engraver::do_try_music (Music* m) 
+Auto_beam_engraver::do_try_music (Music*) 
 {
-  /*
-    Mag dit?  Nu word-i toch maar geswallowed, en
-    komt er dus ook geen announce...
-   */
-  if (Skip_req* s = dynamic_cast <Skip_req*> (m))
-    {
-      if (stem_l_arr_p_)
-	end_beam ();
-      return true;
-    }
   return false;
 } 
 
@@ -197,8 +188,18 @@ Auto_beam_engraver::create_beam_p ()
   Beam* beam_p = new Beam;
 
   for (int i = 0; i < stem_l_arr_p_->size (); i++)
-    beam_p->add_stem ((*stem_l_arr_p_)[i]);
-
+    {
+      /*
+	watch out for stem tremolos and abbreviation beams
+       */
+      if ((*stem_l_arr_p_)[i]->beam_l_)
+	{
+	  delete beam_p;
+	  return 0;
+	}
+      beam_p->add_stem ((*stem_l_arr_p_)[i]);
+    }
+  
   /* urg, copied from Beam_engraver */
   Scalar prop = get_property ("beamslopedamping", 0);
   if (prop.isnum_b ()) 
@@ -222,7 +223,8 @@ Auto_beam_engraver::end_beam ()
   else
     {
       finished_beam_p_ = create_beam_p ();
-      finished_grouping_p_ = grouping_p_;
+      if (finished_beam_p_)
+	finished_grouping_p_ = grouping_p_;
       delete stem_l_arr_p_;
       stem_l_arr_p_ = 0;
       grouping_p_ = 0;
@@ -248,6 +250,17 @@ Auto_beam_engraver::typeset_beam ()
 void
 Auto_beam_engraver::do_post_move_processing ()
 {
+  /*
+    don't beam over skips
+   */
+  if (stem_l_arr_p_)
+    {
+      Moment now = now_mom ();
+      if (extend_mom_ < now)
+	{
+	  end_beam ();
+	}
+    }
 }
 
 void
@@ -286,6 +299,10 @@ Auto_beam_engraver::acknowledge_element (Score_element_info info)
 	{
 	  junk_beam ();
 	}
+      else if (Abbreviation_beam *b = dynamic_cast<Abbreviation_beam*> (info.elem_l_))
+	{
+	  junk_beam ();
+	}
       else if (Bar *b = dynamic_cast<Bar *> (info.elem_l_))
 	{
 	  junk_beam ();
@@ -305,30 +322,15 @@ Auto_beam_engraver::acknowledge_element (Score_element_info info)
 	  return;
 	}
       
-#if 0
       /*
-	Don't (start) auto-beam over empty stems.
-	ugly check for rests!
-	--> doesn't even work: stem-dir is not set
-
-	../flower/include/drul-array.hh:26: Real & Drul_array<double>::elem<Real>(enum Direction): Assertion `d==1 || d== -1' failed.
-/home/fred/root/usr/scripts/src/out/Linux/li: line 8: 14641 Aborted                 (core dumped) lilypond $opts
-
-      */
-      if (stem_l->extent (Y_AXIS).empty_b ())
-	{
-	  if (stem_l_arr_p_)
-	    end_beam ();
-	  return;
-	}
-#else
+	Don't (start) auto-beam over empty stems; skips or rests
+	*/
       if (!stem_l->head_l_arr_.size ())
 	{
 	  if (stem_l_arr_p_)
 	    end_beam ();
 	  return;
 	}
-#endif
 
       if (stem_l->beam_l_)
 	{
@@ -337,11 +339,6 @@ Auto_beam_engraver::acknowledge_element (Score_element_info info)
 	  return ;
 	}
 	      
-      /*
-	now that we have last_add_mom_, perhaps we can (should) do away
-	with these individual junk_beams
-      */
-      
       int durlog  =rhythmic_req->duration_.durlog_i_;
       if (durlog <= 2)
 	{
@@ -371,7 +368,8 @@ Auto_beam_engraver::acknowledge_element (Score_element_info info)
 	}
       Moment now = now_mom ();
       
-      grouping_p_->add_stem (now - beam_start_moment_ + beam_start_location_, durlog - 2);
+      grouping_p_->add_stem (now - beam_start_moment_ + beam_start_location_,
+			     durlog - 2);
       stem_l_arr_p_->push (stem_l);
       last_add_mom_ = now;
       extend_mom_ = extend_mom_ >? now + rhythmic_req->length_mom ();
diff --git a/lily/beam.cc b/lily/beam.cc
index 43975b65dc..64448f2450 100644
--- a/lily/beam.cc
+++ b/lily/beam.cc
@@ -170,7 +170,6 @@ Beam::get_default_dir () const
   count[UP]  = count[DOWN] = 0;
   Direction d = DOWN;
 
-  Direction beamdir;
   for (int i=0; i <stems_.size (); i++)
     do {
       Stem *s = stems_[i];
@@ -198,28 +197,38 @@ Beam::get_default_dir () const
      If dir is not determined: up (see stem::get_default_dir ())
   */
 
+  Direction beam_dir;
+  Direction neutral_dir = (int)paper_l ()->get_var ("stem_default_neutral_direction");
+
   Dir_algorithm a = (Dir_algorithm)rint(paper_l ()->get_var ("beam_dir_algorithm"));
   switch (a)
     {
     case MAJORITY:
-      beamdir = (count[UP] >= count[DOWN]) ? UP : DOWN;
+      beam_dir = (count[UP] == count[DOWN]) ? neutral_dir 
+        : (count[UP] > count[DOWN]) ? UP : DOWN;
       break;
     case MEAN:
       // mean center distance
-      beamdir = (total[UP] >= total[DOWN]) ? UP : DOWN;
+      beam_dir = (total[UP] == total[DOWN]) ? neutral_dir
+        : (total[UP] > total[DOWN]) ? UP : DOWN;
       break;
     default:
     case MEDIAN:
       // median center distance
-      if (!count[DOWN])
-	beamdir = UP;
-      if (!count[UP])
-	beamdir = DOWN;
+      if (!count[DOWN] || !count[UP])
+        {
+	  beam_dir = (count[UP] == count[DOWN]) ? neutral_dir 
+	    : (count[UP] > count[DOWN]) ? UP : DOWN;
+	}
       else
-	beamdir = (total[UP] / count[UP] >= total[DOWN] / count[DOWN]) ? UP : DOWN;
+        {
+	  beam_dir = (total[UP] / count[UP] == total[DOWN] / count[DOWN]) 
+	    ? neutral_dir 
+	      : (total[UP] / count[UP] > total[DOWN] / count[DOWN]) ? UP : DOWN;
+	}
       break;
     }
-  return beamdir;
+  return beam_dir;
 }
 
 void
@@ -332,8 +341,11 @@ Beam::set_steminfo ()
   for (int i=0; i < stems_.size (); i++)
     {
       Stem *s = stems_[i];
+#if 0
+      // abbreviation beam needs to beam over invisible stems of wholes
       if (s->invisible_b ())
 	continue;
+#endif
 
       Stem_info info (s, multiple_i_);
       if (leftx == 0)
@@ -654,7 +666,13 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
   Molecule rightbeams;
 
   // UGH
-  Real nw_f = paper_l ()->note_width () * 0.8;
+  Real nw_f;
+  if (here->type_i ()== 1)
+    nw_f = paper_l ()->get_var ("wholewidth");
+  else if (here->type_i () == 2)
+    nw_f = paper_l ()->note_width () * 0.8;
+  else
+    nw_f = paper_l ()->get_var ("quartwidth");
 
   /* half beams extending to the left. */
   if (prev)
@@ -693,7 +711,7 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
       SCM gap = get_elt_property (beam_gap_scm_sym);
       if (gap != SCM_BOOL_F)
 	{
-	  int gap_i = gh_scm2int (gap);
+	  int gap_i = gh_scm2int (SCM_CDR (gap));
 	  int nogap = rwholebeams - gap_i;
 	  
 	  for (; j  < nogap; j++)
@@ -711,7 +729,10 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
       for (; j  < rwholebeams; j++)
 	{
 	  Molecule b (a);
-	  b.translate (Offset (gap_f, -dir_ * dy * j));
+	  if (!here->invisible_b ())
+	    b.translate (Offset (gap_f, -dir_ * dy * j));
+	  else
+	    b.translate (Offset (0, -dir_ * dy * j));
 	  rightbeams.add_molecule (b);
 	}
 
diff --git a/lily/include/abbreviation-beam-engraver.hh b/lily/include/abbreviation-beam-engraver.hh
index 6e957038e8..d3610592be 100644
--- a/lily/include/abbreviation-beam-engraver.hh
+++ b/lily/include/abbreviation-beam-engraver.hh
@@ -31,10 +31,14 @@ protected:
   virtual bool do_try_music (Music*);
   virtual void acknowledge_element (Score_element_info);
   virtual void do_pre_move_processing();
+  virtual void do_post_move_processing();
 
 private:
-  Drul_array<Abbreviation_beam_req *> span_reqs_drul_;
+  void typeset_beam ();
+  Drul_array<Abbreviation_beam_req*> reqs_drul_;
+  Abbreviation_beam_req* prev_start_req_;
   Abbreviation_beam* abeam_p_;
+  Abbreviation_beam* finished_abeam_p_;
 };
 
 #endif // ABBREVIATION_BEAM_ENGRAVER_HH
diff --git a/lily/include/musical-request.hh b/lily/include/musical-request.hh
index d3cfc3dd1e..8f380e9a04 100644
--- a/lily/include/musical-request.hh
+++ b/lily/include/musical-request.hh
@@ -166,6 +166,19 @@ class Melisma_req : public Span_req
 public:
   VIRTUAL_COPY_CONS(Music);
 };
+/** 
+ Start / stop an abbreviation beam. */
+class Abbreviation_beam_req : public Span_req  
+{
+public:
+  VIRTUAL_COPY_CONS (Music);
+
+  Abbreviation_beam_req ();
+
+  virtual void do_print () const;
+
+  int type_i_;
+};
 
 /**
    Helping req to signal start of a melisma from within a context, and
diff --git a/lily/include/my-lily-parser.hh b/lily/include/my-lily-parser.hh
index ddd55c7517..301eb358ee 100644
--- a/lily/include/my-lily-parser.hh
+++ b/lily/include/my-lily-parser.hh
@@ -39,6 +39,7 @@ public:
   Duration default_duration_;
   Musical_pitch default_pitch_;
   Scope *default_header_p_;
+  int abbrev_beam_type_i_;
   bool first_b_;
   int fatal_error_i_;
   Sources * source_l_;
@@ -70,6 +71,7 @@ private:
   Simultaneous_music* get_rest_element (String, Duration *);
   Simultaneous_music* get_word_element (String, Duration*);
   String notename_str (Melodic_req* melodic);
+  void set_abbrev_beam (int type_i);
   void set_last_duration (Duration const *);
   void set_last_pitch (Musical_pitch const *);
   friend int yyparse (void*);
diff --git a/lily/key-engraver.cc b/lily/key-engraver.cc
index 50b137ab89..eff74dbb29 100644
--- a/lily/key-engraver.cc
+++ b/lily/key-engraver.cc
@@ -126,7 +126,7 @@ Key_engraver::read_req (Key_change_req const * r)
 {
   old_accidental_idx_arr_ = accidental_idx_arr_;
   key_.clear ();
-  Scalar prop = get_property ("keyoctaviation", 0);
+  Scalar prop = get_property ("keyOctaviation", 0);
   if (prop.length_i () > 0)
     {
       key_.multi_octave_b_ = ! prop.to_bool ();
diff --git a/lily/musical-request.cc b/lily/musical-request.cc
index 00faa6f0f4..c4d8efa4fe 100644
--- a/lily/musical-request.cc
+++ b/lily/musical-request.cc
@@ -159,6 +159,18 @@ Span_req::Span_req ()
   span_dir_ = CENTER;
 }
 
+Abbreviation_beam_req::Abbreviation_beam_req ()
+{
+  type_i_ = 0;
+}
+
+void
+Abbreviation_beam_req::do_print () const
+{
+#ifndef NPRINT
+  DOUT << type_i_;
+#endif
+}
 
 void
 Text_script_req::do_print () const
diff --git a/lily/my-lily-parser.cc b/lily/my-lily-parser.cc
index 46f09be711..61f52df13f 100644
--- a/lily/my-lily-parser.cc
+++ b/lily/my-lily-parser.cc
@@ -27,6 +27,7 @@ My_lily_parser::My_lily_parser (Sources * source_l)
   first_b_ = true;
   source_l_ = source_l;
   lexer_p_ = 0;
+  abbrev_beam_type_i_ = 0;
   default_duration_.durlog_i_ = 2;
   default_pitch_ = Musical_pitch (5*7, 0);
   error_level_i_ = 0;
@@ -102,6 +103,12 @@ My_lily_parser::set_last_duration (Duration const *d)
   default_duration_ = *d;
 }
 
+void
+My_lily_parser::set_abbrev_beam (int type_i)
+{
+  abbrev_beam_type_i_ = type_i;
+}
+
 void
 My_lily_parser::set_last_pitch (Musical_pitch const* p)
 {
@@ -189,8 +196,7 @@ My_lily_parser::pop_spot()
 Input
 My_lily_parser::here_input() const
 {
-  Source_file * f_l= lexer_p_->source_file_l();
-  return Input (f_l, here_ch_C());
+  return  lexer_p_->here_input ();
 }
 
 Paper_def*
diff --git a/lily/parser.yy b/lily/parser.yy
index bcbcf0cf10..7a6189007b 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -923,11 +923,35 @@ abbrev_command_req:
 		b->span_type_str_ = "beam";
 		$$ =b;
 	}
+	| '[' ':' unsigned {
+		if (!Duration::duration_type_b ($3))
+		  THIS->parser_error (_f ("not a duration: %d", $3));
+		else if ($3 < 8)
+		  THIS->parser_error (_ ("can't abbreviate"));
+		else
+		  THIS->set_abbrev_beam ($3);
+
+		Abbreviation_beam_req* a = new Abbreviation_beam_req;
+		a->span_dir_ = START;
+		a->type_i_ = THIS->abbrev_beam_type_i_;
+		$$=a;
+	}
 	| ']'		{
-		Span_req*b= new Span_req;
-		b->span_dir_ = STOP;
-		b->span_type_str_ = "beam";
-		$$ = b;
+		if (!THIS->abbrev_beam_type_i_)
+		  {
+		     Span_req*b= new Span_req;
+		     b->span_dir_ = STOP;
+		     b->span_type_str_ = "beam";
+		     $$ = b;
+		   }
+		else
+		  {
+		    Abbreviation_beam_req* a = new Abbreviation_beam_req;
+		    a->span_dir_ = STOP;
+		    a->type_i_ = THIS->abbrev_beam_type_i_;
+		    THIS->set_abbrev_beam (0);
+		    $$ = a;
+		  }
 	}
 	| BREATHE {
 		$$ = new Breathing_sign_req;
@@ -1355,6 +1379,13 @@ simple_element:
 		delete $1;
 		n->duration_ = *$4;
 		delete $4;
+		if (THIS->abbrev_beam_type_i_)
+		  {
+		    if (n->duration_.plet_b ())
+		      THIS->parser_error (_ ("can't abbreviate tuplet"));
+		    else
+		      n->duration_.set_plet (1, 2);
+		  }
 		n->cautionary_b_ = $3 % 2;
 		n->forceacc_b_ = $2 % 2 || n->cautionary_b_;
 
diff --git a/lily/slur-engraver.cc b/lily/slur-engraver.cc
index d2464fc5a7..b97a0de7b7 100644
--- a/lily/slur-engraver.cc
+++ b/lily/slur-engraver.cc
@@ -10,6 +10,7 @@
 #include "slur.hh"
 #include "debug.hh"
 #include "note-column.hh"
+#include "translator-group.hh"
 
 bool
 Slur_engraver::do_try_music (Music *req_l)
@@ -19,11 +20,23 @@ Slur_engraver::do_try_music (Music *req_l)
       if (sl->span_type_str_ != "slur")
 	return false;
       new_slur_req_l_arr_.push (sl);
+
       return true;
     }
   return false;
 }
 
+void
+Slur_engraver::set_melisma (bool m)
+{
+    Translator_group *where = daddy_trans_l_;
+    get_property ("melismaBusy", &where);
+    if (!where)
+      where = daddy_trans_l_;
+    
+    daddy_trans_l_->set_property ("melismaBusy", m ? "1" :"0");
+}
+
 void
 Slur_engraver::acknowledge_element (Score_element_info info)
 {
@@ -76,7 +89,7 @@ Slur_engraver::do_process_requests()
 	  // push a new slur onto stack.
 	  //(use temp. array to wait for all slur STOPs)
 	  Slur * s_p =new Slur;
-	  Scalar prop = get_property ("slurdash", 0);
+	  Scalar prop = get_property ("slurDash", 0);
 	  if (prop.isnum_b ()) 
 	    s_p->set_elt_property (dashed_scm_sym, gh_int2scm(prop));
 
@@ -113,6 +126,10 @@ void
 Slur_engraver::do_post_move_processing()
 {
   new_slur_req_l_arr_.clear();
+  if (get_property ("automaticMelismas",0).to_bool ())
+    {
+      set_melisma (slur_l_stack_.size ());
+    }
 }
 
 
diff --git a/ly/declarations.ly b/ly/declarations.ly
index 4e5d37d751..837777d921 100644
--- a/ly/declarations.ly
+++ b/ly/declarations.ly
@@ -48,7 +48,8 @@ papersize = "a4"
 % ugh
 \include "midi.ly"
 
-\include "dynamic.ly"
+\include "textscripts.ly"
+\include "spanners.ly"
 
 \include "property.ly"
 
diff --git a/ly/engraver.ly b/ly/engraver.ly
index 7cca986936..d8cd95439b 100644
--- a/ly/engraver.ly
+++ b/ly/engraver.ly
@@ -95,7 +95,7 @@ VoiceContext = \translator {
 	beamAuto = "1";
 	\consists "Auto_beam_engraver";
 	\include "auto-beam-settings.ly";
-%	\consists "Abbreviation_beam_engraver";
+	\consists "Abbreviation_beam_engraver";
 %	\consists "Multi_measure_rest_engraver";
 
 	% ugh.  Order matters here.
diff --git a/ly/params.ly b/ly/params.ly
index 033f1c9a3f..1189cd97aa 100644
--- a/ly/params.ly
+++ b/ly/params.ly
@@ -22,13 +22,26 @@ interbeam4 = (3.0 * \interline - \beam_thickness) / 3.0;
 % poor man's array size
 stem_max = 3.0;
 
-% stem stuff measured in staff positions.
+%{ Specify length of stems for notes in the staff
+that don't have beams. 
+ Measured in staff positions.
+%}
 stem_length0 = 7.;
 stem_length1 = 5.;
 stem_length2 = 4.;
 stem_length3 = 3.;
 
-%
+%{
+The space taken by a note is determined by the formula 
+
+arithmetic_multiplier * ( c + log2 (time) ))
+
+where code(time) is the amount of time a note occupies.  The value
+of code(c) is chosen such that the smallest space within a measure is
+arithmetic_basicspace.  The smallest space is the one following the
+shortest note in the measure.  Typically arithmetic_basicspace is set
+to the width of a quarter note head.
+%}
 arithmetic_basicspace = 2.;
 arithmetic_multiplier = 0.9 * \quartwidth ;
 
@@ -54,10 +67,12 @@ grace_minimum_stem_length1 = \minimum_stem_length1 * \grace_factor;
 grace_minimum_stem_length2 = \minimum_stem_length2 * \grace_factor;
 grace_minimum_stem_length3 = \minimum_stem_length3 * \grace_factor;
 
-% stems in unnatural (forced) direction should be shortened,
-% according to [Roush & Gourlay].  Their suggestion to knock off
-% a whole staffspace seems a bit drastical: we'll do half.
-%
+%{
+  stems in unnatural (forced) direction should be shortened,
+  according to [Roush & Gourlay].  Their suggestion to knock off
+  a whole staffspace seems a bit drastical: we'll do half.
+%}
+
 forced_stem_shorten0 = 1.0;
 forced_stem_shorten1 = \forced_stem_shorten0;
 forced_stem_shorten2 = \forced_stem_shorten1;
@@ -82,6 +97,15 @@ UP = 1.0;
 MAJORITY = 2.0;
 MEAN = 3.0;
 MEDIAN = 4.0;
+
+%{
+dit(code(beam_dir_algorithm)) Specify algorithm for determining
+whether beams go up or down.  It is real valued.  If set to 2.0 then
+majority selection is used.  If set to 3.0, then mean selection is
+used based on the mean center distance.  If set to 4.0 then median
+selection is used, based on the median center distance.
+%}
+
 % [Ross]: majority
 beam_dir_algorithm = \MAJORITY;
 
@@ -91,12 +115,21 @@ beam_lengthened = 0.2 * \interline;
 % and slope is running away steeper than
 beam_steep_slope = 0.2 / 1.0;
 
+%{
+dit(code(slur_x_gap)) Horizontal space between note and slur.  Set to
+code(\interline / 5) by default.  
+
+%}
 % OSU: suggested gap = ss / 5;
 slur_x_gap = \interline / 5.0;
 slur_y_gap = 0.25 * \interline;
 slur_y_free = 0.75 * \interline;
 slur_x_minimum = 3.0 * \interline;
 
+%{
+Like beams, slurs often aren't as steep as the notes they encompass.
+This sets the amount of damping.
+%}
 % slope damping: keep dy/dx < slur_slope_damping
 slur_slope_damping = 0.3;
 slur_interstaff_slope_damping = 0.6;
@@ -122,9 +155,17 @@ tie_staffspace_length = 4.0 * \interline;
 % ugh: rename to bow (in bezier.cc and fonts.doc too...)
 % slur_thickness = 1.8 * \staffline;
 slur_thickness = 1.4 * \staffline;
+
+%{
+ Specifies the maximum height of slurs.
+%}
 slur_height_limit = \staffheight;
 
 
+%{
+Specifes the ratio of slur hight to slur width
+to aim for.  Default value is 0.3. 
+%}
 
 % slur_ratio = 0.3;
 % try bit flatter slurs
@@ -142,8 +183,8 @@ rulethickness = \staffline;
 
 gourlay_energybound = 100000.;
 %{
-The following bounds the number of measures
-on a line.  Decreasing it greatly reduces computation time
+Maximum number of measures per line to try when using Gourlay
+method. Decreasing this greatly reduces computation time.  
 %}
 gourlay_maxmeasures = 10.;
 castingalgorithm = \Gourlay;
diff --git a/ly/property.ly b/ly/property.ly
index 24a6f8c066..a8a404f055 100644
--- a/ly/property.ly
+++ b/ly/property.ly
@@ -95,11 +95,11 @@ beampostraditional =
 
 
 slurnormal = 
-	\property Voice.slurdash = ""
+	\property Voice.slurDash = ""
 
 
 slurdotted = 
-	\property Voice.slurdash = 1
+	\property Voice.slurDash = 1
 
 
 tupletoff = {
diff --git a/ly/spanners.ly b/ly/spanners.ly
new file mode 100644
index 0000000000..bf8cafcee2
--- /dev/null
+++ b/ly/spanners.ly
@@ -0,0 +1,7 @@
+
+
+% 1st arg dynamic (louder/softer). 2nd arg spantype
+cr = \spanrequest \start "crescendo"
+decr = \spanrequest  \start "decrescendo"
+rc = \spanrequest   \stop "crescendo"
+rced = \spanrequest \stop "decrescendo"
diff --git a/ly/textscripts.ly b/ly/textscripts.ly
new file mode 100644
index 0000000000..0a2942cd2a
--- /dev/null
+++ b/ly/textscripts.ly
@@ -0,0 +1,28 @@
+
+%
+% declare the standard dynamic identifiers.
+%
+
+pppppp = \textscript"pppppp" "dynamic"	
+ppppp = \textscript"ppppp" "dynamic"
+pppp = \textscript "pppp" "dynamic"
+ppp = \textscript "ppp" "dynamic"
+pp = \textscript "pp" "dynamic"
+p = \textscript "p" "dynamic"
+mp = \textscript "mp" "dynamic"
+mf = \textscript "mf" "dynamic"
+f = \textscript "e" "dynamic"			% see feta-din layout
+ff = \textscript "ff" "dynamic"
+fff = \textscript "fff" "dynamic"
+ffff = \textscript "ffff" "dynamic"
+fffff = \textscript "fffff" "dynamic"
+ffffff = \textscript "ffffff" "dynamic"
+fp = \textscript "fp" "dynamic"
+sf = \textscript "sf" "dynamic"
+sff = \textscript "sff" "dynamic"
+sfz = \textscript "sfz" "dynamic"
+fz = \textscript "fz" "dynamic"
+sp = \textscript "sp" "dynamic"
+spp = \textscript "spp" "dynamic"
+rfz = \textscript "rfz" "dynamic"
+
diff --git a/mutopia/Coriolan/viola-1.ly b/mutopia/Coriolan/viola-1.ly
index 1ee2457763..6dbd46b2d6 100644
--- a/mutopia/Coriolan/viola-1.ly
+++ b/mutopia/Coriolan/viola-1.ly
@@ -10,7 +10,6 @@ copyright =	 "public domain";
 \version "1.1.52";
 
 viola1 = \notes \relative c {
-	\context Voice=one
 	c'1\ff ~ | c | f,4-. r r2 | r1 |
 	% copied 3 bars from three back...
 	%5
diff --git a/mutopia/Coriolan/viola-2.ly b/mutopia/Coriolan/viola-2.ly
index 4b960a8acd..ebec60e0ed 100644
--- a/mutopia/Coriolan/viola-2.ly
+++ b/mutopia/Coriolan/viola-2.ly
@@ -13,8 +13,9 @@ viola2 = \notes \relative c {
 	% starts on (actualy, most part is on) same staff as viola1
 	%urg, parse error
 %urg	\translator Staff=viola1
+	\context Thread
 	\translator Staff=violai
-	\context Voice=one
+	\translator Voice=one
 	c1 ~ | c | s1*2 |
 	% copied 3 bars from three back...
 	c ~ | c | s1*2 % |
@@ -36,9 +37,10 @@ $viola2_staff = \context Staff = violaii <
 	\property Staff.instrument = "Viola II"
 	\property Staff.instr = "Vla. II"
 	\clef "alto";
-	\notes \context Voice=one< 
+	% notes must go to Staff context: we want to switch Staff translators
+	%\notes \context Voice=one< 
 		\global
 		\$viola2
-	>
+	%>
 >
 
diff --git a/scripts/convert-mudela.py b/scripts/convert-mudela.py
index a36b83edf9..47308fcf54 100644
--- a/scripts/convert-mudela.py
+++ b/scripts/convert-mudela.py
@@ -373,6 +373,18 @@ if 1:
 	conversions.append ((1,1,55), conv,
 			    '\\wheel -> \\coda')
 
+if 1:
+	def conv(lines):
+		newlines =[]
+		for x in lines:
+			x =  re.sub ('keyoctaviation','keyOctaviation', x)
+			x =  re.sub ('slurdash','slurDash', x)
+			newlines.append (x)
+		return newlines
+
+	conversions.append ((1,1,65), conv,
+			    'slurdash -> slurDash, keyoctaviation -> keyOctaviation')
+
 
 ############################
 	
-- 
2.39.5