From: Jan Nieuwenhuizen <janneke@gnu.org>
Date: Mon, 25 Jan 1999 22:50:15 +0000 (+0100)
Subject: patch::: 1.1.24.jcn2: jcn2
X-Git-Tag: release/1.1.25~1
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=3bcb994d1aae1a51345f33a7c0851ce9da7b4ede;p=lilypond.git

patch::: 1.1.24.jcn2: jcn2

pl 24.jcn2
	- website fixes
	- bf's: chords:
  	  * reverted c1*2, collides with \times {}
	  * should use: c\breve, c\longa for long chords
	  * addition: c-9, subtraction: c^5
	  * multiple -add, ^sub: c-7+.9-^3.5
	- bf: lyric chord
	- bf: lookup text height
	- bf's: autobeamer

---
Generated by janneke@gnu.org using package-diff 0.62,
>From = lilypond-1.1.24.jcn1, To = lilypond-1.1.24.jcn2

usage

    cd lilypond-source-dir; patch -E -p1 < lilypond-1.1.24.jcn2.diff

Patches do not contain automatically generated files
or (urg) empty directories,
i.e., you should rerun autoconf, configure
and possibly make outdirs.

--state
1.1.24.jcn1
1.1.24.jcn2
++state
---

diff --git a/NEWS b/NEWS
index b83847bb03..156cc698fb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,20 @@
---- ../lilypond-1.1.24/NEWS	Mon Jan 25 22:38:25 1999
+--- ../lilypond-1.1.24.jcn1/NEWS	Mon Jan 25 17:34:49 1999
+++ b/NEWS	Mon Jan 25 23:43:11 1999
+@@ -1,3 +1,14 @@
+pl 24.jcn2
+	- website fixes
+	- bf's: chords:
+  	  * reverted c1*2, collides with \times {}
+	  * should use: c\breve, c\longa for long chords
+	  * addition: c-9, subtraction: c^5
+	  * multiple -add, ^sub: c-7+.9-^3.5
+	- bf: lyric chord
+	- bf: lookup text height
+	- bf's: autobeamer
+
+ pl 24.jcn1
+ 	- bf: rest collisions
+ 	- separate tfm-reader--- ../lilypond-1.1.24/NEWS	Mon Jan 25 22:38:25 1999
 ++ b/NEWS	Mon Jan 25 22:36:28 1999
 @@ -1,3 +1,6 @@
 pl 24.mb1
diff --git a/VERSION b/VERSION
index ddbb383d79..c35a2b5a0e 100644
--- a/VERSION
+++ b/VERSION
@@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=1
 PATCH_LEVEL=24
-MY_PATCH_LEVEL=mb1
+MY_PATCH_LEVEL=jcn2
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
diff --git a/flower/include/scalar.hh b/flower/include/scalar.hh
index 8f442d9041..f78776709e 100644
--- a/flower/include/scalar.hh
+++ b/flower/include/scalar.hh
@@ -28,6 +28,9 @@ struct Scalar : public String
   operator Real();
   operator int();
   bool to_bool () const;
+  Rational to_rat () const;
+  int to_i () const;
+  Real to_f () const;
 
   /*
     urg, these are bit silly; perhaps should make "Print_string" class
diff --git a/flower/scalar.cc b/flower/scalar.cc
index 7008880ccc..ba7d810b03 100644
--- a/flower/scalar.cc
+++ b/flower/scalar.cc
@@ -18,10 +18,16 @@ Scalar::Scalar (Rational r)
 }
 
 Scalar::operator Rational ()
+{
+  return to_rat ();
+}
+
+Rational
+Scalar::to_rat () const
 {
   int p = index_i ('/');
   if (p == -1)
-    return int (*this);
+    return this->to_i ();
   
   String s2 = right_str (length_i ()-p-1);
   String s1 = left_str (p);
@@ -42,12 +48,24 @@ Scalar::isnum_b () const
 }
 
 Scalar::operator Real()
+{
+  return to_f ();
+}
+
+Real
+Scalar::to_f () const
 {
   assert (isnum_b ());
   return value_f ();
 }
 
-Scalar::operator int()
+Scalar::operator int ()
+{
+  return to_i ();
+}
+
+int
+Scalar::to_i () const
 {
   if (!length_i ())
     return 0;			// ugh
diff --git a/input/test/chord-table.ly b/input/test/chord-table.ly
index 37e0ae9ef6..14c758c52e 100644
--- a/input/test/chord-table.ly
+++ b/input/test/chord-table.ly
@@ -5,9 +5,7 @@ enteredby = 	"jcn";
 }
 
 tab = \notes\transpose c'''\chords{
-	c1 c-m c-4 c-m4 c-5+ c-5- c-m5- c-5-5+ c-6\break %c-m6\break
-	% Han-Wen: try this instead, and Wierd Things (spacing etc) happen:
-%	\notes {<c1 e g>} c1-m c-4 c-m4 c-5+ c-5- c-m5- c-5-5+ c-6  c-m6\break
+	c1 c-m c-4 c-m4 c-5+ c-5- c-m5- c-5.5+ c-6\break %c-m6\break
 }
 
 \score{
diff --git a/input/test/chords.ly b/input/test/chords.ly
index 1133280d3f..973faf1923 100644
--- a/input/test/chords.ly
+++ b/input/test/chords.ly
@@ -13,16 +13,21 @@ Would this be acceptable/good enough/convenient for entry?
    Cmaj7                  c-7+; c-maj
    C7                     c-7
    Csus; Csus4            c-4; c-sus
+
 %}
 
 scales = \notes \transpose c'' \chords{
 		%<c1 e g>
 		c1-m c-min c4-dim c-aug c-sus c-maj
                 c1-6 c4-7 c-9 c-11 c-13
-		c1-7^5 c-13^5^7^9^11
+		c1-7^5 c-13^5.7.9.11
 		% c1-7^5 c-13^5
 		c1 g d a e b fis
                 c1 f bes es as des ges
+		% wierd, multiple -add, ^sub
+		c-7+.9-^3.5
+		% long
+		c\breve c\longa
 	}
 
 keys = \notes{
@@ -43,6 +48,8 @@ keys = \notes{
                 \key as; s1
                 \key des; s1
                 \key ges; s1
+                \key c; s1*2
+                \key c; s1*6
 	}
 
 \score{
diff --git a/input/test/grace.ly b/input/test/grace.ly
index 8419d39a3f..315df05808 100644
--- a/input/test/grace.ly
+++ b/input/test/grace.ly
@@ -1,9 +1,6 @@
 
 \version "1.0.14";
 
-\include "table13.ly";
-\include "table16.ly";
-
 \score{
 	<
 	\type Staff = a \notes\relative c <
@@ -21,8 +18,8 @@
 	>
 	\paper {
 		linewidth = 120.0\mm;
-		-2 = \symboltables { \table_thirteen }	
-		-1 = \symboltables { \table_sixteen }
+		-2 = \font "feta13"
+		-1 = \font "feta16"
 
 	}
 }
diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc
index 78e0848227..23698891e4 100644
--- a/lily/auto-beam-engraver.cc
+++ b/lily/auto-beam-engraver.cc
@@ -27,42 +27,32 @@ Auto_beam_engraver::Auto_beam_engraver ()
   grouping_p_ = 0;
 }
 
-/*
-  should move this to rational, but may reject now
-  */
-Rational
-str2rat (String str)
+void
+Auto_beam_engraver::do_process_requests ()
 {
-  int num;
-  int den = 1;
-  if (int i = str.index_i ('/') != -1)
-    {
-      den = str.cut_str (i + 1, str.length_i ()).value_i ();
-      str = str.left_str (i);
-    }
-  num = str.value_i ();
-  return Rational (num, den);
+  consider_end_and_begin ();
 }
 
 void
-Auto_beam_engraver::do_process_requests ()
+Auto_beam_engraver::consider_end_and_begin ()
 {
   Time_description const *time = get_staff_info().time_C_;
 
   Scalar begin = get_property ("beamAutoBegin", 0);
-  Moment begin_mom = str2rat (begin);
+  Moment begin_mom = begin.to_rat ();
   
   Scalar end = get_property ("beamAutoEnd", 0);
-  Moment end_mom = str2rat (end);
+  Moment end_mom = end.to_rat ();
 
   if (mult_i_)
     {
+      int type = 1 << (mult_i_ + 2);
       Scalar end_mult = get_property (String ("beamAutoEnd")
-				      + to_str (1 << (mult_i_ + 2)), 0);
+				      + to_str (type), 0);
       if (end_mult.length_i ())
-	end_mom = str2rat (end_mult);
-      else if (end_mom / Moment (mult_i_, 1) > Moment (4))
-	end_mom /= Moment (mult_i_);
+	end_mom = end_mult.to_rat ();
+      else if (Moment (type, 4) / end_mom > Moment (4))
+	end_mom /= Moment (type, 8);
     }
 
   Real f;
@@ -240,13 +230,23 @@ Auto_beam_engraver::acknowledge_element (Score_element_info info)
 	}
       else
 	{
+	  int m = (rhythmic_req->duration_.durlog_i_ - 2);
+	  /*
+	    if multiplicity would become greater,
+	    reconsider ending/starting beam first.
+	   */
+	  if (m > mult_i_)
+	    {
+	      mult_i_ = m;
+	      consider_end_and_begin ();
+	    }
+	  mult_i_ = m;
 	  grouping_p_->add_child (start, rhythmic_req->duration ());
 	  stem_l->flag_i_ = rhythmic_req->duration_.durlog_i_;
 	  beam_p_->add_stem (stem_l);
 	  Moment now = now_moment ();
 	  last_add_mom_ = now;
 	  extend_mom_ = extend_mom_ >? now + rhythmic_req->duration ();
-	  mult_i_ = mult_i_ >? (rhythmic_req->duration_.durlog_i_ - 2);
 	}
     }
 }
diff --git a/lily/include/auto-beam-engraver.hh b/lily/include/auto-beam-engraver.hh
index 76d060b148..a2ebc6d4cc 100644
--- a/lily/include/auto-beam-engraver.hh
+++ b/lily/include/auto-beam-engraver.hh
@@ -28,6 +28,7 @@ protected:
 
 private:
   void begin_beam ();
+  void consider_end_and_begin ();
   void end_beam ();
   void junk_beam ();
   void typeset_beam ();
diff --git a/lily/include/lyric-engraver.hh b/lily/include/lyric-engraver.hh
index 99a1aa1462..599474fabb 100644
--- a/lily/include/lyric-engraver.hh
+++ b/lily/include/lyric-engraver.hh
@@ -9,10 +9,26 @@
 
 #ifndef LYRIC_ENGRAVER_HH
 #define LYRIC_ENGRAVER_HH
+
+#include "lily-proto.hh"
 #include "engraver.hh"
 #include "array.hh"
 
-#include "lily-proto.hh"
+class Lyric_engraver : public Engraver 
+{
+protected:
+  virtual void do_pre_move_processing();
+  virtual bool do_try_music (Music*);
+  virtual void do_process_requests();
+
+public:
+  Lyric_engraver ();
+  VIRTUAL_COPY_CONS (Translator);
+
+private:
+  Link_array<Lyric_req> lyric_req_l_arr_;
+  Link_array<Item> text_p_arr_;
+};
 
 
 #endif // LYRIC_ENGRAVER_HH
diff --git a/lily/lookup.cc b/lily/lookup.cc
index da8272b549..53375b93ec 100644
--- a/lily/lookup.cc
+++ b/lily/lookup.cc
@@ -401,7 +401,11 @@ Lookup::text (String style, String text) const
     {
       style = String (cmr_dict [style]) + to_str  ((int)font_h); // ugh
     }
+
   Real w = 0;
+  Real h = 0;
+  Real d = 0;
+
   Font_metric* afm_l = all_fonts_global_p->find_font (style);
   DOUT << "\nChars: ";
   
@@ -414,11 +418,14 @@ Lookup::text (String style, String text) const
 	{
 	  Character_metric *c = afm_l->get_char (text[i],false);
 	  w += c->dimensions()[X_AXIS].length ();
+ 	  h = h >? c->dimensions()[Y_AXIS].max ();
+	  d = d <? c->dimensions()[Y_AXIS].min ();
 	}
     }
 
   DOUT << "\n" << to_str (w) << "\n";
   a.dim_.x () = Interval (0, w);
+  a.dim_.y () = Interval (d, h);
   a.font_ = font_name_;
   return a;
 }
diff --git a/lily/lookup.cc.orig b/lily/lookup.cc.orig
new file mode 100644
index 0000000000..da8272b549
--- /dev/null
+++ b/lily/lookup.cc.orig
@@ -0,0 +1,541 @@
+/*
+  lookup.cc -- implement simple Lookup methods.
+
+  source file of the GNU LilyPond music typesetter
+
+  (c)  1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+  Jan Nieuwenhuizen <janneke@gnu.org>
+
+  TODO
+      Glissando
+*/
+
+#include <ctype.h>
+#include "lookup.hh"
+#include "debug.hh"
+#include "dimensions.hh"
+#include "scalar.hh"
+#include "paper-def.hh"
+#include "string-convert.hh"
+#include "file-path.hh"
+#include "main.hh"
+#include "lily-guile.hh"
+#include "all-fonts.hh"
+#include "afm.hh"
+#include "scope.hh"
+#include "molecule.hh"
+
+SCM
+array_to_list (SCM *a , int l)
+{
+  SCM list = SCM_EOL;
+  for (int i= l; i--;  )
+    {
+      list =  gh_cons (a[i], list);
+    }
+  return list;
+}
+
+
+Lookup::Lookup ()
+{
+  paper_l_ = 0;
+  afm_l_ = 0;  
+}
+
+Lookup::Lookup (Lookup const& s)
+{
+  font_name_ = s.font_name_;
+  paper_l_ = 0;
+  afm_l_ = 0;  
+}
+
+
+
+Molecule
+Lookup::accidental (int j, bool cautionary) const
+{
+  Molecule m(afm_find (String ("accidentals") + String ("-") + to_str (j)));
+  if (cautionary) 
+    {
+      Atom open = afm_find (String ("accidentals") + String ("-("));
+      Atom close = afm_find (String ("accidentals") + String ("-)"));
+      m.add_at_edge(X_AXIS, LEFT, Molecule(open), 0);
+      m.add_at_edge(X_AXIS, RIGHT, Molecule(close), 0);
+    }
+  return m;
+}
+
+
+
+Atom
+Lookup::afm_find (String s, bool warn) const
+{
+  if (!afm_l_)      
+    ((Lookup*)this)->afm_l_ = all_fonts_global_p->find_afm (font_name_);
+  
+  Adobe_font_char_metric m = afm_l_->find_char (s, warn);
+
+  Atom a;
+  if (m.code () < 0)
+    return a;
+    
+  a.dim_ = m.dimensions();
+  
+  a.lambda_ = gh_list (ly_symbol ("char"),
+		       gh_int2scm (m.code ()),
+		       SCM_UNDEFINED);
+  a.font_ = font_name_;
+  return a;
+}
+
+Atom
+Lookup::ball (int j) const
+{
+  if (j > 2)
+    j = 2;
+
+  return afm_find (String ("balls") + String ("-") + to_str (j));
+}
+
+Atom
+Lookup::simple_bar (String type, Real h) const
+{
+  SCM thick = ly_symbol ("barthick_" + type);
+  Real w = 0.1 PT;
+  if (paper_l_->scope_p_->elem_b (thick))
+    {
+      w = paper_l_->get_realvar (thick);
+    }
+  
+  Atom a;
+  a.lambda_ = gh_list (ly_symbol ("filledbox"),
+		       gh_double2scm (0),
+		       gh_double2scm (w),		       
+		       gh_double2scm (h/2),
+		       gh_double2scm (h/2),		       
+		       SCM_UNDEFINED);
+
+  a.dim_[X_AXIS] = Interval(0,w);
+  a.dim_[Y_AXIS] = Interval (-h/2, h/2);
+  return a;
+}
+
+  
+Molecule
+Lookup::bar (String str, Real h) const
+{
+  Real kern = paper_l_->get_var ("bar_kern");
+  Real thinkern = paper_l_->get_var ("bar_thinkern");  
+  Atom thin = simple_bar ("thin", h);
+  Atom thick = simple_bar ("thick", h);
+  Atom colon = afm_find ("dots-repeatcolon");  
+
+  Molecule m;
+
+  if (str == "")
+    {
+      return fill (Box (Interval(0,0),Interval (-h/2, h/2)));
+    }
+  else if (str == "|")
+    {
+      return thin;
+    }
+  else if (str == "|.")
+    {
+      m.add_at_edge (X_AXIS, LEFT, thick, 0);      
+      m.add_at_edge (X_AXIS, LEFT, thin,kern);
+    }
+  else if (str == ".|")
+    {
+      m.add_at_edge (X_AXIS, RIGHT, thick, kern);
+      m.add_at_edge (X_AXIS, RIGHT, thin, 0);
+    }
+  else if (str == ":|")
+    {
+      m.add_at_edge (X_AXIS, LEFT, thick, 0);
+      m.add_at_edge (X_AXIS, LEFT, thin, kern);
+      m.add_at_edge (X_AXIS, LEFT, colon, kern);      
+    }
+  else if (str == "|:")
+    {
+      m.add_at_edge (X_AXIS, RIGHT, thick,0);
+      m.add_at_edge (X_AXIS, RIGHT, thin,kern);
+      m.add_at_edge (X_AXIS, RIGHT, colon,kern);      
+    }
+  else if (str == ":|:")
+    {
+      m.add_at_edge (X_AXIS, LEFT, thick,kern/2);
+      m.add_at_edge (X_AXIS, LEFT, colon,kern);      
+      m.add_at_edge (X_AXIS, RIGHT, thick,kern);
+      m.add_at_edge (X_AXIS, RIGHT, colon,kern);      
+    }
+  else if (str == "||")
+    {
+      m.add_at_edge (X_AXIS, RIGHT, thin,0);
+      m.add_at_edge (X_AXIS, RIGHT, thin,thinkern);      
+    }
+
+  else if (str == ".|.")
+    {
+      m.add_at_edge (X_AXIS, RIGHT, thick, 0);
+      m.add_at_edge (X_AXIS, RIGHT, thick, kern);      
+    }
+
+  return m;
+}
+
+Atom 
+Lookup::beam (Real slope, Real width, Real thick) const
+{
+  Real height = slope * width; 
+  Real min_y = (0 <? height) - thick/2;
+  Real max_y = (0 >? height) + thick/2;
+
+  Atom a;
+  a.lambda_ =   gh_list (ly_symbol ("beam"),
+	   gh_double2scm (width),
+	   gh_double2scm (slope),
+	   gh_double2scm (thick),
+	   SCM_UNDEFINED);
+
+  a.dim_[X_AXIS] = Interval (0, width);
+  a.dim_[Y_AXIS] = Interval (min_y, max_y);
+  return a;
+}
+
+Atom
+Lookup::clef (String st) const
+{
+  return afm_find (String ("clefs") + String ("-") + st);
+}
+
+SCM
+offset2scm (Offset o)
+{
+  return gh_list (gh_double2scm (o[X_AXIS]), gh_double2scm(o[Y_AXIS]),
+		  SCM_UNDEFINED);
+}
+
+Atom
+Lookup::dashed_slur (Array<Offset> controls, Real thick, Real dash) const
+{
+  assert (controls.size () == 8);
+  Offset d = controls[3] - controls[0];
+  
+  Real dx = d[X_AXIS];
+  Real dy = d[Y_AXIS];
+
+  Atom a;
+  a.font_ = font_name_;
+  a.dim_[X_AXIS] = Interval (0, dx);
+  a.dim_[Y_AXIS] = Interval (0 <? dy,  0 >? dy);
+
+  SCM sc[4];
+  for (int i=0; i<  4; i++)
+    {
+      sc[i] =  offset2scm (controls[i]);
+    }
+
+  a.lambda_ = 
+    gh_list (ly_symbol ("dashed-slur"),
+	     gh_double2scm (thick), 
+	     gh_double2scm (dash),
+	     ly_quote_scm (array_to_list (sc, 4)),
+	     SCM_UNDEFINED);
+
+  return a;
+}
+
+Atom
+Lookup::dots () const
+{
+  return afm_find (String ("dots") + String ("-") + String ("dot"));
+}
+
+
+Atom
+Lookup::extender (Real width) const
+{
+  Atom a;
+  a.lambda_ = gh_list (ly_symbol ("extender"),
+		       gh_double2scm (width),
+		       SCM_UNDEFINED);
+
+  a.dim_[X_AXIS] = Interval (0, width);
+  a.dim_[Y_AXIS] = Interval (0,0);
+  
+  a.font_ = font_name_;
+  return a;
+}
+
+Atom
+Lookup::fill (Box b) const
+{
+  Atom a;
+  a.dim_ = b;
+  return a;
+}
+
+Atom
+Lookup::flag (int j, Direction d) const
+{
+  char c = (d == UP) ? 'u' : 'd';
+  Atom a = afm_find (String ("flags") + String ("-") + to_str (c) + to_str (j));
+  return a;
+}
+
+Atom
+Lookup::rest (int j, bool o) const
+{
+   return afm_find (String ("rests")
+		    + String ("-") + to_str (j) + (o ? "o" : ""));
+}
+
+Atom
+Lookup::rule_symbol (Real height, Real width) const
+{
+  Atom a;
+  a.lambda_ = gh_list (ly_symbol ("rulesym"),
+		       gh_double2scm (height),
+		       gh_double2scm (width),
+		       SCM_UNDEFINED);
+  a.dim_.x () = Interval (0, width);
+  a.dim_.y () = Interval (0, height);
+  return a;
+}
+
+Atom
+Lookup::script (String str) const
+{
+  return afm_find (String ("scripts") + String ("-") + str);
+}
+
+Atom
+Lookup::special_time_signature (String s, Array<int> arr) const
+{
+  // First guess: s contains only the signature style
+  assert (arr.size () >1);
+  String symbolname = "timesig-" + s + to_str (arr[0]) + "/" + to_str (arr[1]);
+  
+  Atom a = afm_find (symbolname, false);
+  if (!a.empty ()) 
+    return a;
+
+  // Second guess: s contains the full signature name
+  a = afm_find ("timesig-"+s, false);
+  if (!a.empty ()) 
+    return a;
+
+  // Resort to default layout with numbers
+  return time_signature (arr);
+}
+
+Atom
+Lookup::stem (Real y1, Real y2) const
+{
+  if (y1 > y2)
+    {
+      Real t = y1;
+      y1 = y2;
+      y2 = t;
+    }
+  Atom a;
+
+  a.dim_.x () = Interval (0,0);
+  a.dim_.y () = Interval (y1,y2);
+
+  Real stem_width = paper_l_->get_var ("stemthickness");
+
+  a.lambda_ = gh_list (ly_symbol ("filledbox"),
+		       gh_double2scm(stem_width /2),
+		       gh_double2scm(stem_width/2),
+		       gh_double2scm(y2),
+		       gh_double2scm(-y1),
+		       SCM_UNDEFINED);
+
+  a.font_ = font_name_;
+  return a;
+}
+
+Atom
+Lookup::streepje (int type) const
+{
+  if (type > 2)
+    type = 2;
+
+  return  afm_find ("balls" + String ("-") +to_str (type) + "l");
+}
+
+static Dict_initialiser<char const*> cmr_init[] = {
+  {"bold", "cmbx"},
+  {"dynamic", "feta-din"},
+  {"finger", "feta-nummer"},
+  {"italic", "cmti"},
+  {"roman", "cmr"},
+  {"large", "cmbx"},
+  {"Large", "cmbx"},
+  {"mark", "feta-nummer"},
+  {"nummer", "feta-nummer"},
+  {0,0}
+};
+
+static Dictionary<char const *> cmr_dict (cmr_init);
+
+Atom
+Lookup::text (String style, String text) const
+{
+  Atom a;
+  a.lambda_ = gh_list(ly_symbol ("set" + style),
+		      gh_str02scm (text.ch_C()),
+		      SCM_UNDEFINED);
+
+  Real font_h = paper_l_->get_var ("font_normal");
+  if (paper_l_->scope_p_->elem_b ("font_" + style))
+    {
+      font_h = paper_l_->get_var ("font_" + style);
+    }
+  
+  if (cmr_dict.elem_b (style))
+    {
+      style = String (cmr_dict [style]) + to_str  ((int)font_h); // ugh
+    }
+  Real w = 0;
+  Font_metric* afm_l = all_fonts_global_p->find_font (style);
+  DOUT << "\nChars: ";
+  
+  for (int i = 0; i < text.length_i (); i++) 
+    {
+      if (text[i]=='\\')
+	for (i++; (i < text.length_i ()) && isalpha(text[i]); i++)
+	  ;
+      else
+	{
+	  Character_metric *c = afm_l->get_char (text[i],false);
+	  w += c->dimensions()[X_AXIS].length ();
+	}
+    }
+
+  DOUT << "\n" << to_str (w) << "\n";
+  a.dim_.x () = Interval (0, w);
+  a.font_ = font_name_;
+  return a;
+}
+  
+
+/*
+  TODO: should return a molecule with 2 stacked nums.
+ */
+Atom
+Lookup::time_signature (Array<int> a) const
+{
+  Atom s;
+  s.lambda_ = gh_list (ly_symbol ("generalmeter"),
+		       gh_int2scm (a[0]),
+		       gh_int2scm (a[1]),
+		       SCM_UNDEFINED);
+
+  Real r = paper_l_->interline_f () ;
+  s.dim_[Y_AXIS] =  Interval (-2*r, 2*r);
+  s.dim_[X_AXIS] = Interval (0, 2*r);
+  return s;
+}
+
+Atom
+Lookup::vbrace (Real &y) const
+{
+  Atom a;
+  a.lambda_ = gh_list (ly_symbol ("pianobrace"),
+		       gh_double2scm (y),
+		       SCM_UNDEFINED
+		       );
+  a.dim_[Y_AXIS] = Interval (-y/2,y/2);
+  a.dim_[X_AXIS] = Interval (0,0);
+  a.font_ = font_name_;
+  return a;
+}
+
+Atom
+Lookup::hairpin (Real width, bool decresc, bool continued) const
+{
+  Atom a;  
+  Real height = paper_l_->staffheight_f () / 6;
+
+  String hairpin = String (decresc ? "de" : "") + "crescendo";
+  a.lambda_ = gh_list (ly_symbol (hairpin),
+		       gh_double2scm (width),
+		       gh_double2scm (height),
+		       gh_double2scm (continued ? height/2 : 0.0),
+		       SCM_UNDEFINED);
+  a.dim_.x () = Interval (0, width);
+  a.dim_.y () = Interval (-2*height, 2*height);
+  a.font_ = font_name_;
+  return a;
+}
+
+Atom
+Lookup::plet (Real dy , Real dx, Direction dir) const
+{
+  Atom a;
+  a.lambda_ = gh_list(ly_symbol ("tuplet"),
+		      gh_double2scm (dx),
+		      gh_double2scm (dy),
+		      gh_int2scm (dir), SCM_UNDEFINED);
+  return a;
+}
+
+
+Atom
+Lookup::slur (Array<Offset> controls) const
+{
+  assert (controls.size () == 8);
+  Real dx = controls[3].x () - controls[0].x ();
+  Real dy = controls[3].y () - controls[0].y ();
+  Atom a;
+
+  SCM scontrols [8];
+  int indices[] = {5,6,7,4,1,2,3,0};
+
+  for (int i= 0; i < 8; i++)
+    scontrols[i] = offset2scm (controls[indices[i]]);
+
+
+  a.lambda_ =gh_list (ly_symbol ("slur"),
+		      ly_quote_scm (array_to_list (scontrols, 8)),
+		      SCM_UNDEFINED);
+
+  a.dim_[X_AXIS] = Interval (0, dx);
+  a.dim_[Y_AXIS] = Interval (0 <? dy,  0 >? dy);
+  a.font_ = font_name_;
+  return a;
+}
+
+Atom
+Lookup::vbracket (Real &y) const
+{
+  Atom a;
+  a.lambda_ =  gh_list (ly_symbol ("bracket"),
+			gh_double2scm (y),
+			SCM_UNDEFINED);
+  a.dim_[Y_AXIS] = Interval (-y/2,y/2);
+  a.dim_[X_AXIS] = Interval (0,4 PT);
+  return a;
+}
+
+Atom
+Lookup::volta (Real w, bool last_b) const
+{
+  Atom a;
+  a.lambda_ = gh_list (ly_symbol ("volta"),
+		       gh_double2scm (w),
+		       gh_int2scm (last_b),
+		       SCM_UNDEFINED);
+
+  Real interline_f = paper_l_->interline_f ();
+
+  a.dim_[Y_AXIS] = Interval (-interline_f, interline_f);
+  a.dim_[X_AXIS] = Interval (0, w);
+  return a;
+}
+
diff --git a/lily/lyric-engraver.cc b/lily/lyric-engraver.cc
index b2942c91fc..84c5fc87f7 100644
--- a/lily/lyric-engraver.cc
+++ b/lily/lyric-engraver.cc
@@ -7,32 +7,13 @@
   Jan Nieuwenhuizen <janneke@gnu.org>
 */
 
+#include "lyric-engraver.hh"
 #include "musical-request.hh"
-#include "main.hh"
-#include "dimensions.hh"
 #include "g-text-item.hh"
-#include "engraver.hh"
-#include "array.hh"
-#include "lily-proto.hh"
+#include "paper-def.hh"
+#include "lookup.hh"
 
-class Lyric_engraver : public Engraver 
-{
-protected:
-  virtual void do_pre_move_processing();
-  virtual bool do_try_music (Music*);
-  virtual void do_process_requests();
-
-public:
-  Lyric_engraver();
-  VIRTUAL_COPY_CONS(Translator);
-
-private:
-  Link_array<Lyric_req> lyric_req_l_arr_;
-  Link_array<Item> text_p_arr_;
-};
-
-
-ADD_THIS_TRANSLATOR(Lyric_engraver);
+ADD_THIS_TRANSLATOR (Lyric_engraver);
 
 
 Lyric_engraver::Lyric_engraver()
@@ -65,8 +46,13 @@ Lyric_engraver::do_process_requests()
       Scalar style = get_property ("textstyle", 0);
       if (style.length_i ())
 	item_p->style_str_ = style;
-      // urg, when/how can one get the height of this thing?
-      item_p->translate (Offset (0, - i * 12 PT));
+      if (i)
+	{
+	  Real dy = paper ()->lookup_l (0)-> text
+	    (item_p->style_str_, String ("Cg")).dim_. y ().length ();
+	  dy *= 1.1;
+	  item_p->translate_axis (-i * dy, Y_AXIS);
+	}
       
       text_p_arr_.push (item_p);
       announce_element (Score_element_info (item_p, request_l));
diff --git a/lily/parser.yy b/lily/parser.yy
index 50e13b4fa3..e8f216ea50 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -240,7 +240,7 @@ yylex (YYSTYPE *s,  void * v_l)
 %type <notereq>	steno_notepitch
 %type <pitch_arr>	pitch_list
 %type <music>	chord notemode_chord
-%type <pitch_arr>	chord_additions chord_subtractions
+%type <pitch_arr>	chord_additions chord_subtractions chord_notes
 %type <pitch>	chord_addsub chord_note chord_inversion notemode_chord_inversion
 %type <midi>	midi_block midi_body
 %type <duration>	duration_length
@@ -1389,12 +1389,12 @@ simple_element:
 	;
 
 chord:
-	steno_tonic_pitch duration_length chord_additions chord_subtractions chord_inversion {
+	steno_tonic_pitch notemode_duration chord_additions chord_subtractions chord_inversion {
                 $$ = THIS->get_chord (*$1, $3, $4, $5, *$2);
         };
 
 notemode_chord:
-	steno_musical_pitch duration_length chord_additions chord_subtractions notemode_chord_inversion {
+	steno_musical_pitch notemode_duration chord_additions chord_subtractions notemode_chord_inversion {
                 $$ = THIS->get_chord (*$1, $3, $4, $5, *$2);
         };
 
@@ -1402,9 +1402,18 @@ chord_additions:
 	{
 		$$ = new Array<Musical_pitch>;
 	} 
-	| chord_additions '-' chord_addsub {
+	| '-' chord_notes {
+		$$ = $2;
+	}
+	;
+
+chord_notes:
+	{
+		$$ = new Array<Musical_pitch>;
+	}
+	| chord_notes chord_addsub {
 		$$ = $1;
-		$$->push (*$3);
+		$$->push (*$2);
 	}
 	;
 
@@ -1452,13 +1461,12 @@ chord_note:
 	}
         ;
 
-chord_subtractions:
+chord_subtractions: 
 	{
 		$$ = new Array<Musical_pitch>;
-	}
-	| chord_subtractions '^' chord_addsub {
-		$$ = $1;
-		$$->push (*$3);
+	} 
+	| '^' chord_notes {
+		$$ = $2;
 	}
 	;
 
diff --git a/lily/text-def.cc b/lily/text-def.cc
index ecff7e8479..b55d3cb743 100644
--- a/lily/text-def.cc
+++ b/lily/text-def.cc
@@ -65,10 +65,6 @@ Text_def::get_atom (Paper_def *p, Direction) const
   Atom a= p->lookup_l(0)->text (style_str_, text_str_);
 
   a.translate_axis (-(align_dir_ + 1)* guess_width_f (a) / 2, X_AXIS);
-  // urg 1/1 is too much; see input/test/vertical-text.ly
-//  a.translate_axis (a.dim_.y ().length () * 9 / 10, Y_AXIS);
-  // fine for one lyric, urg for lyric chord
-  a.translate_axis (a.dim_.y ().length () * 2 / 5, Y_AXIS);
   
   return a;
 }
diff --git a/mutopia/D.Scarlatti/sonata-k3-l378.ly b/mutopia/D.Scarlatti/sonata-k3-l378.ly
index 0ff9b9ee04..8dec651b9c 100644
--- a/mutopia/D.Scarlatti/sonata-k3-l378.ly
+++ b/mutopia/D.Scarlatti/sonata-k3-l378.ly
@@ -1,6 +1,6 @@
  \header {
  composer =  "Domenico Scarlatti";
- title="Sonata K.3"
+ title="Sonata K.3";
  opus="L.378";
  movement="Presto";
  copyright = "General Public License";